SPB Git
5.2 KB · 49 lines typescript
1import { expect, test } from "@playwright/test";2test.describe("public site", () => {3  test("home shows live statistics, latest papers and constellation", async ({ page }) => {4    await page.goto("/"); await expect(page).toHaveTitle(/Research Working Papers/); await expect(page.getByRole("heading", { level: 1 })).toHaveText("Research Working Papers");5    const stats = await page.request.get("/api/v1/stats").then((r) => r.json()); await expect(page.locator("dl dd").first()).toHaveText(String(stats.papers));6    await expect(page.getByRole("heading", { name: "Latest working papers" })).toBeVisible(); await expect(page.locator("svg[role=img]").first()).toBeVisible();7  });8  test("library filters, sorts and switches display modes", async ({ page }) => {9    await page.goto("/papers?domain=real-estate-economics&sort=number"); await expect(page.getByText(/^\d+ results?$/)).toBeVisible();10    const n = await page.locator("article").count(); expect(n).toBeGreaterThan(3);11    await page.goto("/papers?view=table"); await expect(page.locator("table.data")).toBeVisible();12    await page.goto("/papers?view=cards&q=hedonic"); expect(await page.locator("article").count()).toBeGreaterThan(0);13    await page.goto("/papers?q=zzzzqqqq-nothing"); await expect(page.getByText("No paper matches these filters.")).toBeVisible();14  });15  test("paper page: metadata, citation tools, versions, related, download", async ({ page }) => {16    await page.goto("/papers/wp38"); await expect(page.getByRole("heading", { level: 1 })).toContainText("Economic Geography");17    await expect(page.locator('meta[name="citation_title"]')).toHaveAttribute("content", /Economic Geography/); await expect(page.locator('meta[name="citation_pdf_url"]')).toHaveAttribute("content", /\.pdf$/);18    await expect(page.locator('script[type="application/ld+json"]')).toHaveCount(1);19    await page.getByRole("button", { name: /Cite/ }).click(); await expect(page.getByText("Boucher, S.-P. (2026)")).toBeVisible();20    await expect(page.getByRole("heading", { name: "Version history" })).toBeVisible(); await expect(page.getByRole("heading", { name: "Related research" })).toBeVisible(); await expect(page.getByText(/Why related:/).first()).toBeVisible();21    const href = await page.getByRole("link", { name: /Download PDF/ }).first().getAttribute("href"); const r = await page.request.head(href!); expect(r.status()).toBe(200); expect(r.headers()["content-type"]).toContain("application/pdf");22  });23  test("identifier aliases redirect to the canonical slug; unknown and reserved numbers 404", async ({ page }) => {24    const r1 = await page.request.get("/papers/WP38", { maxRedirects: 0 }); expect(r1.status()).toBe(308); expect(r1.headers().location).toMatch(/\/papers\/wp38$/);25    expect((await page.request.get("/papers/wp999")).status()).toBe(404); expect((await page.request.get("/papers/wp39")).status()).toBe(404);26    const v = await page.request.get("/papers/wp38/v1"); expect(v.status()).toBe(200);27  });28  test("french locale renders translated chrome on the same canonical path", async ({ page }) => {29    await page.goto("/fr/papers/wp38"); await expect(page.locator("html")).toHaveAttribute("lang", "fr"); await expect(page.getByRole("heading", { name: "Résumé" })).toBeVisible(); await expect(page.getByRole("link", { name: /Télécharger le PDF/ }).first()).toBeVisible();30    await page.goto("/fr"); await expect(page.getByRole("heading", { level: 1 })).toHaveText("Cahiers de recherche");31  });32  test("search returns highlighted passages", async ({ page }) => {33    await page.goto("/search?q=hedonic+quebec&mode=lexical"); await expect(page.locator("ol li").first()).toBeVisible(); await expect(page.locator("mark").first()).toBeVisible();34  });35  test("discovery pages render", async ({ page }) => {36    for (const p of ["/topics", "/topics/real-estate-economics", "/methods", "/datasets", "/authors", "/authors/simon-pierre-boucher", "/series", "/timeline", "/research-map", "/about", "/citation", "/api/docs"]) { const r = await page.goto(p); expect(r?.status(), p).toBe(200); await expect(page.getByRole("heading", { level: 1 })).toBeVisible(); }37  });38  test("machine endpoints", async ({ request }) => {39    const bib = await request.get("/api/v1/papers/wp7/citation.bib"); expect(bib.status()).toBe(200); expect(await bib.text()).toContain("@techreport{");40    const oai = await request.get("/api/oai?verb=Identify"); expect(await oai.text()).toContain("<repositoryName>");41    const feed = await request.get("/feed.xml"); expect(feed.headers()["content-type"]).toContain("rss"); const sm = await request.get("/sitemap.xml"); expect(await sm.text()).toContain("/papers/wp38");42    const g = await request.get("/api/v1/graph").then((r) => r.json()); expect(g.nodes.length).toBeGreaterThan(30); expect(g.edges.some((e: { inferred: boolean }) => e.inferred)).toBe(true);43    const h = await request.get("/api/health").then((r) => r.json()); expect(h.ok).toBe(true);44  });45  test("mobile navigation works", async ({ page, isMobile }) => {46    test.skip(!isMobile, "mobile only"); await page.goto("/"); await page.getByRole("button", { name: "Menu" }).click(); await page.locator("#mobile-nav").getByRole("link", { name: "Papers", exact: true }).click(); await expect(page).toHaveURL(/\/papers$/);47  });48});49
Files · main
Menu

Theme