Playwright для Directum RX, часть 1: первый автотест, вход один раз и проверка после обновления
Первая часть серии об автотестах веб-клиента Directum RX на Playwright. Зачем они нужны инфраструктуре, как поставить Playwright, получить устойчивые селекторы через codegen, войти один раз на все тесты и написать проверку, которую стоит запускать после каждого обновления.
Коротко. Playwright ходит в RX как пользователь и ловит то, что мониторинг сервисов не видит. Селекторы берите из
codegenпо ролям и подписям, а не по CSS-классам. Входите один раз и сохраняйте состояние. Первая проверка: загрузка веб-клиента, список заданий, отсутствие ошибок в консоли.
После обновления RX кто-то должен войти в систему, открыть документ, создать задачу и убедиться, что всё работает. Обычно это администратор в два часа ночи, и обычно он проверяет не всё. Автотест на Playwright делает то же самое за минуту, одинаково каждый раз, и его можно запускать не только после обновления, но и каждое утро. Это первая часть серии: от установки до первой проверки, которой уже можно пользоваться. Дальше будут данные для тестов, проверка сценариев с несколькими пользователями и запуск по расписанию с уведомлениями.
Симптом
- После обновления часть функций сломана, и узнают об этом пользователи утром.
- Проверка после работ это список в голове одного человека.
- Мониторинг показывает, что сервисы живы, а войти в систему нельзя: сломан единый вход или веб-клиент не загружается.
Почему так
Мониторинг сервисов отвечает на вопрос «процессы работают?», а пользователю важно «могу ли я сделать свою работу?». Между этими вопросами пропасть: сертификат, прокси, кэш браузера, прикладная разработка, права. Закрыть её можно только проверкой, которая ходит в систему как пользователь.
Playwright управляет настоящим браузером (Chromium, Firefox, WebKit), сам ждёт появления элементов и записывает трассу каждого шага: снимки экрана, сетевые запросы, консоль. Для одностраничного веб-клиента RX, где всё появляется асинхронно, это важнее, чем для обычных сайтов.
Установка
Нужен Node.js. В пустой папке:
npm init playwright@latest
Установщик спросит язык (выбирайте TypeScript), папку для тестов и скачает браузеры. В закрытом контуре браузеры
скачиваются заранее на машине с интернетом и переносятся, путь к ним задаётся переменной
PLAYWRIGHT_BROWSERS_PATH. Второй вариант: не скачивать браузер совсем, а использовать уже установленный
Google Chrome или Microsoft Edge, указав в настройках channel: 'chrome' или channel: 'msedge'. Так тест
к тому же идёт в том же браузере, что у пользователей.
В playwright.config.ts задаём адрес системы и общие настройки:
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
timeout: 60_000,
retries: 1,
use: {
baseURL: process.env.RX_URL ?? 'https://rx.example.local/Client/',
trace: 'retain-on-failure',
screenshot: 'only-on-failure',
ignoreHTTPSErrors: false,
},
projects: [
{ name: 'setup', testMatch: /auth\.setup\.ts/ },
{ name: 'smoke', dependencies: ['setup'], use: { storageState: '.auth/user.json' } },
],
});
ignoreHTTPSErrors: false оставляем намеренно: если сертификат системы истёк или цепочка неполная, тест должен
упасть, как упал бы браузер пользователя.
Селекторы: не угадывать, а записать
Самая частая ошибка первых автотестов: селекторы по CSS-классам вида .x-btn-123. Классы в веб-клиенте генерируются
при сборке и меняются с версиями, тест ломается при каждом обновлении.
Playwright предлагает селекторы по тому, что видит пользователь: роль элемента и его подпись. Не придумывайте их, а запишите:
npx playwright codegen https://rx.example.local/Client/
Откроется браузер и окно с кодом. Пройдите вход и нужное действие руками, Playwright запишет шаги с селекторами
вида getByRole('button', { name: 'Войти' }). Подписи в вашей системе могут отличаться от примеров ниже,
поэтому берите их из записи.
Вход один раз
Входить в начале каждого теста долго и нагружает систему. Playwright умеет войти один раз и сохранить состояние браузера (куки и локальное хранилище) в файл, который используют остальные тесты.
Файл tests/auth.setup.ts:
import { test as setup, expect } from '@playwright/test';
setup('вход', async ({ page }) => {
await page.goto('');
// подписи полей и кнопки возьмите из записи codegen
await page.getByLabel('Имя пользователя').fill(process.env.RX_USER!);
await page.getByLabel('Пароль').fill(process.env.RX_PASSWORD!);
await page.getByRole('button', { name: 'Войти' }).click();
// признак успешного входа: элемент, который есть только у вошедшего пользователя
await expect(page.getByRole('navigation')).toBeVisible();
await page.context().storageState({ path: '.auth/user.json' });
});
Учётная запись для тестов отдельная, с паролем, без второго фактора и с минимальными правами: только то,
что нужно проверкам. Пароль передаётся переменной окружения, в коде его нет. Папку .auth добавляем в .gitignore.
Если в системе настроен единый вход через внешнего поставщика, тестовая учётка всё равно нужна: либо с входом по паролю в RX, либо в поставщике без второго фактора, доступная только из сети, где работают тесты.
Первая проверка
Файл tests/smoke.spec.ts. Проверяем то, без чего пользователи не работают: веб-клиент загрузился, открывается
список заданий, работает поиск.
import { test, expect } from '@playwright/test';
test('веб-клиент загружается и показывает задания', async ({ page }) => {
const started = Date.now();
await page.goto('');
await expect(page.getByRole('navigation')).toBeVisible();
// название раздела возьмите из записи codegen
await page.getByText('Входящие').first().click();
await expect(page.getByRole('grid')).toBeVisible();
console.log(`загрузка до списка заданий: ${Date.now() - started} мс`);
});
test('нет ошибок в консоли при загрузке', async ({ page }) => {
const errors: string[] = [];
page.on('console', (m) => { if (m.type() === 'error') errors.push(m.text()); });
await page.goto('');
await expect(page.getByRole('navigation')).toBeVisible();
expect(errors, errors.join('\n')).toHaveLength(0);
});
Запуск:
RX_URL=https://rx.example.local/Client/ RX_USER=autotest RX_PASSWORD='…' npx playwright test
Если тест упал, отчёт покажет шаг, снимок экрана и полную трассу: npx playwright show-report. По трассе видно
сетевые запросы и ответы, это часто сразу показывает причину: 502 от прокси, 401 от поставщика входа,
скрипт веб-клиента не загрузился.
Ожидания
Playwright сам ждёт, пока элемент появится и станет доступен для действия. Поэтому:
- не пишите
waitForTimeout(5000): тест станет медленным и всё равно будет иногда падать; - ждите результат, который видит пользователь:
expect(...).toBeVisible(),toHaveText(),toHaveCount(); - если действие запускает долгую операцию, увеличьте таймаут конкретной проверки, а не всего теста.
Что дальше
Во второй части: тестовые данные (создать документ и задачу в начале, убрать за собой в конце), проверки с двумя пользователями (отправил задачу, исполнитель получил) и устойчивость к медленной системе. В третьей: запуск по расписанию из CI, уведомление при падении и время шагов как метрика в мониторинге.
Чего не делать
- Не использовать CSS-классы веб-клиента в селекторах. Они меняются с версиями.
- Не запускать тесты под учёткой администратора. Тест должен видеть систему глазами пользователя и не иметь возможности что-то сломать.
- Не отключать проверку сертификата. Истёкший сертификат это как раз то, что тест должен поймать.
- Не делать один огромный тест на всё. Короткие независимые тесты показывают, что именно сломалось.
Похожая картина у вас?
Разберём ваш контур за 30 минут бесплатного созвона: версия RX, состав сервисов, что болит сильнее всего.
Написать