| 1 | import path from "node:path"; |
| 2 | import os from "node:os"; |
| 3 | import { fileURLToPath } from "node:url"; |
| 4 | import { createServer } from "vite"; |
| 5 | const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); |
| 6 | process.env.PLAYWRIGHT_BROWSERS_PATH = path.join(root, ".pw-browsers"); |
| 7 | const { chromium } = await import("playwright"); |
| 8 | const server = await createServer({ root, logLevel: "error", server: { host: "127.0.0.1", port: 0 } }); |
| 9 | await server.listen(); |
| 10 | const browser = await chromium.launch({ headless: true }); |
| 11 | const page = await browser.newPage({ viewport: { width: 1000, height: 720 } }); |
| 12 | const errors = []; |
| 13 | page.on("pageerror", e => errors.push(e.message)); |
| 14 | const check = (ok, msg) => { if (!ok) throw new Error(msg); console.log("PASS " + msg); }; |
| 15 | try { |
| 16 | const base = server.resolvedUrls.local[0]; |
| 17 | await page.goto(base + "bench/tool-recovery.html"); |
| 18 | const buttons = page.locator("button"); |
| 19 | await buttons.first().waitFor(); |
| 20 | const viewportHeight = await page.locator(".transcript").evaluate(el => el.clientHeight); |
| 21 | check(await buttons.nth(1).isDisabled(), "confirmation requires inspection"); |
| 22 | check(await buttons.nth(3).isDisabled(), "unknown writer cannot be retried"); |
| 23 | await buttons.nth(0).click(); |
| 24 | await page.waitForFunction(() => !document.querySelectorAll("button")[1].disabled); |
| 25 | await page.locator("details details > summary").click(); |
| 26 | check((await page.locator("pre").textContent()).includes("local receipt"), "inspect shows stored argument receipt"); |
| 27 | check(await page.locator(".transcript").evaluate(el => el.clientHeight) === viewportHeight, "recovery details do not resize the transcript viewport"); |
| 28 | await page.screenshot({ path: path.join(os.tmpdir(), "reasonix-tool-recovery.png") }); |
| 29 | await buttons.nth(1).click(); |
| 30 | await page.waitForFunction(() => document.querySelectorAll("button").length === 1); |
| 31 | await buttons.first().click(); |
| 32 | check(JSON.stringify(await page.evaluate(() => window.recoveryFixture.actions)) === '["inspect","confirm","resume"]', "inspect confirm resume uses backend actions"); |
| 33 | await page.reload(); await buttons.first().waitFor(); |
| 34 | await page.evaluate(() => { window.holdRecovery = true; }); |
| 35 | await buttons.first().click(); |
| 36 | await page.evaluate(() => window.recoveryFixture.render("new-tab")); |
| 37 | await page.waitForFunction(() => document.querySelectorAll("section").length === 0); |
| 38 | await page.evaluate(() => window.recoveryFixture.release()); |
| 39 | check(!(await page.locator("body").textContent()).includes("STALE_RESULT"), "late inspection cannot overwrite a new session"); |
| 40 | check(errors.length === 0, "no browser errors: " + errors.join(";")); |
| 41 | } finally { await browser.close(); await server.close(); } |
| 42 |