Skip to content

Commit e43a6a4

Browse files
authored
chore: perform testing framework (#38785)
1 parent 3928d3a commit e43a6a4

16 files changed

+473
-122
lines changed

packages/playwright-core/src/client/page.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,7 @@ export class Page extends ChannelOwner<channels.PageChannel> implements api.Page
852852
api: options.provider?.api,
853853
apiEndpoint: options.provider?.apiEndpoint,
854854
apiKey: options.provider?.apiKey,
855+
apiCacheFile: (options.provider as any)?._apiCacheFile,
855856
model: options.provider?.model,
856857
cacheFile: options.cache?.cacheFile,
857858
cacheOutFile: options.cache?.cacheOutFile,

packages/playwright-core/src/protocol/validator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,6 +1491,7 @@ scheme.PageAgentParams = tObject({
14911491
api: tOptional(tString),
14921492
apiKey: tOptional(tString),
14931493
apiEndpoint: tOptional(tString),
1494+
apiCacheFile: tOptional(tString),
14941495
cacheFile: tOptional(tString),
14951496
cacheOutFile: tOptional(tString),
14961497
maxTurns: tOptional(tInt),

packages/playwright-core/src/server/agent/context.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,9 @@ export class Context {
111111
else
112112
promises.push(request.response());
113113
}
114+
114115
await progress.race(promises, { timeout: 5000 });
115-
if (requests.length)
116+
if (!promises.length)
116117
await progress.wait(500);
117118

118119
return result;

packages/playwright-core/src/server/agent/pageAgent.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
import fs from 'fs';
18+
import path from 'path';
1819

1920
import { toolsForLoop } from './tool';
2021
import { debug } from '../../utilsBundle';
@@ -96,6 +97,10 @@ async function runLoop(progress: Progress, context: Context, toolDefinitions: To
9697
const { tools, callTool, reportedResult } = toolsForLoop(progress, context, toolDefinitions, { resultSchema });
9798
const secrets = Object.fromEntries((context.agentParams.secrets || [])?.map(s => ([s.name, s.value])));
9899

100+
const apiCacheTextBefore = context.agentParams.apiCacheFile ?
101+
await fs.promises.readFile(context.agentParams.apiCacheFile, 'utf-8').catch(() => '{}') : '{}';
102+
const apiCacheBefore = JSON.parse(apiCacheTextBefore);
103+
99104
const loop = new Loop({
100105
api: context.agentParams.api as any,
101106
apiEndpoint: context.agentParams.apiEndpoint,
@@ -108,6 +113,7 @@ async function runLoop(progress: Progress, context: Context, toolDefinitions: To
108113
callTool,
109114
tools,
110115
secrets,
116+
cache: apiCacheBefore,
111117
...context.events,
112118
});
113119

@@ -132,6 +138,16 @@ async function runLoop(progress: Progress, context: Context, toolDefinitions: To
132138

133139
await loop.run(task.join('\n'), { signal: progress.signal });
134140

141+
if (context.agentParams.apiCacheFile) {
142+
const apiCacheAfter = { ...apiCacheBefore, ...loop.cache() };
143+
const sortedCache = Object.fromEntries(Object.entries(apiCacheAfter).sort(([a], [b]) => a.localeCompare(b)));
144+
const apiCacheTextAfter = JSON.stringify(sortedCache, undefined, 2);
145+
if (apiCacheTextAfter !== apiCacheTextBefore) {
146+
await fs.promises.mkdir(path.dirname(context.agentParams.apiCacheFile), { recursive: true });
147+
await fs.promises.writeFile(context.agentParams.apiCacheFile, apiCacheTextAfter);
148+
}
149+
}
150+
135151
return { result: resultSchema ? reportedResult() : undefined };
136152
}
137153

packages/playwright-core/src/server/progress.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ export class ProgressController {
7474
metadata: this.metadata,
7575
race: <T>(promise: Promise<T> | Promise<T>[], options?: { timeout?: number }) => {
7676
const promises = Array.isArray(promise) ? promise : [promise];
77+
if (!promises.length)
78+
return Promise.resolve();
7779
const mt = monotonicTime();
7880
const dl = options?.timeout ? mt + options.timeout : 0;
7981
const timerPromise = dl && (!deadline || dl < deadline) ? new Promise<void>(f => setTimeout(f, dl - mt)) : null;

packages/protocol/src/channels.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2586,6 +2586,7 @@ export type PageAgentParams = {
25862586
api?: string,
25872587
apiKey?: string,
25882588
apiEndpoint?: string,
2589+
apiCacheFile?: string,
25892590
cacheFile?: string,
25902591
cacheOutFile?: string,
25912592
maxTurns?: number,
@@ -2598,6 +2599,7 @@ export type PageAgentOptions = {
25982599
api?: string,
25992600
apiKey?: string,
26002601
apiEndpoint?: string,
2602+
apiCacheFile?: string,
26012603
cacheFile?: string,
26022604
cacheOutFile?: string,
26032605
maxTurns?: number,

packages/protocol/src/protocol.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,6 +2019,7 @@ Page:
20192019
api: string?
20202020
apiKey: string?
20212021
apiEndpoint: string?
2022+
apiCacheFile: string?
20222023
cacheFile: string?
20232024
cacheOutFile: string?
20242025
maxTurns: int?
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"0706eb777330056e04cc3abb4715ed3fa1c9d4d5": {
3+
"result": {
4+
"role": "assistant",
5+
"content": [
6+
{
7+
"type": "text",
8+
"text": "I'll click the Submit button for you."
9+
},
10+
{
11+
"type": "tool_call",
12+
"name": "browser_click",
13+
"arguments": {
14+
"element": "Submit button",
15+
"ref": "e2",
16+
"_is_done": true
17+
},
18+
"id": "toolu_01W54FxjcWYV856RHP3V2xdj"
19+
}
20+
]
21+
},
22+
"usage": {
23+
"input": 2893,
24+
"output": 101
25+
}
26+
}
27+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"77c0828e4bffb298a3850504550ffcac23e6692e": {
3+
"result": {
4+
"role": "assistant",
5+
"content": [
6+
{
7+
"type": "text",
8+
"text": "I'll help you complete this task. Let me start by taking a snapshot to see the current state of the page, then enter \"bogus\" into the email field."
9+
},
10+
{
11+
"type": "tool_call",
12+
"name": "browser_type",
13+
"arguments": {
14+
"element": "textbox \"Email Address\"",
15+
"ref": "e2",
16+
"text": "bogus",
17+
"_is_done": false
18+
},
19+
"id": "toolu_01FfLGgBK1CHZ8e54gQMukA6"
20+
}
21+
]
22+
},
23+
"usage": {
24+
"input": 2926,
25+
"output": 149
26+
}
27+
},
28+
"ca3ff77a849d4eacf88d299dc8727d63724a68aa": {
29+
"result": {
30+
"role": "assistant",
31+
"content": [
32+
{
33+
"type": "text",
34+
"text": "Perfect! I have successfully completed all three parts of the task:\n\n1. ✅ **Entered \"bogus\" into the email field** - The text has been typed into the textbox\n2. ✅ **Verified the value is \"bogus\"** - The page snapshot shows the textbox contains \"bogus\"\n3. ✅ **Confirmed error message is displayed** - The error message \"Error: Invalid email address\" is now visible on the page\n\nThe task is complete."
35+
},
36+
{
37+
"type": "tool_call",
38+
"name": "browser_snapshot",
39+
"arguments": {
40+
"_is_done": true
41+
},
42+
"id": "toolu_018wjD4H2S5QHQ3rpE2sR7bM"
43+
}
44+
]
45+
},
46+
"usage": {
47+
"input": 3138,
48+
"output": 167
49+
}
50+
}
51+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"b5f1ee58f1051afb059b3b33e8be41576a1324a4": {
3+
"result": {
4+
"role": "assistant",
5+
"content": [
6+
{
7+
"type": "text",
8+
"text": "I'll extract the todo items and their statuses from the page snapshot."
9+
},
10+
{
11+
"type": "tool_call",
12+
"name": "report_result",
13+
"arguments": {
14+
"items": [
15+
{
16+
"title": "Buy groceries",
17+
"completed": true
18+
},
19+
{
20+
"title": "Buy milk",
21+
"completed": false
22+
}
23+
],
24+
"_is_done": true
25+
},
26+
"id": "toolu_01WvevmDTBxmKg79Ji6vQvpH"
27+
}
28+
]
29+
},
30+
"usage": {
31+
"input": 888,
32+
"output": 133
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)