| 1 | // Run against a local Vite server. The real React surface uses a deterministic |
| 2 | // host fixture; Go tests separately exercise the same RPC admission invariants. |
| 3 | import assert from "node:assert/strict"; |
| 4 | import { chromium } from "playwright"; |
| 5 | const browser = await chromium.launch({ headless: true }); |
| 6 | try { |
| 7 | const page = await browser.newPage(); |
| 8 | const errors = []; |
| 9 | page.on("pageerror", error => errors.push(error.message)); |
| 10 | const url = process.env.REASONIX_TRASH_BROWSER_URL || "http://127.0.0.1:4771/bench/trash-lifecycle.html"; |
| 11 | await page.goto(url); |
| 12 | await page.getByRole("button", { name: "Permanently delete Fixture conversation" }).click(); |
| 13 | await page.getByRole("dialog").waitFor(); |
| 14 | await page.evaluate(() => window.trashFixture.changeTarget()); |
| 15 | await page.getByRole("button", { name: "Permanently delete", exact: true }).click(); |
| 16 | await page.getByRole("alert").filter({ hasText: "changed state" }).waitFor(); |
| 17 | assert.equal(await page.evaluate(() => window.trashFixture.requests[0].expectedGeneration), 7); |
| 18 | assert.equal(await page.getByRole("button", { name: "Retry failed items" }).count(), 0); |
| 19 | |
| 20 | await page.reload(); |
| 21 | await page.locator(".archived-sessions__open").click(); |
| 22 | await page.evaluate(() => window.trashFixture.invalidatePreview()); |
| 23 | await page.locator(".archived-sessions__preview").waitFor({ state: "detached" }); |
| 24 | await page.evaluate(() => window.trashFixture.finishPreview()); |
| 25 | assert.equal(await page.getByText("late fixture history").count(), 0); |
| 26 | |
| 27 | await page.reload(); |
| 28 | await page.getByRole("button", { name: "Permanently delete Fixture conversation" }).click(); |
| 29 | await page.evaluate(() => { window.trashFixture.changeOther(); window.trashFixture.loseResult(); }); |
| 30 | await page.getByRole("button", { name: "Permanently delete", exact: true }).click(); |
| 31 | await page.getByRole("button", { name: "Retry failed items" }).waitFor(); |
| 32 | await page.evaluate(() => window.trashFixture.changeOther()); |
| 33 | await page.getByRole("button", { name: "Retry failed items" }).click(); |
| 34 | await page.waitForFunction(() => window.trashFixture.requests.length === 2); |
| 35 | const requests = await page.evaluate(() => window.trashFixture.requests); |
| 36 | assert.deepEqual(requests[0], requests[1]); |
| 37 | assert.equal(requests[1].expectedGeneration, 7); |
| 38 | await page.waitForFunction(() => document.querySelector('[role="status"]')?.textContent?.includes("1")); |
| 39 | assert.deepEqual(errors, []); |
| 40 | console.log("PASS Chromium confirmation snapshot, conflict guidance, preview invalidation, unchanged retry after refresh"); |
| 41 | } finally { await browser.close(); } |
| 42 |