import { test, expect } from "@playwright/test"; import { MODULES } from "../fixtures/module-list"; import { ConsoleCollector } from "../helpers/console-collector"; for (const mod of MODULES) { test.describe(`demo/${mod.id} (${mod.name})`, () => { test("loads with 200, shell renders, no JS errors", async ({ page }) => { const collector = new ConsoleCollector(page); // Track failed asset requests (CSS/JS) const failedAssets: string[] = []; page.on("response", (res) => { const url = res.url(); if ( (url.endsWith(".js") || url.endsWith(".css") || url.includes(".js?") || url.includes(".css?")) && res.status() >= 400 ) { failedAssets.push(`${res.status()} ${url}`); } }); const response = await page.goto(`/demo/${mod.id}`); expect(response?.status()).toBe(200); // Shell header renders await expect(page.locator("header.rstack-header")).toBeVisible(); // App switcher and identity components are in the DOM await expect(page.locator("rstack-app-switcher")).toBeAttached(); await expect(page.locator("rstack-identity")).toBeAttached(); // Main content area exists await expect(page.locator("#app, main").first()).toBeAttached(); // Primary custom element attached (if module has one) if (mod.primarySelector) { await expect(page.locator(mod.primarySelector)).toBeAttached({ timeout: 10_000 }); } // No failed CSS/JS assets expect(failedAssets, `Failed asset loads:\n${failedAssets.join("\n")}`).toHaveLength(0); // No uncaught JS errors collector.assertNoErrors(); }); }); }