refactor: organize E2E tests with page objects

This commit is contained in:
2026-10-07 21:13:40 +09:00
parent 1e03e8f4ff
commit 48ef396ec1
28 changed files with 1494 additions and 834 deletions
+42 -51
View File
@@ -1,75 +1,66 @@
import { expect, test } from "../fixtures";
test("selects articles and keeps the reader focused on their content", async ({ page }) => {
await page.goto("/inbox");
await page.waitForLoadState("networkidle");
const rows = page.locator("[data-testid='inbox-article-row']");
await expect(rows).toHaveCount(9);
test("selects articles and keeps the reader focused on their content", async ({ readerPage }) => {
await readerPage.goTo();
await expect(readerPage.rows).toHaveCount(9);
const articleTitle = "Context for an agent can be brief";
await rows.filter({ hasText: articleTitle }).click();
const reader = page.getByRole("article", { name: articleTitle, exact: true });
await readerPage.selectArticle(articleTitle);
const reader = readerPage.article(articleTitle);
await expect(reader).toBeVisible();
await expect(reader.getByRole("heading", { name: articleTitle, exact: true })).toBeVisible();
await expect(readerPage.articleHeading(articleTitle)).toBeVisible();
await expect(
reader.getByText("Start with a one-sentence goal, then add the constraints that must hold.", {
exact: false,
}),
).toBeVisible();
await expect(page.getByText("FOR YOU", { exact: true })).toHaveCount(0);
await expect(page.getByText("Mock", { exact: true })).toHaveCount(0);
await expect(page.getByText("Why this article", { exact: true })).toHaveCount(0);
await expect(page.getByRole("button", { name: /For you|Read later|Unread only/ })).toHaveCount(0);
const back = page.getByRole("button", { name: "Back to articles" });
if (await back.isVisible()) await back.click();
await rows.filter({ hasText: "Three columns create a rhythm for reading" }).click();
await expect(
page.getByRole("article", {
name: "Three columns create a rhythm for reading",
exact: true,
}),
readerPage.articleText(
articleTitle,
"Start with a one-sentence goal, then add the constraints that must hold.",
),
).toBeVisible();
await expect(readerPage.forYouLabel).toHaveCount(0);
await expect(readerPage.mockLabel).toHaveCount(0);
await expect(readerPage.articleExplanation).toHaveCount(0);
await expect(readerPage.legacyFilters).toHaveCount(0);
await readerPage.backToArticles();
await readerPage.selectArticle("Three columns create a rhythm for reading");
await expect(readerPage.article("Three columns create a rhythm for reading")).toBeVisible();
});
test("recovers from empty search and shares navigation with Research", async ({ page, a11y }) => {
await page.goto("/inbox");
await page.waitForLoadState("networkidle");
const rows = page.locator("[data-testid='inbox-article-row']");
await page.getByRole("textbox", { name: "Search articles" }).fill("nonexistent-query-xyz");
await expect(rows).toHaveCount(0);
await expect(page.getByText("No articles found", { exact: true })).toBeVisible();
await page.getByRole("button", { name: "Clear search" }).click();
await expect(rows).toHaveCount(9);
test("recovers from empty search and shares navigation with Research", async ({
page,
readerPage,
workspacePage,
a11y,
}) => {
await readerPage.goTo();
await readerPage.search("nonexistent-query-xyz");
await expect(readerPage.rows).toHaveCount(0);
await expect(readerPage.emptyState).toBeVisible();
await readerPage.clearSearch();
await expect(readerPage.rows).toHaveCount(9);
expect((await a11y().analyze()).violations).toEqual([]);
await expect(page.getByRole("button", { name: "Edit interests", exact: true })).toHaveCount(0);
await page.getByRole("link", { name: "Research", exact: true }).click();
await expect(readerPage.editInterestsButton).toHaveCount(0);
await workspacePage.navigateTo("Research");
await expect(page).toHaveURL(/\/deck$/);
await page.getByRole("link", { name: "Reader", exact: true }).click();
await workspacePage.navigateTo("Reader");
await expect(page).toHaveURL(/\/inbox$/);
await expect(rows).toHaveCount(9);
await expect(readerPage.rows).toHaveCount(9);
});
test("keeps article navigation readable without horizontal overflow", async ({
page,
readerPage,
a11y,
}, testInfo) => {
await page.goto("/inbox");
await page.waitForLoadState("networkidle");
await readerPage.goTo();
for (const width of [320, 375, 414, 768]) {
await page.setViewportSize({ width, height: 850 });
await expect(page.getByRole("textbox", { name: "Search articles" })).toBeVisible();
await expect(readerPage.searchInput).toBeVisible();
expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBe(width);
await page.locator("[data-testid='inbox-article-row']").first().click();
const reader = page.getByRole("article", {
name: "Thinking in the browser: a new workflow with AI agents",
exact: true,
});
await expect(reader).toBeVisible();
await readerPage.openFirstArticle();
await expect(
readerPage.article("Thinking in the browser: a new workflow with AI agents"),
).toBeVisible();
expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBe(width);
await page.screenshot({
path: testInfo.outputPath(`inbox-reader-${width}.png`),
});
await page.screenshot({ path: testInfo.outputPath(`inbox-reader-${width}.png`) });
if (width === 320) expect((await a11y().analyze()).violations).toEqual([]);
const back = page.getByRole("button", { name: "Back to articles" });
if (await back.isVisible()) await back.click();
await readerPage.backToArticles();
}
});