Something went wrong. Try again.
Monorepo for the nibling.run platform
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123import { expect, test, type Page } from "@playwright/test";import { run, terminalInput, terminalLog } from "./fixtures/terminal.ts";
/** * The demo project's `npm run dev` (node:http on port 3000, served from `index.ts`) from the * Processes panel and from the terminal. Set NIB_SHOTS to a directory to also save screenshots there. */
const escape = (text: string) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");const tab = (page: Page, title: string) => page.locator("nib-tablist > nib-tab").filter({ hasText: new RegExp(`^${escape(title)}×?$`) });const processes = (page: Page) => page.locator("nib-processes");const list = (page: Page) => processes(page).getByRole("list", { name: "Processes", exact: true });const server = (page: Page) => page.frameLocator("nib-browser iframe");const shoot = async (page: Page, name: string) => { if (process.env.NIB_SHOTS) await page.screenshot({ path: `${process.env.NIB_SHOTS}/processes-${name}.png`, animations: "disabled" });};
test.use({ viewport: { width: 1280, height: 800 } });
test.beforeEach(async ({ page }) => { await page.goto("/new?reset"); await tab(page, "Processes").click();});
test("Run dev starts the server, the Preview panel binds to it, and Stop ends it", async ({ page }) => { await expect(processes(page).getByRole("status")).toHaveText("No processes. Run a script, or npm run dev in the terminal.", { timeout: 20_000 }); const empty = page.locator("nib-browser").getByRole("region", { name: "No server is running" }); await expect(empty).toHaveText("No server is runningRun npm run dev in the terminal, or Run dev in Processes."); await expect(tab(page, "Preview")).toHaveJSProperty("selected", true); await expect(page.locator("nib-browser iframe")).toHaveCount(0); await processes(page).getByRole("button", { name: "Run dev" }).click();
const npm = list(page).getByRole("listitem").filter({ hasText: "npm run dev" }); const child = npm.getByRole("list", { name: "Started by npm run dev" }).getByRole("listitem"); await expect(child).toHaveCount(1, { timeout: 20_000 }); await expect(child.getByText("node index.ts", { exact: true })).toBeVisible(); await expect(child.getByRole("button", { name: "Open localhost:3000" })).toHaveText("localhost:3000"); await expect(tab(page, "localhost:3000")).toHaveJSProperty("selected", true); await expect(server(page).getByRole("heading", { level: 1 })).toHaveText("Hello from nibling"); await expect(page.locator("nib-browser")).toHaveCount(1); await expect(tab(page, "Preview")).toHaveCount(0); await shoot(page, "running");
// The script ran in the terminal, where its output and Ctrl+C are. await tab(page, "Terminal").click(); await expect(terminalLog(page)).toContainText("~ $ npm run dev\n"); await expect(terminalLog(page)).toContainText("Listening on http://localhost:3000/"); await tab(page, "Processes").click();
await npm.getByRole("button", { name: /^Stop npm run dev/ }).first().click(); await expect(list(page).getByRole("listitem")).toHaveCount(0); await expect(page.locator("nib-browser").getByRole("status")).toHaveText("Waiting for localhost:3000…"); await shoot(page, "stopped");});
test("npm run dev in the terminal does the same, and a closed auto-opened panel stays closed", async ({ page }) => { await tab(page, "Terminal").click(); await run(page, "npm run dev"); await expect(server(page).getByRole("heading", { level: 1 })).toHaveText("Hello from nibling", { timeout: 20_000 }); await expect(terminalLog(page)).toContainText("Listening on http://localhost:3000/");
await tab(page, "Processes").click(); await expect(list(page).getByRole("button", { name: "Open localhost:3000" })).toBeVisible(); await tab(page, "localhost:3000").locator("[part=close]").click(); await expect(page.locator("nib-browser")).toHaveCount(0);
// Ctrl+C reaches npm, which passes it to the server; running it again leaves the closed panel closed. await tab(page, "Terminal").click(); await terminalInput(page).focus(); await page.keyboard.press("Control+c"); await tab(page, "Processes").click(); await expect(list(page).getByRole("listitem")).toHaveCount(0); await tab(page, "Terminal").click(); await run(page, "npm run dev"); await tab(page, "Processes").click(); await expect(list(page).getByRole("button", { name: "Open localhost:3000" })).toBeVisible({ timeout: 20_000 }); await expect(page.locator("nib-browser")).toHaveCount(0);
// The port button opens it by hand. await list(page).getByRole("button", { name: "Open localhost:3000" }).click(); await expect(server(page).getByRole("heading", { level: 1 })).toHaveText("Hello from nibling");});
test("the bound Preview stays bound across a reload, waiting until its server runs again", async ({ page }) => { await processes(page).getByRole("button", { name: "Run dev" }).click(); await expect(server(page).getByRole("heading", { level: 1 })).toHaveText("Hello from nibling", { timeout: 20_000 });
await page.goto("/new"); await expect(tab(page, "localhost:3000")).toHaveCount(1); await expect(tab(page, "Preview")).toHaveCount(0); await expect(page.locator("nib-browser").getByRole("status")).toHaveText("Waiting for localhost:3000…"); await tab(page, "Processes").click(); await processes(page).getByRole("button", { name: "Run dev" }).click(); await expect(server(page).getByRole("heading", { level: 1 })).toHaveText("Hello from nibling", { timeout: 20_000 }); await expect(page.locator("nib-browser")).toHaveCount(1);});
test("with the Preview closed, Run dev opens a browser panel of its own", async ({ page }) => { await tab(page, "Preview").locator("[part=close]").click(); await expect(page.locator("nib-browser")).toHaveCount(0); await processes(page).getByRole("button", { name: "Run dev" }).click(); await expect(server(page).getByRole("heading", { level: 1 })).toHaveText("Hello from nibling", { timeout: 20_000 }); await expect(page.locator("nib-browser")).toHaveCount(1); await expect(tab(page, "localhost:3000")).toHaveJSProperty("selected", true); await expect(tab(page, "Preview")).toHaveCount(0);});
test("a browser panel restored before its server runs waits, then loads, and reloads when the server restarts", async ({ page }) => { await page.evaluate(() => (globalThis as unknown as { workbench: import("../src/shell/index.ts").Workbench }).workbench.open( { kind: "browser", input: { url: "http://localhost:3000/" } }, )); await expect(page.locator("nib-browser").getByRole("status")).toHaveText("Waiting for localhost:3000…"); await processes(page).getByRole("button", { name: "Run dev" }).click(); await expect(server(page).getByRole("heading", { level: 1 })).toHaveText("Hello from nibling", { timeout: 20_000 });
await list(page).getByRole("button", { name: /^Stop npm run dev/ }).click(); await expect(page.locator("nib-browser").getByRole("status")).toHaveText("Waiting for localhost:3000…"); await processes(page).getByRole("button", { name: "Run dev" }).click(); await expect(server(page).getByRole("heading", { level: 1 })).toHaveText("Hello from nibling", { timeout: 20_000 }); await expect(page.locator("nib-browser")).toHaveCount(2); await expect(page.locator("nib-browser").getByRole("region", { name: "No server is running" })).toHaveCount(1);});