Skip to main content

评估 JavaScript

介绍

¥Introduction

Playwright 脚本在你的 Playwright 环境中运行。你的页面脚本在浏览器页面环境中运行。这些环境并不交叉,它们运行在不同进程的不同虚拟机中,甚至可能运行在不同的计算机上。

¥Playwright scripts run in your Playwright environment. Your page scripts run in the browser page environment. Those environments don't intersect, they are running in different virtual machines in different processes and even potentially on different computers.

page.evaluate() API 可以在网页上下文中运行 JavaScript 函数,并将结果带回 Playwright 环境。像 windowdocument 这样的浏览器全局变量可以在 evaluate 中使用。

¥The page.evaluate() API can run a JavaScript function in the context of the web page and bring results back to the Playwright environment. Browser globals like window and document can be used in evaluate.

const href = await page.evaluate(() => document.location.href);

如果结果是 Promise 或者函数是异步的,则评估将自动等待直到解决:

¥If the result is a Promise or if the function is asynchronous evaluate will automatically wait until it's resolved:

const status = await page.evaluate(async () => {
const response = await fetch(location.href);
return response.status;
});

评价参数

¥Evaluation Argument

page.evaluate() 这样的 Playwright 评估方法采用单个可选参数。该参数可以是 可串行化 值和 JSHandleElementHandle 实例的混合。句柄会自动转换为其代表的值。

¥Playwright evaluation methods like page.evaluate() take a single optional argument. This argument can be a mix of Serializable values and JSHandle or ElementHandle instances. Handles are automatically converted to the value they represent.

// A primitive value.
await page.evaluate(num => num, 42);

// An array.
await page.evaluate(array => array.length, [1, 2, 3]);

// An object.
await page.evaluate(object => object.foo, { foo: 'bar' });

// A single handle.
const button = await page.evaluateHandle('window.button');
await page.evaluate(button => button.textContent, button);

// Alternative notation using elementHandle.evaluate.
await button.evaluate((button, from) => button.textContent.substring(from), 5);

// Object with multiple handles.
const button1 = await page.evaluateHandle('window.button1');
const button2 = await page.evaluateHandle('window.button2');
await page.evaluate(
o => o.button1.textContent + o.button2.textContent,
{ button1, button2 });

// Object destructuring works. Note that property names must match
// between the destructured object and the argument.
// Also note the required parenthesis.
await page.evaluate(
({ button1, button2 }) => button1.textContent + button2.textContent,
{ button1, button2 });

// Array works as well. Arbitrary names can be used for destructuring.
// Note the required parenthesis.
await page.evaluate(
([b1, b2]) => b1.textContent + b2.textContent,
[button1, button2]);

// Any non-cyclic mix of serializables and handles works.
await page.evaluate(
x => x.button1.textContent + x.list[0].textContent + String(x.foo),
{ button1, list: [button2], foo: null });

正确的:

¥Right:

const data = { text: 'some data', value: 1 };
// Pass |data| as a parameter.
const result = await page.evaluate(data => {
window.myApp.use(data);
}, data);

错误的:

¥Wrong:

const data = { text: 'some data', value: 1 };
const result = await page.evaluate(() => {
// There is no |data| in the web page.
window.myApp.use(data);
});