@empiricalrun/playwright-utils 0.21.0 → 0.21.1

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,12 @@
1
1
  # @empiricalrun/playwright-utils
2
2
 
3
+ ## 0.21.1
4
+
5
+ ### Patch Changes
6
+
7
+ - d2513a2: fix: don't save screenshot to disk for visual assertions
8
+ - 1ff54e7: fix: use CSS.escape for overlay text content and wrap in try-catch
9
+
3
10
  ## 0.21.0
4
11
 
5
12
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../../src/test/expect.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAO7C,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AA0BF,wBAAsB,WAAW,CAC/B,IAAI,EAAE,IAAI,EACV,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,mBAAmB,CAAC,CA6E9B"}
1
+ {"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../../src/test/expect.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAO7C,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AA0BF,wBAAsB,WAAW,CAC/B,IAAI,EAAE,IAAI,EACV,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,mBAAmB,CAAC,CA4E9B"}
@@ -30,7 +30,6 @@ a reason for your evaluation.
30
30
  async function toLookRight(page, pageDescription) {
31
31
  await (0, mouse_pointer_1.removeMousePointerHighlighter)(page);
32
32
  const screenshot = await page.screenshot();
33
- await page.screenshot({ path: "screenshot-from-assertion.png" });
34
33
  const base64Image = screenshot.toString("base64");
35
34
  await (0, mouse_pointer_1.addHighlighterScriptsToPage)(page);
36
35
  const llm = new llm_1.LLM({
@@ -1 +1 @@
1
- {"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/highlight/click.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAQ,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA8BrC,KAAK,cAAc,GAAG;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,CAAC;AAEF,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,GACnB,cAAc,GAAG,SAAS,CAiC5B;AAkHD,wBAAgB,UAAU,CACxB,YAAY,EAAE,QAAQ,GAAG;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,EAC/C,MAAM,EAAE,MAAM,QA+Df"}
1
+ {"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/highlight/click.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAQ,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA8BrC,KAAK,cAAc,GAAG;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,CAAC;AAEF,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,GACnB,cAAc,GAAG,SAAS,CAiC5B;AA0HD,wBAAgB,UAAU,CACxB,YAAY,EAAE,QAAQ,GAAG;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,EAC/C,MAAM,EAAE,MAAM,QA+Df"}
@@ -75,46 +75,51 @@ function overlayDescription(element) {
75
75
  }
76
76
  }
77
77
  async function textContent(pageRef, element) {
78
- if (element) {
79
- const { interceptor, parent } = element;
80
- let startTag = parent ? parent : interceptor;
81
- let endTag;
82
- const match = startTag.match(/^<\s*([^\s>]+)/);
83
- if (match) {
84
- const tagName = match[1]; // "div"
85
- endTag = `</${tagName}>`;
86
- }
87
- if (!startTag || !endTag) {
88
- return undefined;
89
- }
90
- return await pageRef.evaluate((tags) => {
91
- const [startTag, endTag] = tags;
92
- const htmlString = `${startTag}temp${endTag}`;
93
- const parser = new DOMParser();
94
- const doc = parser.parseFromString(htmlString, "text/html");
95
- const tempEl = doc.body.firstElementChild;
96
- let selector = tempEl.tagName.toLowerCase(); // start with the tag name, e.g., 'div'
97
- // If there's an id, add it (id is unique and very specific)
98
- if (tempEl.id) {
99
- selector += `#${tempEl.id}`;
78
+ try {
79
+ if (element) {
80
+ const { interceptor, parent } = element;
81
+ let startTag = parent ? parent : interceptor;
82
+ let endTag;
83
+ const match = startTag.match(/^<\s*([^\s>]+)/);
84
+ if (match) {
85
+ const tagName = match[1]; // "div"
86
+ endTag = `</${tagName}>`;
100
87
  }
101
- // Add all classes (if any)
102
- if (tempEl.classList.length > 0) {
103
- tempEl.classList.forEach((cls) => {
104
- selector += `.${cls}`;
105
- });
88
+ if (!startTag || !endTag) {
89
+ return undefined;
106
90
  }
107
- // Add any other attributes that might help narrow it down.
108
- // (Skip 'id' and 'class' because they are already included.)
109
- Array.from(tempEl.attributes).forEach((attr) => {
110
- if (attr.name === "id" || attr.name === "class")
111
- return;
112
- // Note: if attribute values contain special characters, consider escaping them.
113
- selector += `[${attr.name}="${attr.value}"]`;
114
- });
115
- const realElement = document.querySelector(selector);
116
- return realElement?.textContent?.trim();
117
- }, [startTag, endTag]);
91
+ return await pageRef.evaluate((tags) => {
92
+ const [startTag, endTag] = tags;
93
+ const htmlString = `${startTag}temp${endTag}`;
94
+ const parser = new DOMParser();
95
+ const doc = parser.parseFromString(htmlString, "text/html");
96
+ const tempEl = doc.body.firstElementChild;
97
+ let selector = tempEl.tagName.toLowerCase(); // start with the tag name, e.g., 'div'
98
+ // If there's an id, add it (id is unique and very specific)
99
+ if (tempEl.id) {
100
+ selector += `#${CSS.escape(tempEl.id)}`;
101
+ }
102
+ // Add classes individually, escaping each one
103
+ if (tempEl.classList.length > 0) {
104
+ Array.from(tempEl.classList).forEach((cls) => {
105
+ selector += `.${CSS.escape(cls)}`;
106
+ });
107
+ }
108
+ // Add other attributes, being careful with escaping
109
+ Array.from(tempEl.attributes).forEach((attr) => {
110
+ if (attr.name === "id" || attr.name === "class")
111
+ return;
112
+ selector += `[${attr.name}="${attr.value.replace(/"/g, '\\"')}"]`;
113
+ });
114
+ console.log("Generated selector:", selector);
115
+ const realElement = document.querySelector(selector);
116
+ return realElement?.textContent?.trim();
117
+ }, [startTag, endTag]);
118
+ }
119
+ }
120
+ catch (err) {
121
+ console.error("Unable to determine text content for overlay:", err);
122
+ return undefined;
118
123
  }
119
124
  }
120
125
  function isProductFruitsOverlay(element) {
@@ -126,7 +131,11 @@ async function runAgentOnOverlay(pageRef, element) {
126
131
  const promptAddition = content
127
132
  ? `
128
133
  The popup can be identified with its text content:
129
- ${content}`
134
+
135
+ <popup_text_content>
136
+ ${content}
137
+ </popup_text_content>
138
+ `
130
139
  : ``;
131
140
  let task = isProductFruitsOverlay(element)
132
141
  ? `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/playwright-utils",
3
- "version": "0.21.0",
3
+ "version": "0.21.1",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -42,8 +42,8 @@
42
42
  "playwright-core": "1.47.1",
43
43
  "puppeteer-extra-plugin-recaptcha": "^3.6.8",
44
44
  "rimraf": "^6.0.1",
45
- "@empiricalrun/r2-uploader": "^0.3.8",
46
45
  "@empiricalrun/llm": "^0.9.35",
46
+ "@empiricalrun/r2-uploader": "^0.3.8",
47
47
  "@empiricalrun/test-gen": "^0.45.1"
48
48
  },
49
49
  "scripts": {