@empiricalrun/playwright-utils 0.16.3 → 0.18.0

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # @empiricalrun/playwright-utils
2
2
 
3
+ ## 0.18.0
4
+
5
+ ### Minor Changes
6
+
7
+ - dbe713b: fix: auto dismiss popup at test runtime
8
+
9
+ ### Patch Changes
10
+
11
+ - 041cd97: fix: remove log line
12
+ - Updated dependencies [dbe713b]
13
+ - @empiricalrun/test-gen@0.38.30
14
+
15
+ ## 0.17.0
16
+
17
+ ### Minor Changes
18
+
19
+ - 9f0a413: feat: auth store can extract cookies/localstorage
20
+
3
21
  ## 0.16.3
4
22
 
5
23
  ### Patch Changes
@@ -3,6 +3,11 @@ type WithKey<T> = T & {
3
3
  key: string;
4
4
  };
5
5
  type AppType = "web-app" | "chrome-extension";
6
+ type QueryFilter = {
7
+ type: "cookie" | "localStorage";
8
+ origin: string;
9
+ name: string;
10
+ };
6
11
  export declare class AuthStore<T extends WithKey<{}>> {
7
12
  appType: AppType;
8
13
  page: Page;
@@ -18,6 +23,9 @@ export declare class AuthStore<T extends WithKey<{}>> {
18
23
  });
19
24
  loginIfRequired(): Promise<void>;
20
25
  loggedInPage(): Promise<Page | undefined>;
26
+ static getValueFromAuthState(userContext: {
27
+ key: string;
28
+ }, query: QueryFilter): string | undefined;
21
29
  private newPageWithAuthState;
22
30
  private saveAuthState;
23
31
  static location(userContext: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAU,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE/D,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,KAAK,OAAO,GAAG,SAAS,GAAG,kBAAkB,CAAC;AAE9C,qBAAa,SAAS,CAAC,CAAC,SAAS,OAAO,CAAC,EAAE,CAAC;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,CAAC,CAAC;IACf,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,iBAAiB,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;gBACxD,EACV,IAAI,EACJ,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,OAAmB,GACpB,EAAE;QACD,IAAI,EAAE,IAAI,CAAC;QACX,WAAW,EAAE,CAAC,CAAC;QACf,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACzD,iBAAiB,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACpE,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB;IAQK,eAAe;IAIf,YAAY,IAAI,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;YAqCjC,oBAAoB;YAsBpB,aAAa;IA6B3B,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM;WAIxC,eAAe,CAC1B,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC;CAoB5B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAU,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAI/D,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,KAAK,OAAO,GAAG,SAAS,GAAG,kBAAkB,CAAC;AAE9C,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,QAAQ,GAAG,cAAc,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,qBAAa,SAAS,CAAC,CAAC,SAAS,OAAO,CAAC,EAAE,CAAC;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,CAAC,CAAC;IACf,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,iBAAiB,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;gBACxD,EACV,IAAI,EACJ,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,OAAmB,GACpB,EAAE;QACD,IAAI,EAAE,IAAI,CAAC;QACX,WAAW,EAAE,CAAC,CAAC;QACf,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACzD,iBAAiB,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACpE,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB;IAQK,eAAe;IAIf,YAAY,IAAI,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAqC/C,MAAM,CAAC,qBAAqB,CAC1B,WAAW,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,EAC5B,KAAK,EAAE,WAAW,GACjB,MAAM,GAAG,SAAS;YAyBP,oBAAoB;YAsBpB,aAAa;IA6B3B,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM;WAIxC,eAAe,CAC1B,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC;CAoB5B"}
@@ -58,6 +58,29 @@ class AuthStore {
58
58
  }
59
59
  return loggedInPage;
60
60
  }
61
+ static getValueFromAuthState(userContext, query) {
62
+ const storagePath = AuthStore.location(userContext);
63
+ const contents = fs_1.default.readFileSync(storagePath);
64
+ if (!contents) {
65
+ throw new Error("No auth state found");
66
+ }
67
+ const authState = JSON.parse(contents.toString());
68
+ if (query.type === "cookie") {
69
+ const cookie = authState.cookies.find((c) => c.name === query.name && c.domain === query.origin);
70
+ if (cookie) {
71
+ return cookie.value;
72
+ }
73
+ }
74
+ else if (query.type === "localStorage") {
75
+ const origin = authState.origins.find((o) => o.origin === query.origin);
76
+ if (origin) {
77
+ const item = origin.localStorage.find((i) => i.name === query.name);
78
+ if (item) {
79
+ return item.value;
80
+ }
81
+ }
82
+ }
83
+ }
61
84
  async newPageWithAuthState(page, storagePath) {
62
85
  if (this.appType === "web-app") {
63
86
  // Load state from the file in a new context
@@ -0,0 +1,24 @@
1
+ type AuthStateCookie = {
2
+ name: string;
3
+ value: string;
4
+ domain: string;
5
+ path: string;
6
+ expires: number;
7
+ httpOnly: boolean;
8
+ secure: boolean;
9
+ sameSite: "Strict" | "Lax" | "None";
10
+ };
11
+ type AuthStateLocalStorage = {
12
+ name: string;
13
+ value: string;
14
+ };
15
+ type AuthStateOrigin = {
16
+ origin: string;
17
+ localStorage: AuthStateLocalStorage[];
18
+ };
19
+ export type AuthStateFileContent = {
20
+ cookies: AuthStateCookie[];
21
+ origins: AuthStateOrigin[];
22
+ };
23
+ export {};
24
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;CACrC,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,qBAAqB,EAAE,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,IAAI,EACJ,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,yBAAyB,EAAE,CACzB,OAAO,CAAC,EAAE,qBAAqB,KAC5B,OAAO,CAAC;QAAE,OAAO,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IACtD,UAAU,EAAE,IAAI,CAAC;CAClB,CAAC;AAIF,eAAO,MAAM,eAAe,WAClB,SACN,kBAAkB,GAAG,qBAAqB,EAC1C,oBAAoB,GAAG,uBAAuB,CAC/C,YACQ,eAAe,uHAwDzB,CAAC;AAEF,OAAO,EAAE,6BAA6B,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,IAAI,EACJ,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,yBAAyB,EAAE,CACzB,OAAO,CAAC,EAAE,qBAAqB,KAC5B,OAAO,CAAC;QAAE,OAAO,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IACtD,UAAU,EAAE,IAAI,CAAC;CAClB,CAAC;AAIF,eAAO,MAAM,eAAe,WAClB,SACN,kBAAkB,GAAG,qBAAqB,EAC1C,oBAAoB,GAAG,uBAAuB,CAC/C,YACQ,eAAe,uHA4DzB,CAAC;AAEF,OAAO,EAAE,6BAA6B,EAAE,CAAC"}
@@ -14,8 +14,9 @@ const baseTestFixture = function (testFn, options = {
14
14
  mousePointerHighlighter: true,
15
15
  locatorHighlighter: true,
16
16
  visionMethods: true,
17
+ agentCapabilities: true,
17
18
  }) {
18
- return testFn.extend({
19
+ const extendedTestFn = testFn.extend({
19
20
  page: async ({ page }, use) => {
20
21
  (0, scripts_1.injectLocatorHighlightScripts)(page, options);
21
22
  await use(page);
@@ -57,5 +58,8 @@ const baseTestFixture = function (testFn, options = {
57
58
  { auto: true },
58
59
  ],
59
60
  });
61
+ //@ts-ignore
62
+ global.testFn = extendedTestFn;
63
+ return extendedTestFn;
60
64
  };
61
65
  exports.baseTestFixture = baseTestFixture;
@@ -0,0 +1,3 @@
1
+ import type { Page } from "@playwright/test";
2
+ export declare function addAgentCapabilities(page: Page): void;
3
+ //# sourceMappingURL=agent-capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-capabilities.d.ts","sourceRoot":"","sources":["../../../src/test/scripts/agent-capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAI7C,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,QAK9C"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addAgentCapabilities = void 0;
4
+ const click_1 = require("./pw-locator-patch/highlight/click");
5
+ function addAgentCapabilities(page) {
6
+ applyPatchForAutoDismissOverlay(page);
7
+ page.context().on("page", async (newPage) => {
8
+ applyPatchForAutoDismissOverlay(newPage);
9
+ });
10
+ }
11
+ exports.addAgentCapabilities = addAgentCapabilities;
12
+ function applyPatchForAutoDismissOverlay(page) {
13
+ const LocatorClass = page.locator("").constructor;
14
+ (0, click_1.patchClick)(LocatorClass);
15
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/test/scripts/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAW3C,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,eAAgC,QAwB1C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/test/scripts/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAa3C,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,eAAgC,QA4B1C"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.injectLocatorHighlightScripts = void 0;
4
4
  const logger_1 = require("../../logger");
5
+ const agent_capabilities_1 = require("./agent-capabilities");
5
6
  const locator_highlights_1 = require("./locator-highlights");
6
7
  const locator_vision_1 = require("./locator-vision");
7
8
  const mouse_pointer_1 = require("./mouse-pointer");
@@ -9,6 +10,7 @@ const defaultOptions = {
9
10
  mousePointerHighlighter: true,
10
11
  locatorHighlighter: true,
11
12
  visionMethods: true,
13
+ agentCapabilities: true,
12
14
  };
13
15
  function injectLocatorHighlightScripts(page, options = defaultOptions) {
14
16
  // TODO: if this method is used standalone (not through the fixture),
@@ -30,6 +32,10 @@ function injectLocatorHighlightScripts(page, options = defaultOptions) {
30
32
  // patch with vision methods
31
33
  (0, locator_vision_1.addLocatorVisionMethods)(page);
32
34
  }
35
+ if (opts.agentCapabilities) {
36
+ //patch to enable agents at runtime
37
+ (0, agent_capabilities_1.addAgentCapabilities)(page);
38
+ }
33
39
  }
34
40
  catch (e) {
35
41
  logger_1.logger.debug("Failed to add mouse pointer highlighter", e);
@@ -0,0 +1,5 @@
1
+ import type { Locator } from "@playwright/test";
2
+ export declare function patchClick(LocatorClass: {
3
+ prototype: Locator;
4
+ }): void;
5
+ //# sourceMappingURL=click.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/highlight/click.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,wBAAgB,UAAU,CAAC,YAAY,EAAE;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,QA4C9D"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.patchClick = void 0;
4
+ const planner_1 = require("@empiricalrun/test-gen/agent/master/planner");
5
+ const run_1 = require("@empiricalrun/test-gen/agent/master/run");
6
+ function patchClick(LocatorClass) {
7
+ const originalClick = LocatorClass.prototype.click;
8
+ //ref: github.com/microsoft/playwright/blob/69287f26bc514b740eac40160503d6fac8185d37/packages/playwright-core/src/client/locator.ts#L255
9
+ LocatorClass.prototype.click = async function (options) {
10
+ try {
11
+ await originalClick.apply(this, [options]);
12
+ }
13
+ catch (e) {
14
+ // If its a test gen, don't trigger the flow
15
+ if (process.env.TEST_GEN_TOKEN) {
16
+ throw new Error(`waiting for ${this.toString()} with options ${JSON.stringify(options)}`);
17
+ }
18
+ const plannerResp = await (0, planner_1.runtimePlannerWithScreenshot)({
19
+ task: "Find a way to dismiss the popup. If the popup is non dismissible or there is no popup then return immediately. Also note that you just need to dismiss popup and do nothing else.",
20
+ conversation: [],
21
+ //Need to add the type for frame
22
+ //@ts-ignore
23
+ page: this._frame._page,
24
+ });
25
+ if (plannerResp.isDone) {
26
+ throw new Error(`waiting for ${this.toString()} with options ${JSON.stringify(options)}`);
27
+ }
28
+ await (0, run_1.createTestUsingMasterAgent)({
29
+ task: "Find a way to dismiss the popup. If the popup is non dismissible or there is no popup then return immediately. Also note that you just need to dismiss popup and do nothing else.",
30
+ //Need to add the type for frame
31
+ //@ts-ignore
32
+ page: this._frame._page,
33
+ options: {
34
+ useHints: true,
35
+ },
36
+ });
37
+ //@ts-ignore
38
+ global.testFn?.info().annotations.push({
39
+ type: "auto-overlay-dismissed",
40
+ description: "This test run had an overlay that was dismissed during runtime",
41
+ });
42
+ await originalClick.apply(this, [options]);
43
+ }
44
+ };
45
+ }
46
+ exports.patchClick = patchClick;
@@ -2,5 +2,6 @@ export type HighlighterOpts = {
2
2
  mousePointerHighlighter?: boolean;
3
3
  locatorHighlighter?: boolean;
4
4
  visionMethods?: boolean;
5
+ agentCapabilities?: boolean;
5
6
  };
6
7
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/test/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/test/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/playwright-utils",
3
- "version": "0.16.3",
3
+ "version": "0.18.0",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -42,7 +42,8 @@
42
42
  "puppeteer-extra-plugin-recaptcha": "^3.6.8",
43
43
  "rimraf": "^6.0.1",
44
44
  "@empiricalrun/llm": "^0.9.27",
45
- "@empiricalrun/r2-uploader": "^0.3.7"
45
+ "@empiricalrun/r2-uploader": "^0.3.7",
46
+ "@empiricalrun/test-gen": "^0.38.30"
46
47
  },
47
48
  "scripts": {
48
49
  "dev": "tsc --build --watch",