fix: address final PWA review findings
This commit is contained in:
+34
-3
@@ -3,6 +3,9 @@ import { chromium } from "playwright";
|
||||
|
||||
const BASE = process.env.PWA_BASE_URL || "http://localhost:3000";
|
||||
const baseUrl = BASE.endsWith("/") ? BASE : `${BASE}/`;
|
||||
const OWNER_EMAIL = process.env.PWA_OWNER_EMAIL || "[email protected]";
|
||||
const ADMIN_EMAIL = process.env.PWA_ADMIN_EMAIL || "[email protected]";
|
||||
const PWA_PASSWORD = process.env.PWA_PASSWORD || "demo1234";
|
||||
const NETWORK_TIMEOUT_MS = 8000;
|
||||
const UI_TIMEOUT_MS = 8000;
|
||||
|
||||
@@ -113,9 +116,18 @@ async function dispatchInstallPrompt(page) {
|
||||
}, undefined, { timeout: UI_TIMEOUT_MS });
|
||||
}
|
||||
|
||||
async function dispatchDismissedInstallPrompt(page) {
|
||||
await page.evaluate(() => {
|
||||
const event = new Event("beforeinstallprompt", { cancelable: true });
|
||||
event.prompt = async () => { window.__installPromptCalls += 1; };
|
||||
event.userChoice = Promise.resolve({ outcome: "dismissed", platform: "web" });
|
||||
window.dispatchEvent(event);
|
||||
});
|
||||
}
|
||||
|
||||
async function login(page, email, expectedPath) {
|
||||
await page.fill('input[type="email"]', email);
|
||||
await page.fill('input[type="password"]', "demo1234");
|
||||
await page.fill('input[type="password"]', PWA_PASSWORD);
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForURL(expectedPath, { timeout: UI_TIMEOUT_MS });
|
||||
await page.waitForSelector("header", { state: "attached", timeout: UI_TIMEOUT_MS });
|
||||
@@ -179,6 +191,23 @@ async function main() {
|
||||
await chromiumPage.waitForFunction(() => window.__installPromptCalls === 1);
|
||||
assert.equal(await chromiumPage.evaluate(() => window.__installPromptCalls), 1);
|
||||
|
||||
const dismissalContext = await browser.newContext();
|
||||
contexts.push(dismissalContext);
|
||||
dismissalContext.setDefaultTimeout(UI_TIMEOUT_MS);
|
||||
dismissalContext.setDefaultNavigationTimeout(UI_TIMEOUT_MS);
|
||||
await dismissalContext.addInitScript(() => { window.__installPromptCalls = 0; });
|
||||
const dismissalPage = await dismissalContext.newPage();
|
||||
await dismissalPage.goto(baseUrl, { waitUntil: "networkidle" });
|
||||
await dispatchDismissedInstallPrompt(dismissalPage);
|
||||
const dismissalAction = await assertInstallAction(dismissalPage, true, "dismissal");
|
||||
await dismissalAction.click();
|
||||
await assertInstallAction(dismissalPage, false, "dismissed prompt");
|
||||
assert.equal(await dismissalPage.evaluate(() => sessionStorage.getItem("agendamax-install-dismissed")), "1");
|
||||
await dismissalPage.reload({ waitUntil: "networkidle" });
|
||||
assert.equal(await dismissalPage.evaluate(() => sessionStorage.getItem("agendamax-install-dismissed")), "1");
|
||||
await dispatchDismissedInstallPrompt(dismissalPage);
|
||||
await assertInstallAction(dismissalPage, false, "dismissed prompt after reload");
|
||||
|
||||
const apiResult = await chromiumPage.evaluate(async () => {
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), 8000);
|
||||
@@ -199,7 +228,7 @@ async function main() {
|
||||
const businessPage = await chromiumContext.newPage();
|
||||
await businessPage.setViewportSize({ width: 375, height: 720 });
|
||||
await businessPage.goto(baseUrl, { waitUntil: "networkidle" });
|
||||
await login(businessPage, "[email protected]", /\/dashboard/);
|
||||
await login(businessPage, OWNER_EMAIL, /\/dashboard/);
|
||||
await dispatchInstallPrompt(businessPage);
|
||||
const businessAction = await assertInstallAction(businessPage, true, "business shell");
|
||||
await businessAction.click();
|
||||
@@ -231,7 +260,7 @@ async function main() {
|
||||
await adminContext.addInitScript(() => { window.__installPromptCalls = 0; });
|
||||
const adminPage = await adminContext.newPage();
|
||||
await adminPage.goto(baseUrl, { waitUntil: "networkidle" });
|
||||
await login(adminPage, "[email protected]", /\/admin/);
|
||||
await login(adminPage, ADMIN_EMAIL, /\/admin/);
|
||||
await dispatchInstallPrompt(adminPage);
|
||||
const adminAction = await assertInstallAction(adminPage, true, "admin shell");
|
||||
await adminAction.click();
|
||||
@@ -262,6 +291,8 @@ async function main() {
|
||||
const swSource = (await assertEndpoint("/sw.js")).body;
|
||||
assert.match(swSource, /pathname\s*\.\s*startsWith\s*\(\s*["']\/api\/["']\s*\)/, "Service worker lacks API bypass");
|
||||
assert.match(swSource, /request\s*\.\s*method\s*!==\s*["']GET["']/, "Service worker lacks non-GET guard");
|
||||
assert.match(swSource, /request\.credentials\s*!==\s*["']omit["']/, "Service worker lacks credential bypass");
|
||||
assert.match(swSource, /key\.startsWith\(["']agendamax-shell-["']\)/, "Service worker cleanup is not scoped to AgendaMax caches");
|
||||
console.log("PWA checks passed");
|
||||
} finally {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user