diff --git a/package.json b/package.json index 5905d02..ce1f7bd 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "pg-connection-string": "2.14.1" }, "devDependencies": { - "@playwright/test": "1.56.0", + "@playwright/test": "1.63.0", "fflate": "0.8.3", "prettier": "3.9.9" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4b0e208..0c41968 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -186,8 +186,8 @@ importers: version: 2.14.1 devDependencies: '@playwright/test': - specifier: 1.56.0 - version: 1.56.0 + specifier: 1.63.0 + version: 1.63.0 fflate: specifier: 0.8.3 version: 0.8.3 @@ -249,9 +249,9 @@ packages: '@pgsql/types@18.0.0': resolution: {integrity: sha512-jtAY4JU7jdVYZ/Vv3zlZqVP+FRWZokyCLKPPCnAApiaJAElpyyiMC3HRiquBu29kSrVs+rkqZD50SUIb/zyEGw==} - '@playwright/test@1.56.0': - resolution: {integrity: sha512-Tzh95Twig7hUwwNe381/K3PggZBZblKUe2wv25oIpzWLr6Z0m4KgV1ZVIjnR6GM9ANEqjZD7XsZEa6JL/7YEgg==} - engines: {node: '>=18'} + '@playwright/test@1.63.0': + resolution: {integrity: sha512-oxMK4vllB9RK5NQ2l1pq1IfOf2AvnEuj/vYGDj0H2nMtmtZpKtCwt/l00GEO6xjGfpBNAvjovvYdCm50dRQkpQ==} + engines: {node: '>=20'} hasBin: true '@rolldown/binding-android-arm-eabi@1.2.13': @@ -532,11 +532,6 @@ packages: react-dom: optional: true - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -702,14 +697,14 @@ packages: resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} engines: {node: '>=12'} - playwright-core@1.56.0: - resolution: {integrity: sha512-1SXl7pMfemAMSDn5rkPeZljxOCYAmQnYLBTExuh6E8USHXGSX3dx6lYZN/xPpTz1vimXmPA9CDnILvmJaB8aSQ==} - engines: {node: '>=18'} + playwright-core@1.63.0: + resolution: {integrity: sha512-rYCsBF/M5HjUch52bbtVONEFjv6Xu8sm8h72dNlR5bzIE1fvC/bxgspzkjSfU+MweEMmPM8KJebG6nnyxo5mCg==} + engines: {node: '>=20'} hasBin: true - playwright@1.56.0: - resolution: {integrity: sha512-X5Q1b8lOdWIE4KAoHpW3SE8HvUB+ZZsUoN64ZhjnN8dOb1UpujxBtENGiZFE+9F/yhzJwYa+ca3u43FeLbboHA==} - engines: {node: '>=18'} + playwright@1.63.0: + resolution: {integrity: sha512-+7ziBLidS4NaNCdt57SUDT+wYmmd5fmiQejUic/kb+YsYSCPyOOE9sebzMjNmQrsnNpDJqd4WHvV/8lfKfUDUg==} + engines: {node: '>=20'} hasBin: true postcss@8.5.29: @@ -835,9 +830,9 @@ snapshots: '@pgsql/types@18.0.0': {} - '@playwright/test@1.56.0': + '@playwright/test@1.63.0': dependencies: - playwright: 1.56.0 + playwright: 1.63.0 '@rolldown/binding-android-arm-eabi@1.2.13': optional: true @@ -990,9 +985,6 @@ snapshots: react: 19.3.0 react-dom: 19.3.0(react@19.3.0) - fsevents@2.3.2: - optional: true - fsevents@2.3.3: optional: true @@ -1112,13 +1104,11 @@ snapshots: picomatch@4.0.7: {} - playwright-core@1.56.0: {} + playwright-core@1.63.0: {} - playwright@1.56.0: + playwright@1.63.0: dependencies: - playwright-core: 1.56.0 - optionalDependencies: - fsevents: 2.3.2 + playwright-core: 1.63.0 postcss@8.5.29: dependencies: diff --git a/tests/browser/report-preferences.spec.mjs b/tests/browser/report-preferences.spec.mjs index 6bf7f12..793e8ab 100644 --- a/tests/browser/report-preferences.spec.mjs +++ b/tests/browser/report-preferences.spec.mjs @@ -129,7 +129,6 @@ test("English is the default and theme follows the system until explicitly chose page, }) => { await page.emulateMedia({ colorScheme: "dark" }); - await page.addInitScript(() => localStorage.clear()); await page.goto(reportUrl); await expect(page.locator("html")).toHaveAttribute("lang", "en"); await expect(page.locator("html")).toHaveAttribute("data-theme", "dark"); @@ -141,12 +140,36 @@ test("English is the default and theme follows the system until explicitly chose localStorage.getItem("dbdep-locale"), ]), ).toEqual(["light", "es"]); - // Remove the initialization script by loading the same file in a new page in this context. - const reloaded = await page.context().newPage(); - await reloaded.goto(reportUrl); - await expect(reloaded.locator("html")).toHaveAttribute("lang", "es"); - await expect(reloaded.locator("html")).toHaveAttribute("data-theme", "light"); - await reloaded.close(); + await page.reload(); + await expect(page.locator("html")).toHaveAttribute("lang", "es"); + await expect(page.locator("html")).toHaveAttribute("data-theme", "light"); +}); + +test("report preferences persist between tabs with the same HTTP origin", async ({ + page, + context, +}) => { + // Cross-tab storage sharing is defined for HTTP origins, not file URLs. + const url = "http://127.0.0.1:4173/preference-report.html"; + const body = await readFile(new URL(reportUrl), "utf8"); + await context.route(url, (route) => + route.fulfill({ contentType: "text/html", body }), + ); + await page.emulateMedia({ colorScheme: "light" }); + await page.goto(url); + await page.getByRole("button", { name: "Switch to dark mode" }).click(); + await page.getByRole("button", { name: "EspaƱol", exact: true }).click(); + expect( + await page.evaluate(() => [ + localStorage.getItem("dbdep-theme"), + localStorage.getItem("dbdep-locale"), + ]), + ).toEqual(["dark", "es"]); + const reopened = await context.newPage(); + await reopened.goto(url); + await expect(reopened.locator("html")).toHaveAttribute("lang", "es"); + await expect(reopened.locator("html")).toHaveAttribute("data-theme", "dark"); + await reopened.close(); }); test("preferences remain usable when browser storage throws", async ({ diff --git a/tests/browser/site-docs.spec.mjs b/tests/browser/site-docs.spec.mjs index 4d55018..5e940f1 100644 --- a/tests/browser/site-docs.spec.mjs +++ b/tests/browser/site-docs.spec.mjs @@ -91,6 +91,9 @@ test("the skip link focuses the current documentation page without changing its page, }) => { await page.goto(`${site}/#/docs/installation`); + await expect( + page.getByRole("link", { name: "Skip to content" }), + ).toBeVisible(); await page.keyboard.press("Tab"); await expect( page.getByRole("link", { name: "Skip to content" }),