mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-16 10:43:18 +03:00
refactor(web-test): uniform ok:true/false в filled-items + контракт fillTableRow (Phase 4)
Раньше per-item shape в filled[] был heterogeneous:
- success: {field, ok: true, method, value}
- failure: {field, error, message} ← без ok!
Естественная проверка `item.ok === false` молча промахивалась (latent bug в
production-клиенте Titan C:\WS\projects\titan\tests\helpers\query.mjs:69).
И документация утверждала «все функции throw'ают на ошибке» (guide.md:352),
что для fillTableRow было неправдой.
Что изменено:
- engine/table/row-fill.mjs v1.18 → v1.19: 15 error-pushes теперь включают
ok: false. item.ok — единый дискриминатор success/failure.
- SKILL.md: fillFields раздел уточнён («throws on per-field failure — если
вернулся, всё заполнено»). fillTableRow раздел: документирует контракт
(НЕ throws на per-field), перечисляет error-коды и recovery hints
(composite_type → retry с {value, type}, column_not_found → проверить
readTable, и т.д.).
- docs/web-test-guide.md: строка 352 нюансирована (fillTableRow исключение
из «все throw'ают»); строка 296 (таблица) уточнена.
Контракт обеих функций теперь сознательно различается и явно описан:
- fillFields = fail-fast (throws на любую ошибку, удобно для fill-and-go)
- fillTableRow = partial-recovery (errors в filled[] как ok:false, модель
может retry'нуть селективно отдельную ячейку)
Бонус: query.mjs в Titan'е теперь работает корректно без правки клиентского
кода — cell.ok === false наконец-то дискриминирует error-items.
Полный регресс 19/19 зелёный.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -293,7 +293,7 @@ await clickElement('150 000', { dblclick: true }); // найдёт ячейку
|
||||
| `clickElement(text, {dblclick?, modifier?})` | Клик по кнопке/ссылке/строке. `{dblclick: true}` для открытия, `{modifier: 'ctrl'\|'shift'}` для мультиселекции. Первый аргумент может быть `{row, column}` для клика по ячейке SpreadsheetDocument (см. выше) | form state или `{ submenu }` |
|
||||
| `fillFields({name: value})` | Заполнить поля (текст, чекбокс, радио, ссылки, DCS-фильтры). Пустое значение (`''`/`null`) = очистка | form state с `filled` |
|
||||
| `selectValue(field, search, opts?)` | Выбрать из справочника. search: текст, `{поле: значение}` или `''`/`null` для очистки. `{ type }` для составного типа | form state с `selected` |
|
||||
| `fillTableRow(fields, {tab?, add?, row?})` | Заполнить строку. Значение: строка, `{ value, type }` для составного типа, `''`/`null` для очистки | form state с `filled` (+ `notFilled?`) |
|
||||
| `fillTableRow(fields, {tab?, add?, row?})` | Заполнить строку. Значение: строка, `{ value, type }` для составного типа, `''`/`null` для очистки | form state с `filled` (per-field ошибки как items `ok: false`, см. ниже) + `notFilled?` |
|
||||
| `deleteTableRow(row, {tab?})` | Удалить строку по индексу | form state |
|
||||
| `closeForm({save?})` | Закрыть форму. `save: false` = "Нет", `save: true` = "Да". Возвращает `closed: true/false` | form state с `closed` |
|
||||
| `filterList(text, {field?, exact?})` | Фильтр списка. Без field = все колонки, с field = расширенный поиск | form state |
|
||||
@@ -349,13 +349,16 @@ await page.keyboard.press('F8'); // пример: создать новый э
|
||||
|
||||
## Типичные ошибки
|
||||
|
||||
Все функции бросают исключение при ошибке (не возвращают `{ error }`). Сценарий прерывается на проблемном шаге с информативным сообщением. В интерактиве — `try/catch` для обработки.
|
||||
Большинство функций бросают исключение при ошибке. Сценарий прерывается на проблемном шаге с информативным сообщением. В интерактиве — `try/catch` для обработки.
|
||||
|
||||
**Исключение — `fillTableRow`**: на per-field ошибках не throws, а возвращает их в `filled[]` как items с `ok: false` (`{ field, ok: false, error: 'code', message: '...' }`). Это позволяет частичное восстановление: например при `error: 'composite_type'` модель может retry'нуть конкретную ячейку с `{ value, type }` синтаксисом, не перезаполняя всю строку. Проверка — `r.filled.filter(f => !f.ok)`. Жёсткие ошибки (нет формы, table не найдена) и soft validation errors от 1С (balloon/modal) — всё равно throws.
|
||||
|
||||
| Проблема | Решение |
|
||||
|----------|---------|
|
||||
| `no form found` — форма не открыта | Добавьте `await wait(2)` после навигации |
|
||||
| `not found. Available: ...` — элемент не найден | Проверьте имя через `getFormState()`, используйте вариант из Available |
|
||||
| `fillFields: N of M field(s) failed` | Текст ошибки содержит список проблемных полей и доступные варианты |
|
||||
| `fillTableRow` вернул item с `ok: false` | См. поле `error` — `composite_type` → retry с `{value, type}`; `column_not_found` → проверьте имя поля через `readTable`; `not_found` → уточните значение поиска |
|
||||
| Пустой `readSpreadsheet()` | Увеличьте `await wait(N)` перед чтением |
|
||||
|
||||
## Особенности
|
||||
|
||||
Reference in New Issue
Block a user