mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-10 16:14:54 +03:00
fix(web-test): skip checkbox columns in row clicks + document table parameter
Row selection clicks in deleteTableRow and fillTableRow commit now target the second visible gridBox instead of the first, avoiding accidental checkbox toggles on forms with checkbox columns (e.g. BP links master). Also documents the new `table` parameter in SKILL.md for readTable, clickElement, fillTableRow, deleteTableRow, and getFormState tables[]. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -118,12 +118,14 @@ Switch to an already-open tab/window (fuzzy match).
|
||||
|
||||
### Reading form state
|
||||
|
||||
#### `getFormState()` → `{ fields, buttons, tabs, table, filters, reportSettings? }`
|
||||
#### `getFormState()` → `{ fields, buttons, tabs, table, tables, filters, reportSettings? }`
|
||||
Returns current form structure. This is the primary way to understand what's on screen.
|
||||
|
||||
**fields** — each field has: `name`, `value`, `label?`, `actions?` (select, clear, open), `required?` (true for unfilled mandatory fields)
|
||||
|
||||
**table** — summary only: `{ name, columns, rowCount }`. Use `readTable()` for actual data.
|
||||
**tables** — array of all visible grids: `[{ name, columns, rowCount }]`. Use `readTable()` for actual data.
|
||||
|
||||
**table** — backward-compatible alias for the first grid: `{ present, columns, rowCount }`.
|
||||
|
||||
**reportSettings** — for DCS reports: human-readable filter settings instead of raw technical names:
|
||||
```js
|
||||
@@ -140,13 +142,14 @@ const form = await getFormState();
|
||||
|
||||
### Reading data
|
||||
|
||||
#### `readTable({ maxRows?, offset? })` → `{ columns, rows, total, shown, offset }`
|
||||
#### `readTable({ maxRows?, offset?, table? })` → `{ columns, rows, total, shown, offset }`
|
||||
Read actual grid data with pagination. Each row is `{ columnName: value }`.
|
||||
|
||||
| Option | Default | Description |
|
||||
|--------|---------|-------------|
|
||||
| `maxRows` | 20 | Max rows to return per call |
|
||||
| `offset` | 0 | Skip first N rows |
|
||||
| `table` | — | Grid name from `tables[]` (for multi-grid forms) |
|
||||
|
||||
Special row fields:
|
||||
- `_kind: 'group'` — hierarchical group row
|
||||
@@ -190,9 +193,13 @@ Sections + all open tabs.
|
||||
|
||||
### Actions
|
||||
|
||||
#### `clickElement(text, { dblclick? })` → form state
|
||||
#### `clickElement(text, { dblclick?, table? })` → form state
|
||||
Click button, hyperlink, tab, or grid row (fuzzy match).
|
||||
|
||||
- `table` — scope button search to a specific grid's command panel (by name from `tables[]`):
|
||||
```js
|
||||
await clickElement('Добавить', { table: 'Исходящие' }); // clicks "Добавить" near "Исходящие" grid
|
||||
```
|
||||
- Single click selects a row in a list. **Double-click opens** the item:
|
||||
```js
|
||||
await clickElement('0000-000227', { dblclick: true }); // opens document
|
||||
@@ -250,6 +257,13 @@ Also supports DCS labels — auto-enables the paired checkbox.
|
||||
#### `fillTableRow(fields, opts)` → form state
|
||||
Fill table row cells via Tab navigation. Value is a plain string or `{ value, type }` for composite-type cells.
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `tab` | Switch to tab before filling |
|
||||
| `add` | Add new row before filling |
|
||||
| `row` | Edit existing row by 0-based index |
|
||||
| `table` | Grid name from `tables[]` (for multi-grid forms) |
|
||||
|
||||
```js
|
||||
// Add new row:
|
||||
await fillTableRow(
|
||||
@@ -261,6 +275,11 @@ await fillTableRow(
|
||||
{ 'Количество': '20' },
|
||||
{ tab: 'Товары', row: 0 }
|
||||
);
|
||||
// Multi-grid form — add row to specific table:
|
||||
await fillTableRow(
|
||||
{ 'Объект': 'БДДС' },
|
||||
{ table: 'Исходящие', add: true }
|
||||
);
|
||||
// Composite-type cell (e.g. SubConto accepting multiple types):
|
||||
await fillTableRow(
|
||||
{ 'СубконтоКт1': { value: 'Голованов', type: 'Физическое лицо' } },
|
||||
@@ -272,8 +291,8 @@ await fillTableRow(
|
||||
- Fuzzy cell match: "Количество" matches "ТоварыКоличество"
|
||||
- Reference cells auto-detected by autocomplete popup
|
||||
|
||||
#### `deleteTableRow(row, { tab? })` → form state
|
||||
Delete row by 0-based index.
|
||||
#### `deleteTableRow(row, { tab?, table? })` → form state
|
||||
Delete row by 0-based index. `table` targets a specific grid on multi-grid forms.
|
||||
|
||||
#### `closeForm({ save? })` → form state
|
||||
Close the current form via Escape.
|
||||
|
||||
@@ -2417,7 +2417,8 @@ export async function fillTableRow(fields, { tab, add, row, table } = {}) {
|
||||
const otherIdx = ${row} === 0 ? 1 : 0;
|
||||
const other = rows[otherIdx];
|
||||
if (!other) return null;
|
||||
const box = [...other.children].filter(b => b.offsetWidth > 0)[0];
|
||||
const visBoxes = [...other.children].filter(b => b.offsetWidth > 0 && !b.classList.contains('gridBoxComp'));
|
||||
const box = visBoxes.length > 1 ? visBoxes[1] : visBoxes[0];
|
||||
if (!box) return null;
|
||||
const r = box.getBoundingClientRect();
|
||||
return { x: Math.round(r.x + r.width / 2), y: Math.round(r.y + r.height / 2) };
|
||||
@@ -2981,7 +2982,8 @@ export async function fillTableRow(fields, { tab, add, row, table } = {}) {
|
||||
const targetIdx = activeRowIdx === 0 ? 1 : 0;
|
||||
const target = rows[targetIdx];
|
||||
if (target) {
|
||||
const box = [...target.children].find(b => b.offsetWidth > 0);
|
||||
const visBoxes = [...target.children].filter(b => b.offsetWidth > 0 && !b.classList.contains('gridBoxComp'));
|
||||
const box = visBoxes.length > 1 ? visBoxes[1] : visBoxes[0];
|
||||
if (box) {
|
||||
const r = box.getBoundingClientRect();
|
||||
return { x: Math.round(r.x + r.width / 2), y: Math.round(r.y + r.height / 2) };
|
||||
@@ -3062,9 +3064,12 @@ export async function deleteTableRow(row, { tab, table } = {}) {
|
||||
const rows = [...body.querySelectorAll('.gridLine')];
|
||||
if (${row} >= rows.length) return { error: 'row_out_of_range', total: rows.length };
|
||||
const line = rows[${row}];
|
||||
const cells = [...line.querySelectorAll('.gridBoxText')];
|
||||
const cell = cells.length > 1 ? cells[1] : cells[0];
|
||||
if (!cell) return { error: 'no_cell' };
|
||||
// Use visible gridBox containers (not gridBoxText) to avoid clicking checkboxes
|
||||
const boxes = [...line.children].filter(b => b.offsetWidth > 0 && !b.classList.contains('gridBoxComp'));
|
||||
// Skip first column (row number / checkbox) — pick second visible box
|
||||
const box = boxes.length > 1 ? boxes[1] : boxes[0];
|
||||
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), total: rows.length };
|
||||
})()`);
|
||||
|
||||
Reference in New Issue
Block a user