Управление системой как пользователь — Примеры

Пример 1 — Набор из одного теста на каждый экран

Команда написала по тесту на каждый экран и проверяет в них значения, которые видит только приложение, — набор получился медленным и пропускает важные отказы. Скажите, что эти тесты на самом деле проверяют, а затем перепишите один из них как путь.

test("dashboard renders", async ({ page }) => {
  await page.goto("/dashboard");
  await expect(page.locator("#user-count")).toHaveText("1");   // внутренний флаг
});

Решение

test("a new account reaches the dashboard", async ({ page }) => {
  await page.goto("/");
  await page.getByRole("link", { name: "Create account" }).click();
  await page.getByLabel("Email").fill("new@example.test");
  await page.getByRole("button", { name: "Sign up" }).click();
  await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();
});

Старый тест доказывает лишь то, что компонент отрисовался, поэтому он не может упасть, когда маршрут регистрации зарегистрирован по неверному пути или cookie выставлен для неверного домена: он начинается уже после того, как это произошло. Тест пути пересекает сборку, которую не видит больше никто, и проверяет результат, который пользователь сумел бы описать. Выбор по роли и подписи вместо сгенерированного id заставляет тест падать только тогда, когда интерфейс меняется по-настоящему, и требует, чтобы элемент был доступен по имени — а это как раз то, что нужно и программе чтения с экрана.

Пример 2 — Один длинный тест, выполняющий три пути

Единственный тест регистрируется, оформляет заказ и восстанавливает пароль по очереди, с фиксированной задержкой между шагами, поэтому когда он падает, первый сломанный шаг скрывает остальные. Перестройте его, не потеряв покрытие.

test("the whole product", async ({ page }) => {
  await signUp(page);
  await page.waitForTimeout(3000);      // надеемся, что аккаунт готов
  await placeOrder(page);
  await recoverPassword(page);
});

Решение

test("places an order", async ({ page }) => {
  await signInAs(page, "buyer@example.test");      // общая подготовка, вынесена
  await placeOrder(page);
  await expect(page.getByText("Order confirmed")).toBeVisible({ timeout: 15_000 });
});

// остальные пути становятся своими тестами, деля один и тот же помощник подготовки

Один путь на тест означает, что отказ называет сломанную пользовательскую цель, а исправление очевидно из заголовка. Пять путей в одном тесте падают по пяти возможным причинам и останавливаются на первой. Вынесение общего начала держит подготовку в одном месте, не сцепляя проверки. Замена фиксированного ожидания на проверку нужного состояния убирает и ставку наугад: тест возвращается, как только страница готова, и падает с понятным сообщением, когда она так и не готова.