mirror of https://github.com/zulip/zulip.git
puppeteer_tests: Remove jQuery dependency.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
96f15e3665
commit
dfda6d2895
|
@ -143,7 +143,6 @@
|
|||
{
|
||||
"files": ["frontend_tests/puppeteer_lib/**", "frontend_tests/puppeteer_tests/**"],
|
||||
"globals": {
|
||||
"$": false,
|
||||
"zulip_test": false
|
||||
}
|
||||
},
|
||||
|
|
|
@ -106,6 +106,7 @@ export async function page_url_with_fragment(page: Page): Promise<string> {
|
|||
export async function clear_and_type(page: Page, selector: string, text: string): Promise<void> {
|
||||
// Select all text currently in the element.
|
||||
await page.click(selector, {clickCount: 3});
|
||||
await page.keyboard.press("Delete");
|
||||
await page.type(selector, text);
|
||||
}
|
||||
|
||||
|
@ -301,6 +302,10 @@ export async function assert_compose_box_content(
|
|||
}
|
||||
|
||||
export async function wait_for_fully_processed_message(page: Page, content: string): Promise<void> {
|
||||
// Wait in parallel for the message list scroll animation, which
|
||||
// interferes with Puppeteer accurately clicking on messages.
|
||||
const scroll_delay = page.waitForTimeout(400);
|
||||
|
||||
await page.waitForFunction(
|
||||
(content: string) => {
|
||||
/*
|
||||
|
@ -354,6 +359,8 @@ export async function wait_for_fully_processed_message(page: Page, content: stri
|
|||
{},
|
||||
content,
|
||||
);
|
||||
|
||||
await scroll_delay;
|
||||
}
|
||||
|
||||
// Wait for any previous send to finish, then send a message.
|
||||
|
|
|
@ -35,17 +35,11 @@ async function test_change_new_stream_notifications_setting(page: Page): Promise
|
|||
"#realm_notifications_stream_id_widget .dropdown-search > input[type=text]",
|
||||
"rome",
|
||||
);
|
||||
await page.waitForFunction(
|
||||
() =>
|
||||
$(
|
||||
"#realm_notifications_stream_id_widget .dropdown-search > input[type=text]",
|
||||
).val() === "rome",
|
||||
);
|
||||
|
||||
const rome_in_dropdown = await page.waitForSelector(
|
||||
`xpath///*[@id="realm_notifications_stream_id_widget"]//*[${common.has_class_x(
|
||||
"dropdown-list-body",
|
||||
)}]/li[1]`,
|
||||
)} and count(li)=1]/li[normalize-space()="Rome"]`,
|
||||
{visible: true},
|
||||
);
|
||||
assert.ok(rome_in_dropdown);
|
||||
|
@ -126,11 +120,7 @@ async function test_changing_create_streams_and_invite_to_stream_policies(
|
|||
for (const [policy_value_name, policy_value] of Object.entries(policy_values)) {
|
||||
console.log(`Test setting ${policy} policy to '${policy_value_name}'.`);
|
||||
await page.waitForSelector(selector, {visible: true});
|
||||
await page.evaluate(
|
||||
(selector, policy_value) => $(selector).val(policy_value).trigger("change"),
|
||||
selector,
|
||||
policy_value,
|
||||
);
|
||||
await page.select(selector, `${policy_value}`);
|
||||
await submit_stream_permissions_change(page);
|
||||
}
|
||||
}
|
||||
|
@ -161,21 +151,17 @@ async function submit_joining_organization_change(page: Page): Promise<void> {
|
|||
async function test_set_new_user_threshold_to_three_days(page: Page): Promise<void> {
|
||||
console.log("Test setting new user threshold to three days.");
|
||||
await page.waitForSelector("#id_realm_waiting_period_setting", {visible: true});
|
||||
await page.evaluate(() =>
|
||||
$("#id_realm_waiting_period_setting").val("three_days").trigger("change"),
|
||||
);
|
||||
await page.select("#id_realm_waiting_period_setting", "three_days");
|
||||
await submit_joining_organization_change(page);
|
||||
}
|
||||
|
||||
async function test_set_new_user_threshold_to_N_days(page: Page): Promise<void> {
|
||||
console.log("Test setting new user threshold to three days.");
|
||||
await page.waitForSelector("#id_realm_waiting_period_setting", {visible: true});
|
||||
await page.evaluate(() =>
|
||||
$("#id_realm_waiting_period_setting").val("custom_days").trigger("change"),
|
||||
);
|
||||
await page.select("#id_realm_waiting_period_setting", "custom_days");
|
||||
|
||||
const N = 10;
|
||||
await page.evaluate((N: number) => $("#id_realm_waiting_period_threshold").val(N), N);
|
||||
const N = "10";
|
||||
await common.clear_and_type(page, "#id_realm_waiting_period_threshold", N);
|
||||
await submit_joining_organization_change(page);
|
||||
}
|
||||
|
||||
|
@ -218,7 +204,7 @@ async function test_delete_emoji(page: Page): Promise<void> {
|
|||
await page.click("tr#emoji_zulip_logo button.delete");
|
||||
|
||||
// assert the emoji is deleted.
|
||||
await page.waitForFunction(() => $("tr#emoji_zulip_logo").length === 0);
|
||||
await page.waitForSelector("tr#emoji_zulip_logo", {hidden: true});
|
||||
}
|
||||
|
||||
async function test_custom_realm_emoji(page: Page): Promise<void> {
|
||||
|
@ -229,28 +215,6 @@ async function test_custom_realm_emoji(page: Page): Promise<void> {
|
|||
await test_delete_emoji(page);
|
||||
}
|
||||
|
||||
async function get_suggestions(page: Page, str: string): Promise<void> {
|
||||
await page.evaluate((str: string) => {
|
||||
$(".create_default_stream")
|
||||
.trigger("focus")
|
||||
.val(str)
|
||||
.trigger(new $.Event("keyup", {which: 0}));
|
||||
}, str);
|
||||
}
|
||||
|
||||
async function select_from_suggestions(page: Page, item: string): Promise<void> {
|
||||
await page.evaluate((item: string) => {
|
||||
const tah = $(".create_default_stream").data().typeahead;
|
||||
tah.mousemove({
|
||||
currentTarget: $(`.typeahead:visible li:contains("${CSS.escape(item)}")`)[0],
|
||||
});
|
||||
tah.mouseenter({
|
||||
currentTarget: $(`.typeahead:visible li:contains("${CSS.escape(item)}")`)[0],
|
||||
});
|
||||
tah.select();
|
||||
}, item);
|
||||
}
|
||||
|
||||
async function test_add_default_stream(
|
||||
page: Page,
|
||||
stream_name: string,
|
||||
|
@ -260,8 +224,7 @@ async function test_add_default_stream(
|
|||
// etc). 'O' is used to make sure that it works even if there are multiple suggestions.
|
||||
// Uppercase 'O' is used instead of the lowercase version to make sure that the suggestions
|
||||
// are case insensitive.
|
||||
await get_suggestions(page, "o");
|
||||
await select_from_suggestions(page, stream_name);
|
||||
await common.select_item_via_typeahead(page, ".create_default_stream", "O", stream_name);
|
||||
await page.click(".default-stream-form #do_submit_stream");
|
||||
|
||||
await page.waitForSelector(row, {visible: true});
|
||||
|
@ -271,7 +234,7 @@ async function test_remove_default_stream(page: Page, row: string): Promise<void
|
|||
await page.click(row + " button.remove-default-stream");
|
||||
|
||||
// assert row doesn't exist.
|
||||
await page.waitForFunction((row: string) => $(row).length === 0, {}, row);
|
||||
await page.waitForSelector(row, {hidden: true});
|
||||
}
|
||||
|
||||
async function test_default_streams(page: Page): Promise<void> {
|
||||
|
@ -349,10 +312,8 @@ async function test_authentication_methods(page: Page): Promise<void> {
|
|||
await page.waitForSelector(".method_row[data-method='Google'] input[type='checkbox'] + span", {
|
||||
visible: true,
|
||||
});
|
||||
await page.waitForFunction(
|
||||
() =>
|
||||
!($(".method_row[data-method='Google'] input[type='checkbox']")[0] as HTMLInputElement)
|
||||
.checked,
|
||||
await page.waitForSelector(
|
||||
".method_row[data-method='Google'] input[type='checkbox']:not(:checked)",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,17 +22,14 @@ function get_message_selector(text: string): string {
|
|||
}
|
||||
|
||||
async function test_send_messages(page: Page): Promise<void> {
|
||||
const initial_msgs_count = await page.evaluate(() => $("#zhome .message_row").length);
|
||||
const initial_msgs_count = (await page.$$("#zhome .message_row")).length;
|
||||
|
||||
await common.send_multiple_messages(page, [
|
||||
{stream: "Verona", topic: "Reply test", content: "Compose stream reply test"},
|
||||
{recipient: "cordelia@zulip.com", content: "Compose private message reply test"},
|
||||
]);
|
||||
|
||||
assert.equal(
|
||||
await page.evaluate(() => $("#zhome .message_row").length),
|
||||
initial_msgs_count + 2,
|
||||
);
|
||||
assert.equal((await page.$$("#zhome .message_row")).length, initial_msgs_count + 2);
|
||||
}
|
||||
|
||||
async function test_stream_compose_keyboard_shortcut(page: Page): Promise<void> {
|
||||
|
@ -120,16 +117,15 @@ async function test_narrow_to_private_messages_with_cordelia(page: Page): Promis
|
|||
|
||||
await page.keyboard.press("KeyC");
|
||||
await page.waitForSelector("#compose", {visible: true});
|
||||
await page.waitForFunction(
|
||||
() => document.activeElement === $(".compose_table #stream_message_recipient_stream")[0],
|
||||
);
|
||||
await page.waitForSelector(".compose_table #stream_message_recipient_stream:focus", {
|
||||
visible: true,
|
||||
});
|
||||
await close_compose_box(page);
|
||||
}
|
||||
|
||||
async function test_send_multirecipient_pm_from_cordelia_pm_narrow(page: Page): Promise<void> {
|
||||
const recipients = ["cordelia@zulip.com", "othello@zulip.com"];
|
||||
const multiple_recipients_pm = "A huddle to check spaces";
|
||||
const pm_selector = `.messagebox:contains('${CSS.escape(multiple_recipients_pm)}')`;
|
||||
await common.send_message(page, "private", {
|
||||
recipient: recipients.join(", "),
|
||||
outside_view: true,
|
||||
|
@ -140,10 +136,13 @@ async function test_send_multirecipient_pm_from_cordelia_pm_narrow(page: Page):
|
|||
await page.click(".top_left_all_messages");
|
||||
|
||||
await page.waitForSelector("#zhome .message_row", {visible: true});
|
||||
await page.waitForFunction((selector: string) => $(selector).length !== 0, {}, pm_selector);
|
||||
await page.evaluate((selector: string) => {
|
||||
$(selector).slice(-1)[0].click();
|
||||
}, pm_selector);
|
||||
const pm = await page.waitForSelector(
|
||||
`xpath/(//*[${common.has_class_x(
|
||||
"messagebox",
|
||||
)} and contains(normalize-space(), "${multiple_recipients_pm}")])[last()]`,
|
||||
);
|
||||
assert.ok(pm !== null);
|
||||
await pm.click();
|
||||
await page.waitForSelector("#compose-textarea", {visible: true});
|
||||
const recipient_internal_emails = [
|
||||
await common.get_internal_email_from_name(page, "othello"),
|
||||
|
@ -184,24 +183,21 @@ async function test_markdown_preview_without_any_content(page: Page): Promise<vo
|
|||
|
||||
async function test_markdown_rendering(page: Page): Promise<void> {
|
||||
await page.waitForSelector("#compose .markdown_preview", {visible: true});
|
||||
let markdown_preview_element = await page.$("#compose .preview_content");
|
||||
assert.ok(markdown_preview_element);
|
||||
assert.equal(
|
||||
await page.evaluate((element: Element) => element.textContent, markdown_preview_element),
|
||||
"",
|
||||
);
|
||||
assert.equal(await common.get_text_from_selector(page, "#compose .preview_content"), "");
|
||||
await common.fill_form(page, 'form[action^="/json/messages"]', {
|
||||
content: "**Markdown preview** >> Test for Markdown preview",
|
||||
});
|
||||
await page.click("#compose .markdown_preview");
|
||||
await page.waitForSelector("#compose .preview_content", {visible: true});
|
||||
const preview_content = (await page.waitForSelector(
|
||||
`xpath///*[@id="compose"]//*[${common.has_class_x(
|
||||
"preview_content",
|
||||
)} and normalize-space()!=""]`,
|
||||
{visible: true},
|
||||
)) as ElementHandle<Element>;
|
||||
const expected_markdown_html =
|
||||
"<p><strong>Markdown preview</strong> >> Test for Markdown preview</p>";
|
||||
await page.waitForFunction(() => $("#compose .preview_content").html() !== "");
|
||||
markdown_preview_element = await page.$("#compose .preview_content");
|
||||
assert.ok(markdown_preview_element);
|
||||
assert.equal(
|
||||
await page.evaluate((element: Element) => element.innerHTML, markdown_preview_element),
|
||||
await (await preview_content.getProperty("innerHTML")).jsonValue(),
|
||||
expected_markdown_html,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,9 @@ async function copy_messages(
|
|||
return await page.evaluate(
|
||||
(start_message: string, end_message: string) => {
|
||||
function get_message_node(message: string): Element {
|
||||
return $(`.message_row .message_content:contains("${CSS.escape(message)}")`)[0];
|
||||
return [...document.querySelectorAll("#zhome .message_content")].find(
|
||||
(node) => node.textContent?.trim() === message,
|
||||
)!;
|
||||
}
|
||||
|
||||
// select messages from start_message to end_message
|
||||
|
@ -25,17 +27,21 @@ async function copy_messages(
|
|||
// Remove existing copy/paste divs, which may linger from the previous
|
||||
// example. (The code clears these out with a zero-second timeout, which
|
||||
// is probably sufficient for human users, but which causes problems here.)
|
||||
$("#copytempdiv").remove();
|
||||
document.querySelector("#copytempdiv")?.remove();
|
||||
|
||||
// emulate copy event
|
||||
$("body").trigger(new $.Event("keydown", {which: 67, ctrlKey: true}));
|
||||
document.dispatchEvent(
|
||||
new KeyboardEvent("keydown", {
|
||||
key: "c",
|
||||
code: "KeyC",
|
||||
ctrlKey: true,
|
||||
keyCode: 67,
|
||||
which: 67,
|
||||
} as KeyboardEventInit),
|
||||
);
|
||||
|
||||
// find temp div with copied text
|
||||
const $temp_div = $("#copytempdiv");
|
||||
return $temp_div
|
||||
.children("p")
|
||||
.get()
|
||||
.map((p) => p.textContent!);
|
||||
return [...document.querySelectorAll("#copytempdiv > p")].map((p) => p.textContent!);
|
||||
},
|
||||
start_message,
|
||||
end_message,
|
||||
|
|
|
@ -1,21 +1,29 @@
|
|||
import type {Page} from "puppeteer";
|
||||
import {strict as assert} from "assert";
|
||||
|
||||
import type {ElementHandle, Page} from "puppeteer";
|
||||
|
||||
import * as common from "../puppeteer_lib/common";
|
||||
|
||||
async function click_delete_and_return_last_msg_id(page: Page): Promise<string | undefined> {
|
||||
return await page.evaluate(() => {
|
||||
const $msg = $("#zhome .message_row").last();
|
||||
$msg.find(".message_control_button.actions_hover").trigger("click");
|
||||
$(".delete_message").trigger("click");
|
||||
return $msg.attr("id");
|
||||
});
|
||||
async function click_delete_and_return_last_msg_id(page: Page): Promise<string> {
|
||||
const msg = (await page.$$("#zhome .message_row")).at(-1) as ElementHandle<Element>;
|
||||
const id = await (await msg.getProperty("id")).jsonValue();
|
||||
await msg.hover();
|
||||
const info = await page.waitForSelector(
|
||||
`#${CSS.escape(id)} .message_control_button.actions_hover`,
|
||||
{visible: true},
|
||||
);
|
||||
assert.ok(info !== null);
|
||||
await info.click();
|
||||
await page.waitForSelector(".delete_message", {visible: true});
|
||||
await page.click(".delete_message");
|
||||
return id;
|
||||
}
|
||||
|
||||
async function delete_message_test(page: Page): Promise<void> {
|
||||
await common.log_in(page);
|
||||
await page.click(".top_left_all_messages");
|
||||
await page.waitForSelector("#zhome .message_row", {visible: true});
|
||||
const messages_quantitiy = await page.evaluate(() => $("#zhome .message_row").length);
|
||||
const messages_quantity = (await page.$$("#zhome .message_row")).length;
|
||||
const last_message_id = await click_delete_and_return_last_msg_id(page);
|
||||
|
||||
await common.wait_for_micromodal_to_open(page);
|
||||
|
@ -24,13 +32,8 @@ async function delete_message_test(page: Page): Promise<void> {
|
|||
});
|
||||
await common.wait_for_micromodal_to_close(page);
|
||||
|
||||
await page.waitForFunction(
|
||||
(expected_length: number) => $("#zhome .message_row").length === expected_length,
|
||||
{},
|
||||
messages_quantitiy - 1,
|
||||
);
|
||||
|
||||
await page.waitForSelector(`#${CSS.escape(last_message_id!)}`, {hidden: true});
|
||||
await page.waitForSelector(`#${CSS.escape(last_message_id)}`, {hidden: true});
|
||||
assert.equal((await page.$$("#zhome .message_row")).length, messages_quantity - 1);
|
||||
}
|
||||
|
||||
common.run_test(delete_message_test);
|
||||
|
|
|
@ -5,15 +5,11 @@ import type {Page} from "puppeteer";
|
|||
import * as common from "../puppeteer_lib/common";
|
||||
|
||||
async function wait_for_drafts_to_disappear(page: Page): Promise<void> {
|
||||
await page.waitForFunction(
|
||||
() => $("#draft_overlay").length === 0 || $("#draft_overlay").css("opacity") === "0",
|
||||
);
|
||||
await page.waitForSelector("#draft_overlay.show", {hidden: true});
|
||||
}
|
||||
|
||||
async function wait_for_drafts_to_appear(page: Page): Promise<void> {
|
||||
await page.waitForFunction(
|
||||
() => $("#draft_overlay").length === 1 && $("#draft_overlay").css("opacity") === "1",
|
||||
);
|
||||
await page.waitForSelector("#draft_overlay.show");
|
||||
}
|
||||
|
||||
async function get_drafts_count(page: Page): Promise<number> {
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
import type {Page} from "puppeteer";
|
||||
import {strict as assert} from "assert";
|
||||
|
||||
import type {ElementHandle, Page} from "puppeteer";
|
||||
|
||||
import * as common from "../puppeteer_lib/common";
|
||||
|
||||
async function trigger_edit_last_message(page: Page): Promise<void> {
|
||||
await page.evaluate(() => {
|
||||
const $msg = $("#zhome .message_row").last();
|
||||
$msg.find(".message_control_button.actions_hover").trigger("click");
|
||||
$(".popover_edit_message").trigger("click");
|
||||
});
|
||||
const msg = (await page.$$("#zhome .message_row")).at(-1) as ElementHandle<Element>;
|
||||
const id = await (await msg.getProperty("id")).jsonValue();
|
||||
await msg.hover();
|
||||
const info = await page.waitForSelector(
|
||||
`#${CSS.escape(id)} .message_control_button.actions_hover`,
|
||||
{visible: true},
|
||||
);
|
||||
assert.ok(info !== null);
|
||||
await info.click();
|
||||
await page.waitForSelector(".popover_edit_message", {visible: true});
|
||||
await page.click(".popover_edit_message");
|
||||
await page.waitForSelector(".message_edit_content", {visible: true});
|
||||
}
|
||||
|
||||
|
@ -34,25 +42,35 @@ async function test_stream_message_edit(page: Page): Promise<void> {
|
|||
}
|
||||
|
||||
async function test_edit_message_with_slash_me(page: Page): Promise<void> {
|
||||
const last_message_xpath = `(//*[@id="zhome"]//*[${common.has_class_x("messagebox")}])[last()]`;
|
||||
|
||||
await common.send_message(page, "stream", {
|
||||
stream: "Verona",
|
||||
topic: "edits",
|
||||
content: "/me test editing a message with me",
|
||||
});
|
||||
await page.waitForFunction(
|
||||
() => $(".last_message .status-message").text() === "test editing a message with me",
|
||||
await page.waitForSelector(
|
||||
`xpath/${last_message_xpath}//*[${common.has_class_x(
|
||||
"status-message",
|
||||
)} and text()="test editing a message with me"]`,
|
||||
);
|
||||
await page.waitForFunction(
|
||||
() => $(".last_message .sender_name-in-status").text().trim() === "Desdemona",
|
||||
await page.waitForSelector(
|
||||
`xpath/${last_message_xpath}//*[${common.has_class_x(
|
||||
"sender_name-in-status",
|
||||
)} and normalize-space()="Desdemona"]`,
|
||||
);
|
||||
|
||||
await edit_stream_message(page, "edited", "/me test edited a message with me");
|
||||
|
||||
await page.waitForFunction(
|
||||
() => $(".last_message .status-message").text() === "test edited a message with me",
|
||||
await page.waitForSelector(
|
||||
`xpath/${last_message_xpath}//*[${common.has_class_x(
|
||||
"status-message",
|
||||
)} and text()="test edited a message with me"]`,
|
||||
);
|
||||
await page.waitForFunction(
|
||||
() => $(".last_message .sender_name-in-status").text().trim() === "Desdemona",
|
||||
await page.waitForSelector(
|
||||
`xpath/${last_message_xpath}//*[${common.has_class_x(
|
||||
"sender_name-in-status",
|
||||
)} and normalize-space()="Desdemona"]`,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ async function expect_cordelia_private_narrow(page: Page): Promise<void> {
|
|||
}
|
||||
|
||||
async function un_narrow(page: Page): Promise<void> {
|
||||
if (await page.evaluate(() => $(".message_comp").is(":visible"))) {
|
||||
if ((await (await page.$(".message_comp"))!.boundingBox())?.height) {
|
||||
await page.keyboard.press("Escape");
|
||||
}
|
||||
await page.click(".top_left_all_messages");
|
||||
|
@ -100,7 +100,7 @@ async function expect_recent_topics(page: Page): Promise<void> {
|
|||
|
||||
async function test_navigations_from_home(page: Page): Promise<void> {
|
||||
console.log("Narrowing by clicking stream");
|
||||
await page.evaluate(() => $(`*[title='Narrow to stream "Verona"']`).trigger("click"));
|
||||
await page.click(`#zhome [title='Narrow to stream "Verona"']`);
|
||||
await expect_verona_stream(page);
|
||||
|
||||
assert.strictEqual(await page.title(), "Verona - Zulip Dev - Zulip");
|
||||
|
@ -108,27 +108,23 @@ async function test_navigations_from_home(page: Page): Promise<void> {
|
|||
await expect_home(page);
|
||||
|
||||
console.log("Narrowing by clicking topic");
|
||||
await page.click('*[title="Narrow to stream \\"Verona\\", topic \\"test\\""]');
|
||||
await page.click(`#zhome [title='Narrow to stream "Verona", topic "test"']`);
|
||||
await expect_verona_stream_test_topic(page);
|
||||
|
||||
await un_narrow(page);
|
||||
await expect_home(page);
|
||||
|
||||
console.log("Narrowing by clicking group personal header");
|
||||
await page.evaluate(() =>
|
||||
$(
|
||||
'*[title="Narrow to your private messages with Cordelia, Lear\'s daughter, King Hamlet"]',
|
||||
).trigger("click"),
|
||||
await page.click(
|
||||
`#zhome [title="Narrow to your private messages with Cordelia, Lear's daughter, King Hamlet"]`,
|
||||
);
|
||||
await expect_huddle(page);
|
||||
|
||||
await un_narrow(page);
|
||||
await expect_home(page);
|
||||
|
||||
await page.evaluate(() =>
|
||||
$(
|
||||
'*[title="Narrow to your private messages with Cordelia, Lear\'s daughter, King Hamlet"]',
|
||||
).trigger("click"),
|
||||
await page.click(
|
||||
`#zhome [title="Narrow to your private messages with Cordelia, Lear's daughter, King Hamlet"]`,
|
||||
);
|
||||
await un_narrow_by_clicking_org_icon(page);
|
||||
await expect_recent_topics(page);
|
||||
|
@ -294,15 +290,7 @@ async function arrow(page: Page, direction: "Up" | "Down"): Promise<void> {
|
|||
}
|
||||
|
||||
async function test_search_venice(page: Page): Promise<void> {
|
||||
await page.evaluate(() => {
|
||||
$(".stream-list-filter")
|
||||
.expectOne()
|
||||
.trigger("focus")
|
||||
.val("vEnI") // Must be case insensitive.
|
||||
.trigger("input")
|
||||
.trigger("click");
|
||||
});
|
||||
|
||||
await common.clear_and_type(page, ".stream-list-filter", "vEnI"); // Must be case insensitive.
|
||||
await page.waitForSelector(await get_stream_li(page, "Denmark"), {hidden: true});
|
||||
await page.waitForSelector(await get_stream_li(page, "Verona"), {hidden: true});
|
||||
await page.waitForSelector((await get_stream_li(page, "Venice")) + ".highlighted_stream", {
|
||||
|
@ -310,9 +298,7 @@ async function test_search_venice(page: Page): Promise<void> {
|
|||
});
|
||||
|
||||
// Clearing list gives back all the streams in the list
|
||||
await page.evaluate(() =>
|
||||
$(".stream-list-filter").expectOne().trigger("focus").val("").trigger("input"),
|
||||
);
|
||||
await common.clear_and_type(page, ".stream-list-filter", "");
|
||||
await page.waitForSelector(await get_stream_li(page, "Denmark"), {visible: true});
|
||||
await page.waitForSelector(await get_stream_li(page, "Venice"), {visible: true});
|
||||
await page.waitForSelector(await get_stream_li(page, "Verona"), {visible: true});
|
||||
|
@ -463,17 +449,20 @@ async function test_narrow_public_streams(page: Page): Promise<void> {
|
|||
await page.goto(`http://zulip.zulipdev.com:9981/#streams/${stream_id}/Denmark`);
|
||||
await page.waitForSelector("button.sub_unsub_button", {visible: true});
|
||||
await page.click("button.sub_unsub_button");
|
||||
await page.waitForFunction(() => $("button.sub_unsub_button").text().trim() === "Subscribe");
|
||||
await page.waitForSelector(
|
||||
`xpath///button[${common.has_class_x(
|
||||
"sub_unsub_button",
|
||||
)} and normalize-space()="Subscribe"]`,
|
||||
);
|
||||
await page.click(".subscriptions-header .exit-sign");
|
||||
await page.waitForSelector("#subscription_overlay", {hidden: true});
|
||||
await page.goto(`http://zulip.zulipdev.com:9981/#narrow/stream/${stream_id}-Denmark`);
|
||||
await page.waitForFunction(() => $(".recipient_row:visible").length >= 3);
|
||||
assert.equal(await page.evaluate(() => $(".stream-status:visible").length), 1);
|
||||
await page.waitForSelector("#zfilt .recipient_row ~ .recipient_row ~ .recipient_row");
|
||||
assert.ok((await page.$("#zfilt .stream-status")) !== null);
|
||||
|
||||
await page.goto("http://zulip.zulipdev.com:9981/#narrow/streams/public");
|
||||
await page.waitForFunction(() => $(".recipient_row:visible").length >= 3);
|
||||
|
||||
assert.equal(await page.evaluate(() => $(".stream-status:visible").length), 0);
|
||||
await page.waitForSelector("#zfilt .recipient_row ~ .recipient_row ~ .recipient_row");
|
||||
assert.ok((await page.$("#zfilt .stream-status")) === null);
|
||||
}
|
||||
|
||||
async function message_basic_tests(page: Page): Promise<void> {
|
||||
|
|
|
@ -93,9 +93,7 @@ async function navigation_tests(page: Page): Promise<void> {
|
|||
|
||||
await navigate_using_left_sidebar(page, verona_narrow, "message_feed_container");
|
||||
|
||||
// Hardcoded this instead of using `navigate_to`
|
||||
// as Puppeteer cannot click hidden elements.
|
||||
await page.evaluate(() => $("a[href='#message_feed_container]'").trigger("click"));
|
||||
await page.click(".home-link");
|
||||
await wait_for_tab(page, "message_feed_container");
|
||||
|
||||
await navigate_to_subscriptions(page);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {strict as assert} from "assert";
|
||||
|
||||
import type {Page} from "puppeteer";
|
||||
import type {ElementHandle, Page} from "puppeteer";
|
||||
|
||||
import {test_credentials} from "../../var/puppeteer/test_credentials";
|
||||
import * as common from "../puppeteer_lib/common";
|
||||
|
@ -12,10 +12,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> {
|
||||
return await page.evaluate(
|
||||
(selector: string) => decodeURIComponent($(selector).attr("href")!),
|
||||
selector,
|
||||
);
|
||||
const a = (await page.$(selector)) as ElementHandle<HTMLAnchorElement>;
|
||||
return decodeURIComponent(await (await a.getProperty("href")).jsonValue());
|
||||
}
|
||||
|
||||
async function open_settings(page: Page): Promise<void> {
|
||||
|
@ -43,7 +41,9 @@ async function test_change_full_name(page: Page): Promise<void> {
|
|||
|
||||
await page.click("#settings_content .profile-settings-form");
|
||||
await page.waitForSelector(".full-name-change-form .alert-success", {visible: true});
|
||||
await page.waitForFunction(() => $("#full_name").val() === "New name");
|
||||
await page.waitForFunction(
|
||||
() => document.querySelector<HTMLInputElement>("#full_name")?.value === "New name",
|
||||
);
|
||||
}
|
||||
|
||||
async function test_change_password(page: Page): Promise<void> {
|
||||
|
|
|
@ -7,23 +7,24 @@ import * as common from "../puppeteer_lib/common";
|
|||
const message = "test star";
|
||||
|
||||
async function stars_count(page: Page): Promise<number> {
|
||||
return await page.evaluate(() => $("#zhome .fa-star:not(.empty-star)").length);
|
||||
return (await page.$$("#zhome .fa-star:not(.empty-star)")).length;
|
||||
}
|
||||
|
||||
async function toggle_test_star_message(page: Page): Promise<void> {
|
||||
await page.evaluate((message: string) => {
|
||||
const $msg = $(`.message_content:contains("${CSS.escape(message)}"):visible`).last();
|
||||
if ($msg.length !== 1) {
|
||||
throw new Error("cannot find test star message");
|
||||
}
|
||||
const messagebox = await page.waitForSelector(
|
||||
`xpath/(//*[@id="zhome"]//*[${common.has_class_x(
|
||||
"message_content",
|
||||
)} and normalize-space()="${message}"])[last()]/ancestor::*[${common.has_class_x(
|
||||
"messagebox",
|
||||
)}]`,
|
||||
{visible: true},
|
||||
);
|
||||
assert.ok(messagebox !== null);
|
||||
await messagebox.hover();
|
||||
|
||||
const $star_icon = $msg.closest(".messagebox").find(".star");
|
||||
if ($star_icon.length !== 1) {
|
||||
throw new Error("cannot find star icon");
|
||||
}
|
||||
|
||||
$star_icon.trigger("click");
|
||||
}, message);
|
||||
const star_icon = await messagebox.waitForSelector(".star", {visible: true});
|
||||
assert.ok(star_icon !== null);
|
||||
await star_icon.click();
|
||||
}
|
||||
|
||||
async function test_narrow_to_starred_messages(page: Page): Promise<void> {
|
||||
|
|
|
@ -84,7 +84,9 @@ async function create_stream(page: Page): Promise<void> {
|
|||
stream_description: "Everything Puppeteer",
|
||||
});
|
||||
await page.click("form#stream_creation_form .finalize_create_stream");
|
||||
await page.waitForFunction(() => $(".stream-name").is(':contains("Puppeteer")'));
|
||||
await page.waitForSelector(
|
||||
`xpath///*[${common.has_class_x("stream-name")} and text()="Puppeteer"]`,
|
||||
);
|
||||
const stream_name = await common.get_text_from_selector(
|
||||
page,
|
||||
".stream-header .stream-name .sub-stream-name",
|
||||
|
@ -93,15 +95,14 @@ async function create_stream(page: Page): Promise<void> {
|
|||
page,
|
||||
".stream-description .sub-stream-description",
|
||||
);
|
||||
const subscriber_count_selector = "[data-stream-name='Puppeteer'] .subscriber-count";
|
||||
assert.strictEqual(stream_name, "Puppeteer");
|
||||
assert.strictEqual(stream_description, "Everything Puppeteer");
|
||||
|
||||
// Assert subscriber count becomes 3 (cordelia, desdemona, othello)
|
||||
await page.waitForFunction(
|
||||
(subscriber_count_selector: string) => $(subscriber_count_selector).text().trim() === "3",
|
||||
{},
|
||||
subscriber_count_selector,
|
||||
await page.waitForSelector(
|
||||
`xpath///*[@data-stream-name="Puppeteer"]//*[${common.has_class_x(
|
||||
"subscriber-count",
|
||||
)} and normalize-space()="3"]`,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,15 +9,19 @@ async function test_subscription_button(page: Page): Promise<void> {
|
|||
const unsubscribed_selector = `${button_selector}:not(.checked)`;
|
||||
|
||||
async function subscribed(): Promise<ElementHandle | null> {
|
||||
await page.waitForFunction(
|
||||
() => $(".stream_settings_header .sub_unsub_button").text().trim() === "Unsubscribe",
|
||||
await page.waitForSelector(
|
||||
`xpath///*[${common.has_class_x("stream_settings_header")}]//*[${common.has_class_x(
|
||||
"sub_unsub_button",
|
||||
)} and normalize-space()="Unsubscribe"]`,
|
||||
);
|
||||
return await page.waitForSelector(subscribed_selector, {visible: true});
|
||||
}
|
||||
|
||||
async function unsubscribed(): Promise<ElementHandle | null> {
|
||||
await page.waitForFunction(
|
||||
() => $(".stream_settings_header .sub_unsub_button").text().trim() === "Subscribe",
|
||||
await page.waitForSelector(
|
||||
`xpath///*[${common.has_class_x("stream_settings_header")}]//*[${common.has_class_x(
|
||||
"sub_unsub_button",
|
||||
)} and normalize-space()="Subscribe"]`,
|
||||
);
|
||||
return await page.waitForSelector(unsubscribed_selector, {visible: true});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue