Botanica/scripts/verify-m3.cjs

163 lines
5.2 KiB
JavaScript

const fs = require("fs");
const { chromium } = require(process.env.PLAYWRIGHT_MODULE || "playwright");
(async () => {
fs.mkdirSync("artifacts/m3", { recursive: true });
const browser = await chromium.launch({
headless: true,
...(process.env.BROWSER_EXECUTABLE
? { executablePath: process.env.BROWSER_EXECUTABLE }
: {}),
});
const page = await browser.newPage({
viewport: { width: 1440, height: 1100 },
reducedMotion: "reduce",
});
const errors = [];
page.on("pageerror", (e) => errors.push(e.message));
await page.goto("http://localhost:8155/lab");
await page
.getByRole("combobox", { name: "Pigment allele A", exact: true })
.waitFor();
const original = await page.locator(".specimen>.plant-preview").innerHTML();
await page
.getByRole("combobox", { name: "Pigment allele A", exact: true })
.selectOption("G");
await page.waitForFunction(() =>
document
.querySelector(".phenotype-inspector")
.textContent.includes("green"),
);
if (original === (await page.locator(".specimen>.plant-preview").innerHTML()))
throw Error("Allele edit did not update illustration");
await page
.getByLabel("Golden veins · manual preview only", { exact: true })
.check();
await page
.getByLabel("Plant name", { exact: true })
.fill("M3 acceptance founder");
const savedResponse = page.waitForResponse(
(r) =>
r.url().endsWith("/api/v1/plants") && r.request().method() === "POST",
);
await page
.getByRole("button", { name: "Save designed plant", exact: true })
.click();
const saved = await (await savedResponse).json();
if (saved.mutations.length || saved.generation !== 0)
throw Error("Manual preview persisted as mutation");
await page.getByText("Saved to your collection.", { exact: false }).waitFor();
await page.screenshot({
path: "artifacts/m3/lab-desktop.png",
fullPage: true,
});
await page
.getByRole("link", { name: "Inspect M3 acceptance founder →", exact: true })
.click();
await page
.getByRole("heading", { name: "M3 acceptance founder", exact: true })
.waitFor();
await page.reload();
await page
.getByRole("heading", { name: "M3 acceptance founder", exact: true })
.waitFor();
await page.goto("http://localhost:8155/breed");
await page
.getByRole("combobox", { name: "Parent A", exact: true })
.selectOption(saved.id);
await page
.getByRole("combobox", { name: "Parent B", exact: true })
.selectOption("10000000-0000-4000-8000-000000000002");
const bredResponse = page.waitForResponse(
(r) =>
r.url().endsWith("/api/v1/breeding") && r.request().method() === "POST",
);
await page
.getByRole("button", { name: "Breed selected parents", exact: true })
.click();
const result = await (await bredResponse).json();
if (
result.plant.parents.join(",") !==
[saved.id, "10000000-0000-4000-8000-000000000002"].join(",") ||
result.plant.generation !== 1
)
throw Error("Incorrect lineage");
await page
.getByRole("heading", { name: "Velvetleaf · generation 1", exact: true })
.waitFor();
await page.screenshot({
path: "artifacts/m3/breed-desktop.png",
fullPage: true,
});
await page
.getByRole("link", { name: "Inspect child & lineage →", exact: true })
.click();
await page
.getByRole("heading", { name: "Velvetleaf · generation 1", exact: true })
.waitFor();
await page.screenshot({
path: "artifacts/m3/lineage-desktop.png",
fullPage: true,
});
await page.reload();
await page
.getByRole("heading", { name: "Velvetleaf · generation 1", exact: true })
.waitFor();
await page
.getByRole("link", {
name: "Parent A · " + saved.id.slice(0, 8) + " →",
exact: true,
})
.click();
await page
.getByRole("heading", { name: "M3 acceptance founder", exact: true })
.waitFor();
for (const route of ["/lab", "/breed", "/plants/" + result.plant.id]) {
await page.setViewportSize({ width: 360, height: 1000 });
await page.goto("http://localhost:8155" + route);
await page
.getByRole("status")
.filter({ hasText: "Laboratory online" })
.waitFor();
if (
await page.evaluate(
() => document.documentElement.scrollWidth > innerWidth,
)
)
throw Error("Mobile overflow " + route);
await page.screenshot({
path:
"artifacts/m3/" +
(route.startsWith("/plants") ? "details" : route.slice(1)) +
"-mobile.png",
fullPage: true,
});
}
if (errors.length) throw Error(errors.join("\n"));
fs.writeFileSync(
"artifacts/m3/browser-checks.json",
JSON.stringify(
{
savedPlantId: saved.id,
childId: result.plant.id,
eventId: result.event.id,
checks: [
"allele preview update",
"manual mutation not persisted",
"saved founder reload",
"persisted cross and generation",
"child reload",
"lineage parent link",
"360px no overflow",
],
errors,
},
null,
2,
),
);
console.log("M3 browser acceptance passed", result.plant.id);
await browser.close();
})().catch((e) => {
console.error(e);
process.exit(1);
});