Fix snapshot evaluate: scope queries to container element, handle Page fallback
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -329,14 +329,10 @@ Answer:`;
|
|||||||
* Returns a plain JSON object describing every field, avoiding per-element CDP round-trips.
|
* Returns a plain JSON object describing every field, avoiding per-element CDP round-trips.
|
||||||
*/
|
*/
|
||||||
async _snapshotFields(container) {
|
async _snapshotFields(container) {
|
||||||
return await container.evaluate((extractLabelSrc, checkRequiredSrc, normalizeLegendSrc) => {
|
return await container.evaluate((rootOrUndefined) => {
|
||||||
// Reconstruct functions inside browser context
|
// When container is an ElementHandle, root is the element.
|
||||||
const extractLabel = new Function('node', `
|
// When container is a Page, root is undefined — use document.
|
||||||
${extractLabelSrc}
|
const root = rootOrUndefined || document;
|
||||||
return extractLabel(node);
|
|
||||||
`);
|
|
||||||
// Can't pass functions directly — inline the logic instead
|
|
||||||
// We'll inline extractLabel and checkRequired logic directly
|
|
||||||
|
|
||||||
function _extractLabel(node) {
|
function _extractLabel(node) {
|
||||||
const id = node.id;
|
const id = node.id;
|
||||||
@@ -419,7 +415,7 @@ Answer:`;
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Resume radios
|
// Resume radios
|
||||||
const resumeInputs = document.querySelectorAll('input[type="radio"][aria-label*="resume"], input[type="radio"][aria-label*="Resume"]');
|
const resumeInputs = root.querySelectorAll('input[type="radio"][aria-label*="resume"], input[type="radio"][aria-label*="Resume"]');
|
||||||
let resumeChecked = false;
|
let resumeChecked = false;
|
||||||
resumeInputs.forEach((r, i) => {
|
resumeInputs.forEach((r, i) => {
|
||||||
if (r.checked) resumeChecked = true;
|
if (r.checked) resumeChecked = true;
|
||||||
@@ -428,10 +424,10 @@ Answer:`;
|
|||||||
result.resumeChecked = resumeChecked;
|
result.resumeChecked = resumeChecked;
|
||||||
|
|
||||||
// File input
|
// File input
|
||||||
result.hasFileInput = !!document.querySelector('input[type="file"]');
|
result.hasFileInput = !!root.querySelector('input[type="file"]');
|
||||||
|
|
||||||
// Text / number / url / email / tel inputs
|
// Text / number / url / email / tel inputs
|
||||||
const inputEls = document.querySelectorAll('input[type="text"], input[type="number"], input[type="url"], input[type="email"], input[type="tel"]');
|
const inputEls = root.querySelectorAll('input[type="text"], input[type="number"], input[type="url"], input[type="email"], input[type="tel"]');
|
||||||
inputEls.forEach((inp, i) => {
|
inputEls.forEach((inp, i) => {
|
||||||
if (!isVisible(inp)) return;
|
if (!isVisible(inp)) return;
|
||||||
const label = _extractLabel(inp);
|
const label = _extractLabel(inp);
|
||||||
@@ -442,7 +438,7 @@ Answer:`;
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Textareas
|
// Textareas
|
||||||
const taEls = document.querySelectorAll('textarea');
|
const taEls = root.querySelectorAll('textarea');
|
||||||
taEls.forEach((ta, i) => {
|
taEls.forEach((ta, i) => {
|
||||||
if (!isVisible(ta)) return;
|
if (!isVisible(ta)) return;
|
||||||
const label = _extractLabel(ta);
|
const label = _extractLabel(ta);
|
||||||
@@ -452,7 +448,7 @@ Answer:`;
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Fieldsets
|
// Fieldsets
|
||||||
const fsEls = document.querySelectorAll('fieldset');
|
const fsEls = root.querySelectorAll('fieldset');
|
||||||
fsEls.forEach((fs, i) => {
|
fsEls.forEach((fs, i) => {
|
||||||
const legend = fs.querySelector('legend');
|
const legend = fs.querySelector('legend');
|
||||||
if (!legend) return;
|
if (!legend) return;
|
||||||
@@ -489,7 +485,7 @@ Answer:`;
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Selects (standalone, not inside fieldsets we already handle)
|
// Selects (standalone, not inside fieldsets we already handle)
|
||||||
const selEls = document.querySelectorAll('select');
|
const selEls = root.querySelectorAll('select');
|
||||||
selEls.forEach((sel, i) => {
|
selEls.forEach((sel, i) => {
|
||||||
if (!isVisible(sel)) return;
|
if (!isVisible(sel)) return;
|
||||||
const label = _extractLabel(sel);
|
const label = _extractLabel(sel);
|
||||||
@@ -507,7 +503,7 @@ Answer:`;
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Checkboxes (standalone)
|
// Checkboxes (standalone)
|
||||||
const cbEls = document.querySelectorAll('input[type="checkbox"]');
|
const cbEls = root.querySelectorAll('input[type="checkbox"]');
|
||||||
cbEls.forEach((cb, i) => {
|
cbEls.forEach((cb, i) => {
|
||||||
if (!isVisible(cb)) return;
|
if (!isVisible(cb)) return;
|
||||||
// Skip if inside a fieldset with a legend (handled in fieldsets section)
|
// Skip if inside a fieldset with a legend (handled in fieldsets section)
|
||||||
|
|||||||
Reference in New Issue
Block a user