From 9e886352a188d06ce9d2b5fe123e39f3cbd94865 Mon Sep 17 00:00:00 2001 From: Cheng Shao <terrorjack@type.dance> Date: Mon, 17 Mar 2025 22:36:37 +0000 Subject: [PATCH] wasm: add puppeteer/playwright support for ghci browser mode This commit adds support for using puppeteer/playwright for automatically launching a headless browser that backs the ghci browser mode. This is useful for testing the ghci browser mode as a part of GHC testsuite, and it's also convenient for local development since the step to start iserv can be automated away. (cherry picked from commit fc57679876b660e1d78a63ee2d84d76f498b550c) (cherry picked from commit 760cb5f97f74db3114e58c423b955a44928ef4eb) --- utils/jsffi/dyld.mjs | 78 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/utils/jsffi/dyld.mjs b/utils/jsffi/dyld.mjs index d41b411ba8c..dd84a579aad 100755 --- a/utils/jsffi/dyld.mjs +++ b/utils/jsffi/dyld.mjs @@ -1127,6 +1127,84 @@ export async function main({ rpc, libdir, ghciSoPath, args }) { }); const origin = originFromServerAddress(await server.listening); + // https://pptr.dev/api/puppeteer.consolemessage + // https://playwright.dev/docs/api/class-consolemessage + const on_console_msg = (msg) => { + switch (msg.type()) { + case "error": + case "warn": + case "warning": + case "trace": + case "assert": { + console.error(msg.text()); + break; + } + default: { + console.log(msg.text()); + break; + } + } + }; + + if (process.env.GHCI_BROWSER_PUPPETEER_LAUNCH_OPTS) { + let puppeteer; + try { + puppeteer = require("puppeteer"); + } catch { + puppeteer = require("puppeteer-core"); + } + + // https://pptr.dev/api/puppeteer.puppeteernode.launch + const browser = await puppeteer.launch( + JSON.parse(process.env.GHCI_BROWSER_PUPPETEER_LAUNCH_OPTS) + ); + try { + const page = await browser.newPage(); + + // https://pptr.dev/api/puppeteer.pageevent + page.on("console", on_console_msg); + page.on("error", (err) => console.error(err)); + page.on("pageerror", (err) => console.error(err)); + + await page.goto(`${origin}/main.html`); + await server.closed; + return; + } finally { + await browser.close(); + } + } + + if (process.env.GHCI_BROWSER_PLAYWRIGHT_BROWSER_TYPE) { + let playwright; + try { + playwright = require("playwright"); + } catch { + playwright = require("playwright-core"); + } + + // https://playwright.dev/docs/api/class-browsertype#browser-type-launch + const browser = await playwright[ + process.env.GHCI_BROWSER_PLAYWRIGHT_BROWSER_TYPE + ].launch( + process.env.GHCI_BROWSER_PLAYWRIGHT_LAUNCH_OPTS + ? JSON.parse(process.env.GHCI_BROWSER_PLAYWRIGHT_LAUNCH_OPTS) + : {} + ); + try { + const page = await browser.newPage(); + + // https://playwright.dev/docs/api/class-page#events + page.on("console", on_console_msg); + page.on("pageerror", (err) => console.error(err)); + + await page.goto(`${origin}/main.html`); + await server.closed; + return; + } finally { + await browser.close(); + } + } + console.log( `Open ${origin}/main.html or import ${origin}/main.js to boot ghci` ); -- GitLab