@empiricalrun/playwright-utils 0.58.5 → 0.58.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/dist/api-worker-client.d.ts +17 -0
- package/dist/api-worker-client.d.ts.map +1 -1
- package/dist/api-worker-client.js +34 -2
- package/dist/generated/api-worker-openapi.d.ts +96 -89
- package/dist/generated/api-worker-openapi.d.ts.map +1 -1
- package/dist/overlay-tests/cache.spec.js +28 -4
- package/dist/reporter/test-case-sync.d.ts +2 -25
- package/dist/reporter/test-case-sync.d.ts.map +1 -1
- package/dist/test/expect/visual.d.ts.map +1 -1
- package/dist/test/expect/visual.js +4 -1
- package/dist/test/scripts/pw-locator-patch/dismiss-overlays/index.d.ts.map +1 -1
- package/dist/test/scripts/pw-locator-patch/dismiss-overlays/index.js +5 -0
- package/dist/test/scripts/pw-locator-patch/vision/query.d.ts.map +1 -1
- package/dist/test/scripts/pw-locator-patch/vision/query.js +4 -1
- package/package.json +4 -4
|
@@ -20,6 +20,25 @@ const useCache = (data) => {
|
|
|
20
20
|
}
|
|
21
21
|
fs_1.default.writeFileSync(cache_1.CACHE_FILE, JSON.stringify(cacheValue, null, 2), "utf8");
|
|
22
22
|
};
|
|
23
|
+
// Unsets env vars for the duration of a test and puts them back exactly as they
|
|
24
|
+
// were — assigning `undefined` to process.env would store the string
|
|
25
|
+
// "undefined", which reads as a present (and truthy) credential.
|
|
26
|
+
function clearEnv(names) {
|
|
27
|
+
const saved = names.map((name) => [name, process.env[name]]);
|
|
28
|
+
for (const name of names) {
|
|
29
|
+
delete process.env[name];
|
|
30
|
+
}
|
|
31
|
+
return () => {
|
|
32
|
+
for (const [name, value] of saved) {
|
|
33
|
+
if (value === undefined) {
|
|
34
|
+
delete process.env[name];
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
process.env[name] = value;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
23
42
|
fixtures_1.test.beforeEach(async ({ page }) => {
|
|
24
43
|
(0, test_1.injectLocatorHighlightScripts)(page, fixtures_1.test);
|
|
25
44
|
});
|
|
@@ -39,9 +58,12 @@ fixtures_1.test.afterEach(() => {
|
|
|
39
58
|
]);
|
|
40
59
|
await page.goto(`${server.baseURL}/glass-pane.html`);
|
|
41
60
|
let error;
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
61
|
+
// The only two routes the browser agent has to a model: the project API key
|
|
62
|
+
// (api-worker's proxy) and a sandbox's OPENAI_BASE_URL. Clearing both makes
|
|
63
|
+
// llmProxyOpenAIConfig throw before any request — which matters here more
|
|
64
|
+
// than elsewhere, because this is the recursive case and every extra
|
|
65
|
+
// dismissal would spawn another agent and another set of screenshots.
|
|
66
|
+
const restoreEnv = clearEnv(["EMPIRICALRUN_API_KEY", "OPENAI_BASE_URL"]);
|
|
45
67
|
try {
|
|
46
68
|
// Target element click will trigger the cache - which will invoke another
|
|
47
69
|
// click to the same element (recursive overlay dismissal)
|
|
@@ -50,7 +72,9 @@ fixtures_1.test.afterEach(() => {
|
|
|
50
72
|
catch (e) {
|
|
51
73
|
error = e;
|
|
52
74
|
}
|
|
75
|
+
finally {
|
|
76
|
+
restoreEnv();
|
|
77
|
+
}
|
|
53
78
|
(0, fixtures_1.expect)(error).toBeDefined();
|
|
54
|
-
process.env.OPENAI_API_KEY = originalApiKey;
|
|
55
79
|
(0, fixtures_1.expect)(error.message).toContain('<div class="glass-pane"></div> intercepts pointer events');
|
|
56
80
|
});
|
|
@@ -1,28 +1,5 @@
|
|
|
1
|
+
import type { TestCaseSyncManifest } from "@empiricalrun/shared-types/playwright-utils";
|
|
1
2
|
import type { FullConfig, Suite } from "@playwright/test/reporter";
|
|
2
|
-
export
|
|
3
|
-
id: string;
|
|
4
|
-
name: string;
|
|
5
|
-
file_path: string;
|
|
6
|
-
suites: string[];
|
|
7
|
-
playwright_project: string;
|
|
8
|
-
tags: string[];
|
|
9
|
-
}
|
|
10
|
-
export interface TestCaseDependencyGroupMember {
|
|
11
|
-
test_case_id: string;
|
|
12
|
-
dependency_order: number;
|
|
13
|
-
}
|
|
14
|
-
export interface TestCaseDependencyGroup {
|
|
15
|
-
id: string;
|
|
16
|
-
kind: "playwright_serial";
|
|
17
|
-
file_path: string;
|
|
18
|
-
title_path: string[];
|
|
19
|
-
playwright_project: string;
|
|
20
|
-
members: TestCaseDependencyGroupMember[];
|
|
21
|
-
}
|
|
22
|
-
export interface TestCaseSyncManifest {
|
|
23
|
-
version: 1;
|
|
24
|
-
test_cases: TestCaseSyncTestCase[];
|
|
25
|
-
dependency_groups: TestCaseDependencyGroup[];
|
|
26
|
-
}
|
|
3
|
+
export type { TestCaseDependencyGroup, TestCaseDependencyGroupMember, TestCaseSyncManifest, TestCaseSyncTestCase, } from "@empiricalrun/shared-types/playwright-utils";
|
|
27
4
|
export declare function collectTestCaseSyncManifest(config: FullConfig, rootSuite: Suite): TestCaseSyncManifest;
|
|
28
5
|
//# sourceMappingURL=test-case-sync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-case-sync.d.ts","sourceRoot":"","sources":["../../src/reporter/test-case-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"test-case-sync.d.ts","sourceRoot":"","sources":["../../src/reporter/test-case-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,oBAAoB,EAErB,MAAM,6CAA6C,CAAC;AACrD,OAAO,KAAK,EACV,UAAU,EAEV,KAAK,EAEN,MAAM,2BAA2B,CAAC;AAUnC,YAAY,EACV,uBAAuB,EACvB,6BAA6B,EAC7B,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,6CAA6C,CAAC;AA+JrD,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,KAAK,GACf,oBAAoB,CAuBtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"visual.d.ts","sourceRoot":"","sources":["../../../src/test/expect/visual.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAY,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"visual.d.ts","sourceRoot":"","sources":["../../../src/test/expect/visual.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAY,MAAM,kBAAkB,CAAC;AAUhE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AA0E7C,wBAAsB,WAAW,CAC/B,MAAM,EAAE,IAAI,GAAG,OAAO,EACtB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,aAAa,CAAC,CA2FxB"}
|
|
@@ -10,6 +10,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
10
10
|
const openai_1 = __importDefault(require("openai"));
|
|
11
11
|
const os_1 = __importDefault(require("os"));
|
|
12
12
|
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const api_worker_client_1 = require("../../api-worker-client");
|
|
13
14
|
const mouse_pointer_1 = require("../scripts/mouse-pointer");
|
|
14
15
|
function getCallerLine() {
|
|
15
16
|
const stack = new Error().stack;
|
|
@@ -85,7 +86,9 @@ async function toLookRight(target, pageDescription) {
|
|
|
85
86
|
const base64Image = screenshot.toString("base64");
|
|
86
87
|
await (0, mouse_pointer_1.addHighlighterScriptsToPage)(page);
|
|
87
88
|
const model = "gpt-4o";
|
|
88
|
-
|
|
89
|
+
// Same api-worker proxy the overlay-dismissal agent uses, so a test run needs
|
|
90
|
+
// no OpenAI key of its own; undefined falls back to the SDK's env defaults.
|
|
91
|
+
const openai = new openai_1.default({ maxRetries: 5, ...(0, api_worker_client_1.llmProxyOpenAIConfig)() });
|
|
89
92
|
const completion = await openai.chat.completions.create({
|
|
90
93
|
model,
|
|
91
94
|
messages: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAIxC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAK9C,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,WAKhE;AAED,qBAAa,mBAAmB;IAOlB,OAAO,CAAC,QAAQ,CAAC,IAAI;IANjC,OAAO,CAAC,iBAAiB,CAIhB;IAET,YAA6B,IAAI,EAAE,IAAI,EAAI;IAErC,WAAW,kBAIhB;IAEK,GAAG,CACP,aAAa,EAAE,GAAG,EAClB,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,EACvC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAuDf;YAEa,QAAQ;CAqCvB;AAED,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,GACnB,cAAc,GAAG,SAAS,CAiC5B"}
|
|
@@ -4,6 +4,7 @@ exports.OverlayDismissAgent = void 0;
|
|
|
4
4
|
exports.isErrorSupported = isErrorSupported;
|
|
5
5
|
exports.extractInterceptingElement = extractInterceptingElement;
|
|
6
6
|
const cua_1 = require("@empiricalrun/cua");
|
|
7
|
+
const api_worker_client_1 = require("../../../../api-worker-client");
|
|
7
8
|
const telemetry_1 = require("../../../../telemetry");
|
|
8
9
|
const cache_1 = require("./cache");
|
|
9
10
|
const prompt_1 = require("./prompt");
|
|
@@ -99,6 +100,10 @@ class OverlayDismissAgent {
|
|
|
99
100
|
// already on the current page. Including page_goto causes the model
|
|
100
101
|
// to waste turns trying to navigate instead of clicking dismiss.
|
|
101
102
|
includePageGotoTool: false,
|
|
103
|
+
// Route the model call through api-worker (Cloudflare AI Gateway) on the
|
|
104
|
+
// project API key, so test-run containers carry no OpenAI key. Undefined
|
|
105
|
+
// on a dev machine or in a pi sandbox — see the helper.
|
|
106
|
+
openAIClientConfig: (0, api_worker_client_1.llmProxyOpenAIConfig)(),
|
|
102
107
|
});
|
|
103
108
|
this.cachingCandidates.push({
|
|
104
109
|
dom: element?.interceptor,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/vision/query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/vision/query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAIhD,wBAAgB,UAAU,CAAC,YAAY,EAAE,QAAQ,GAAG;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,QASzE"}
|
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.patchQuery = patchQuery;
|
|
4
4
|
const vision_1 = require("@empiricalrun/llm/vision");
|
|
5
|
+
const api_worker_client_1 = require("../../../../api-worker-client");
|
|
5
6
|
function patchQuery(LocatorClass) {
|
|
6
7
|
LocatorClass.prototype.query = async function (instruction) {
|
|
7
8
|
await this.waitFor({ state: "visible" });
|
|
8
9
|
const screenshot = await this.screenshot();
|
|
9
|
-
const answer = await (0, vision_1.query)(screenshot.toString("base64"), instruction
|
|
10
|
+
const answer = await (0, vision_1.query)(screenshot.toString("base64"), instruction, {
|
|
11
|
+
clientConfig: (0, api_worker_client_1.llmProxyOpenAIConfig)(),
|
|
12
|
+
});
|
|
10
13
|
return answer;
|
|
11
14
|
};
|
|
12
15
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/playwright-utils",
|
|
3
|
-
"version": "0.58.
|
|
3
|
+
"version": "0.58.6",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"puppeteer-extra-plugin-recaptcha": "^3.6.8",
|
|
55
55
|
"rimraf": "^6.0.1",
|
|
56
56
|
"ts-morph": "^23.0.0",
|
|
57
|
-
"@empiricalrun/cua": "^0.4.
|
|
58
|
-
"@empiricalrun/llm": "^0.27.
|
|
57
|
+
"@empiricalrun/cua": "^0.4.2",
|
|
58
|
+
"@empiricalrun/llm": "^0.27.1",
|
|
59
59
|
"@empiricalrun/r2-uploader": "^0.10.2",
|
|
60
|
-
"@empiricalrun/reporter": "^0.
|
|
60
|
+
"@empiricalrun/reporter": "^0.30.0"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
63
|
"dev": "pnpm gen:api-worker-openapi && tsgo --build --watch",
|