152 lines
5.0 KiB
JavaScript
152 lines
5.0 KiB
JavaScript
import { chromium } from "@playwright/test";
|
|
import assert from "node:assert/strict";
|
|
import { writeFile } from "node:fs/promises";
|
|
|
|
const url = process.env.FDM_URL || "http://127.0.0.1:4178";
|
|
assert.ok((await fetch(url)).ok);
|
|
const browser = await chromium.launch({
|
|
executablePath:
|
|
"C:/Users/ikun/AppData/Local/ms-playwright/chromium_headless_shell-1234/chrome-headless-shell-win64/chrome-headless-shell.exe",
|
|
args: [
|
|
"--enable-webgl",
|
|
"--use-angle=swiftshader",
|
|
"--enable-unsafe-swiftshader",
|
|
],
|
|
});
|
|
const errors = [],
|
|
reports = [];
|
|
try {
|
|
const page = await browser.newPage({
|
|
viewport: { width: 1440, height: 900 },
|
|
});
|
|
page.on("pageerror", (error) => errors.push(error.message));
|
|
const cdp = await page.context().newCDPSession(page);
|
|
await cdp.send("Network.enable");
|
|
await cdp.send("Network.setCacheDisabled", { cacheDisabled: true });
|
|
await page.goto(url);
|
|
await page.waitForSelector("#loading[hidden]", {
|
|
state: "attached",
|
|
timeout: 60000,
|
|
});
|
|
await page.locator('[data-technology="nozzle"]').click();
|
|
const pixels = () => {
|
|
const canvas = document.createElement("canvas");
|
|
canvas.width = 100;
|
|
canvas.height = 100;
|
|
const ctx = canvas.getContext("2d");
|
|
ctx.drawImage(document.querySelector("#scene > canvas"), 0, 0, 100, 100);
|
|
return [...ctx.getImageData(0, 0, 100, 100).data];
|
|
};
|
|
await page.waitForTimeout(300);
|
|
const assembled = await page.evaluate(pixels);
|
|
await page.locator("#disassemble").click();
|
|
await page.waitForFunction(
|
|
() =>
|
|
Number(document.querySelector("#scene").dataset.nozzleExplode) > 0.995,
|
|
);
|
|
assert.ok(
|
|
(await page.evaluate(pixels)).filter((value, i) => value !== assembled[i])
|
|
.length > 100,
|
|
);
|
|
assert.equal(await page.locator(".nozzle-label").count(), 12);
|
|
for (let i = 0; i < 12; i++) {
|
|
await page.locator(".nozzle-label").nth(i).click();
|
|
assert.equal(await page.locator("#nozzle-module").inputValue(), String(i));
|
|
assert.equal(
|
|
await page.locator("#scene").getAttribute("data-nozzle-selected"),
|
|
String(i),
|
|
);
|
|
assert.ok(
|
|
(await page.locator("#nozzle-part-detail").textContent()).length > 20,
|
|
);
|
|
}
|
|
await page.locator("#nozzle-module").selectOption("4");
|
|
for (const [width, height] of [
|
|
[1440, 900],
|
|
[1280, 720],
|
|
[1920, 1080],
|
|
[390, 844],
|
|
]) {
|
|
await page.setViewportSize({ width, height });
|
|
await page.waitForTimeout(500);
|
|
const layout = await page.evaluate(() => {
|
|
const rect = (el) => el.getBoundingClientRect().toJSON();
|
|
return {
|
|
width: document.documentElement.scrollWidth,
|
|
height: document.documentElement.scrollHeight,
|
|
scene: rect(document.querySelector("#scene")),
|
|
labels: [...document.querySelectorAll(".nozzle-label")].map(rect),
|
|
panel: rect(document.querySelector('[data-panel="nozzle"]')),
|
|
foot: rect(
|
|
document.querySelector('[data-panel="nozzle"] .tech-footnote'),
|
|
),
|
|
};
|
|
});
|
|
assert.ok(layout.width <= width);
|
|
if (width >= 1100) {
|
|
assert.ok(layout.height <= height);
|
|
assert.ok(layout.foot.bottom <= layout.panel.bottom + 1);
|
|
}
|
|
layout.labels.forEach((r, i) => {
|
|
assert.ok(r.top >= layout.scene.top && r.bottom <= layout.scene.bottom);
|
|
layout.labels
|
|
.slice(i + 1)
|
|
.forEach((other) =>
|
|
assert.ok(
|
|
r.right <= other.left ||
|
|
r.left >= other.right ||
|
|
r.bottom <= other.top ||
|
|
r.top >= other.bottom,
|
|
),
|
|
);
|
|
});
|
|
const image = await page.evaluate(pixels);
|
|
assert.ok(new Set(image).size > 40);
|
|
await page.screenshot({
|
|
path: `artifacts/nozzle-detailed-${width}.png`,
|
|
fullPage: true,
|
|
});
|
|
reports.push({
|
|
width,
|
|
height,
|
|
scene: layout.scene,
|
|
labels: layout.labels.length,
|
|
});
|
|
}
|
|
await page.setViewportSize({ width: 1440, height: 900 });
|
|
const sceneRect = await page.locator("#scene").boundingBox();
|
|
const beforeDrag = await page.evaluate(pixels);
|
|
await page.mouse.move(
|
|
sceneRect.x + sceneRect.width / 2,
|
|
sceneRect.y + sceneRect.height / 2,
|
|
);
|
|
await page.mouse.down();
|
|
await page.mouse.move(
|
|
sceneRect.x + sceneRect.width / 2 + 80,
|
|
sceneRect.y + sceneRect.height / 2 + 15,
|
|
{ steps: 12 },
|
|
);
|
|
await page.mouse.up();
|
|
await page.waitForTimeout(600);
|
|
assert.ok(
|
|
(await page.evaluate(pixels)).some((value, i) => value !== beforeDrag[i]),
|
|
);
|
|
await page.locator("#assemble").click();
|
|
await page.waitForFunction(
|
|
() =>
|
|
Number(document.querySelector("#scene").dataset.nozzleExplode) < 0.005,
|
|
);
|
|
await page.screenshot({ path: "artifacts/nozzle-assembled.png" });
|
|
await page.locator('[data-technology="model"]').click();
|
|
assert.ok(await page.locator(".nozzle-annotations").isHidden());
|
|
assert.ok(await page.locator(".temperature").isVisible());
|
|
assert.deepEqual(errors, []);
|
|
await writeFile(
|
|
"artifacts/nozzle-report.json",
|
|
JSON.stringify({ reports, errors }, null, 2),
|
|
);
|
|
console.log(JSON.stringify({ reports, errors }, null, 2));
|
|
} finally {
|
|
await browser.close();
|
|
}
|