Перейти к содержимому

Что нового

0.13.13 — только CLI.

  • Headless на Linux подгоняет окно под вьюпорт — на Ubuntu-раннерах окно браузера после перезапуска иногда оставалось старого размера, прогон предупреждал could not grow to the 1280x800 viewport, а видео и живой просмотр показывали только верхние 1280×657. Теперь tapstep ждёт, пока новый размер применится. Скриншоты всегда были полного размера.

0.13.12 — CLI и десктоп-приложение, выпущены вместе.

CI теперь входит по настоящему токену: вы его создаёте, видите один раз и можете отозвать.

  • tapstep token create|list|revoke — персональный токен tapstep_pat_… для CI: создаётся через браузер один раз и печатается один раз, только в stdout. TAPSTEP_TOKEN сверяется с API раз в сутки и кэшируется; отозванный токен останавливает прогон, недоступный API — только предупреждение. TAPSTEP_TOKEN, который не токен tapstep_pat_…, работает с предупреждением до 0.15.
  • CI-токены в десктопе — Settings → General → CI tokens показывает ваши токены, создаёт новый (показывается один раз, с кнопкой Copy) и отзывает.
  • Страница CI / GitHub Actions — токен, минимальный workflow, доступ к тестируемому приложению и раннеры Android, VS Code и Windows (iOS в CI пока не поддерживается).
  • Chromium запускается на Ubuntu-раннерах и в контейнерах — на Linux Chromium, который сообщает, что песочница недоступна (Ubuntu 23.10+), или отказывается работать от root, перезапускается один раз с --no-sandbox и уведомлением; TAPSTEP_NO_SANDBOX=1 пропускает первую попытку. Окно в headless-режиме теперь размером с вьюпорт, а не 800×600.
  • Пути runFlow: от корня проекта — каждый файл, который называет шаг (хелперы, runScript, схемы запросов, uploadFile, installApp), ищется рядом с подключающим файлом, затем от корня проекта. validate загружает include и показывает отсутствующий хелпер, обязательный параметр, который никто не передаёт, или цикл — со строкой. tapstep fix-paths переписывает пути с ../ от корня (--write сохраняет); старые CLI и десктоп такие пути не прочитают.
  • installApp: или uploadFile: внутри хелпера сначала ищет файл рядом с хелпером. Хелпер, подключённый из другой папки, больше не находит файл рядом с верхним флоу — положите файл рядом с хелпером или запишите путь от корня проекта.

0.13.11 — CLI и десктоп-приложение, выпущены вместе.

У API-шагов появилась общая шапка: один блок http: задаёт базовый URL, заголовки по умолчанию и cookie jar для всех request: флоу. Учётные данные больше не покидают прогон открытым текстом, а упавший прогон не бросает скриншот в ту папку, откуда его запустили.

  • request:-шаги по умолчанию хранят cookie. У флоу теперь есть cookie jar: Set-Cookie, полученный одним запросом, отправляется следующими — как в браузере, с учётом Path, Secure, Expires и чужого Domain=, в том числе через редиректы. Флоу, которому нужно, чтобы каждый запрос приходил без cookie, отключает это через http: { cookies: false }.
  • Артефакты падений — в reports/, а не в текущей папке. Скриншот и сетевой лог упавшего флоу ложатся в папку report.output проекта (по умолчанию reports/), в подпапку по пути флоу, — а вне проекта в reports/ рядом с флоу. Прогон печатает путь и один раз подсказывает, если .gitignore эту папку не игнорирует.
  • Блок http: в шапке флоу или в config.yaml: baseUrl для относительных url в request, заголовки по умолчанию (headers, с ${} на каждом шаге) и cookies. Собственный блок хелпера действует только на его шаги. Импорт curl пишет URL под базой относительными, --to curl склеивает их обратно.
  • Учётные данные маскируются везде — извлечённые токены, значения bearer, cookie и API-ключей, пароли в DSN, JWT и JSON-поля с «секретными» именами сокращаются до подсказки или *** в заметках шагов, ошибках, живых событиях, всех отчётах и ответе try, включая шаги sql:. Ключи вроде key, keyword или passenger остаются как есть, а короткий пароль больше не превращает /admin/users в /***/users.
  • contains: читает фразу через инлайн-теги — Sign in to continue, разбитое <b>, всё равно находится, и copyText копирует то же чтение.
  • Относительные пути считаются от флоу. uploadFile ищет рядом с файлом флоу, потом в корне проекта, потом в рабочей папке и называет все три, если файла нет. openLink: /login (или ./next, ?q=, #x) открывается на уже открытой странице.
  • appId: ${APP}/login выбирает веб-драйвер, как только -e APP=http://… его заполнил, а не падает на iOS-симулятор. tapstep live принимает -e, --env-file, --env-set и --config и разрешает переменные как tapstep test.
  • Написанный руками dragAndDrop в браузере работает с собственным HTML5-перетаскиванием страницы, а не начинает системный drag, который не кончается.
  • Рекордер игнорирует всё, что помечено data-tapstep-ignore, включая фреймы внутри.
  • Экспорт в Playwright умеет больше: request: ложится на фикстуру request, элементы ищутся и во фреймах, переменная, созданная один раз, — один const, launchApp ${APP}/login становится page.goto, а повторный экспорт обновляет свой spec вместо name-2.spec.ts рядом.
  • Ошибка YAML на незакавыченном JSONPath или ${…} внутри { … } советует взять значение в кавычки; tapstep test -v помечает ⚠ только настоящие предупреждения.
  • Панель try, curl туда и обратно и чат следуют умолчаниям http: — пробный запрос берёт блок открытого флоу поверх проектного, вставленный curl под базой проекта приходит относительным, а Copy as curl склеивает его обратно с заголовками по умолчанию. http: дополняется в YAML-виде.
  • Упавший прогон хранит кадр файлом в ~/.tapstep/fail-frames/, пока прогон есть в истории, а не base64 в хранилище прогонов; отчёты прикладывают этот файл.
  • Шаг, который рекордер выполняет сам, читает относительный uploadFile из проекта записи.
  • На Windows встроенный терминал закрывается, когда его шелл завершился.

0.13.10 — 24 сентября 2026, CLI и десктоп-приложение, выпущены вместе.

Каждый отчёт теперь говорит, на какой платформе и на каком устройстве шёл прогон, на машине с несколькими телефонами можно выбрать нужный, а переключатель, который страница прячет за подписью, наконец нажимается там, где его нажал бы человек.

  • Отчёты называют платформу и устройство. В JUnit — свойства platform и device, в JSON-отчёте — те же поля, в Allure — по метке плюс environment.properties, в HTML — строка в шапке: platform ios (iPhone 16). tapstep live показывает то же в строке терминала и в шапке просмотра.
  • tapstep test --device выбирает одно из нескольких. Если поднято больше одного Android-устройства или iOS-симулятора, назовите нужное по serial, udid или имени.
  • uuid(), randomEmail() и randomInt(min, max) — глобальные функции в любом выражении флоу: для свежей регистрации evalScript не нужен.
  • Интерактивные запуски обновляются сами. Если ежедневная проверка нашла новый релиз, интерактивный запуск ставит его на место к следующему прогону, а не только подсказывает. CI и запуски без терминала не трогаются; TAPSTEP_NO_AUTO_UPDATE=1 отключает.
  • retry сразу сдаётся на шаге, который нельзя выполнить как написан. Статический отказ при втором чтении тот же, поэтому блок больше не прогоняется maxRetries + 1 раз, а причина — первый отказ, а не последний.
  • Сочетание клавиш проверяется до драйвера, и имя, которое драйверы отправить не могут, отклоняется везде одними словами.
  • MCP: хост может подписаться на события прогона вместе с кадрами — всех флоу, которые запускает сервер, а не только на его собственном драйвере, каждый с именем, границами и своей нумерацией шагов.
  • Упавший шаг внутри repeat или хелпера несёт строки под собой и в живом прогоне, как всегда было в отчёте, — починка может спуститься до команды, которая правда упала.
  • Отчёты прогона и сьюта называют платформу и устройство — так же, как отчёты CLI.
  • Зеркало рядом с чатом показывает флоу, который гоняет агент, и отпускает его, когда прогон закончился.
  • Чат говорит, какой провайдер выполнил ход, а ход OpenCode считает и токены, записанные в кэш, а не только прочитанные из него.
  • Согласие на статистику спрашивается заново. Политика конфиденциальности (1.3) теперь описывает статистику по согласию, а экран согласия перечисляет каждое событие, которое отправляет приложение, — тесты, скриншоты и текст чата не уходят никогда.
  • Карточка рекордера говорит на языке окна про наведение, перетаскивание, загрузку, отметку и поле, которое страница никак не назвала.
  • Записанный ⌘+стрелка — это сочетание, а не клавиша, которую зеркало выбрасывает.
  • Чекбокс или переключатель, от которого страница ничего не рисует (sr-only, за краем экрана), нажимается через свою подпись, а не в пиксельную рамку или за экраном, а клик по такой подписи записывается одним шагом на подписи, а не двумя.
  • На Windows VS Code больше не показывает диалог ошибки EPIPE на каждую строку своего запуска.
  • Казахская панель инструментов больше не выталкивает стрелку Run за окно 1024 px; длинное действие в шапке разбора переносится; чип рядом с аргументом шага больше не обрезает текст рядом.
  • Подсказки редактора следуют теме, а часы «работаю» в чате не отстают в скрытом окне.

0.13.9 — 16 сентября 2026, CLI и десктоп-приложение, выпущены вместе.

Колесо внутри webview VS Code теперь попадает в тот блок, который правда прокручивается, а каждая команда говорит, на каких платформах она работает, — поэтому VS Code-тесту больше не предлагают installApp, а тест, в котором он уже есть, узнаёт об этом до прогона.

  • within: — это якорь, а не то, что прокручивается. Назовите заголовок или любой элемент внутри прокручиваемой области, и scroll со scrollUntilVisible найдут держащий его скроллер — сначала внутри названного блока, потом выше, — поставят колесо туда и измерят, насколько сдвинулось его содержимое. Раньше заголовок, названный в within:, прокручивался на свои же 48 px, следующее колесо падало на workbench за ним, а панель webview высотой в пару сотен пикселей было не прокрутить вовсе.
  • scrollUntilVisible внутри прокручиваемой панели сначала просит панель. Боковой вид VS Code, список, вложенный фрейм: панель просят показать элемент, прежде чем свайпать экран. На обычной странице шаг по-прежнему свайпает экран за экраном и никогда не прокручивает блок с overflow: hidden. Пометка в прогоне говорит, какой блок прокручен.
  • Команды несут свои платформы. tapstep schema теперь публикует platforms для каждой команды (web, android, ios, vscode), для полей, у которых круг уже (launchApp.arguments, launchApp.permissions), для имён клавиш pressKey (enums.keyNames) и для ключей селектора css (web, VS Code), testId (web, VS Code — у телефона и симулятора вместо него id) и traits (iOS). Тест в движке следит, чтобы таблица не была шире того, что принимают четыре драйвера.
  • Сценарию говорят, какие его шаги не выполнятся там, где он идёт. С шапкой vscode: — или при проверке для известной платформы через CLI или MCP — читается installApp … is not on VS Code — it runs on Android, iOS, и проверка заглядывает в before/after, retry/repeat и в тела вложенных runFlow. tapstep mcp, запущенный с --driver vscode, с testspace или с устройством, перечисляет в шпаргалке только команды этой платформы и по ней же проверяет.
  • back на iOS отклоняется, а не проходит молча. У симулятора нет своего жеста «назад» — раньше шаг ничего не отправлял и зеленел, — поэтому таблица больше не предлагает там back.
  • VS Code — отдельная платформа в when: platform:. Окно VS Code теперь отвечает vscode, и { platform: web } там больше не срабатывает: блок, который должен идти и в браузере, и в редакторе, пишется как { platform: [web, vscode] }. В отчётах и в логе прогона тоже vscode.
  • Справочник команд на этом сайте печатает покрытие из схемы — VS Code отдельной колонкой.
  • Пикер шагов предлагает только то, что тест может выполнить. Пикер, меню More, автодополнение и подсказка при наведении показывают команды платформы теста, а строка On: web, android, ios появляется только в многоплатформенном проекте. Имена клавиш, поля launchApp/installApp и условия селектора подчиняются тому же правилу. Поле, уже написанное в файле, остаётся видимым при любой платформе.
  • VS Code-тест редактируется как VS Code-тест. Секции App (appId) в Details нет; запись, сделанная в VS Code, открывается как VS Code-тест; Before/After уровня проекта в Settings пишутся под платформу проекта; а шаг, ограниченный only:, можно править даже в одноплатформенном проекте.
  • Запуск: сценарий с шапкой vscode: идёт через диалог VS Code, где бы он ни лежал — со ссылкой на Extensions, если в проекте нет testspace. Сьют VS Code больше не опрашивает Android- и iOS-устройства, а второй Run никогда не переписывает запрос на testspace в браузер.
  • Меню создания говорит «Record in VS Code» в VS Code-проекте, на всех шестнадцати языках.
  • Двойной клик в рекордере записывается одним doubleTapOn, а не двумя тапами.
  • На Android placeholder совпадает с подсказкой поля, а value — с текстом, который лежит в редактируемом поле.
  • Две одноимённые кнопки в двух фреймах окна VS Code считаются по одному разу каждая, а не четырьмя.
  • Iframe внутри shadow root находится, а фрейм, ушедший на другой адрес, больше не отдаётся из кеша.
  • На Windows extensions.json пишется так, как его пишет сам VS Code, а сам VS Code запускается через Code.exe и cli.js — % или " в пути больше не ломают запуск.
  • Папки сессий %TEMP%\ts-vs-* убираются: удаление повторяется, а папки, оставшиеся от умершей сессии, выметаются при следующем запуске.
  • Экспортированный спек ExTester или Playwright называет команду-предусловие по id и повторяет попытку для необязательной команды, прежде чем счесть, что её нет.
  • Спек Playwright, экспортированный из VS Code-сценария, отклоняется при импорте одной понятной фразой, а не приходит половиной сценария.
  • Спек ищет свой config.yaml тем же обходом вверх, что и всё остальное, — с остановкой на домашней папке.
  • dragAndDrop.path на телефоне пишет в отчёте, что путь был выпрямлен.
  • Launch из Extensions больше не забирает окно, которое держит сьют, а сьют не закрывает окно, открытое человеком; Launch говорит, когда оставил уже открытое окно.
  • Extensions и диалог Run говорят, кто держит окно, а сьют VS Code показывает это окно по умолчанию.
  • Участник смешанного проекта с веб-шапкой идёт в браузере.
  • Галочка со сборки снимается только после подтверждения удаления.
  • Форма vscodeCommand помнит по названию или по id для каждого шага.
  • Зоны Before и After показывают testspace, в котором пойдёт следующий прогон, а ошибка в пресете показывается, а не проглатывается.
  • Новая строка selectOption, request или sql остаётся черновиком до первого заполненного поля, поэтому неверный YAML в файл не попадает.
  • Преобразованная команда curl пишется туда, где вставка лежит сейчас, либо тост говорит, что она сдвинулась.
  • Диалог запуска API показывает хуки, которые идут вокруг него, а ошибка пресета пропадает при смене testspace.
  • Файл, который не сценарий и содержит в пути обратный слэш, больше не числится пропущенным.
  • Новый чат очищает всё вместе с собой — очередь сообщений и Send now в том числе, — а пустой ответ не принимается за ответ.
  • Бюджет инструментов взводится снова после Send now и после напоминания о проверке, а его поле применяется при потере фокуса.
  • Медленный симулятор больше не гасит вид Agent: таймауты кадра свои для каждой платформы, статус frame behind виден, и молчаливой паузы в 30 с нет.
  • Send now переживает перезагрузку окна, а зеркало чата показывает только прогон самого чата.
  • Польская формулировка подсказки рекордера помещается в свою строку.

0.13.8 — 15 сентября 2026, CLI и десктоп-приложение, выпущены вместе.

Движок понял, почему VS Code-тест проходил через раз, а чат получил управление, о котором попросил тестировщик, две минуты смотревший, как агент кликает без единого слова.

  • before: clean — шесть команд, не пять. Клик по иконке в activity bar VS Code — переключатель: если вид уже открыт, клик прячет боковую панель, и поэтому записанный сценарий проходил через раз. Пресет теперь закрывает и первую боковую панель (workbench.action.closeSidebar), а тап по иконке уже показанного вида пропускается с пометкой, а не отправляется.
  • Шаг, записанный против трёх совпадений, ждёт, пока нарисуется третье. Дерево внутри webview рисуется пачками; index: 1 of: 3 срабатывал на второй строке. Теперь прогон ждёт записанного числа (или пока оно перестанет меняться), прежде чем действовать.
  • Клик по элементу, которого окно не рисует, отклоняется, а не уходит вслепую. Внутри webview прокрутка к элементу теперь идёт в его же фрейме; если вывести элемент на экран не удалось, шаг падает с offscreen, could not scroll into view, а не кликает по тому, что там нарисовано.
  • Устаканивание видит webview. Тишина сети и DOM мерилась только по workbench; webview, который ещё рисуется, теперь держит экран «неустаканенным», а только что открытый — считается загружающимся.
  • Два названия в палитре по VS Code 1.137: View: Hide Panel и View: Hide Secondary Side Bar. Экспорт в Playwright и ExTester использует их, а команду пресета, которой в палитре нет (условие не выполнено), спек пропускает с предупреждением, а не падает.
  • Пустой vscodeCommand — ошибка валидации с позицией в файле, а не таймаут внутри окна.
  • scroll и scrollUntilVisible говорят, что нашли и как далеко прокрутили; отказ читается как not visible after N screens.
  • Чат: сообщение, набранное, пока работает Claude Code, говорит, что будет прочитано по окончании хода — старая подпись обещала доставку на лету, которой CLI не делает. Send now на этом пузыре останавливает ход и продолжает ту же сессию с вашим сообщением; у остальных CLI-провайдеров — останавливает и начинает новый ход. Собственный agent-луп приложения по-прежнему доставляет на лету.
  • Чат: агент отвечает, прежде чем действовать. Ход, начатый тем, что вы написали в предыдущий, начинается с абзаца — что сделано, что найдено, что дальше — до любого инструмента. Бюджет инструментов на ход (Settings → AI, по умолчанию 15) останавливает зациклившийся луп отчётом и кнопкой Continue; строка статуса его считает.
  • Детали прогона для агента начинаются с вердикта — упавший шаг, его ошибка и скриншот первыми, сетевой лог отфильтрован до того, что пошло не так.
  • Extensions — это его testspaces. Сборки подключаются, отмечаются и снимаются внутри диалога testspace; секция Builds и список в боковой панели убраны, кнопка в рейле открывает экран одним кликом.
  • Зоны Before/After: строка Other command… открывается там, где должна, и никогда не пишет пустой шаг; файл, в котором уже лежит пустой vscodeCommand, сохраняет его вместе с диагностикой.
  • Тест, отличающийся от последней версии, помечен синей точкой, отличной от точки статуса прогона.

0.13.7 — 15 сентября 2026, CLI и десктоп-приложение, выпущены вместе.

Восемь починок по итогам дня тестирования настоящего расширения VS Code на Windows, поверх 0.13.6.

  • Рекордер больше не привязывает клик по строке дерева VS Code к её id. VS Code выдаёт id вида vscode-tree-durbuqt9uek-… заново в каждом окне, и записанный так сценарий падал на втором прогоне. Такие id — как и mat-input-0 из Angular Material — теперь считаются нестабильными, шаг записывается по роли и имени (role: treeitem, name: "Platform"). Перезапишите шаг с таким id или выберите альтернативу, которую шаг уже предлагает.
  • Имя расширения читается через package.nls.json: сборка с локализованным displayName показывается как Low Code IDE, а не %Low Code IDE%. Ключ без файла перевода показывается текстом ключа.
  • Шаг с длинным Windows-путём остаётся внутри своей строки. Один записанный путь без пробелов растягивал весь экран Steps вбок, и строки выглядели пустыми; то же в списках прогона.
  • Диалоги больше не дают длинной строке вытолкнуть кнопки за край — в диалоге запуска VS Code строка подготовки прятала половину Run и Cancel.
  • Зоны Before и After: меню + Команда вместо ряда чипов, который читался как «это выполнится». У каждого пункта пояснение и id; Start clean добавляет пресет; Other command… открывает строку для любого id или названия из палитры.
  • Наследованная подготовка объяснена на месте: «5 шагов унаследовано от testspace X» и рядом Don’t inherit for this test; выключено — одна строка об этом и Inherit again. Галочки Inherit больше нет.
  • Тест, отличающийся от последней версии, помечен точкой, как во вкладках, а не курсивом; статус-бар говорит «изменения не в версии», а не «не сохранено» — редактор сохраняет сам.
  • Extensions в левой панели открывает свой экран одним кликом, как Settings; кнопка Manage… убрана.
  • Testspace создаётся в одной модалке с пустого проекта: сборка подключается внутри неё, без шага «сначала подключите сборку».

0.13.6 — 15 сентября 2026, CLI и десктоп-приложение, выпущены вместе.

Релиз из починок для команд, которые тестируют расширения VS Code: before: clean больше не зависает на Kill All Terminals, диалог запуска говорит, что выполнится вокруг теста, сьюты работают в VS Code-проектах, а панель Tests ведёт себя на Windows как на маке.

  • vscodeCommand: workbench.action.terminal.killAll завершается. Команда VS Code ждёт событие завершения от каждого терминала, а терминал, чей процесс уже завершился — терминал задачи с надписью Terminal will be reused, шелл, не сумевший стартовать, — второй раз его не отправляет: шаг стоял 60 с, и подготовка падала на B5. Вспомогательное расширение теперь закрывает терминалы через API расширений и отвечает, когда список пуст.
  • Testspace, выбранный в диалоге запуска, — тот, чьи before:/after: выполняются. Сценарий без vscode: { testspace: … } в шапке молча не получал хуков testspace; сценарий с testspace X, запущенный против Y, выполнял хуки X в окне Y. Теперь выбор диалога заменяет шапку до сборки хуков.
  • before:/after: проекта с runFlow: загружаются на Windows. Поиск конфига возвращал путь с префиксом \\?\, и вложенный файл с прямым слэшем под ним не открывался. Поиск больше не разворачивает симлинки: корень проекта ищется от того пути, который вы ввели.
  • Диалог запуска показывает, что выполнится до и после теста в выбранном testspace — источники (проект, testspace, сам сценарий), количество, пресет по имени, все строки при наведении, ссылка Edit — и называет конфиг, который не удалось прочитать, вместо пустоты.
  • Зоны Before и After у VS Code-теста предлагают пять команд пресета кнопками и Start clean одним нажатием. У vscodeCommand переключатель по id / по названию, args только с id и подсказка, когда id похож на название из палитры.
  • Нижняя панель не смешивает строки подготовки с шагами: B1 больше не затирается шагом 1, сетевой трафик привязан к своему блоку.
  • Сьюты в VS Code-проектах. Сьюты по тегам показываются для kind: vscode; прогон сьюта выбирает testspace — из шапки каждого теста или один для всех — и при именованном testspace держит одно окно на весь прогон.
  • Панель Tests на Windows показывает настоящие папки. Пути нормализуются при сканировании, поэтому новая папка сохраняет имя и переживает перезапуск, а Move to… в меню строки переносит в неё тесты — перетаскивание раньше молча закапывало файл в flows/<папка>/flows/. История прогонов, записанная до этой версии, один раз переписывается при старте.
  • Профиль VS Code у раннера задаёт terminal.integrated.confirmOnKill: never и terminal.integrated.enablePersistentSessions: false.

0.13.5 — 14 сентября 2026, CLI и десктоп-приложение, выпущены вместе.

Окно записи перестроено вокруг одной мысли: это журнал того, что вы сделали, а не редактор. Интерфейс говорит на шестнадцати языках. Знак и цвета новые. Перед обновлением команды прочитайте раздел «Что изменилось»: одно поведение index: изменено намеренно.

  • index: и of: считают элементы, а не узлы дерева. Управляющий элемент, который несёт собственное имя и оборачивает слово с тем же текстом — <button aria-label="Save"><span>Save</span></button>, как пишет любая дизайн-система, — везде один элемент: в строке снапшота (x2, индексы 0 и 1), в tapOn { text: "Save", index: 1 }, в записанном клике. Сценарий, записанный до 0.13.5 на такой странице, может нести старое число и попасть не туда или никуда: перезапишите шаг или уменьшите индекс на число свёрнутых слов перед ним. Записанный of: по-прежнему это ловит — прогон сообщает «N matched when this was recorded, M match now». Шаги css: считают так же.
  • Юридические документы — версия 1.2. Изменилась сторона, названная в EULA, условиях и политике; при следующем запуске приложение попросит принять их заново. Больше в них ничего не менялось.
  • Одна строка шапки. ● REC 0:41 · 7 steps, затем Check, Save и ⋯. Перечитать окно, переключатель карточки, «проверить адрес страницы» и «удалить запись…» живут в меню ⋯. Подсказка под шапкой — одна строка, уходит с первым шагом; через пятнадцать секунд без шага она спрашивает, не блокирует ли страница запись.
  • Шаги читаются как фразы. «Click button “Pay”», «Type “demo@acme.test” into “Email”», «Type into “Password”» с 🔒, «Check “Paid” is shown». Селектор по-прежнему в файле; окно показывает имя, которым назвал бы элемент человек. Один ⚠ отмечает шаг, на который стоит взглянуть ещё раз — на имя отзываются несколько элементов, элемент не нашёлся заново после того, как страница успокоилась, или он адресован по позиции, — и по наведению говорит почему. 🗑 и ⋯ появляются по наведению; «Details», «другие способы найти», «сделать переменной» и «добавить проверку после шага» — в ⋯.
  • Отмена там, где удалили. Удалённый шаг оставляет призрак на своём месте — «Step 7 deleted · Undo» — на десять секунд или до следующего шага; ⌘Z делает то же. Пропуск шага из карточки идёт тем же путём.
  • Check — одно действие. Нажмите Check, кликните по тому, что должно быть на экране: проверка записана, а страница клика не видела — и в браузере, и в VS Code. ⌥-клик (⌃⌥ в VS Code, Ctrl+Shift на Windows и Linux) по-прежнему делает это без кнопки.
  • Save спрашивает имя после нажатия. Шапка превращается в пустое поле «Name this test»; Enter записывает файл, Esc возвращает к идущей записи. Имя больше не подставляется из адреса и хранит набранный регистр. «Save & run» больше нет: главное окно открывает сохранённый тест и предлагает Run в тосте.
  • Карточка рядом с элементом стала маленькой. «Step 7 · Click button “Pay”», одна строка действий, полоска, убывающая пока карточка стоит. Она спрашивает только когда движок не уверен — «6 buttons say “Pay” — the step takes the 2nd», — и ответы — то, что видно глазами: «та, что в строке “#1042”», «вторая “Pay”». Два способа именования, которые читаются одинаково, — один ответ. Набранный текст получает два ответа: оставить текстом или сделать переменной; поле пароля — ни одного, оно ушло в .env, карточка говорит под каким именем. Элемент, о котором карточка, обведён отдельным окном. Наведение или ⋯ открывает полную карточку из 0.13.4.
  • Экран починки («Show it again from here») носит ту же поверхность, что и окно записи.
  • Шестнадцать языков интерфейса. Испанский, украинский, польский, казахский, немецкий, турецкий, французский, итальянский, японский, упрощённый китайский, корейский, вьетнамский и индонезийский — к английскому, русскому и бразильскому португальскому. «System» читает язык машины, а не веб-вью.
  • Новый знак и новые цвета. Чернила и лайм, иконка приложения из того же мастера, та же палитра на tapstep.dev и docs.tapstep.dev.
  • Детали теста — боковая панель рядом с Recordings и Versions, с секциями тегов, приложения и окружения; .md открывается с предпросмотром; Suites сворачиваются в строку; подсветка теста следует за открытой вкладкой; файл в группе Project открывает файл.
  • Починки чата. Отказ CLI сообщается один раз; ошибка провайдера открывает выбор провайдера; узкая колонка сохраняет кнопки шапки; «Open test» на прогоне показывает шаги; текстовая вкладка не теряет ввод во время сохранения; терн, оборванный ошибкой API, завершается честно.
  • Кнопка версии — в шапке любого проекта; клик по пункту рельса закрывает полноэкранный экран поверх; скриншот в отчёте больше не ждёт разрешения на запись экрана.
  • MCP доходит до VS Code. tapstep mcp --driver vscode --testspace <имя> ведёт VS Code проекта так же, как устройство: панель webview — именованная область обзора, сервер говорит, какие фреймы пропустил, имя внутри фрейма разрешается, а кнопка, которая есть в двух webview, считается по разу на фрейм — никогда по два.
  • run_flow находит сценарий и по заголовку, не только по пути.

0.13.4 — 11 сентября 2026, CLI и десктоп-приложение, выпущены вместе.

Обновите все машины команды — и на этот раз старая сборка скажет об этом сама. Записанный здесь сценарий может нести or:, of: и scroll … within: — ключи, которых движок до 0.13.4 не видел, — а незнакомый ключ он называет и отвергает, а не читает мимо. Такой сценарий на старой сборке остановится, а не тихо отработает ослабленную версию себя.

  • Шаг, который на что-то нажимает, имеет в виду контрол, а не подпись. Голое имя в tapOn, doubleTapOn, longPressOn, hover, check/uncheck, selectOption, uploadFile, dragAndDrop или scrollUntilVisible разрешается в элементы, на которые можно нажать, и больше не в подпись с теми же словами, — поэтому сценарий, который опирался на нажатие подписи по имени, теперь нажмёт контрол рядом с ней. Если имени не отвечает ни один контрол, слово нажимается как прежде, а строка несёт пометку matched only text, nothing to press; index: выключает правило; а шаги, которые читают слово (copyText) или доказывают, что оно на экране (assertVisible, waitForVisible, assertNotVisible, условие when:), совпадают со всеми элементами, как и раньше. Контрол, который носит своё имя на обёрнутом элементе, — по-прежнему контрол. Подробнее: Селекторы.
  • Хелпер называется общими шагами. Ничто, что человек читает в десктоп-приложении, больше не называет файл *.helper.yaml хелпером: меню, строки, тосты и README, который получает новый проект, говорят Shared steps. Расширение файла и собственный helper движка не изменились.
  • Переключателя «View as files» в панели тестов больше нет. Одна панель, одна модель: тесты и общие шаги в тех папках, в которых они лежат. Машина, где переключатель был включён, продолжает показывать имена файлов — один раз перенесённая в Settings → Appearance → Tests panel → Names, предпочтение об этом одном списке, а не второй вид.
  • Прогон ждёт страницу, прежде чем действовать. Экран успокоился, когда об этом говорят четыре признака — загрузка завершена, ничего не в полёте, DOM не шевелится, адрес не меняется, — и отсутствию верят только на успокоившемся экране. Медленный экран читается медленно, а не падает как неуспокоившийся, а собственный timeout: шага поднимает бюджет. Подробнее: Как прогон понимает, что страница успокоилась.
  • Рекордер смотрит на экран ещё раз после каждого шага. Записанный селектор несёт of: — сколько элементов ответило ему на момент записи, — и прогон говорит, когда страница перестала отвечать этим числом. Карточка добавляет то, что нашёл второй взгляд, и не повторяет сказанного шагом.
  • Текст читается дважды. Если на экране никто не отвечает тексту как написано, экран читается второй раз без учёта регистра и со схлопнутыми пробелами, а шаг несёт пометку matched ignoring case/spacing. Шаги, которые ищут отсутствие, читают текст только так, как он написан.
  • Скролл становится шагом, только если он им был. Проскроллили, чтобы дотянуться, и кликнули — не запишется ничего, прогон доскроллит сам. Проскроллили и остановились — окно предлагает scroll; скролл внутри блока, который прокручивается сам, называет этот блок, и у шага появляется within:.
  • Селектор может назвать альтернативы. or: даёт ему до трёх запасных, и читаются они только на успокоившейся странице и только когда основной не совпал ни с чем. Попадание проводит шаг и помечает строку drifted во всех отчётах, а tapstep test --strict-selectors валит прогон, который оперся на запасной. Список шагов показывает запасные имена, а разбор предлагает поставить одно из них первым. Подробнее: Селекторы.
  • Рекордер слышит не только клики. Задержка, открывшая меню, — это hover, выбор в нативном списке — selectOption, файл — uploadFile, названный через css, когда стилизованный загрузчик прячет input, перетаскивание — dragAndDrop с тем путём, которым реально шёл указатель, а pressKey теперь принимает и четыре стрелки.
  • Про ссылку, открывшую новую вкладку, говорят, а не пишут шаг. Окно записи скажет об этом, когда клик, открывший её, состоится: вторая вкладка — собственная вкладка браузера, вне страницы, которой управляет этот сценарий.
  • Кнопка без единого слова записывается всё равно кнопкой. Рекордер спрашивает страницу, что ответило на клик — onclick, обработчик React или Vue, зарегистрированный слушатель, курсор-указатель, — и называет шаг по подписи, по подписи в его строке или по картинке, которую он рисует, с index:, когда одна и та же иконка стоит в двух строках.
  • Панели-webview VS Code пишутся глубже. Фрейм двумя фреймами ниже, кросс-доменный фрейм и webview в боковой панели берутся под наблюдение, переоткрываются после навигации и отпускаются, когда их цель ушла; TAPSTEP_RECORD_LOG — любое значение, кроме 0, — заставляет рекордер сказать, почему во фрейм он не вошёл.
  • Фрейм, появившийся, пока рекордер ещё открывает соседний, не теряется. Наблюдение за фреймом включается один раз — после того, как рекордер уже слушает, — а если браузер включить его отказался, окно скажет об этом, вместо того чтобы тихо перестать слышать этот фрейм.
  • Снапшот v2 для агентов. Одна грамматика, один рендерер, один парсер: ref остаётся при своём элементе от действия к действию, а ушедший ref сам об этом говорит; detail: и around: решают, сколько печатать; первые строки называют страницу и успокоилась ли она, а act отвечает строкой net: про запросы, которые он поднял. Подробнее: Нотация снапшота.
  • Агент пробует один шаг вместо того, чтобы читать экран дважды. try выполняет один шаг сценария на живом экране и отвечает тем, что он сделал, что изменилось, и — когда имени отвечает больше одного элемента — списком кандидатов на выбор; snapshot { detail: "regions" } — тот единственный обзор, с которого он начинает. Подробнее: Как агент ведёт экран теперь.
  • Попробовать один шаг, не запуская сценарий. Шаг request или sql выполняется сам по себе прямо из шага — статус, время, заголовки и тело или строки в таблице, — а клик по ответу пишет в этот же шаг один ключ assert: или extract:. Подробнее: Попробовать шаг.
  • tapstep sql --ping "${DATABASE_URL}" проверяет строку подключения раньше, чем на неё обопрётся сценарий, и называет стадию, на которой не вышло: DNS, connect, auth. Окружение он берёт из того конфига, который ему дали; в десктопе это Check рядом с db шага sql:, а сам db выбирается из переменных, поэтому строка подключения не попадает в YAML.
  • Строки шага sql: сохраняют порядок колонок SELECT, поэтому первая строка читается так, как написан запрос.
  • Упавший request: показывает статус и тело, с которыми вернулся, — в строке прогона, а не одну лишь ошибку.
  • Упавший шаг sql: называет сам запрос, его параметры и слова, которыми отказала база, — в строке сохранённого отчёта и теперь в строке живого прогона тоже. Секреты в параметрах и в ячейках маскируются, широкий результат оставляет 32 колонки, а свидетельство режется до 64 КБ с пометкой, сколько его было; шаг, упавший внутри repeat, retry, runFlow или хука, несёт его там, где это случилось.
  • Набор чисто-API сценариев запускается там, где устройства нет. Когда все сценарии папки говорят device: none, прогон перестаёт искать браузер или эмулятор, а в смешанном наборе сценарий с device: none сам берёт пустой драйвер. assertFile нужна рабочая папка, поэтому под device: none его теперь помечают, а не предлагают.
  • css: называет набор, а ключи рядом с ним его сужают. Любой другой ключ селектора — text, name, role, label, placeholder, признак, отношение, состояние — теперь фильтрует то, что нашёл CSS, ровно так же, как фильтровал бы без css, а index:/of: считают уцелевших. Поэтому { css: ".monaco-editor", text: "hello" } — это редактор, показывающий hello, а набор, из которого не уцелело ничего, — это не найдено, и сообщение называет оба ключа. Подробнее: Селекторы.
  • Экспорт Playwright несёт свой конфиг. Папка, в которой лежит спек VS Code, получает playwright.config.ts с одним воркером, а Electron-спек уносит с собой две временные папки, которые он создаёт.
  • README папки следует за папкой — обновляется, когда его текст устарел, включая написанный прошлым релизом, и никогда не остаётся стоять там, где спеков нет.
  • Отсутствующий testspace — это структура, а не ошибка провода. Десктоп называет testspace, которого просит заголовок vscode: сценария, и предлагает Open Extensions, вместо того чтобы печатать сбой в терминал.
  • Заголовок спека называет свой сценарий от того корня проекта, который дал вызывающий, и десктоп разрешает его той же функцией, которой это делает CLI, — заголовок, написанный одним, читается другим, а заголовок с исчезнувшим сценарием не приписывается чужому тесту.
  • Повторный экспорт не уносит несохранённых нажатий из вкладки спека, а подтверждение называет сценарий, чей спек заменит одноимённый тест.
  • Claude Code, в который никогда не входили, говорит об этом до начала терна. Шапка называет это, а CLI, отвечающий run /login, заканчивает терн этой фразой, а не шестью строками stderr.
  • Терн, от которого 90 секунд ничего не слышно, падает, а не считает время вверх; каждая стадия до того, как заговорит AI CLI, называет себя в чате и в логе; а терн, который паникует, всё равно отвечает.
  • Сообщение, написанное в летящий терн, говорит, прочитал ли его агент или ждёт конца терна.
  • Одна строка расхода на терн, раскрываемая до вызовов за свёрнутыми строками.
  • Импорт берёт спек — .spec.ts, .spec.js, .test.ts, .test.js или папку с ними, — карточка обещает только то, что разобралось, а строка проверки называет сценарий, который написал импорт, а не спек, который он прочитал.
  • OpenCode ищется там, где говорит XDG_CONFIG_HOME, а его мост закрывается вместе с приложением, которое его открыло.
  • Чат ведёт экран так же, как агент — один обзор, дальше по одному шагу, а квитанция try читается как текст с экрана, а не как указания, — и об этом говорят и подсказка каждого провайдера, и пустой чат.
  • Вердикт в панели прогона — это фраза, которую написал движок, без проводного обвеса.
  • Починка называет testspace, в котором будет переигрывать, берёт выбранный вами вместо того, что в заголовке сценария, записывает его обратно в заголовок, а на маке вкладка называет Option.
  • Сообщение о баге снимает главное окно и говорит почему, когда не может; а отчёт и баг-репорт больше не пишут поверх архива друг друга.
  • Предложение по вставленному curl переживает набор в нём — первое нажатие после вставки это правка её, а не ответ, — а шаг request: читается как вызов, а не как форма, которой редактор не знает.
  • Карточка рекордера встаёт уже с номером шага, живая подсказка селектора — это один элемент, а не одна подпись, и пикер, хотспот и подсказки пишут $, # и x6 так же, как снапшот.
  • Пикер ролей предлагает собственный словарь движка — с первого момента, а не после того, как приедет схема, — и рекордер называет роль контрола по тому же опубликованному списку.
  • Тест, папку и файл общих шагов можно назвать на любом алфавите. Русское имя становится русским именем файла, а не молча ничем, а имя, которого не вынесет файловая система, — уже занятое или одно из тех, что Windows держит за своими устройствами, — говорит об этом.
  • Удаление отправляет в корзину и десять секунд остаётся отменяемым. Тест, папка и файл общих шагов уходят в системную корзину, а не в никуда, и тост предлагает Вернуть, пока они там.
  • Панель тестов даёт адрес каждому файлу проекта. Строка — это имя, одна точка и слова о том, что это: общие шаги говорят, сколько тестов их использует, исчезнувший файл говорит missing, а в строке есть Copy path. Группу можно создать в любой папке, которую показывает панель, а не только под flows/, и ничто, что читает человек, больше не называет общие шаги helper.
  • У панели тестов есть собственные настройки — в Settings → Appearance → Tests panel: читается ли строка как имя или как имя файла, стоят ли общие шаги в своих папках или одной группой в конце, в каком порядке идут тесты — по имени, по последнему прогону или по свежести записи — и рисуются ли вообще точка прогона, git-пометка и группа Project. Тест, который идёт прямо сейчас, пульсирует и с выключенным Run status.
  • Панель — дерево, по которому ходит клавиатура. Стрелки шагают по нему и открывают папки, Home / End ведут к концам, набранные буквы перепрыгивают, F2 переименовывает, Enter открывает, ⌘Enter запускает. Shift- и ⌘-клик выбирают диапазон или ещё одну строку, а выбранное разом удаляется, экспортируется или перетаскивается на папку — перетаскивание нескольких строк несёт призрак с их числом.
  • Селектор шага умеет сказать role и что ещё должно быть верно. Контрол вверху формы предлагает text, #id, regex, ⌖ point и role с полем для имени элемента рядом, а + Condition добавляет любой другой ключ селектора, который публикует движок, в том порядке, в каком движок ранжирует локаторы.
  • Экранный пикер говорит, что ему нужна запись, и предлагает рядом Record…, а не стоит кнопкой, которая ничего не делает.
  • Open test на прогоне, чей файл исчез, говорит об этом — какой путь ушёл и Show the folder, чтобы посмотреть, где он был, — а переименованный или перенесённый тест забирает историю своих прогонов с собой, а не оставляет её на старом пути.
  • Строка на месте Show it again называет причину и для падения в setup, а также говорит, чего она ещё ждёт, вместо мёртвой кнопки Start.
  • Имя ветки следует собственному правилу git для имён ссылок, а не правилу для имён файлов.
  • tapstep schema публикует роли, которые знает движок, под ключом role селектора — справочник и агенты читают один список вместо ручного, который может отстать.
  • tapstep skill install пишет для каждого найденного агента, включая OpenCode — ~/.config/opencode/skills или туда, куда указывает XDG_CONFIG_HOME, — и оба README называют всех агентов. Подробнее: Рабочие области CLI.
  • tapstep test --strict-selectors валит прогон, который оперся на запасной селектор.
  • TAPSTEP_RECORD_LOG заставляет рекордер назвать фреймы, в которые он не вошёл, и почему.
  • TAPSTEP_NO_DEVICES — любое значение, кроме 0, — не даёт определению драйвера обращаться ни к adb, ни к simctl, поэтому прогон, которому устройство не нужно, не зависит от того, что воткнуто в машину; doctor и явно названный драйвер по-прежнему читают её как есть.
  • Запрос, чей конец обогнал начало, больше не остаётся висеть в полёте.
  • Захват полосы прокрутки, чей отпуск потерялся, больше не присваивает себе все последующие скроллы.
  • Блок с overflow прячет только то, что разложено внутри него, поэтому модалка или портал не объявляются ушедшими из виду.
  • Селектор css считается один раз по всей странице, вместе с фреймами.
  • swipe берёт либо направление, либо две точки, и парсер отказывает, когда дают и то и другое.
  • На Linux и Windows bin/code считается установкой VS Code только вместе с самим приложением рядом.
  • Спек, который файловая система пишет заглавными, — всё ещё спек, а путь к спеку, начинающийся с дефиса, всё так же открывается в VS Code.
  • Шаг, который писатель YAML не может записать, больше не роняет рекордер, а упавший шаг находит свою команду через блоки, внутри которых он выполнялся.
  • Чат, открытый с диска, перестаёт обещать терн, который уже отработал, а ширина чата, сохранённая на широком экране, приводится к тому, на котором он открылся.

0.13.3 — CLI и десктоп-приложение, выпущены вместе.

Обновите все машины команды — старые сборки молча пропускают before/after. Сценарий с хуками для старого движка — валидный YAML: он просто игнорирует два ключа и выполняет нумерованные шаги без подготовки и уборки. Зелено и неверно. То же с vscodeCommand, environments: и настройкой exports: — необновлённая машина читает мимо них.

Сценарий теперь может сказать, что выполняется вокруг его шагов:

before:
- launchApp: https://staging.example.com
commands:
- tapOn: "Log in"
- assertVisible: "Welcome"
after:
- takeScreenshot: end

before: идёт перед шагом 1, и ошибка в нём валит сценарий собственным вердиктом (setup failed at B2: …), не выполняя шагов. after: выполняется после последнего шага всегда — после падения, после остановки, — и каждая его строка выполняется, даже если одна из них упала; ошибка уборки попадает в отчёт рядом с вердиктом и не меняет его. В отчётах и в экране прогона десктопа это блоки Setup и Teardown.

В config.yaml могут лежать before: / after: всего проекта, а у testspace VS Code — свои; они оборачивают хуки сценария, внешние входят первыми и выходят последними. inheritHooks: false в сценарии отключает унаследованное. onFlowStart: / onFlowComplete: — старые имена этих ключей, они всё ещё работают.

Подробнее: Файл флоу и селекторы.

vscodeCommand выполняет команду VS Code напрямую — по id через вспомогательное расширение, которое драйвер ставит сам (и которое отвечает, когда команда действительно завершилась), или по title, который показывает палитра. args идут только с id: палитра аргументов не принимает, и просьба совместить их — ошибка, а не молчаливая потеря.

before: clean — строка вместо списка — возвращает окно VS Code в известное состояние перед шагами: закрыть все редакторы, панель, боковую панель, очистить уведомления, убить терминалы. В десктопе это переключатель Start clean у testspace.

Клики внутри собственной панели расширения (vscode-webview://) теперь записываются, включая панели, открытые уже во время записи. А прогон VS Code можно показать заново из разбора — в том testspace, в котором он шёл.

tapstep export playwright теперь переносит разрешённые хуки в test.beforeEach / test.afterEach спека, а сценарий с vscode: уходит самостоятельным Electron-спеком, который запускает установленный VS Code.

tapstep export extester — новая команда: сценарий с vscode: как тест vscode-extension-tester — Mocha и chai поверх Selenium — с README, где лежат команды extest, --code_version, который назвала эта машина, и workspace, который раннер должен открыть. MCP-инструмент — export_extester, а десктоп предлагает этот вид только там, где у теста есть заголовок vscode:.

Куда попадает экспорт — теперь настройка проекта, и её читают одинаково CLI, MCP-инструменты и десктоп:

exports:
playwright: playwright
extester: ../qa-suite/src/ui-test

Относительный путь едет вместе с проектом; абсолютный — только ваш, и именно так работает QA-сюита в своём репозитории. --out по-прежнему сильнее.

Проект может назвать свои цели и держать набор значений на каждую:

defaultEnvironment: staging
environments:
staging: { BASE_URL: https://staging.example.com }
prod: { BASE_URL: https://example.com }

tapstep test flows/ --env-set prod выбирает одно на весь прогон, без флага это делает defaultEnvironment. Вместе с ним подгружается .env.<имя>, так что локальные секреты окружения едут с ним и не попадают в git; выбранное имя — это ${TAPSTEP_ENV}.

Порядок слоёв изменился. Локальный файл теперь бьёт закоммиченный на каждом уровне:

умолчания params: < env: сценария < env: конфига < environments.<текущее> < .env < .env.<текущее> < --env-file < -e

До 0.13.3 .env стоял ниже; если вы рассчитывали, что закоммиченное значение перебьёт локальное, это и есть случай, который стоит перепроверить. tapstep validate предупреждает про ${VAR}, который окружение оставляет открытым, и называет, какое именно; каждый отчёт говорит, против какого окружения шёл прогон; а в десктопе появились переключатель окружения в титульной строке и матрица Environments, которая пишет обычные config.yaml и dotenv-файлы.

Подробнее: config.yaml и Десктоп → Окружения.

Клик по переключателю или чекбоксу пишется как check / uncheck, а не tapOn, и берётся из состояния, которое застало нажатие: вслепую тап переворачивает то, во что попал. Контрол, который никто не назвал, адресуется подписью рядом с ним — реляционным селектором ({ role: switch, leftOf: "Published" }), с index: там, где одна подпись достаёт до нескольких контролов.

Движок читает эти отношения строже, чтобы совпадало: above/below/leftOf/rightOf теперь требуют собственной колонки или строки якоря, а совпадения упорядочены по близости к нему — так что подпись называет контрол рядом с собой, а не всё дальше по странице. Экран, где на линии якоря нет ничего, откатывается к прежнему, более широкому правилу, так что существующие сценарии продолжают разрешаться.

  • Английский и русский, язык берётся у системы, пока вы не выберете свой в Settings → General. Без перезапуска.
  • Settings → Appearance — тема, масштаб интерфейса (⌘= / ⌘− / ⌘0 и меню View), шрифт редактора, что рисуют редакторы, плотность и уменьшение анимации, с одним сбросом.
  • AI-чат — одна лента: шаги стоят там, где случились, один переключатель Details и строка состояния с фазой: Thinking, Working, Verifying. Любой ход заканчивается done. К провайдерам добавился OpenCode.
  • Report a bug в титульной строке: подписанный issue с серьёзностью, скриншотом и замаскированными логами, а свои issue видны списком со статусом.
  • Редактор шагов — три зоны: Before, Steps, After, и унаследованные строки помечены тем, откуда пришли.

Подробнее: Десктоп.