Files
matrix-screen-controller/核桃派软件源代码/scripts/check_font_favorites_browser.mjs
T

80 lines
4.3 KiB
JavaScript

// Caller supplies an isolated browser context. No display/apply operation is performed.
import assert from "node:assert/strict";
export async function checkFontFavoritesBrowser(page, baseUrl, fontId = "default") {
const errors = [];
const onError = error => errors.push(error.message);
page.on("pageerror", onError);
const catalog = await (await page.request.get(`${baseUrl}/api/fonts`)).json();
const originallyFavorite = catalog.favorite_ids.includes(fontId);
const item = catalog.items.find(item => item.id === fontId);
assert.ok(item);
const update = favorite => page.request.put(`${baseUrl}/api/fonts/favorite`, { data: { id: fontId, favorite } });
const rows = () => page.locator(".font-option-row").filter({ has: page.locator(`[data-font-id="${fontId}"]`) });
const draft = () => page.evaluate(async () => JSON.stringify((await import("/static/scene-board.js")).getScene()));
try {
await update(false);
await page.goto(`${baseUrl}/#canvas`);
await page.locator("#new-text-layer").click();
await page.locator("#create-text").click();
const input = page.locator("#text-font");
await input.click();
assert.equal(await page.locator(".font-option-group").first().textContent(), "收藏字体");
const before = await draft();
const selected = await input.inputValue();
await rows().locator("button").first().click();
await page.waitForFunction(id => document.querySelectorAll(`[data-font-id="${id}"]`).length === 2, fontId);
assert.equal(await rows().locator('[aria-pressed="true"]').count(), 2);
assert.equal(await draft(), before);
assert.equal(await input.inputValue(), selected);
const ids = await page.locator('[role="option"]').evaluateAll(options => options.map(option => option.id));
assert.equal(new Set(ids).size, ids.length);
await rows().locator("button").first().click();
await page.locator(".font-favorite-dialog button").first().click();
assert.equal(await rows().count(), 2);
await rows().locator("button").first().click();
await page.keyboard.press("Escape");
assert.equal(await rows().count(), 2);
await input.fill(item.family);
assert.equal(await rows().count(), 2);
await input.press("Home");
await input.press("ArrowDown");
const active = await input.getAttribute("aria-activedescendant");
assert.equal(await page.locator(`[id="${active}"]`).count(), 1);
await input.press("End");
await input.press("Escape");
await input.click();
await input.press("Tab");
assert.equal(await page.locator(".font-favorite-button:focus").count(), 1);
await page.keyboard.press("Enter");
await page.locator(".font-favorite-dialog button").last().click();
await page.waitForFunction(id => document.querySelectorAll(`[data-font-id="${id}"]`).length === 1, fontId);
assert.equal(await draft(), before);
// A failed save keeps both catalog and UI unchanged.
await page.route("**/api/fonts/favorite", route => route.fulfill({ status: 500, contentType: "application/json", body: '{"detail":"injected failure"}' }));
await rows().locator("button").click();
await page.locator("#font-feedback[data-state=error]").waitFor();
assert.equal(await rows().count(), 1);
assert.equal(await rows().locator('[aria-pressed="false"]').count(), 1);
await page.unroute("**/api/fonts/favorite");
// Another browser changes the shared record; reopening reads it.
await input.press("Escape");
const other = await page.context().browser().newContext();
try {
const response = await other.request.put(`${baseUrl}/api/fonts/favorite`, { data: { id: fontId, favorite: true } });
assert.equal(response.status(), 200);
} finally { await other.close(); }
await input.click();
await page.waitForFunction(id => document.querySelectorAll(`[data-font-id="${id}"]`).length === 2, fontId);
assert.equal(await draft(), before);
const bounds = await page.locator("#text-font-options").boundingBox();
assert.ok(bounds.x >= 0 && bounds.x + bounds.width <= page.viewportSize().width + 1);
assert.deepEqual(errors, []);
return { passed: true, width: page.viewportSize().width, duplicateOptions: true, sceneUnchanged: true, errors };
} finally {
await page.unroute("**/api/fonts/favorite");
await update(originallyFavorite);
page.off("pageerror", onError);
}
}