Something went wrong. Try again.
[READ-ONLY]
a fast, modern browser for the npm registry forked from npmx.dev/npmx.dev
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091/** * Lighthouse CI puppeteer setup script. * * Sets the color mode (light/dark) before running accessibility audits * and intercepts client-side API requests using the same fixture data * as the Playwright E2E tests. * * The color mode is determined by the LIGHTHOUSE_COLOR_MODE environment variable. * If not set, defaults to 'dark'. * * Request interception uses CDP (Chrome DevTools Protocol) Fetch domain * at the browser level, which avoids conflicts with Lighthouse's own * Puppeteer-level request interception. */
const mockRoutes = require('./test/fixtures/mock-routes.cjs')
module.exports = async function setup(browser, { url }) { const colorMode = process.env.LIGHTHOUSE_COLOR_MODE || 'dark'
// Set up browser-level request interception via CDP Fetch domain. // This operates below Puppeteer's request interception layer so it // doesn't conflict with Lighthouse's own setRequestInterception usage. await setupCdpRequestInterception(browser)
const page = await browser.newPage()
// Set localStorage before navigating so @nuxtjs/color-mode picks it up await page.evaluateOnNewDocument(mode => { localStorage.setItem('npmx-color-mode', mode) }, colorMode)
// Navigate and wait for DOM only - Lighthouse will do its own full load await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 })
// Close the page - Lighthouse will open its own with localStorage already set await page.close()}
/** * Set up request interception using CDP's Fetch domain on the browser's * default context. This intercepts requests at a lower level than Puppeteer's * page.setRequestInterception(), avoiding "Request is already handled!" errors * when Lighthouse sets up its own interception. * * @param {import('puppeteer').Browser} browser */async function setupCdpRequestInterception(browser) { // Build URL pattern list for CDP Fetch.enable from our route definitions const cdpPatterns = mockRoutes.routes.map(route => ({ urlPattern: route.pattern.replace('/**', '/*'), requestStage: 'Request', }))
// Listen for new targets so we can attach CDP interception to each page browser.on('targetcreated', async target => { if (target.type() !== 'page') return
try { const cdp = await target.createCDPSession()
cdp.on('Fetch.requestPaused', async event => { const requestUrl = event.request.url const result = mockRoutes.matchRoute(requestUrl)
if (result) { const body = Buffer.from(result.response.body).toString('base64') await cdp.send('Fetch.fulfillRequest', { requestId: event.requestId, responseCode: result.response.status, responseHeaders: [ { name: 'Content-Type', value: result.response.contentType }, { name: 'Access-Control-Allow-Origin', value: '*' }, ], body, }) } else { await cdp.send('Fetch.continueRequest', { requestId: event.requestId, }) } })
await cdp.send('Fetch.enable', { patterns: cdpPatterns }) } catch { // Target may have been closed before we could attach. // This is expected for transient targets like service workers. } })}