高级自定义代码执行
使用 run-code 执行 CLI 命令未覆盖的高级 Playwright 代码。
语法
playwright-cli run-code "async page => {
// Playwright 代码
}"
playwright-cli run-code --filename=./my-script.js
代码必须是单个函数表达式,不支持 import/export/require。
地理位置
playwright-cli run-code "async page => {
await page.context().grantPermissions(['geolocation']);
await page.context().setGeolocation({ latitude: 37.7749, longitude: -122.4194 });
}"
权限管理
playwright-cli run-code "async page => {
await page.context().grantPermissions(['geolocation', 'notifications', 'camera', 'microphone']);
}"
指定来源的权限:
playwright-cli run-code "async page => {
await page.context().grantPermissions(['clipboard-read'], {
origin: 'https://example.com'
});
}"
媒体模拟
# 暗色主题
playwright-cli run-code "async page => { await page.emulateMedia({ colorScheme: 'dark' }); }"
# 亮色主题
playwright-cli run-code "async page => { await page.emulateMedia({ colorScheme: 'light' }); }"
# 减少动效
playwright-cli run-code "async page => { await page.emulateMedia({ reducedMotion: 'reduce' }); }"
# 打印模式
playwright-cli run-code "async page => { await page.emulateMedia({ media: 'print' }); }"
等待策略
# 等待网络空闲
playwright-cli run-code "async page => { await page.waitForLoadState('networkidle'); }"
# 等待元素消失
playwright-cli run-code "async page => { await page.locator('.loading').waitFor({ state: 'hidden' }); }"
# 等待函数返回 true
playwright-cli run-code "async page => { await page.waitForFunction(() => window.appReady === true); }"
# 带超时等待
playwright-cli run-code "async page => { await page.locator('.result').waitFor({ timeout: 10000 }); }"
iframe 操作
playwright-cli run-code "async page => {
const frame = page.locator('iframe#my-iframe').contentFrame();
await frame.locator('button').click();
}"
# 获取所有 frame
playwright-cli run-code "async page => {
const frames = page.frames();
return frames.map(f => f.url());
}"
文件下载
playwright-cli run-code "async page => {
const downloadPromise = page.waitForEvent('download');
await page.getByRole('link', { name: 'Download' }).click();
const download = await downloadPromise;
await download.saveAs('./downloaded-file.pdf');
return download.suggestedFilename();
}"
剪贴板
# 读取剪贴板(需要权限)
playwright-cli run-code "async page => {
await page.context().grantPermissions(['clipboard-read']);
return await page.evaluate(() => navigator.clipboard.readText());
}"
# 写入剪贴板
playwright-cli run-code "async page => {
await page.evaluate(text => navigator.clipboard.writeText(text), 'Hello clipboard!');
}"
页面信息
playwright-cli run-code "async page => { return await page.title(); }"
playwright-cli run-code "async page => { return page.url(); }"
playwright-cli run-code "async page => { return await page.content(); }"
playwright-cli run-code "async page => { return page.viewportSize(); }"
JavaScript 执行
playwright-cli run-code "async page => {
return await page.evaluate(() => {
return {
userAgent: navigator.userAgent,
language: navigator.language,
cookiesEnabled: navigator.cookieEnabled
};
});
}"
错误处理
playwright-cli run-code "async page => {
try {
await page.getByRole('button', { name: 'Submit' }).click({ timeout: 1000 });
return 'clicked';
} catch (e) {
return 'element not found';
}
}"
复杂工作流
# 登录并保存状态
playwright-cli run-code "async page => {
await page.goto('https://example.com/login');
await page.getByRole('textbox', { name: 'Email' }).fill('user@example.com');
await page.getByRole('textbox', { name: 'Password' }).fill('secret');
await page.getByRole('button', { name: 'Sign in' }).click();
await page.waitForURL('**/dashboard');
await page.context().storageState({ path: 'auth.json' });
return 'Login successful';
}"
# 多页面数据抓取
playwright-cli run-code "async page => {
const results = [];
for (let i = 1; i <= 3; i++) {
await page.goto(`https://example.com/page/${i}`);
const items = await page.locator('.item').allTextContents();
results.push(...items);
}
return results;
}"