import { chromium } from "@playwright/test"; import { existsSync } from "node:fs"; const baseUrl = process.argv[2] || "http://localhost:5173/?device=wasm"; const executablePath = process.env.CHROMIUM_PATH || (existsSync("/usr/bin/google-chrome") ? "/usr/bin/google-chrome" : "/snap/bin/chromium"); const maxNewTokens = process.env.MAX_NEW_TOKENS || "80"; const browser = await chromium.launch({ executablePath, headless: true, args: ["--no-sandbox", "--disable-dev-shm-usage"], }); try { const page = await browser.newPage(); page.setDefaultTimeout(600000); const consoleLines = []; page.on("console", (message) => { consoleLines.push(`${message.type()}: ${message.text()}`); }); page.on("pageerror", (error) => { consoleLines.push(`pageerror: ${error.stack || error.message}`); }); await page.goto(baseUrl, { waitUntil: "networkidle" }); await page.waitForFunction(() => document.querySelector("#status")?.textContent === "Ready"); const isolated = await page.evaluate(() => globalThis.crossOriginIsolated); if (!isolated) throw new Error("Page is not cross-origin isolated."); await page.fill("#max-new-tokens", maxNewTokens); await page.fill("#temperature", "0"); await page.selectOption("#gate-device", "wasm"); await page.click("#confirm-load-model"); await page.waitForFunction(() => window.__piWebAgent?.modelReady === true, null, { timeout: 600000, }); await page.click("#send"); await page.waitForFunction(() => document.querySelector("#status")?.textContent === "Agent running", null, { timeout: 120000, }); await page.waitForFunction(() => document.querySelector("#status")?.textContent === "Ready", null, { timeout: 600000, }); await page.waitForFunction(() => window.__piWebAgent?.transcript?.includes("42"), null, { timeout: 120000, }); const transcript = await page.evaluate(() => window.__piWebAgent?.transcript || ""); const chatText = await page.textContent("#chat"); const files = await page.textContent("#files"); const events = await page.textContent("#event-log"); const modelStatus = await page.textContent("#model-status"); if (!transcript.includes("42") || !chatText?.includes("42")) { throw new Error(`Expected command output in chat transcript.\n\nTranscript:\n${transcript}\n\nChat:\n${chatText}\n\nEvents:\n${events}`); } if (!files?.includes("hello.js")) { throw new Error(`Expected hello.js in file listing.\n\nFiles:\n${files}`); } if (modelStatus !== "Model ready") { throw new Error(`Expected local model status to be ready, got: ${modelStatus}`); } console.log(JSON.stringify({ ok: true, isolated, maxNewTokens, modelStatus, transcript, files }, null, 2)); } catch (error) { console.error(error instanceof Error ? error.stack || error.message : String(error)); throw error; } finally { await browser.close(); }