Что нового
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 для имён ссылок, а не правилу для имён файлов.
CLI и скилл
Заголовок раздела «CLI и скилл»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.comcommands: - tapOn: "Log in" - assertVisible: "Welcome"after: - takeScreenshot: endbefore: идёт перед шагом 1, и ошибка в нём валит сценарий собственным
вердиктом (setup failed at B2: …), не выполняя шагов. after: выполняется
после последнего шага всегда — после падения, после остановки, — и каждая
его строка выполняется, даже если одна из них упала; ошибка уборки попадает в
отчёт рядом с вердиктом и не меняет его. В отчётах и в экране прогона десктопа
это блоки Setup и Teardown.
В config.yaml могут лежать before: / after: всего проекта, а у testspace
VS Code — свои; они оборачивают хуки сценария, внешние входят первыми и выходят
последними. inheritHooks: false в сценарии отключает унаследованное.
onFlowStart: / onFlowComplete: — старые имена этих ключей, они всё ещё
работают.
Подробнее: Файл флоу и селекторы.
VS Code: команда и чистый старт
Заголовок раздела «VS Code: команда и чистый старт»vscodeCommand выполняет команду
VS Code напрямую — по id через вспомогательное расширение, которое драйвер
ставит сам (и которое отвечает, когда команда действительно завершилась), или
по title, который показывает палитра. args идут только с id: палитра
аргументов не принимает, и просьба совместить их — ошибка, а не молчаливая
потеря.
before: clean — строка вместо списка — возвращает окно VS Code в известное
состояние перед шагами: закрыть все редакторы, панель, боковую панель, очистить
уведомления, убить терминалы. В десктопе это переключатель Start clean у
testspace.
Клики внутри собственной панели расширения (vscode-webview://) теперь
записываются, включая панели, открытые уже во время записи. А прогон VS Code
можно показать заново из разбора — в том testspace, в котором он шёл.
Экспорты: Playwright и ExTester
Заголовок раздела «Экспорты: Playwright и ExTester»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: stagingenvironments: 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, и унаследованные строки помечены тем, откуда пришли.
Подробнее: Десктоп.