e2e-tests: Remove unchecked casts of DOM objects.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2023-10-24 17:19:36 -07:00
committed by Tim Abbott
parent af8465b7fd
commit da80661592
7 changed files with 49 additions and 57 deletions

View File

@@ -1,6 +1,6 @@
import {strict as assert} from "assert";
import type {ElementHandle, Page} from "puppeteer";
import type {Page} from "puppeteer";
import * as common from "./lib/common";
@@ -156,11 +156,9 @@ async function test_organization_permissions(page: Page): Promise<void> {
async function test_add_emoji(page: Page): Promise<void> {
await common.fill_form(page, "#add-custom-emoji-form", {name: "zulip logo"});
const emoji_upload_handle = await page.$("#emoji_file_input");
const emoji_upload_handle = await page.$("input#emoji_file_input");
assert.ok(emoji_upload_handle);
await (emoji_upload_handle as ElementHandle<HTMLInputElement>).uploadFile(
"static/images/logo/zulip-icon-128x128.png",
);
await emoji_upload_handle.uploadFile("static/images/logo/zulip-icon-128x128.png");
await page.click("#add-custom-emoji-modal .dialog_submit_button");
await common.wait_for_micromodal_to_close(page);
@@ -194,11 +192,9 @@ async function test_custom_realm_emoji(page: Page): Promise<void> {
}
async function test_upload_realm_icon_image(page: Page): Promise<void> {
const upload_handle = await page.$("#realm-icon-upload-widget .image_file_input");
const upload_handle = await page.$("#realm-icon-upload-widget input.image_file_input");
assert.ok(upload_handle);
await (upload_handle as ElementHandle<HTMLInputElement>).uploadFile(
"static/images/logo/zulip-icon-128x128.png",
);
await upload_handle.uploadFile("static/images/logo/zulip-icon-128x128.png");
await page.waitForSelector("#realm-icon-upload-widget .upload-spinner-background", {
visible: true,

View File

@@ -37,7 +37,7 @@ async function copy_messages(
ctrlKey: true,
keyCode: 67,
which: 67,
} as KeyboardEventInit),
}),
);
// find temp div with copied text

View File

@@ -140,13 +140,12 @@ export async function fill_form(
return (await page.$(`select[name="${CSS.escape(name)}"]`)) !== null;
}
for (const name of Object.keys(params)) {
const name_selector = `${form_selector} [name="${name}"]`;
const value = params[name];
if (typeof value === "boolean") {
await page.$eval(
name_selector,
`${form_selector} input[name="${CSS.escape(name)}"]`,
(el, value) => {
if (el instanceof HTMLInputElement && el.checked !== value) {
if (el.checked !== value) {
el.click();
}
},
@@ -156,13 +155,9 @@ export async function fill_form(
if (typeof value !== "string") {
throw new TypeError(`Expected string for ${name}`);
}
await page.select(name_selector, value);
await page.select(`${form_selector} select[name="${CSS.escape(name)}"]`, value);
} else {
// clear any existing text in the input field before filling.
await page.$eval(name_selector, (el) => {
(el as HTMLInputElement).value = "";
});
await page.type(name_selector, value);
await clear_and_type(page, `${form_selector} [name="${CSS.escape(name)}"`, value);
}
}
}
@@ -173,17 +168,24 @@ export async function check_form_contents(
params: Record<string, boolean | string>,
): Promise<void> {
for (const name of Object.keys(params)) {
const name_selector = `${form_selector} [name="${name}"]`;
const expected_value = params[name];
if (typeof expected_value === "boolean") {
assert.equal(
await page.$eval(name_selector, (el) => (el as HTMLInputElement).checked),
await page.$eval(
`${form_selector} input[name="${CSS.escape(name)}"]`,
(el) => el.checked,
),
expected_value,
"Form content is not as expected.",
);
} else {
assert.equal(
await page.$eval(name_selector, (el) => (el as HTMLInputElement).value),
await page.$eval(`${form_selector} [name="${CSS.escape(name)}"]`, (el) => {
if (!(el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement)) {
throw new TypeError("Expected <input> or <textarea>");
}
return el.value;
}),
expected_value,
"Form content is not as expected.",
);
@@ -266,8 +268,8 @@ export async function log_in(
username: credentials.username,
password: credentials.password,
};
await fill_form(page, "#login_form", params);
await page.$eval("#login_form", (form) => (form as HTMLFormElement).submit());
await fill_form(page, "form#login_form", params);
await page.$eval("form#login_form", (form) => form.submit());
await page.waitForSelector("#recent_view_filter_buttons", {visible: true});
}
@@ -295,8 +297,8 @@ export function set_realm_url(new_realm_url: string): void {
export async function ensure_enter_does_not_send(page: Page): Promise<void> {
// NOTE: Caller should ensure that the compose box is already open.
const enter_sends = await page.$eval(
".enter_sends_true",
(el) => (el as HTMLElement).style.display !== "none",
"span.enter_sends_true",
(el) => el.style.display !== "none",
);
if (enter_sends) {
@@ -311,13 +313,12 @@ export async function assert_compose_box_content(
page: Page,
expected_value: string,
): Promise<void> {
const compose_box_element = await page.waitForSelector("#compose-textarea");
const compose_box_content = await page.evaluate((element) => {
if (!(element instanceof HTMLTextAreaElement)) {
throw new TypeError("expected HTMLTextAreaElement");
}
return element.value;
}, compose_box_element);
const compose_box_element = await page.waitForSelector("textarea#compose-textarea");
assert(compose_box_element !== null);
const compose_box_content = await page.evaluate(
(element) => element.value,
compose_box_element,
);
assert.equal(
compose_box_content,
expected_value,

View File

@@ -15,11 +15,11 @@ async function realm_creation_tests(page: Page): Promise<void> {
await page.waitForSelector("#email");
await page.type("#email", email);
await page.type("#id_team_name", organization_name);
await page.$eval("#realm_in_root_domain", (el) => (el as HTMLInputElement).click());
await page.$eval("input#realm_in_root_domain", (el) => el.click());
await Promise.all([
page.waitForNavigation(),
page.$eval("#create_realm", (form) => (form as HTMLFormElement).submit()),
page.$eval("form#create_realm", (form) => form.submit()),
]);
// Make sure confirmation email is sent.
@@ -59,7 +59,7 @@ async function realm_creation_tests(page: Page): Promise<void> {
// For some reason, page.click() does not work this for particular checkbox
// so use page.$eval here to call the .click method in the browser.
await common.fill_form(page, "#registration", params);
await page.$eval("#registration", (form) => (form as HTMLFormElement).submit());
await page.$eval("form#registration", (form) => form.submit());
// Check if realm is created and user is logged in by checking if
// element of id `lightbox_overlay` exists.

View File

@@ -20,7 +20,7 @@ async function _add_playground_and_return_status(page: Page, payload: Playground
await common.fill_form(page, "form.admin-playground-form", payload);
// Not sure why, but page.click() doesn't seem to always click the submit button.
// So we resort to using eval with the button ID instead.
await page.$eval("#submit_playground_button", (el) => (el as HTMLInputElement).click());
await page.$eval("button#submit_playground_button", (el) => el.click());
// We return the success/failure status message back to the caller.
await page.waitForSelector(admin_playground_status_selector, {visible: true});

View File

@@ -1,6 +1,6 @@
import {strict as assert} from "assert";
import type {ElementHandle, Page} from "puppeteer";
import type {Page} from "puppeteer";
import {test_credentials} from "../../var/puppeteer/test_credentials";
@@ -13,8 +13,8 @@ const zuliprc_regex =
/^data:application\/octet-stream;charset=utf-8,\[api]\nemail=.+\nkey=.+\nsite=.+\n$/;
async function get_decoded_url_in_selector(page: Page, selector: string): Promise<string> {
const a = (await page.$(selector)) as ElementHandle<HTMLAnchorElement>;
return decodeURIComponent(await (await a.getProperty("href")).jsonValue());
const a = await page.$(`a:is(${selector})`);
return decodeURIComponent(await (await a!.getProperty("href")).jsonValue());
}
async function open_settings(page: Page): Promise<void> {
@@ -198,9 +198,8 @@ async function test_edit_bot_form(page: Page): Promise<void> {
const edit_form_selector = `#bot-edit-form[data-email="${CSS.escape(bot1_email)}"]`;
await page.waitForSelector(edit_form_selector, {visible: true});
const name_field_selector = edit_form_selector + " [name=full_name]";
assert.equal(
await page.$eval(name_field_selector, (el) => (el as HTMLInputElement).value),
await page.$eval(`${edit_form_selector} input[name=full_name]`, (el) => el.value),
"Bot 1",
);
@@ -233,9 +232,8 @@ async function test_invalid_edit_bot_form(page: Page): Promise<void> {
const edit_form_selector = `#bot-edit-form[data-email="${CSS.escape(bot1_email)}"]`;
await page.waitForSelector(edit_form_selector, {visible: true});
const name_field_selector = edit_form_selector + " [name=full_name]";
assert.equal(
await page.$eval(name_field_selector, (el) => (el as HTMLInputElement).value),
await page.$eval(`${edit_form_selector} input[name=full_name]`, (el) => el.value),
"Bot one",
);

View File

@@ -3,21 +3,18 @@ import type {Page} from "puppeteer";
import * as common from "./lib/common";
async function open_set_user_status_modal(page: Page): Promise<void> {
const menu_icon_selector = ".user_sidebar_entry:first-child .user-list-sidebar-menu-icon";
// We are clicking on the menu icon with the help of `waitForFunction` because the list
// re-renders many times and can cause the element to become stale.
await page.waitForFunction(
(selector: string): boolean => {
const menu_icon = document.querySelector(selector);
if (menu_icon) {
(menu_icon as HTMLSpanElement).click();
return true;
}
return false;
},
{},
menu_icon_selector,
);
await page.waitForFunction((): boolean => {
const menu_icon = document.querySelector<HTMLSpanElement>(
".user_sidebar_entry:first-child span.user-list-sidebar-menu-icon",
);
if (menu_icon) {
menu_icon.click();
return true;
}
return false;
});
await page.waitForSelector(".user_popover_email", {visible: true});
// We are using evaluate to click because it is very hard to detect if the user info popover has opened.
await page.evaluate(() =>