WIP red: mouse editor stale seed and touched (improvise-ugj4, improvise-jibp)
This commit is contained in:
@@ -9,6 +9,19 @@ import { test, expect } from "@playwright/test";
|
||||
// the same with the handshake window).
|
||||
import { NOTICE_KEY } from "../../web/shell.js";
|
||||
|
||||
/** Every string the page posts to its worker, kept on `window.__posted`. */
|
||||
function recordPosts() {
|
||||
window.__posted = [];
|
||||
const post = Worker.prototype.postMessage;
|
||||
Worker.prototype.postMessage = function (message, ...rest) {
|
||||
window.__posted.push(String(message));
|
||||
return post.call(this, message, ...rest);
|
||||
};
|
||||
}
|
||||
|
||||
const setCells = (page) =>
|
||||
page.evaluate(() => window.__posted.filter((m) => m.includes("SetCell")).length);
|
||||
|
||||
async function openApp(page) {
|
||||
await page.goto("/app/index.html");
|
||||
await expect(page.locator("#grid table")).toBeVisible({ timeout: 20_000 });
|
||||
@@ -320,6 +333,76 @@ test.describe("a pointer event reaches the client and its answer is painted", ()
|
||||
await expect.poll(writes).toBe(1);
|
||||
});
|
||||
|
||||
// improvise-jibp. The page reports its first edit, so retyping the seed over
|
||||
// the selection is a write, not an untouched editor.
|
||||
test("a mouse editor typed back to its own seed still writes", async ({ page }) => {
|
||||
await page.addInitScript(recordPosts);
|
||||
await openApp(page);
|
||||
const cells = page.locator("#grid tbody td");
|
||||
await cells.nth(4).click();
|
||||
const input = cells.nth(4).locator("input");
|
||||
await expect(input).toHaveCount(1);
|
||||
const seed = await input.inputValue();
|
||||
expect(seed, "the fixture cell has no seed to retype").not.toBe("");
|
||||
await page.keyboard.type(seed);
|
||||
await expect(input).toHaveValue(seed);
|
||||
await page.keyboard.press("Enter");
|
||||
await expect.poll(() => setCells(page)).toBe(1);
|
||||
});
|
||||
|
||||
// improvise-ugj4. A frame that lands while an editor is open changes the
|
||||
// cache but not the paint; the next editor must open on what it captured.
|
||||
test("an editor opened after an unpainted write shows and commits what it captured", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.addInitScript(recordPosts);
|
||||
await page.addInitScript(() => {
|
||||
window.__frames = [];
|
||||
const add = Worker.prototype.addEventListener;
|
||||
Worker.prototype.addEventListener = function (type, listener, ...rest) {
|
||||
if (type !== "message") return add.call(this, type, listener, ...rest);
|
||||
window.__deliver = (data) => listener.call(this, new MessageEvent("message", { data }));
|
||||
const recorded = (event) => {
|
||||
if (typeof event.data === "string") window.__frames.push(event.data);
|
||||
return listener.call(this, event);
|
||||
};
|
||||
return add.call(this, type, recorded, ...rest);
|
||||
};
|
||||
});
|
||||
await openApp(page);
|
||||
const cells = page.locator("#grid tbody td");
|
||||
const target = cells.nth(4);
|
||||
const where = await target.evaluate((td) => [Number(td.dataset.row), Number(td.dataset.col)]);
|
||||
|
||||
await cells.nth(0).click();
|
||||
await expect(cells.nth(0).locator("input")).toHaveCount(1);
|
||||
// Another client's write to cell 4, delivered while cell 0's editor is open.
|
||||
await page.evaluate(([row, col]) => {
|
||||
let latest = null;
|
||||
const walk = (node) => {
|
||||
if (Array.isArray(node)) node.forEach(walk);
|
||||
else if (node && typeof node === "object") {
|
||||
for (const [key, value] of Object.entries(node)) {
|
||||
if (key === "Cells" && Array.isArray(value)) {
|
||||
for (const [[r, c], cell] of value) if (r === row && c === col) latest = cell;
|
||||
} else walk(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
window.__frames.forEach((f) => walk(JSON.parse(f)));
|
||||
const moved = { ...latest, text: "777", edit_text: "777", value: { Number: 777 } };
|
||||
window.__deliver(JSON.stringify({ Commands: [{ Project: { Grid: { Cells: [[[row, col], moved]] } } }] }));
|
||||
}, where);
|
||||
|
||||
await target.click();
|
||||
const input = target.locator("input");
|
||||
await expect(input).toHaveCount(1);
|
||||
await expect(input, "the editor opened on the stale paint").toHaveValue("777");
|
||||
await page.keyboard.press("Enter");
|
||||
await page.waitForTimeout(300);
|
||||
expect(await setCells(page), "an untouched editor wrote the stale text").toBe(0);
|
||||
});
|
||||
|
||||
// improvise-b8ot moved these five surfaces onto one handler per stable root.
|
||||
// The three tests below are the properties a naive delegation loses, each of
|
||||
// which is silent: the page still paints, and only the pointer stops working.
|
||||
|
||||
Reference in New Issue
Block a user