API 参考(Web)

当你需要自定义 Midscene 的浏览器自动化 Agent,或查阅 Web 专属构造参数时,请参考本篇。关于通用参数(报告、Hook、缓存等),请阅读API 参考(通用)

Action Space(动作空间)

PuppeteerAgent、PlaywrightAgent 和 Chrome Bridge 共用一套 Action Space,Midscene Agent 在规划任务时可以使用这些操作:

  • Tap —— 左键点击元素。
  • RightClick —— 右键点击元素。
  • DoubleClick —— 双击元素。
  • Hover —— 悬停目标元素。
  • Input —— 输入文本,支持 replace/append/clear 模式。
  • KeyboardPress —— 按下指定键(可在按键前先聚焦目标)。
  • Scroll —— 以元素为起点或从屏幕中央滚动,支持滚动到顶/底/左/右。
  • DragAndDrop —— 从一个元素拖拽到另一个元素。
  • LongPress —— 长按目标元素,可选自定义时长。
  • Swipe —— 触摸式滑动(开启 enableTouchEventsInActionSpace 时可用)。
  • ClearInput —— 清空输入框内容。
  • Navigate —— 在当前标签页打开指定 URL。
  • Reload —— 刷新当前页面。
  • GoBack —— 浏览器后退。

PuppeteerAgent

当你需要在 Puppeteer 控制的浏览器里复用 Midscene 的 AI 操作能力时使用。

导入

import { PuppeteerAgent } from '@midscene/web/puppeteer';

构造器

const agent = new PuppeteerAgent(page, {
  // 浏览器特有配置...
});

浏览器特有选项

除了通用 Agent 参数,Puppeteer 还提供:

  • forceSameTabNavigation: boolean —— 限制始终在当前标签页内导航,默认 true
  • waitForNavigationTimeout: number —— 当操作触发页面跳转时的最长等待时间,默认 5000(设为 0 表示不等待)。
  • waitForNetworkIdleTimeout: number —— 每次操作后等待网络空闲的时间,默认 2000(设为 0 关闭)。
  • enableTouchEventsInActionSpace: boolean —— 在动作空间里增加触摸手势(如滑动),用于需要触摸事件的页面,默认 false
  • forceChromeSelectRendering: boolean —— 强制 select 元素使用 Chrome 的 base-select 样式,避免系统原生样式导致截图/元素提取不可见;需要 Puppeteer > 24.6.0
  • customActions: DeviceAction[] —— 借助 defineAction 注册自定义动作,让规划器可以调用领域特定步骤。

使用说明

Info
  • 每个页面一个 Agent:默认情况下(forceSameTabNavigation: true)Midscene 会拦截新标签并在当前页打开,便于调试;若想保留新标签行为可设为 false,并为每个标签创建新的 Agent。
  • 更多交互方法请参考 API 参考(通用)

示例

快速上手

import puppeteer from 'puppeteer';
import { PuppeteerAgent } from '@midscene/web/puppeteer';

const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://www.ebay.com');

const agent = new PuppeteerAgent(page, {
  actionContext: 'When a cookie dialog appears, accept it.',
});

await agent.aiAct('search "Noise cancelling headphones" and open first result');
const items = await agent.aiQuery(
  '{itemTitle: string, price: number}[], list two products with price',
);
console.log(items);

await agent.aiAssert('there is a category filter on the left sidebar');
await browser.close();

连接远程 Puppeteer 浏览器

import puppeteer from 'puppeteer';
import { PuppeteerAgent } from '@midscene/web/puppeteer';

const browser = await puppeteer.connect({
  browserWSEndpoint: process.env.REMOTE_CDP_URL!,
});

const [page = await browser.newPage()] = await browser.pages();
const agent = new PuppeteerAgent(page, {
  waitForNetworkIdleTimeout: 0,
});

await agent.aiAct('open https://example.com and click the login button');
await agent.destroy();
await browser.disconnect();

另请参阅

PlaywrightAgent

在 Playwright 浏览器中使用 Midscene 以支持带 AI 的测试或自动化流程。

导入

import { PlaywrightAgent } from '@midscene/web/playwright';

构造器

const agent = new PlaywrightAgent(page, {
  // 浏览器特有配置...
});

浏览器特有选项

  • forceSameTabNavigation: boolean —— 强制在当前标签页内执行,默认 true
  • waitForNavigationTimeout: number —— 等待导航完成的时间,默认 5000(设为 0 关闭)。
  • waitForNetworkIdleTimeout: number —— 每次操作后等待网络空闲的时间,默认 2000(设为 0 关闭)。
  • enableTouchEventsInActionSpace: boolean —— 在动作空间里增加触摸手势(如滑动),用于需要触摸事件的页面,默认 false
  • forceChromeSelectRendering: boolean —— 强制 select 元素使用 Chrome 的 base-select 样式,避免系统原生样式导致截图/元素提取不可见;需要 Playwright ≥ 1.52.0
  • customActions: DeviceAction[] —— 追加项目特有的动作,供规划器调用。

使用说明

Info
  • 每个页面一个 Agent:默认 forceSameTabNavigationtrue,Midscene 会拦截新标签确保稳定性;如需新标签请设为 false 并为每个标签创建新的 Agent。
  • 更多交互方法请参考 API 参考(通用)

示例

快速上手

import { chromium } from 'playwright';
import { PlaywrightAgent } from '@midscene/web/playwright';

const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://www.ebay.com');

const agent = new PlaywrightAgent(page);
await agent.aiAct('search "Noise cancelling headphones" and wait for results');
await agent.aiWaitFor('the results grid becomes visible');

const price = await agent.aiNumber('price of the first headphone');
console.log('first price', price);

await agent.aiTap('click the first result card');
await browser.close();

使用 Midscene fixture 扩展 Playwright 测试

// playwright.config.ts
export default defineConfig({
  reporter: [['list'], ['@midscene/web/playwright-reporter']],
});

// e2e/fixture.ts
import { test as base } from '@playwright/test';
import { PlaywrightAiFixture } from '@midscene/web/playwright';

export const test = base.extend(
  PlaywrightAiFixture({ waitForNetworkIdleTimeout: 1000 }),
);

// e2e/examples.spec.ts
test('search flow', async ({ agentForPage, page }) => {
  await page.goto('https://www.ebay.com');
  const agent = await agentForPage(page);
  await agent.aiAct('search "keyboard" and open first listing');
  await agent.aiAssert('a product detail page is opened');
});

另请参阅

Chrome Bridge Agent

Bridge Mode 允许 Midscene 通过扩展控制当前桌面 Chrome 标签页,而无需再启动独立的自动化浏览器。

导入

import { AgentOverChromeBridge } from '@midscene/web/bridge-mode';

构造器

const agent = new AgentOverChromeBridge({
  allowRemoteAccess: false,
  // 其他桥接配置...
});

桥接配置

  • closeNewTabsAfterDisconnect?: boolean —— 是否在销毁时自动关闭桥接创建的新标签页,默认 false
  • allowRemoteAccess?: boolean —— 是否允许远程机器连接,默认 false(监听 127.0.0.1)。
  • host?: string —— 自定义 Bridge Server 的监听地址,优先级高于 allowRemoteAccess
  • port?: number —— Bridge Server 端口,默认 3766

完整安装与能力说明,见 Chrome 插件桥接模式

使用说明

Info

请先调用 connectCurrentTabconnectNewTabWithUrl 再执行其他操作。每个 AgentOverChromeBridge 只能连接一个标签页;destroy 之后需要重新创建实例。

方法

connectCurrentTab()

function connectCurrentTab(options?: {
  forceSameTabNavigation?: boolean;
}): Promise<void>;
  • options.forceSameTabNavigation(默认 true)会拦截新标签并在当前页打开,方便调试;若想保留新标签行为可设为 false,但需要为每个新标签创建新的 Agent。
  • 连接当前激活标签页,成功后返回 Promise<void>,如果扩展未允许连接会报错。

connectNewTabWithUrl()

function connectNewTabWithUrl(
  url: string,
  options?: { forceSameTabNavigation?: boolean },
): Promise<void>;
  • url —— 新标签页要打开的地址。
  • options —— 与 connectCurrentTab 相同。
  • 打开新标签并连接成功后返回 Promise<void>

destroy()

function destroy(closeNewTabsAfterDisconnect?: boolean): Promise<void>;
  • closeNewTabsAfterDisconnect —— 运行时覆盖构造器配置,为 true 时销毁时关闭桥接创建的新标签页。
  • 清理桥接连接和本地服务完成后返回 Promise<void>

示例

打开新的桌面标签页

import { AgentOverChromeBridge } from '@midscene/web/bridge-mode';

const agent = new AgentOverChromeBridge();
await agent.connectNewTabWithUrl('https://www.bing.com');

await agent.ai('search "AI automation" and summarise first result');
await agent.aiAssert('some search results show up');
await agent.destroy();

附着到当前标签页

import { AgentOverChromeBridge } from '@midscene/web/bridge-mode';

const agent = new AgentOverChromeBridge({
  allowRemoteAccess: false,
  closeNewTabsAfterDisconnect: true,
});

await agent.connectCurrentTab({ forceSameTabNavigation: true });
await agent.aiAct('open Gmail and report how many unread emails are visible');
await agent.destroy();

另请参阅