76 lines
5.5 KiB
JavaScript
76 lines
5.5 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
import { pathToFileURL } from "node:url";
|
|
const { chromium } = await import(pathToFileURL(process.env.PLAYWRIGHT_MODULE).href);
|
|
const output = new URL("../coverage/recovery/", import.meta.url);
|
|
await mkdir(output, { recursive: true });
|
|
const browser = await chromium.launch({ executablePath: process.env.BROWSER_EXECUTABLE_PATH ?? "/usr/bin/google-chrome", headless: true, args: ["--no-sandbox", "--use-angle=swiftshader", "--enable-unsafe-swiftshader"] });
|
|
const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
|
|
const selectedMachine = process.env.RECOVERY_MACHINE ?? "xyzac-trt";
|
|
const suffix = selectedMachine === "xyzac-trt" ? "" : `-${selectedMachine}`;
|
|
if (selectedMachine !== "xyzac-trt") {
|
|
const catalog = JSON.parse(await readFile(new URL("../web/workspace/machine-catalog.json", import.meta.url), "utf8"));
|
|
catalog.default_machine = selectedMachine;
|
|
await page.route(/machine-catalog\.json\?import/, (route) => route.fulfill({ contentType: "text/javascript", body: `export default ${JSON.stringify(catalog)};` }));
|
|
}
|
|
const errors = []; page.on("pageerror", (error) => errors.push(error.message));
|
|
await page.addInitScript(() => {
|
|
window.recoveryMessages = [];
|
|
const NativeWorker = window.Worker;
|
|
window.Worker = class extends NativeWorker {
|
|
constructor(...args) {
|
|
super(...args);
|
|
this.addEventListener("message", ({ data }) => {
|
|
if (!data.payload?.command) return;
|
|
window.recoveryMessages.push({ command: data.payload.command, kind: data.kind, status: data.payload.status, persistence: data.payload.recovery_persistence, recovery: data.payload.power_off_recovery?.status });
|
|
});
|
|
}
|
|
};
|
|
});
|
|
const control = (id) => page.locator(`[data-axis-control="${id}"]`);
|
|
const ready = () => page.waitForFunction(() => document.querySelector("main")?.dataset.axisProgramLoading === "false");
|
|
const joints = () => page.locator(".xyzac-machine-view").evaluate((node) => JSON.parse(node.dataset.xyzacJoints));
|
|
const report = { report_id: "checkpoint-browser-reload-v1", machine: selectedMachine, status: "running" };
|
|
try {
|
|
await page.goto(process.env.XYZAC_PANEL_URL ?? "http://127.0.0.1:5174/"); await ready();
|
|
await control("program-file-input").setInputFiles({ name: "recovery-browser.ngc", mimeType: "text/plain", buffer: Buffer.from("G21 G90\nG1 X8 Y3 Z2 F600\nM2\n") });
|
|
await page.waitForFunction(() => document.querySelector("main")?.dataset.axisProgramPath?.endsWith("recovery-browser.ngc") && document.querySelector("main")?.dataset.axisProgramLoading === "false");
|
|
await control("toolbar-power").click(); await control("manual-home-all").click();
|
|
await page.waitForFunction(() => !document.querySelector('[data-axis-control="manual-axis-x"]').disabled);
|
|
await control("manual-axis-x").check();
|
|
const button = await control("manual-jog-positive").boundingBox();
|
|
await page.mouse.move(button.x + button.width / 2, button.y + button.height / 2); await page.mouse.down();
|
|
await page.waitForFunction(() => JSON.parse(document.querySelector(".xyzac-machine-view").dataset.xyzacJoints)[0] > 2);
|
|
await page.mouse.up();
|
|
await page.waitForFunction(() => window.recoveryMessages.some((row) => row.command === "JOG_STOP"));
|
|
report.before = await joints();
|
|
await control("toolbar-power").click();
|
|
await page.waitForFunction(() => window.recoveryMessages.some((row) => row.command === "POWER" && row.persistence?.status === "verified" && row.persistence?.bytes > 0));
|
|
report.saved = await page.evaluate(() => window.recoveryMessages.filter((row) => row.command === "POWER" && row.persistence?.bytes > 0).at(-1).persistence);
|
|
await page.reload(); await ready();
|
|
await page.waitForFunction(() => window.recoveryMessages.some((row) => row.command === "LOAD_WORKSPACE" && row.recovery === "verified"));
|
|
report.after = await joints();
|
|
report.preview_segments = Number(await page.locator(".xyzac-tool-preview").getAttribute("data-xyzac-toolpath-count"));
|
|
assert.ok(report.preview_segments > 0, "restore must publish the regenerated preview");
|
|
assert.deepEqual(report.after, report.before);
|
|
assert.match(await page.locator("main").getAttribute("data-axis-program-path"), /recovery-browser\.ngc$/);
|
|
assert.equal(await page.evaluate(() => window.recoveryMessages.filter((row) => row.command === "PROGRAM_LOAD").length), 0, "startup must not overwrite the recovered program with the packaged demo");
|
|
await control("toolbar-power").click();
|
|
await control("manual-jog-increment").selectOption("0.1000");
|
|
await control("manual-axis-x").check(); await control("manual-jog-positive").click();
|
|
await page.waitForFunction((start) => JSON.parse(document.querySelector(".xyzac-machine-view").dataset.xyzacJoints)[0] >= start + .0999, report.after[0]);
|
|
report.continued = await joints();
|
|
assert.deepEqual(errors, []); report.status = "verified";
|
|
await page.screenshot({ path: new URL(`browser-reload${suffix}.png`, output).pathname, fullPage: true });
|
|
} catch (error) {
|
|
report.status = "failed"; report.error = String(error.stack ?? error);
|
|
report.messages = await page.evaluate(() => window.recoveryMessages);
|
|
await page.screenshot({ path: new URL(`browser-reload-failure${suffix}.png`, output).pathname, fullPage: true });
|
|
throw error;
|
|
} finally {
|
|
report.browser_errors = errors;
|
|
await writeFile(new URL(`browser-reload${suffix}.report.json`, output), JSON.stringify(report, null, 2) + "\n");
|
|
await browser.close();
|
|
}
|
|
console.log(JSON.stringify(report));
|