Skip to content

Commit fe8f136

Browse files
authored
fix(web-integration): align yaml waitForNetworkIdle behavior and docs (#2279)
1 parent 8673bb5 commit fe8f136

5 files changed

Lines changed: 54 additions & 6 deletions

File tree

apps/site/docs/en/automate-with-scripts-in-yaml.mdx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,14 @@ web:
166166
# Path to a JSON format browser cookie file, optional.
167167
cookie: <path-to-cookie-file>
168168

169-
# The strategy for waiting for network idle, optional.
169+
# The strategy for waiting for network idle in Puppeteer mode, optional.
170+
# `timeout` applies to the initial opening of `web.url` defined in YAML and to later actions such as `aiTap` and `aiInput`.
171+
# `continueOnNetworkIdleError` only applies to the initial opening of `web.url` defined in YAML.
170172
waitForNetworkIdle:
171-
# The timeout in milliseconds, optional, defaults to 2000ms.
173+
# The timeout in milliseconds for each network idle wait, optional, defaults to 2000ms.
172174
timeout: <ms>
173-
# Whether to continue on timeout, optional, defaults to true.
175+
# Whether to continue if the initial opening of `web.url` defined in YAML times out while waiting for network idle, optional, defaults to true.
176+
# Later action-time waits always continue even if they time out.
174177
continueOnNetworkIdleError: <boolean>
175178

176179
# The path to the JSON file for outputting aiQuery/aiAssert results, optional.

apps/site/docs/zh/automate-with-scripts-in-yaml.mdx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,14 @@ web:
165165
# JSON 格式的浏览器 Cookie 文件路径,可选
166166
cookie: <path-to-cookie-file>
167167

168-
# 等待网络空闲的策略,可选
168+
# Puppeteer 模式下等待网络空闲的策略,可选
169+
# `timeout` 会作用于初始打开 YAML 中的 `web.url`,以及后续 `aiTap`、`aiInput` 等操作后的等待
170+
# `continueOnNetworkIdleError` 只作用于初始打开 YAML 中的 `web.url`
169171
waitForNetworkIdle:
170-
# 等待超时时间,可选,默认 2000ms
172+
# 每次网络空闲等待的超时时间,可选,默认 2000ms
171173
timeout: <ms>
172-
# 是否在等待超时后继续,可选,默认 true
174+
# 初始打开 YAML 中的 `web.url` 时,如果网络空闲等待超时,是否继续执行,可选,默认 true
175+
# 后续脚本执行中的等待即使超时也总是继续执行
173176
continueOnNetworkIdleError: <boolean>
174177

175178
# 输出 aiQuery/aiAssert 结果的 JSON 文件路径,可选

packages/web-integration/src/puppeteer/agent-launcher.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,10 @@ export async function puppeteerAgentForTarget(
372372
const agent = new PuppeteerAgent(page, {
373373
...preferenceToUse,
374374
aiActContext,
375+
waitForNetworkIdleTimeout:
376+
typeof target.waitForNetworkIdle?.timeout === 'number'
377+
? target.waitForNetworkIdle.timeout
378+
: undefined,
375379
forceSameTabNavigation:
376380
typeof target.forceSameTabNavigation !== 'undefined'
377381
? target.forceSameTabNavigation

packages/web-integration/tests/unit-test/base-page-invoke-action.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,28 @@ describe('Page - beforeInvokeAction and afterInvokeAction', () => {
276276
expect(mockPage.waitForNetworkIdle).not.toHaveBeenCalled();
277277
});
278278

279+
it('should use the configured network idle timeout', async () => {
280+
const mockPage = {
281+
url: () => 'http://example.com',
282+
mouse: { move: vi.fn() },
283+
keyboard: { down: vi.fn(), up: vi.fn(), press: vi.fn(), type: vi.fn() },
284+
waitForSelector: vi.fn().mockResolvedValue(true),
285+
waitForNetworkIdle: vi.fn().mockResolvedValue(true),
286+
evaluate: vi.fn(),
287+
} as any;
288+
289+
const page = new Page(mockPage, 'puppeteer', {
290+
waitForNetworkIdleTimeout: 4321,
291+
});
292+
await page.afterInvokeAction('testAction', {});
293+
294+
expect(mockPage.waitForNetworkIdle).toHaveBeenCalledWith({
295+
idleTime: 200,
296+
concurrency: 2,
297+
timeout: 4321,
298+
});
299+
});
300+
279301
it('should handle navigation timeout gracefully', async () => {
280302
const consoleWarnSpy = vi
281303
.spyOn(console, 'warn')

packages/web-integration/tests/unit-test/puppeteer/agent-launcher.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
defaultViewportHeight,
33
defaultViewportWidth,
44
launchPuppeteerPage,
5+
puppeteerAgentForTarget,
56
} from '@/puppeteer/agent-launcher';
67
import { beforeEach, describe, expect, it, vi } from 'vitest';
78

@@ -21,6 +22,8 @@ const createPageMock = () => ({
2122
setViewport: vi.fn().mockResolvedValue(undefined),
2223
goto: vi.fn().mockResolvedValue(undefined),
2324
waitForNetworkIdle: vi.fn().mockResolvedValue(undefined),
25+
on: vi.fn(),
26+
isClosed: vi.fn().mockReturnValue(false),
2427
});
2528

2629
vi.mock('puppeteer', () => ({
@@ -67,4 +70,17 @@ describe('launchPuppeteerPage', () => {
6770
expect.objectContaining({ defaultViewport: null }),
6871
);
6972
});
73+
74+
it('passes yaml waitForNetworkIdle settings to the agent for later actions', async () => {
75+
const { agent } = await puppeteerAgentForTarget({
76+
url: 'https://example.com',
77+
forceSameTabNavigation: false,
78+
waitForNetworkIdle: {
79+
timeout: 4321,
80+
continueOnNetworkIdleError: false,
81+
},
82+
});
83+
84+
expect((agent.page as any).waitForNetworkIdleTimeout).toBe(4321);
85+
});
7086
});

0 commit comments

Comments
 (0)