docs/plugins/expose.md
Exposes properties from helper instances as injectable test arguments.
Use it to access the underlying Playwright/Puppeteer page, the wdio browser client,
or any other helper internal directly from a Scenario:
Scenario('listen for requests', async ({ I, page, browser }) => {
page.on('request', r => console.log(r.url()))
await page.evaluate(() => 1 + 1)
I.amOnPage('/')
})
The injected value is a live proxy: every property access reads the current
helper property, so mid-test reassignments (popups, switchToNextTab,
openNewTab) are reflected automatically. Calls are not wrapped as
CodeceptJS steps — await page.evaluate(...) runs as native Playwright.
inject maps an injection name to a HelperName.propertyName string. A
value with no dot is shorthand for "first configured browser helper that
exposes this property" (allowed properties: page, browser,
browserContext, context).
plugins: {
expose: {
enabled: true,
inject: {
page: 'Playwright.page',
browser: 'Playwright.browser',
browserContext: 'Playwright.browserContext',
frame: 'Playwright.context', // current frame set by switchTo
wdio: 'WebDriver.browser',
}
}
}
Shorthand:
plugins: {
expose: {
enabled: true,
inject: {
page: 'page', // resolves to Playwright.page or Puppeteer.page
}
}
}
Proxy, not the actual Page/Browser instance,
so page instanceof Page is false. Use duck typing instead.page.click(...),
not const click = page.click; click(...).undefined; accessing
any property on the proxy returns undefined rather than throwing.config