Why is page.goto never awaited for Firefox addons pages in Puppeteer?
PuppeteerSummary
Firefox addon pages navigated via moz-extension:// are treated as webextension contexts. Puppeteer currently does not emit the usual navigation events (like domContentLoaded or load) for such pages, so page.goto may not resolve as expected in this context.
Why this happens
- Firefox treats moz-extension pages as webextension contexts. In this scenario, Puppeteer does not start modules that emit the load/domContentLoaded events for these pages.
- While some navigation events may surface (e.g., navigationCommitted), the key DOM load events are not reliably emitted for addon pages, which leads to the navigation promise not resolving in the expected way.
- This is a Firefox behavior/limitation rather than a straightforward Puppeteer bug fix.
Practical guidance
- Do not rely on domContentLoaded or load to determine that a moz-extension navigation is complete.
- Instead, proceed after a short fixed delay or wait for a known UI element within the addon page to become available before interacting.
- If you need to interact with UI, target known selectors directly rather than waiting for navigation lifecycle events.
Minimal workaround (avoid waiting for dom loaded)
// Skip waiting for dom loaded when testing firefox addon pages
const internalUUID = await readInternalUuidSomehow() // your logic to obtain addon id
page.goto(`moz-extension://${internalUUID}/static/app.html`)
await sleep(0.5)
await page.focus('#my-input')
// Working for typing letters
await page.keyboard.type('foobar')
// Not relying on domContentLoaded to proceed
Notes
- This limitation is tied to how Firefox handles addon contexts and is not a Puppeteer feature toggle. See discussions around webextension contexts and navigation events for moz-extension pages for context.