diff --git a/tools/test-js-with-node b/tools/test-js-with-node index 24e288dd06..b2df22c002 100755 --- a/tools/test-js-with-node +++ b/tools/test-js-with-node @@ -290,7 +290,7 @@ EXEMPT_FILES = make_set( "web/src/zcommand.ts", "web/src/zform.js", "web/src/zulip.js", - "web/src/zulip_test.js", + "web/src/zulip_test.ts", "web/tests/lib/mdiff.js", "web/tests/lib/real_jquery.js", "web/tests/lib/zjquery_element.js", diff --git a/web/e2e-tests/compose.test.ts b/web/e2e-tests/compose.test.ts index 3c3e6c3381..81d5ae3861 100644 --- a/web/e2e-tests/compose.test.ts +++ b/web/e2e-tests/compose.test.ts @@ -78,10 +78,9 @@ async function test_reply_by_click_prepopulates_private_message_recipient( assert.ok(private_message !== null); await private_message.click(); await page.waitForSelector("#private_message_recipient", {visible: true}); - await common.pm_recipient.expect( - page, - await common.get_internal_email_from_name(page, "cordelia"), - ); + const email = await common.get_internal_email_from_name(page, "cordelia"); + assert(email !== undefined); + await common.pm_recipient.expect(page, email); await close_compose_box(page); } diff --git a/web/e2e-tests/lib/common.ts b/web/e2e-tests/lib/common.ts index bf0fc59178..a3a04bfc72 100644 --- a/web/e2e-tests/lib/common.ts +++ b/web/e2e-tests/lib/common.ts @@ -26,7 +26,7 @@ export const is_firefox = process.env.PUPPETEER_PRODUCT === "firefox"; let realm_url = "http://zulip.zulipdev.com:9981/"; const gps = new StackTraceGPS({ajax: async (url) => (await fetch(url)).text()}); -let last_current_msg_list_id: number | null = null; +let last_current_msg_list_id: number | undefined; export const pm_recipient = { async set(page: Page, recipient: string): Promise { @@ -231,27 +231,30 @@ export function has_class_x(class_name: string): string { return `contains(concat(" ", @class, " "), " ${class_name} ")`; } -export async function get_stream_id(page: Page, stream_name: string): Promise { +export async function get_stream_id(page: Page, stream_name: string): Promise { return await page.evaluate( (stream_name: string) => zulip_test.get_stream_id(stream_name), stream_name, ); } -export async function get_user_id_from_name(page: Page, name: string): Promise { +export async function get_user_id_from_name(page: Page, name: string): Promise { if (fullname[name] !== undefined) { name = fullname[name]; } return await page.evaluate((name: string) => zulip_test.get_user_id_from_name(name), name); } -export async function get_internal_email_from_name(page: Page, name: string): Promise { +export async function get_internal_email_from_name( + page: Page, + name: string, +): Promise { if (fullname[name] !== undefined) { name = fullname[name]; } return await page.evaluate((fullname: string) => { const user_id = zulip_test.get_user_id_from_name(fullname); - return zulip_test.get_person_by_user_id(user_id).email; + return user_id === undefined ? undefined : zulip_test.get_person_by_user_id(user_id).email; }, name); } @@ -359,7 +362,7 @@ export async function wait_for_fully_processed_message(page: Page, content: stri - does it look to have been re-rendered based on server info? */ - const last_msg = zulip_test.current_msg_list.last(); + const last_msg = zulip_test.current_msg_list?.last(); if (last_msg === undefined) { return false; } @@ -463,7 +466,9 @@ export async function send_message( } // Close the compose box after sending the message. - await page.evaluate(() => zulip_test.cancel_compose()); + await page.evaluate(() => { + zulip_test.cancel_compose(); + }); // Make sure the compose box is closed. await page.waitForSelector("#compose-textarea", {hidden: true}); } @@ -731,12 +736,18 @@ export async function get_current_msg_list_id( // NOTE: This only checks if the current message list id changed from the last call to this function, // so, make sure to have a call to this function before changing to the narrow that you want to check. await page.waitForFunction( - (last_current_msg_list_id) => - zulip_test.current_msg_list.id !== last_current_msg_list_id, + (last_current_msg_list_id) => { + const current_msg_list = zulip_test.current_msg_list; + return ( + current_msg_list !== undefined && + current_msg_list.id !== last_current_msg_list_id + ); + }, {}, last_current_msg_list_id, ); } - last_current_msg_list_id = await page.evaluate(() => zulip_test.current_msg_list.id); - return last_current_msg_list_id!; + last_current_msg_list_id = await page.evaluate(() => zulip_test.current_msg_list?.id); + assert(last_current_msg_list_id !== undefined); + return last_current_msg_list_id; } diff --git a/web/e2e-tests/mention.test.ts b/web/e2e-tests/mention.test.ts index 0fa6ff33c9..4f680d43dc 100644 --- a/web/e2e-tests/mention.test.ts +++ b/web/e2e-tests/mention.test.ts @@ -20,7 +20,7 @@ async function test_mention(page: Page): Promise { console.log("Checking for all everyone warning"); const stream_size = await page.evaluate(() => - zulip_test.get_subscriber_count(zulip_test.get_sub("Verona").stream_id), + zulip_test.get_subscriber_count(zulip_test.get_sub("Verona")!.stream_id), ); const threshold = await page.evaluate(() => { zulip_test.set_wildcard_mention_threshold(5); diff --git a/web/e2e-tests/message-basics.test.ts b/web/e2e-tests/message-basics.test.ts index 674a92c01f..8e19a06503 100644 --- a/web/e2e-tests/message-basics.test.ts +++ b/web/e2e-tests/message-basics.test.ts @@ -6,6 +6,7 @@ import * as common from "./lib/common"; async function get_stream_li(page: Page, stream_name: string): Promise { const stream_id = await common.get_stream_id(page, stream_name); + assert(stream_id !== undefined); return `#stream_filters [data-stream-id="${CSS.escape(stream_id.toString())}"]`; } diff --git a/web/e2e-tests/navigation.test.ts b/web/e2e-tests/navigation.test.ts index ae5208d36e..e4300198f6 100644 --- a/web/e2e-tests/navigation.test.ts +++ b/web/e2e-tests/navigation.test.ts @@ -64,12 +64,15 @@ async function navigate_to_private_messages(page: Page): Promise { } async function test_reload_hash(page: Page): Promise { - const initial_page_load_time = await page.evaluate((): number => zulip_test.page_load_time); + const initial_page_load_time = await page.evaluate(() => zulip_test.page_load_time); + assert(initial_page_load_time !== undefined); console.log(`initial load time: ${initial_page_load_time}`); const initial_hash = await page.evaluate(() => window.location.hash); - await page.evaluate(() => zulip_test.initiate_reload({immediate: true})); + await page.evaluate(() => { + zulip_test.initiate_reload({immediate: true}); + }); await page.waitForNavigation(); const message_list_id = await common.get_current_msg_list_id(page, true); await page.waitForSelector(`.message-list[data-message-list-id='${message_list_id}']`, { @@ -77,6 +80,7 @@ async function test_reload_hash(page: Page): Promise { }); const page_load_time = await page.evaluate(() => zulip_test.page_load_time); + assert(page_load_time !== undefined); assert.ok(page_load_time > initial_page_load_time, "Page not reloaded."); const hash = await page.evaluate(() => window.location.hash); @@ -88,7 +92,7 @@ async function navigation_tests(page: Page): Promise { await navigate_to_settings(page); - const verona_id = await page.evaluate((): number => zulip_test.get_stream_id("Verona")); + const verona_id = await page.evaluate(() => zulip_test.get_stream_id("Verona")); const verona_narrow = `narrow/stream/${verona_id}-Verona`; await navigate_using_left_sidebar(page, verona_narrow); diff --git a/web/e2e-tests/stream_create.test.ts b/web/e2e-tests/stream_create.test.ts index d8f835d489..c7624eff90 100644 --- a/web/e2e-tests/stream_create.test.ts +++ b/web/e2e-tests/stream_create.test.ts @@ -22,7 +22,9 @@ async function await_user_hidden(page: Page, name: string): Promise { async function add_user_to_stream(page: Page, name: string): Promise { const user_id = await common.get_user_id_from_name(page, name); - await page.evaluate((user_id) => zulip_test.add_user_id_to_new_stream(user_id), user_id); + await page.evaluate((user_id) => { + zulip_test.add_user_id_to_new_stream(user_id); + }, user_id); await await_user_visible(page, name); } diff --git a/web/e2e-tests/user-deactivation.test.ts b/web/e2e-tests/user-deactivation.test.ts index 9ef4fabf0d..968940765a 100644 --- a/web/e2e-tests/user-deactivation.test.ts +++ b/web/e2e-tests/user-deactivation.test.ts @@ -19,6 +19,7 @@ async function navigate_to_user_list(page: Page): Promise { async function user_row(page: Page, name: string): Promise { const user_id = await common.get_user_id_from_name(page, name); + assert(user_id !== undefined); return `.user_row[data-user-id="${CSS.escape(user_id.toString())}"]`; } diff --git a/web/src/global.ts b/web/src/global.ts index 4ac48be0a3..796d4bf5f1 100644 --- a/web/src/global.ts +++ b/web/src/global.ts @@ -1,11 +1,6 @@ -// These declarations tell the TypeScript compiler about the existence -// of the global variables for our untyped JavaScript modules. Please -// remove each declaration when the corresponding module is migrated -// to TS. - /// -export {}; +import type * as zulip_test_module from "./zulip_test"; type JQueryCaretRange = { start: number; @@ -23,7 +18,7 @@ type JQueryIdleOptions = Partial<{ }>; declare global { - let zulip_test: any; // eslint-disable-line @typescript-eslint/no-explicit-any + const zulip_test: typeof zulip_test_module; // eslint-disable-next-line @typescript-eslint/no-namespace namespace JQueryValidation { diff --git a/web/src/message_lists.ts b/web/src/message_lists.ts index 95830a0747..5b9400f2e0 100644 --- a/web/src/message_lists.ts +++ b/web/src/message_lists.ts @@ -48,6 +48,7 @@ export type MessageList = { messages: Message[], append_opts: {messages_are_new: boolean}, ) => RenderInfo | undefined; + last: () => Message | undefined; }; export let current: MessageList | undefined; diff --git a/web/src/message_store.ts b/web/src/message_store.ts index 62d54433c6..3f0e092c51 100644 --- a/web/src/message_store.ts +++ b/web/src/message_store.ts @@ -115,6 +115,7 @@ export type Message = ( clean_reactions: Map; locally_echoed?: boolean; + raw_content?: string; // Added in `message_helper.process_new_message`. sent_by_me: boolean; diff --git a/web/src/zulip_test.js b/web/src/zulip_test.ts similarity index 88% rename from web/src/zulip_test.js rename to web/src/zulip_test.ts index e3ea7e75e3..d642a7128c 100644 --- a/web/src/zulip_test.js +++ b/web/src/zulip_test.ts @@ -10,7 +10,9 @@ export {get_by_user_id as get_person_by_user_id, get_user_id_from_name} from "./ export {last_visible as last_visible_row, id as row_id} from "./rows"; export {cancel as cancel_compose} from "./compose_actions"; export {page_params, page_params_parse_time} from "./base_page_params"; +// @ts-expect-error We haven't converted reload.js yet export {initiate as initiate_reload} from "./reload"; export {page_load_time} from "./setup"; export {current_user, realm} from "./state_data"; +// @ts-expect-error We haven't converted stream_create_subscribers.js yet export {add_user_id_to_new_stream} from "./stream_create_subscribers";