
Я пишу E2E Playwright тесты на typescript в кровавом энтерпрайзе. Задача – выполнить полный рабочий цикл с так как это делает живой пользователь, симулировать ввод данных и клики мышкой. Последний этаж тестовой пирамиды, после которого можно и в продакшн.
Достаточно часто всплывают проблемные места, на которых тест валится. Не просто изменившийся селектор, эту мелочь с помощью AI можно поправить за секунды. Что-нибудь посложнее – плохая гидрация, двойной рефреш или зависимые поля. Что говорить, если даже на самом сайте Playwright встречается такое.
У Playwright неплохие трейсы, но приходится перезапускать тест каждый раз. Исправил, перезапустил, упало, смотришь логи. И так по кругу, пока не заработает. Если проблема в конце теста, ждать приходилось долго. Куча времени потрачена просто на ожидание.
Хотелось бы менять код «на лету», без перезапуска. В консоли браузера я, например, могу в любой момент напечатать и запустить команду.
Хотелось бы такого и для Plywright в связке с TypeScript, только лучше. Чтобы запускать прямо в редакторе Visual Studio Code, а не в консоли. Чтобы синтаксис проверялся, tslinter‘ы всякие работали, автодополнение на лету и прочий AI.
Напечатал
await page.getByRole("search", {name : "Search"});
Запустил. Посмотрел на реакцию, поправил
await page.getByRole("searchbox", {name : "Search"});
Запустил снова. И так много раз, если надо. Можно несколько команд сразу запускать, если хочется. Модули импортировать на лету. Чтобы scope запоминался, если выполнил
const searchBox = page.getByRole("searchbox", {name "Search"})
то потом searchBox можно использовать дальше
await searchBox.click();
Мозговой штурм с агентом выдал следующие результаты:
Попытка 1 - Debug Console REPL (Read-Eval-Print Loop) в VSCode
По факту у эта консоль привязана к дебагу и и‑за этого возникает куча проблем:
Breakpoint останавливает Event Loop, значит запуск await — команды ничего не выполнит вплоть до нажатия F5/ F10 / F11. После этого Visual Studio с breakpoint'а уйдёт. Да, есть хак, можно каждый раз писать фиктивный цикл и ставить breakpoint внутрь, ��о каждый раз так делать это для сильных духом терминаторов.
Попыка 2 - node:repl
Следующая попытка была использовать node:repl. Дебаг не нужен, просто добавляешь вызов REPL внутрь теста
const msg = 'message'; repl.start('> ').context.m = msg;
Когда тест выполнится до этого места, можно запускать Playwright команды прямо в командной строке. Не зашло, потому что неудобно копировать текст из редактора и обратно, нужно помнить синтаксис REPL. Впрочем, если VIM вам как родной, то будет ок.
Попытка 3 – готовые REPL расширения для VSCode
Нашлись REPL расширения для VSCode! Целых 2! Одно не заработало, другое заброшено 6 лет назад. И всё это многообразие не рассчитано на Playwright, значит, как минимум точно будут проблемы с таймаутами.
У нас большие таймауты на операции и навигацию, опечатаешься в локаторе и ждёшь полминуты.
Забудешь увеличить таймаут на тест целиком – выкинет на самом интересном месте.
Хотелось бы Playwright – фишки, например лог для каждой операции как в trace viewer.
В существующих плагинах этого ожидать не приходится. Пришлось написать свой, Playwright – ориентированный, «PW Write-And-Run».
PW Write-And-Run
Ставишь Run Point через меню и запускаешь тест.

Желательно не забыть галочку «Show browser», иначе наблюдать реакцию системы на команды будет затруднительно. Тест запускается, со всеми fixture и прочей авторизацией. Когда он дойдёт до Run Point, индикатор поменяется на W&R✓ , теперь можно писать и запускать код. Поддерживается весь scope до строки с RunPoint: все константы, функции, всё, включая импорты.
Выделяешь нужный код и запускаешь. Тут же видишь результат в браузере. Меняешь, дописываешь, запускаешь снова. Много раз.Тест не упадёт по таймауту через минуту, потому что Run Point его отключает. Большие таймауты на операции/навигацию мешают в интерактивном режиме. В расширении их можно установить одной кнопкой.
Сложности и засады
Модули и их импорт
Во-первых, TypeScript при компиляции делает import elision и удаляет неиспользуемое.
import { test, expect } from '@playwright/test';
test('simple title', async ({ page }) => {
await page.goto('https://playwright.dev/');
});
Здесь expect нигде не используется, поэтому будет вычищен при компиляции и потом нельзя (спойлер: теперь можно) написать и запустить
expect(1).toBe(1);
Конечно, import elision можно отключить в настройках, но признаемся честно, никто не будет править tsconfig ради одного VSCode - расширения. Решение было простым и прямолинейным - так как для eval всё равно создаётся своё окружение, принудительно импортируем туда все модули из теста. Теперь, раз у нас уже есть функция импорта, разрешаем её использовать для перезагрузки модулей.
Есть у вас модуль testusers.ts
export const testuser = {name : „Max“};
И тест где этот модуль используется
import { testuser } from '../testusers'
...
expect(testuser.name).toBe(„Mustermann“);
Поправили имя в testusers.ts и хотите проверить, что expect теперь отрабатывает, без перезапуска теста.
Можно, конечно, самому написать и выполнить
const testuser = import('../testusers');
Но проще просто встать на строчку с импортом и нажать Ctrl+Enter.
Так расширение и делает, автоматически преобразовывает import в import().
Была попытка автоматизировать перезагрузку полностью, чтобы изменённые модули распознавались и перезагружались автоматически. Но в реальной жизни это привело только к излишней путанице, потому что вот здесь например надо дополнительно перезагружать константу, а люди это забывают и громко удивляются.
import { TestuserClass } from '../testusersClasses'; test('simple title', async ({ page }) => { const testUser = new TestuserClass(usrName); expect(testUser.name).toBe(„Mustermann “);});
Кстати, о константах.
Обидно, когда вы запустили команду с опечаткой
const pageURL = 'htps://playwright.dev/';
и при повторном запуске получаете
SyntaxError: redeclaration of const
В расширении это не проблема, запускайте сколько хотите. Всё перезапишется.
Прерывание команды
Хотелось бы иметь кнопку для прерывания команды. Увы, я не нашёл здесь решения. Playwright команда умирает только по таймауту или вместе с браузером. Запустить отдельный процесс не вариант, ибо как передашь ему весь scope?
Сюрпризы от Playwright
Если установлено расширение «Playwright Test for VSCode», некоторые локаторы подсвечиваются прямо в браузере.
Так же работает Pick Locator, Record New – можно записывать тест по шагам, рефакторить их с помощью CoPilot’а и тут же на лету выполнять\проверять.
Итог
Расширение находится в Visual Studio Code по названию - "Playwright Write-And-Run".
Репозиторий - здесь.
Чтобы заработало, нужно уста��овить модуль контекста в проект с тестами
npm install -D pw-execution-context
Расширение я активно использую. Оно позволяет быстро отладить проблемные участки. Цифра 5 взята не с потолка, а как результат пятидневного эксперимента команды QA инженеров.
Как неожиданный эффект, многим понравилось играться с Playwright в интерактивном режиме, смотреть как реагирует система.
Ставьте звёзды в репозитории, все кто поставил получат pro-версию бесплатно (если я когда-нибудь решусь её сделать).
