CI / GitHub Actions
CI-раннер не может открыть браузер для входа, поэтому входит по персональному токену. Создайте его на своей машине — браузер откроется один раз для SSO, а токен будет показан один раз и больше никогда:
tapstep token create --name github # печатает tapstep_pat_… в stdouttapstep token create --name github | gh secret set TAPSTEP_TOKEN # сразу в секрет репозиторияtapstep token create --name nightly --expires-days 90В stdout уходит только сам токен, поэтому его удобно передавать по пайпу; пояснение к нему уходит в stderr. Десктоп умеет то же в Settings → General → CI tokens: создать, один раз скопировать, отозвать.
Положите токен в GitHub → ваш репозиторий → Settings → Secrets and
variables → Actions под именем TAPSTEP_TOKEN и передайте его джобу
переменной окружения — TAPSTEP_TOKEN в окружении считается входом.
tapstep token list # id, имя, префикс, создан, последнее использование, срок — без самого токенаtapstep token revoke github # по id или по имени, если имя уникальноКак CLI его проверяет: токен tapstep_pat_… сверяется с api.tapstep.dev один
раз, и ответ кэшируется в ~/.tapstep/token-check.json на 24 часа — на свежем
раннере это один запрос на джоб. Отозванный, истёкший или неизвестный токен
останавливает команду с ошибкой. Если API недоступен, прогон идёт дальше — со
строкой warning: в stderr, если эта машина ещё ни разу не проверяла токен
(свежий раннер), и молча, если проверяла. Наш простой никогда не красит ваш
пайплайн.
TAPSTEP_TOKEN с любым другим значением — старые доки пропускали любую
строку — работает с предупреждением в stderr до 0.15. До этого замените его
токеном из tapstep token create.
Минимальный workflow (web)
Заголовок раздела «Минимальный workflow (web)».github/workflows/e2e.yml:
name: e2eon: [push, pull_request]
jobs: web: runs-on: ubuntu-latest env: TAPSTEP_TOKEN: ${{ secrets.TAPSTEP_TOKEN }} TAPSTEP_NO_SANDBOX: "1" # Ubuntu 24.04 не даёт песочнице Chromium стартовать, см. ниже steps: - uses: actions/checkout@v4
- name: Install tapstep run: | curl -fsSL https://s3.tapstep.dev/tapstep-cli/tapstep-latest-linux-x86_64.tar.gz | tar -xz sudo mv tapstep /usr/local/bin/
- name: Validate flows run: tapstep validate flows/
- name: Run flows run: tapstep test flows/ --report junit --output results.xml
- name: Upload results if: always() uses: actions/upload-artifact@v4 with: name: tapstep-results path: | results.xml reports/ if-no-files-found: ignoretapstep validate проверяет разбор каждого флоу и его include’ов без
устройства, так что опечатка валит джоб за секунду, а не на середине прогона.
Код выхода отличает красный прогон от сломанного раннера: 1 — флоу
выполнились, часть упала; 2 — tapstep не смог их запустить (плохой флаг, нет
устройства, нечитаемый конфиг). Оба валят джоб; красный продукт означает только
1.
В образе GitHub Ubuntu уже есть Google Chrome, и tapstep его подхватит.
--browser managed вместо этого скачивает прибитый Chromium в
~/.tapstep/browsers, чтобы CI и все ноутбуки гоняли одну версию браузера, —
если пользуетесь им, кэшируйте эту папку между джобами.
TAPSTEP_NO_SANDBOX=1 нужен потому, что на ubuntu-latest (Ubuntu 24.04)
песочница Chromium не запускается: AppArmor ограничивает непривилегированные
user namespaces, и Chromium выходит с No usable sandbox. В container:-джобах
и большинстве Docker-образов Chromium запущен от root и отказывается от
песочницы сразу (Running as root without --no-sandbox is not supported).
С 0.13.12 tapstep на Linux распознаёт оба отказа, печатает уведомление и один
раз перезапускает Chromium с
--no-sandbox, так что джоб без переменной тоже пройдёт — только заплатит за
неудачный первый запуск. TAPSTEP_NO_SANDBOX=1 пропускает эту попытку и сразу
стартует без песочницы.
Доступ к приложению
Заголовок раздела «Доступ к приложению»Три способа — смотря где живёт тестируемое приложение.
URL стенда. Держите адрес вне флоу и выбирайте его по окружению в
config.yaml:
environments: local: { BASE_URL: http://localhost:3000 } ci: { BASE_URL: https://staging.example.com }appId: ${BASE_URL}/login - name: Run flows run: tapstep test flows/ --env-set ci --report junit --output results.xml env: APP_PASSWORD: ${{ secrets.APP_PASSWORD }}--env-set ci подгружает environments.ci и локальный .env.ci, если он
есть; внутри прогона ${TAPSTEP_ENV} равен ci. Секретам файл не нужен:
любой ${NAME}, который не задал ни один слой, берётся из окружения процесса,
так что секрет GitHub, выставленный в env:, доходит до ${APP_PASSWORD} как
есть. См. config.yaml.
Приложение в том же джобе. Запустите его в фоне, дождитесь порта и гоняйте:
- run: npm ci && npm run build - run: npm start & - run: curl -fsS --retry 30 --retry-delay 2 --retry-connrefused http://localhost:3000 > /dev/null - run: tapstep test flows/ -e BASE_URL=http://localhost:3000 --report junit --output results.xmlИли напишите во флоу прямо appId: http://localhost:3000.
Без UI вообще. Флоу device: none из шагов request: и sql: не нужны ни
браузер, ни устройство — они идут на любом раннере, см.
API-тестирование.
Android
Заголовок раздела «Android»Поднимите эмулятор через
reactivecircus/android-emulator-runner
и запустите tapstep внутри него. Запущенный эмулятор tapstep сам находит через
adb:
android: runs-on: ubuntu-latest env: TAPSTEP_TOKEN: ${{ secrets.TAPSTEP_TOKEN }} steps: - uses: actions/checkout@v4 - name: Enable KVM run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules sudo udevadm trigger --name-match=kvm - name: Install tapstep run: | curl -fsSL https://s3.tapstep.dev/tapstep-cli/tapstep-latest-linux-x86_64.tar.gz | tar -xz sudo mv tapstep /usr/local/bin/ - uses: reactivecircus/android-emulator-runner@v2 with: api-level: 34 arch: x86_64 disable-animations: true script: | adb install -r app/build/outputs/apk/debug/app-debug.apk tapstep test flows/android/ --report junit --output results.xmlКаждая строка script: выполняется отдельной командой. Если подключено
несколько устройств, --device <serial> выбирает одно.
Флоу iOS в CI пока не запускаются: в релизный бинарь не входит XCUITest-раннер, без которого не работает iOS-драйвер. Гоняйте их на Mac, где раннер установлен; поддержка CI появится в релизе, который его поставляет.
Расширения VS Code
Заголовок раздела «Расширения VS Code»Флоу с vscode: запускает установленный десктопный VS Code, поэтому джоб его
ставит и даёт ему виртуальный дисплей:
vscode: runs-on: ubuntu-latest env: TAPSTEP_TOKEN: ${{ secrets.TAPSTEP_TOKEN }} steps: - uses: actions/checkout@v4 - name: Install VS Code and Xvfb run: | curl -fsSL -o code.deb "https://update.code.visualstudio.com/latest/linux-deb-x64/stable" sudo apt-get update && sudo apt-get install -y ./code.deb xvfb - name: Install tapstep run: | curl -fsSL https://s3.tapstep.dev/tapstep-cli/tapstep-latest-linux-x86_64.tar.gz | tar -xz sudo mv tapstep /usr/local/bin/ - run: npm ci && npx @vscode/vsce package -o dist/my-ext.vsix - run: xvfb-run -a tapstep test flows/vscode/ -e VSIX=${{ github.workspace }}/dist/my-ext.vsix --report junit --output results.xml.vsix берётся из предыдущего шага сборки; флоу читает его в заголовке
vscode: как vscode: { vsix: ${VSIX} } или называет testspace: из
config.yaml. Относительный vsix: считается от папки самого флоу (у
testspace — от корня проекта), поэтому передавайте абсолютный путь, как выше, — см.
config.yaml. VS Code tapstep находит через CLI code в
PATH или через TAPSTEP_VSCODE=/path/to/code.
Раннеры Windows
Заголовок раздела «Раннеры Windows»На runs-on: windows-latest ставьте из zip в PowerShell:
- name: Install tapstep shell: pwsh run: | Invoke-WebRequest https://s3.tapstep.dev/tapstep-cli/tapstep-latest-windows-x86_64.zip -OutFile tapstep.zip Expand-Archive tapstep.zip -DestinationPath "$env:LOCALAPPDATA\tapstep\bin" "$env:LOCALAPPDATA\tapstep\bin" | Out-File -Append -Encoding utf8 $env:GITHUB_PATH--report junit|allure|html|json с --output <file> пишет один общий отчёт
для прогона директории; allure пишет папку allure-results/ (в текущей
папке или в --output <dir>). Блок report: в config.yaml пишет отчёт на
каждом прогоне без флагов. Скриншоты и сетевые логи падений ложатся в
reports/ — выгружайте эту папку с if: always(), как в workflow выше. См.
Отчёты.
Флоу с AI-шагами и в CI нужен провайдер (TAPSTEP_AI_MODEL, TAPSTEP_AI_KEY и
TAPSTEP_AI_ENDPOINT из секретов или блок ai: в config.yaml). С
включённым режимом приватности запускайте tapstep privacy install при сборке
образа раннера — модель маскировки весит ~945 МБ, качать её в каждом джобе не
стоит.