mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-11 08:24:57 +03:00
feat(web-test): navigateSection newline normalization + fillTableRow cell skip
navigateSection now normalizes \r\n to spaces, so callers don't need literal newlines in section names. fillTableRow direct-edit path skips cells that already contain the desired value (method: 'skip'). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2129,11 +2129,24 @@ export async function fillTableRow(fields, { tab, add, row } = {}) {
|
||||
if (!box) return { error: 'no_cell' };
|
||||
const cell = box.querySelector('.gridBoxText') || box;
|
||||
const r = cell.getBoundingClientRect();
|
||||
return { x: Math.round(r.x + r.width / 2), y: Math.round(r.y + r.height / 2) };
|
||||
const currentText = (cell.innerText?.trim() || '').replace(/\u00a0/g, ' ');
|
||||
return { x: Math.round(r.x + r.width / 2), y: Math.round(r.y + r.height / 2), currentText };
|
||||
})()`);
|
||||
|
||||
if (cellCoords.error) throw new Error(`fillTableRow: ${cellCoords.error}${cellCoords.total ? ' (total rows: ' + cellCoords.total + ')' : ''}`);
|
||||
|
||||
// Skip if cell already contains the desired value (single-field optimization)
|
||||
const firstKey0 = Object.keys(fields)[0];
|
||||
const firstVal0 = typeof fields[firstKey0] === 'object' ? fields[firstKey0].value : String(fields[firstKey0]);
|
||||
let firstFieldSkipped = false;
|
||||
if (cellCoords.currentText && firstVal0 &&
|
||||
cellCoords.currentText.toLowerCase().includes(firstVal0.toLowerCase())) {
|
||||
firstFieldSkipped = true;
|
||||
if (Object.keys(fields).length === 1) {
|
||||
return [{ field: firstKey0, ok: true, method: 'skip', value: cellCoords.currentText }];
|
||||
}
|
||||
}
|
||||
|
||||
// Click first (tree grids enter edit on single click; dblclick toggles expand/collapse).
|
||||
// Then escalate: dblclick → F4 if needed.
|
||||
await page.mouse.click(cellCoords.x, cellCoords.y);
|
||||
@@ -2274,9 +2287,17 @@ export async function fillTableRow(fields, { tab, add, row } = {}) {
|
||||
// First field: selection form is already open from the dblclick above
|
||||
const firstKey = Object.keys(fields)[0];
|
||||
const firstInfo = pending.get(firstKey);
|
||||
const pickResult = await directEditPick(directEditForm, firstKey, firstInfo);
|
||||
firstInfo.filled = true;
|
||||
results.push(pickResult);
|
||||
if (firstFieldSkipped) {
|
||||
firstInfo.filled = true;
|
||||
results.push({ field: firstKey, ok: true, method: 'skip', value: cellCoords.currentText });
|
||||
// Close the selection form that opened from the click
|
||||
await page.keyboard.press('Escape');
|
||||
await waitForStable(formNum);
|
||||
} else {
|
||||
const pickResult = await directEditPick(directEditForm, firstKey, firstInfo);
|
||||
firstInfo.filled = true;
|
||||
results.push(pickResult);
|
||||
}
|
||||
|
||||
// Remaining fields: dblclick on each column cell individually
|
||||
for (const [key, info] of pending) {
|
||||
@@ -2315,13 +2336,21 @@ export async function fillTableRow(fields, { tab, add, row } = {}) {
|
||||
if (!box) return null;
|
||||
const cell = box.querySelector('.gridBoxText') || box;
|
||||
const r = cell.getBoundingClientRect();
|
||||
return { x: Math.round(r.x + r.width / 2), y: Math.round(r.y + r.height / 2) };
|
||||
const currentText = (cell.innerText?.trim() || '').replace(/\\u00a0/g, ' ');
|
||||
return { x: Math.round(r.x + r.width / 2), y: Math.round(r.y + r.height / 2), currentText };
|
||||
})()`);
|
||||
if (!nextCoords) {
|
||||
info.filled = true;
|
||||
results.push({ field: key, error: 'column_not_found', message: `Column for "${key}" not found` });
|
||||
continue;
|
||||
}
|
||||
// Skip if cell already contains the desired value
|
||||
if (nextCoords.currentText && info.value &&
|
||||
nextCoords.currentText.toLowerCase().includes(info.value.toLowerCase())) {
|
||||
info.filled = true;
|
||||
results.push({ field: key, ok: true, method: 'skip', value: nextCoords.currentText });
|
||||
continue;
|
||||
}
|
||||
await page.mouse.dblclick(nextCoords.x, nextCoords.y);
|
||||
// Poll for selection form (with F4 fallback if dblclick didn't open it)
|
||||
let selForm = null;
|
||||
|
||||
@@ -476,8 +476,8 @@ export function getFormStateScript() {
|
||||
*/
|
||||
export function navigateSectionScript(name) {
|
||||
return `(() => {
|
||||
const norm = s => (s?.trim().replace(/\\u00a0/g, ' ') || '').replace(/ё/gi, 'е');
|
||||
const target = ${JSON.stringify(name.toLowerCase().replace(/ё/g, 'е'))};
|
||||
const norm = s => (s?.trim().replace(/\\u00a0/g, ' ').replace(/[\\r\\n]+/g, ' ').replace(/ +/g, ' ') || '').replace(/ё/gi, 'е');
|
||||
const target = ${JSON.stringify(name.toLowerCase().replace(/ё/g, 'е').replace(/[\r\n]+/g, ' ').replace(/ +/g, ' '))};
|
||||
const els = [...document.querySelectorAll('[id^="themesCell_theme_"]')];
|
||||
let bestEl = els.find(el => norm(el.innerText).toLowerCase() === target);
|
||||
if (!bestEl) bestEl = els.find(el => norm(el.innerText).toLowerCase().includes(target));
|
||||
|
||||
Reference in New Issue
Block a user