refactor: organize E2E tests with page objects
This commit is contained in:
@@ -1,96 +1,101 @@
|
||||
import { expect, test } from "../fixtures";
|
||||
|
||||
test("restores article selection with browser history and reload", async ({ page }) => {
|
||||
await page.goto("/inbox", { waitUntil: "networkidle" });
|
||||
const rows = page.locator("[data-testid='inbox-article-row']");
|
||||
const heading = await rows.nth(1).locator("[data-testid='inbox-row-title']").innerText();
|
||||
test("restores article selection with browser history and reload", async ({ page, readerPage }) => {
|
||||
await readerPage.goTo();
|
||||
const rows = readerPage.rows;
|
||||
const heading = await readerPage.rowTitle(1).innerText();
|
||||
await rows.nth(1).click();
|
||||
await expect(page.locator("[data-testid='inbox-article-title']")).toHaveText(heading);
|
||||
await expect(readerPage.articleTitle).toHaveText(heading);
|
||||
const selectedUrl = page.url();
|
||||
expect(new URL(selectedUrl).searchParams.get("article")).toBeTruthy();
|
||||
await page.reload({ waitUntil: "networkidle" });
|
||||
await expect(page.locator("[data-testid='inbox-article-title']")).toHaveText(heading ?? "");
|
||||
await expect(readerPage.articleTitle).toHaveText(heading ?? "");
|
||||
await page.goBack();
|
||||
await expect(page.locator("[data-testid='inbox-workspace']")).toHaveAttribute(
|
||||
"data-reading",
|
||||
"false",
|
||||
);
|
||||
await expect(readerPage.workspace).toHaveAttribute("data-reading", "false");
|
||||
await page.goForward();
|
||||
await expect(page).toHaveURL(selectedUrl);
|
||||
await expect(page.locator("[data-testid='inbox-article-title']")).toHaveText(heading ?? "");
|
||||
await expect(readerPage.articleTitle).toHaveText(heading ?? "");
|
||||
});
|
||||
|
||||
test("restores search and replaces typing history", async ({ page }) => {
|
||||
await page.goto("/", { waitUntil: "networkidle" });
|
||||
await page.getByRole("link", { name: "Reader", exact: true }).click();
|
||||
const search = page.getByRole("textbox", { name: "Search articles" });
|
||||
test("restores search and replaces typing history", async ({
|
||||
page,
|
||||
readerPage,
|
||||
homePage,
|
||||
workspacePage,
|
||||
}) => {
|
||||
await homePage.goTo();
|
||||
await page.waitForLoadState("networkidle");
|
||||
await workspacePage.navigateTo("Reader");
|
||||
const search = readerPage.searchInput;
|
||||
await search.pressSequentially("browser");
|
||||
await expect(search).toHaveValue("browser");
|
||||
await expect.poll(() => new URL(page.url()).searchParams.get("q")).toBe("browser");
|
||||
const count = await page.locator("[data-testid='inbox-article-row']").count();
|
||||
const count = await readerPage.rows.count();
|
||||
await page.reload({ waitUntil: "networkidle" });
|
||||
await expect(search).toHaveValue("browser");
|
||||
await expect(page.locator("[data-testid='inbox-article-row']")).toHaveCount(count);
|
||||
await expect(readerPage.rows).toHaveCount(count);
|
||||
await page.goBack();
|
||||
await expect(page).toHaveURL("http://127.0.0.1:4173/");
|
||||
await expect(page).toHaveURL("/");
|
||||
});
|
||||
|
||||
test("restores account dialog without losing underlying article", async ({ page }) => {
|
||||
await page.goto("/inbox", { waitUntil: "networkidle" });
|
||||
await page.getByRole("button", { name: "Manage connected accounts" }).click();
|
||||
test("restores account dialog without losing underlying article", async ({
|
||||
page,
|
||||
readerPage,
|
||||
connectedAccounts,
|
||||
}) => {
|
||||
await readerPage.goTo();
|
||||
await connectedAccounts.open();
|
||||
await expect.poll(() => new URL(page.url()).searchParams.get("accounts")).toBe("true");
|
||||
await page.reload({ waitUntil: "networkidle" });
|
||||
await expect(page.getByRole("dialog")).toBeVisible();
|
||||
await expect(connectedAccounts.dialog).toBeVisible();
|
||||
await page.goBack();
|
||||
await expect(page.getByRole("dialog")).toHaveCount(0);
|
||||
await expect(connectedAccounts.dialog).toHaveCount(0);
|
||||
await page.goForward();
|
||||
await expect(page.getByRole("dialog")).toBeVisible();
|
||||
await expect(connectedAccounts.dialog).toBeVisible();
|
||||
});
|
||||
|
||||
test("restores a message view and conversation from its URL", async ({ page }) => {
|
||||
await page.goto("/support", { waitUntil: "networkidle" });
|
||||
await page.getByRole("button", { name: "All", exact: true }).click();
|
||||
const row = page.locator("[data-testid='support-row']").nth(1);
|
||||
const heading = await row.locator("span").first().innerText();
|
||||
test("restores a message view and conversation from its URL", async ({ page, messagesPage }) => {
|
||||
await messagesPage.goTo();
|
||||
await page.waitForLoadState("networkidle");
|
||||
await messagesPage.selectView("All");
|
||||
const row = messagesPage.rows.nth(1);
|
||||
const heading = await messagesPage.rowName(1).innerText();
|
||||
await row.click();
|
||||
await expect(page.locator("[data-testid='support-toolbar'] > span").first()).toHaveText(heading);
|
||||
await expect(messagesPage.toolbarName).toHaveText(heading);
|
||||
const url = page.url();
|
||||
expect(new URL(url).searchParams.get("view")).toBe("all");
|
||||
expect(new URL(url).searchParams.get("conversation")).toBeTruthy();
|
||||
await page.reload({ waitUntil: "networkidle" });
|
||||
await expect(page.locator("[data-testid='support-toolbar'] > span").first()).toHaveText(
|
||||
heading ?? "",
|
||||
);
|
||||
await expect(page.locator("[data-testid='support-workspace']")).toHaveAttribute(
|
||||
"data-reading",
|
||||
"true",
|
||||
);
|
||||
await expect(messagesPage.toolbarName).toHaveText(heading ?? "");
|
||||
await expect(messagesPage.workspace).toHaveAttribute("data-reading", "true");
|
||||
});
|
||||
|
||||
test("keeps a deep link through login", async ({ page, context }) => {
|
||||
test("keeps a deep link through login", async ({ page, context, readerPage, authPage }) => {
|
||||
await context.clearCookies();
|
||||
await page.goto("/inbox?q=browser", { waitUntil: "networkidle" });
|
||||
await readerPage.goTo("?q=browser");
|
||||
await expect(page).toHaveURL(/\/login\?returnTo=/);
|
||||
await page.getByLabel("Email address").fill("[email protected]");
|
||||
await page.getByLabel("Password", { exact: true }).fill("E2E-only-passphrase-2026");
|
||||
await page.getByRole("button", { name: "Sign in", exact: true }).click();
|
||||
await authPage.signIn("[email protected]", "E2E-only-passphrase-2026");
|
||||
await expect(page).toHaveURL(/\/inbox\?q=browser$/);
|
||||
await expect(page.getByRole("textbox", { name: "Search articles" })).toHaveValue("browser");
|
||||
await expect(readerPage.searchInput).toHaveValue("browser");
|
||||
});
|
||||
|
||||
test("debounces search and cancels pending input on history navigation", async ({ page }) => {
|
||||
await page.goto("/support", { waitUntil: "networkidle" });
|
||||
await page.getByRole("button", { name: "All", exact: true }).click();
|
||||
test("debounces search and cancels pending input on history navigation", async ({
|
||||
page,
|
||||
messagesPage,
|
||||
}) => {
|
||||
await messagesPage.goTo();
|
||||
await page.waitForLoadState("networkidle");
|
||||
await messagesPage.selectView("All");
|
||||
await expect(page).toHaveURL(/view=all/);
|
||||
await page.clock.install();
|
||||
const input = page.getByRole("textbox", { name: "Search messages" });
|
||||
const input = messagesPage.searchInput;
|
||||
await input.fill("not-committed");
|
||||
await expect(input).toHaveValue("not-committed");
|
||||
expect(new URL(page.url()).searchParams.has("q")).toBe(false);
|
||||
await page.clock.runFor(200);
|
||||
expect(new URL(page.url()).searchParams.has("q")).toBe(false);
|
||||
await page.goBack();
|
||||
await expect(page).toHaveURL("http://127.0.0.1:4173/support");
|
||||
await expect(page).toHaveURL("/support");
|
||||
await page.clock.runFor(400);
|
||||
await expect(input).toHaveValue("");
|
||||
expect(new URL(page.url()).searchParams.has("q")).toBe(false);
|
||||
@@ -99,10 +104,10 @@ test("debounces search and cancels pending input on history navigation", async (
|
||||
await expect.poll(() => new URL(page.url()).searchParams.get("q")).toBe("final search");
|
||||
});
|
||||
|
||||
test("waits for IME composition to finish before searching", async ({ page }) => {
|
||||
await page.goto("/inbox", { waitUntil: "networkidle" });
|
||||
test("waits for IME composition to finish before searching", async ({ page, readerPage }) => {
|
||||
await readerPage.goTo();
|
||||
await page.clock.install();
|
||||
const input = page.getByRole("textbox", { name: "Search articles" });
|
||||
const input = readerPage.searchInput;
|
||||
await input.dispatchEvent("compositionstart");
|
||||
await input.fill("browser");
|
||||
await page.clock.runFor(1000);
|
||||
|
||||
Reference in New Issue
Block a user