mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-01 01:07:46 +03:00
fix(web-test): scanSpreadsheetCells — use contentFrame() instead of index-based frame mapping
Replace fragile page.frames()[iframeIdx + 1] with handle.contentFrame() for reliable iframe-to-Playwright-Frame resolution. The old index arithmetic could break when 1C web client accumulates extra frames during prolonged sessions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
e30b518935
commit
00fafd4af5
@@ -1,4 +1,4 @@
|
|||||||
// web-test browser v1.8 — Playwright browser management for 1C web client
|
// web-test browser v1.9 — Playwright browser management for 1C web client
|
||||||
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
/**
|
/**
|
||||||
* Playwright browser management for 1C web client.
|
* Playwright browser management for 1C web client.
|
||||||
@@ -972,30 +972,26 @@ export async function readTable({ maxRows = 20, offset = 0, table } = {}) {
|
|||||||
* where frameIndex is the Playwright frames[] index (1-based, 0 = main).
|
* where frameIndex is the Playwright frames[] index (1-based, 0 = main).
|
||||||
*/
|
*/
|
||||||
async function scanSpreadsheetCells(formNum) {
|
async function scanSpreadsheetCells(formNum) {
|
||||||
const iframeIndices = await page.evaluate(`(() => {
|
const prefix = `form${formNum ?? 0}_`;
|
||||||
const prefix = 'form${formNum ?? 0}_';
|
const iframeHandles = await page.$$('iframe');
|
||||||
const allIframes = [...document.querySelectorAll('iframe')];
|
|
||||||
const indices = [];
|
|
||||||
for (let i = 0; i < allIframes.length; i++) {
|
|
||||||
const f = allIframes[i];
|
|
||||||
if (f.offsetWidth < 100) continue;
|
|
||||||
let el = f.parentElement, found = false;
|
|
||||||
for (let d = 0; el && d < 30; d++, el = el.parentElement) {
|
|
||||||
if (el.id && el.id.startsWith(prefix)) { found = true; break; }
|
|
||||||
}
|
|
||||||
if (found) indices.push(i);
|
|
||||||
}
|
|
||||||
return indices;
|
|
||||||
})()`);
|
|
||||||
|
|
||||||
const frames = page.frames();
|
|
||||||
const allCells = new Map();
|
const allCells = new Map();
|
||||||
const frameMap = new Map(); // key 'r_c' → Playwright frame index
|
const frameMap = new Map(); // key 'r_c' → Playwright Frame object
|
||||||
|
|
||||||
for (const iframeIdx of iframeIndices) {
|
for (const handle of iframeHandles) {
|
||||||
const frameIndex = iframeIdx + 1;
|
const ok = await handle.evaluate((f, pfx) => {
|
||||||
const frame = frames[frameIndex];
|
if (f.offsetWidth < 100) return false;
|
||||||
|
let el = f.parentElement;
|
||||||
|
for (let d = 0; el && d < 30; d++, el = el.parentElement) {
|
||||||
|
if (el.id && el.id.startsWith(pfx)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}, prefix);
|
||||||
|
if (!ok) continue;
|
||||||
|
|
||||||
|
const frame = await handle.contentFrame();
|
||||||
if (!frame) continue;
|
if (!frame) continue;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const cells = await frame.evaluate(`(() => {
|
const cells = await frame.evaluate(`(() => {
|
||||||
const cells = [];
|
const cells = [];
|
||||||
@@ -1014,7 +1010,7 @@ async function scanSpreadsheetCells(formNum) {
|
|||||||
const key = `${cell.r}_${cell.c}`;
|
const key = `${cell.r}_${cell.c}`;
|
||||||
if (!allCells.has(key) || cell.t.length > allCells.get(key).t.length) {
|
if (!allCells.has(key) || cell.t.length > allCells.get(key).t.length) {
|
||||||
allCells.set(key, cell);
|
allCells.set(key, cell);
|
||||||
frameMap.set(key, frameIndex);
|
frameMap.set(key, frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch { /* skip inaccessible frames */ }
|
} catch { /* skip inaccessible frames */ }
|
||||||
@@ -1379,14 +1375,11 @@ async function clickSpreadsheetCell(target, { dblclick: dbl, modifier } = {}) {
|
|||||||
// Map rows[] index → physical row number
|
// Map rows[] index → physical row number
|
||||||
const physRow = sortedRows[rowIdx];
|
const physRow = sortedRows[rowIdx];
|
||||||
const cellKey = `${physRow}_${physCol}`;
|
const cellKey = `${physRow}_${physCol}`;
|
||||||
const frameIndex = frameMap.get(cellKey);
|
const frame = frameMap.get(cellKey);
|
||||||
if (!frameIndex) {
|
if (!frame) {
|
||||||
// Cell exists in mapping but might be empty — try clicking anyway
|
// Cell exists in mapping but might be empty — try clicking anyway
|
||||||
throw new Error(`clickElement: cell at row=${JSON.stringify(target.row)}, column="${colName}" is empty or not rendered.`);
|
throw new Error(`clickElement: cell at row=${JSON.stringify(target.row)}, column="${colName}" is empty or not rendered.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get bounding box and click via page.mouse (bypasses mxlCurrBody overlay)
|
|
||||||
const frame = page.frames()[frameIndex];
|
|
||||||
// Use [y]+[x] attributes — CSS class RxCy uses different numbering than y/x attrs.
|
// Use [y]+[x] attributes — CSS class RxCy uses different numbering than y/x attrs.
|
||||||
const cellDiv = frame.locator(`div[y="${physRow}"] div[x="${physCol}"]`).first();
|
const cellDiv = frame.locator(`div[y="${physRow}"] div[x="${physCol}"]`).first();
|
||||||
// Scroll cell into view using arrow keys — the only reliable way to scroll
|
// Scroll cell into view using arrow keys — the only reliable way to scroll
|
||||||
@@ -1435,17 +1428,16 @@ async function findSpreadsheetCellByText(formNum, searchText) {
|
|||||||
}
|
}
|
||||||
if (!found) return null;
|
if (!found) return null;
|
||||||
|
|
||||||
const frameIndex = frameMap.get(found.key);
|
const frame = frameMap.get(found.key);
|
||||||
if (!frameIndex) return null;
|
if (!frame) return null;
|
||||||
|
|
||||||
const frame = page.frames()[frameIndex];
|
|
||||||
// Scroll cell into view using native arrow-key mechanism
|
// Scroll cell into view using native arrow-key mechanism
|
||||||
const cellDiv = frame.locator(`div[y="${found.cell.r}"] div[x="${found.cell.c}"]`).first();
|
const cellDiv = frame.locator(`div[y="${found.cell.r}"] div[x="${found.cell.c}"]`).first();
|
||||||
await scrollSpreadsheetToCell(frame, found.cell.r, found.cell.c, cellDiv);
|
await scrollSpreadsheetToCell(frame, found.cell.r, found.cell.c, cellDiv);
|
||||||
const box = await cellDiv.boundingBox();
|
const box = await cellDiv.boundingBox();
|
||||||
if (!box) return null;
|
if (!box) return null;
|
||||||
|
|
||||||
return { frameIndex, physRow: found.cell.r, physCol: found.cell.c, text: found.cell.t, box };
|
return { frame, physRow: found.cell.r, physCol: found.cell.c, text: found.cell.t, box };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user