Playwright JavaScript Execution
This chapter introduces how to execute JavaScript code in Playwright, including page context execution, parameter passing, and initial script injection.
page.evaluate() Page Context Execution
page.evaluate()Execute code in the page's JavaScript environment, with access to the DOM and page global variables.
Example
await page.goto('https://www.example.com/');
// Get the page title (executed in page context)
const title = await page.evaluate(() => {
return document.title;
});
console.log('Page title:', title);
// Get the number of all links on the page
const linkCount = await page.evaluate(() => {
return document.querySelectorAll('a').length;
});
console.log('Number of links:', linkCount);
// Get the page scroll position
const scrollY = await page.evaluate(() => {
return window.scrollY;
});
});
Passing Parameters to evaluate
page.evaluate()Its second parameter is passed to the function inside the page.
Example
await page.goto('https://www.example.com/');
// Pass a single parameter
const result1 = await page.evaluate((name) => {
return `Hello, ${name}!`;
}, 'EXAMPLE');
// Pass an object parameter
const userInfo = { name: 'example', role: 'admin' };
const result2 = await page.evaluate((user) => {
return `${user.name}Its role is ${user.role}`;
}, userInfo);
// Pass multiple parameters (using destructuring)
const result3 = await page.evaluate(
({ x, y }) => {
return x + y;
},
{ x: 10, y: 20 }
);
console.log('10 + 20 =', result3); // 30
});
The passed parameters are JSON-serialized and sent to the page context, so objects that cannot be serialized, such as functions and DOM elements, cannot be passed.
The returned value is also serialized.
locator.evaluate() Element Context Execution
locator.evaluate()Execute code in the context of the matched element; the parameter includes a reference to that element's DOM node.
Example
await page.goto('https://www.example.com/');
// Get the textContent of a specific element
const text = await page
.getByRole('heading', { name: 'EXAMPLE' })
.evaluate(node => node.textContent);
// Get the style attribute of the element
const color = await page
.getByRole('button', { name: 'Search' })
.evaluate(node => getComputedStyle(node).backgroundColor);
});
locator.evaluateAll() Iterating Over All Matching Elements
evaluateAll()Executes the same code for all matched elements and returns an array.
Example
await page.goto('https://www.example.com/');
// Get the text of all menu items
const menuItems = await page
.getByRole('navigation')
.locator('a')
.evaluateAll(links => links.map(link => link.textContent));
console.log('Menu items:', menuItems);
// ['Home', 'Tutorial', 'Tools', ...]
});
page.addInitScript() Injecting Initial Scripts
addInitScript()Inject JavaScript code before the page loads, which canbefore the page scripts executemodify the browser environment.
Example
// Modify the navigator property before the page loads
await page.addInitScript(() => {
// Override WebDriver detection
Object.defineProperty(navigator, 'webdriver', {
get: () => false,
});
// Mock global variables on window
window.EXAMPLE_CONFIG = {
env: 'test',
version: '1.0.0',
};
});
await page.goto('https://www.example.com/');
// Verify that the injected variables take effect
const config = await page.evaluate(() => window.EXAMPLE_CONFIG);
console.log(config); // { env: 'test', version: '1.0.0' }
});
addInitScript()Common use cases:
| Use case | Description |
|---|---|
| Mock browser API | Overridenavigator.webdriver、navigator.languagewait |
| Inject custom configuration | Set test environment variables, mock data sources, etc. |
| Disable features | Turn off Service Worker, disable logging, etc. |
| Polyfill | Add functionality that the page depends on but is missing in the test environment. |
Uses and Limitations of ElementHandle
ElementHandle is a direct reference to a DOM element and was widely used in early versions of Playwright.
In most scenarios now, you should useLocatorinstead of ElementHandle.
Example
const handle = await page.$('.my-element');
await handle.click();
// Locator approach (new style, recommended)
await page.locator('.my-element').click();
ElementHandle is only used when you need to getboundingBox()or when performing complex DOM operations.