Files
Thesisly/tests/e2e/reader.spec.mjs
T

109 lines
6.4 KiB
JavaScript

import { test, expect } from "@playwright/test";
import { readFileSync } from "node:fs";
const snapshot = JSON.parse(readFileSync(new URL("../../src/data/papers.json", import.meta.url)));
const errors = new WeakMap();
test.beforeEach(async ({ page }) => {
errors.set(page, []);
page.on("pageerror", error => errors.get(page).push(error.message));
});
test.afterEach(async ({ page }) => {
expect(errors.get(page)).toEqual([]);
expect(await page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth)).toBe(true);
});
test("sample index has working pagination and returns to the same list", async ({ page }, info) => {
await page.goto("/");
await expect(page.getByRole("heading", { level: 1 })).toContainText("好研究");
await expect(page.getByRole("note")).toContainText("前 20 条记录");
await expect(page.locator(".paper-row")).toHaveCount(8);
await expect(page.getByRole("link", { name: "登录", exact: true })).toBeVisible();
const first = await page.locator(".paper-row h3").first().innerText();
await page.screenshot({ path: info.outputPath("home.png"), fullPage: true });
await page.getByRole("link", { name: "下一页" }).click();
await expect(page).toHaveURL(/cursor=/);
await expect(page.locator(".paper-row h3").first()).not.toHaveText(first);
await page.getByRole("link", { name: "上一页" }).click();
await expect(page.locator(".paper-row h3").first()).toHaveText(first);
await page.getByRole("link", { name: "下一页" }).click();
await page.getByRole("link", { name: "下一页" }).click();
await expect(page.locator(".paper-row")).toHaveCount(4);
await expect(page.getByRole("navigation", { name: "论文分页" })).toContainText("本页 4 篇");
await expect(page.getByRole("link", { name: "下一页" })).toHaveCount(0);
});
test("search, empty results, author scope and category filters work", async ({ page }) => {
await page.goto("/");
await page.getByRole("textbox", { name: "搜索论文", exact: true }).fill("no-paper-matches-this-query-92871");
await page.getByRole("button", { name: "搜索论文", exact: true }).click();
await expect(page.getByRole("heading", { name: "没有找到符合条件的论文" })).toBeVisible();
await page.getByRole("link", { name: "查看全部论文" }).click();
await expect(page.getByRole("textbox", {name:"搜索论文",exact:true})).toHaveValue("");
await expect(page.locator(".paper-row")).toHaveCount(8);
const author = snapshot.papers[0].authors[0];
await page.getByRole("combobox", { name: "搜索范围", exact: true }).selectOption("author");
await page.getByRole("textbox", { name: "搜索论文", exact: true }).fill(author);
await page.getByRole("button", { name: "搜索论文", exact: true }).click();
await expect(page).toHaveURL(/searchIn=author/);
await expect(page.locator(".paper-row").first()).toContainText(author);
await page.getByRole("link", { name: "清除筛选" }).click();
const topic = snapshot.papers[0].topics[0];
await page.getByRole("link", { name: topic, exact: true }).click();
await expect(page).toHaveURL(new RegExp("topic=" + encodeURIComponent(topic).replace(/[.*+?^${}()|[\]\\]/g, "\\$&")));
for (const row of await page.locator(".paper-meta").all()) await expect(row).toContainText(topic);
});
test("article preserves original abstract and offers citation copying", async ({ page, baseURL }, info) => {
const paper = snapshot.papers[0];
await page.goto(`/papers/${paper.id}`);
await expect(page.getByRole("heading", { level: 1 })).toHaveText(paper.title);
await expect(page.locator("#abstract")).toContainText(paper.abstract.replace(/\n/g, " "));
await expect(page.getByRole("link", { name: new RegExp(paper.sources[0].externalId.replaceAll(".", "\\.")) })).toHaveAttribute("href", paper.sources[0].url);
await page.getByRole("button", { name: "复制引用" }).click();
await expect(page.getByText("已复制引用信息", { exact: true })).toBeVisible();
await expect.poll(() => page.evaluate(() => navigator.clipboard.readText())).toContain(paper.title);
await expect(page.getByRole("link", { name: "登录", exact: true })).toBeVisible();
await page.screenshot({ path: info.outputPath("article.png"), fullPage: true });
await page.getByRole("link", { name: "返回论文索引" }).click();
await expect(page).toHaveURL(new URL("/", baseURL).href);
});
test("all reading themes apply and persist through a reload", async ({ page }) => {
await page.goto("/");
const theme = page.getByRole("combobox", { name: "阅读主题" });
for (const value of ["editorial", "tufte", "vignelli"]) {
await theme.selectOption(value);
await expect(page.locator("html")).toHaveAttribute("data-theme", value);
await page.reload();
await expect(theme).toHaveValue(value);
const login = page.getByRole("link", { name: "登录", exact: true });
await expect(login).toBeVisible();
expect(await login.evaluate(el => {
const expected = getComputedStyle(document.body).backgroundColor;
return getComputedStyle(el).color === expected;
})).toBe(true);
await expect(page.locator("html")).toHaveAttribute("data-theme", value);
}
});
test("login and registration forms remain usable without sending credentials", async ({ page }, info) => {
await page.goto("/login");
await expect(page.getByRole("button", { name: "Google", exact: true })).toBeVisible();
await expect(page.getByRole("button", { name: "Slack", exact: true })).toBeVisible();
await page.getByRole("button", { name: "创建账户", exact: true }).click();
await expect(page.getByRole("heading", { name: "创建账户" })).toBeVisible();
await expect(page.getByLabel("密码", { exact: true })).toHaveAttribute("minlength", "12");
await page.getByRole("button", { name: "显示密码" }).click();
await expect(page.getByLabel("密码", { exact: true })).toHaveAttribute("type", "text");
await page.screenshot({ path: info.outputPath("register.png"), fullPage: true });
await page.getByRole("button", { name: "登录", exact: true }).last().click();
await expect(page.getByRole("heading", { name: "继续你的阅读。" })).toBeVisible();
});
test("missing paper shows recovery navigation instead of an empty article", async ({ page }) => {
await page.goto("/papers/999999999");
await expect(page.getByRole("heading", { name: "这篇论文不在当前索引里。" })).toBeVisible();
await page.getByRole("link", { name: "返回论文索引" }).click();
await expect(page.getByRole("heading", { level: 1 })).toContainText("好研究");
});