Тест формы входа и регистрации

Собираем всё вместе и пишем полноценные тесты для самого частого сценария — формы входа.

Форма входа — это первый E2E-тест, который пишут почти в любом проекте: она критична и хорошо иллюстрирует и действия, и проверки.

Тестируемая страница

Допустим, у нас простая форма входа. Чтобы тесты были устойчивыми, в разметке есть метки для полей и понятные тексты — именно за них будут цепляться семантические локаторы.

<form>
  <label for="email">Email</label>
  <input id="email" type="email">

  <label for="pwd">Пароль</label>
  <input id="pwd" type="password">

  <button type="submit">Войти</button>
  <div role="alert"></div>
</form>

Успешный вход

Первый и главный сценарий: верные данные ведут в личный кабинет.

import { test, expect } from '@playwright/test';

test('успешный вход с верными данными', async ({ page }) => {
  await page.goto('/login');

  await page.getByLabel('Email').fill('[email protected]');
  await page.getByLabel('Пароль').fill('correct-password');
  await page.getByRole('button', { name: 'Войти' }).click();

  // после входа — переход в кабинет и приветствие
  await expect(page).toHaveURL('/dashboard');
  await expect(page.getByText('Добро пожаловать')).toBeVisible();
});

Неверные данные: проверка ошибки

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

test('ошибка при неверном пароле', async ({ page }) => {
  await page.goto('/login');

  await page.getByLabel('Email').fill('[email protected]');
  await page.getByLabel('Пароль').fill('wrong-password');
  await page.getByRole('button', { name: 'Войти' }).click();

  // остались на странице входа, видна ошибка
  await expect(page).toHaveURL('/login');
  await expect(page.getByRole('alert')).toHaveText('Неверный email или пароль');
});

Валидация на клиенте

Проверим, что пустая форма не отправляется и кнопка заблокирована или появляется подсказка.

test('кнопка заблокирована при пустых полях', async ({ page }) => {
  await page.goto('/login');
  await expect(page.getByRole('button', { name: 'Войти' })).toBeDisabled();
});

Регистрация с уникальными данными

Регистрация требует уникального email — используем метку времени, как обсуждали в уроке про данные.

test('регистрация нового пользователя', async ({ page }) => {
  const email = `new-${Date.now()}@example.com`;

  await page.goto('/register');
  await page.getByLabel('Email').fill(email);
  await page.getByLabel('Пароль').fill('strong-password-123');
  await page.getByLabel('Повторите пароль').fill('strong-password-123');
  await page.getByRole('button', { name: 'Зарегистрироваться' }).click();

  await expect(page.getByText('Аккаунт создан')).toBeVisible();
});

Что проверять в форме

СценарийОжидание
Верные данныепереход и приветствие
Неверный парольсообщение об ошибке, остались на странице
Пустые полякнопка заблокирована / подсказка
Несовпадение паролейошибка валидации

Заметьте, что весь код выше написан без единой ручной паузы: авто-ожидания и web-first assertions делают тесты устойчивыми «бесплатно». Это и есть результат первых трёх разделов курса на практике.

Итог

  • Форма входа — типичный первый E2E-тест: и действия, и проверки.
  • Покрывайте и позитивный (вход удался), и негативные сценарии (ошибки, валидация).
  • Для регистрации используйте уникальный email с меткой времени.
  • Проверяйте не только успех, но и корректные отказы — это важная часть качества.
Проверьте себя
1. Почему в E2E важно проверять негативные сценарии формы?
AОни выполняются быстрее позитивных
BКорректный отказ (ошибка при неверном пароле) — такая же важная часть качества
CБез них Playwright не запустит тест
DНегативные сценарии не нужны, достаточно успешного входа
2. Как обеспечить уникальность email при тесте регистрации?
AВсегда использовать [email protected]
BДобавить метку времени, например new-${Date.now()}@example.com
CОтключить параллельный запуск
DИспользовать XPath по индексу
3. Какая проверка подтверждает, что после успешного входа произошёл переход в кабинет?
Aexpect(page).toHaveURL('/dashboard')
Bexpect(page).toHaveTitle('login')
Cexpect(locator).toBeDisabled()
DwaitForTimeout(2000)
Поддержать проект