Spec-Zone.ru › Playwright

Утверждения

Введение​

Playwright включает в себя тестовые утверждения в форме функции expect. Чтобы сделать утверждение, вызовите expect(value) и выберите согласующееся условие, которое отражает ожидание. Существует множество универсальных согласующихся условий, таких как toEqual, toContain, toBeTruthy, которые могут быть использованы для проверки любых условий.

expect(success).toBeTruthy();

Playwright также включает в себя специфичные для веба асинхронные согласующиеся условия, которые будут ждать, пока ожидаемое условие не будет выполнено. Рассмотрим следующий пример:

await expect(page.getByTestId('status')).toHaveText('Submitted');

Playwright будет повторно тестировать элемент с тестовым идентификатором status, пока полученный элемент не будет иметь текст "Submitted". Он будет повторно получать элемент и проверять его снова и снова, пока условие не будет выполнено или пока не будет достигнут тайм-аут. Вы можете либо передать этот тайм-аут, либо настроить его один раз через значение testConfig.expect в конфигурации теста.

По умолчанию тайм-аут для утверждений установлен на 5 секунд. Узнайте больше о различных тайм-аутах.

Утверждения с автоматическим повтором​

Следующие утверждения будут повторяться до тех пор, пока утверждение не будет пройдено, или пока не будет достигнут тайм-аут утверждения. Обратите внимание, что утверждения с повтором являются асинхронными, поэтому вы должны await их.

Утверждение Описание
await expect(locator).toBeAttached() Элемент прикреплен
await expect(locator).toBeChecked() Флажок установлен
await expect(locator).toBeDisabled() Элемент отключен
await expect(locator).toBeEditable() Элемент редактируем
await expect(locator).toBeEmpty() Контейнер пуст
await expect(locator).toBeEnabled() Элемент включен
await expect(locator).toBeFocused() Элемент находится в фокусе
await expect(locator).toBeHidden() Элемент невидим
await expect(locator).toBeInViewport() Элемент пересекает viewport
await expect(locator).toBeVisible() Элемент видим
await expect(locator).toContainText() Элемент содержит текст
await expect(locator).toHaveAccessibleDescription() Элемент имеет соответствующее доступное описание
await expect(locator).toHaveAccessibleName() Элемент имеет соответствующее доступное имя
await expect(locator).toHaveAttribute() Элемент имеет атрибут DOM
await expect(locator).toHaveClass() Элемент имеет свойство класса
await expect(locator).toHaveCount() Список имеет точное количество дочерних элементов
await expect(locator).toHaveCSS() Элемент имеет свойство CSS
await expect(locator).toHaveId() Элемент имеет ID
await expect(locator).toHaveJSProperty() Элемент имеет свойство JavaScript
await expect(locator).toHaveRole() Элемент имеет определённую роль ARIA
await expect(locator).toHaveScreenshot() Элемент имеет скриншот
await expect(locator).toHaveText() Элемент соответствует тексту
await expect(locator).toHaveValue() Ввод имеет значение
await expect(locator).toHaveValues() Выпадающий список имеет выбранные опции
await expect(page).toHaveScreenshot() Страница имеет скриншот
await expect(page).toHaveTitle() Страница имеет заголовок
await expect(page).toHaveURL() Страница имеет URL
await expect(response).toBeOK() Ответ имеет статус OK

Утверждения без автоматического повтора​

Эти утверждения позволяют проверять любые условия, но не повторяют автоматически. В большинстве случаев веб-страницы отображают информацию асинхронно, и использование утверждений без автоматического повтора может привести к ненадежному тесту.

Предпочитайте утверждения с автоматическим повтором всякий раз, когда это возможно. Для более сложных утверждений, которые необходимо повторять, используйте expect.poll или expect.toPass.

Утверждение Описание
expect(value).toBe() Значение совпадает
expect(value).toBeCloseTo() Число приблизительно равно
expect(value).toBeDefined() Значение не undefined
expect(value).toBeFalsy() Значение ложно, например false, 0, null, и т. д.
expect(value).toBeGreaterThan() Число больше
expect(value).toBeGreaterThanOrEqual() Число больше или равно
expect(value).toBeInstanceOf() Объект является экземпляром класса
expect(value).toBeLessThan() Число меньше
expect(value).toBeLessThanOrEqual() Число меньше или равно
expect(value).toBeNaN() Значение NaN
expect(value).toBeNull() Значение null
expect(value).toBeTruthy() Значение истинно, т. е. не false, 0, null, и т. д.
expect(value).toBeUndefined() Значение undefined
expect(value).toContain() Строка содержит подстроку
expect(value).toContain() Массив или множество содержит элемент
expect(value).toContainEqual() Массив или множество содержит похожий элемент
expect(value).toEqual() Значение похоже — глубокое равенство и сопоставление шаблонов
expect(value).toHaveLength() Массив или строка имеет длину
expect(value).toHaveProperty() Объект имеет свойство
expect(value).toMatch() Строка соответствует регулярному выражению
expect(value).toMatchObject() Объект содержит указанные свойства
expect(value).toStrictEqual() Значение похоже, включая типы свойств
expect(value).toThrow() Функция вызывает ошибку
expect(value).any() Соответствует любому экземпляру класса/примитива
expect(value).anything() Соответствует чему угодно
expect(value).arrayContaining() Массив содержит определенные элементы
expect(value).closeTo() Число приблизительно равно
expect(value).objectContaining() Объект содержит определенные свойства
expect(value).stringContaining() Строка содержит подстроку
expect(value).stringMatching() Строка соответствует регулярному выражению

Отрицающие соответствия​

В общем случае мы можем ожидать обратного, добавив .not к начала утверждений:

expect(value).not.toEqual(0);
await expect(locator).not.toContainText('some text');

Мягкие утверждения​

По умолчанию, при неудачном утверждении выполнение теста завершается. Playwright также поддерживает мягкие утверждения: при неудачном мягком утверждении выполнение теста не завершается, но тест помечается как неудавшийся.

// Make a few checks that will not stop the test when failed...
await expect.soft(page.getByTestId('status')).toHaveText('Success');
await expect.soft(page.getByTestId('eta')).toHaveText('1 day');

// ... and continue the test to check more things.
await page.getByRole('link', { name: 'next page' }).click();
await expect.soft(page.getByRole('heading', { name: 'Make another order' })).toBeVisible();

В любой момент выполнения теста вы можете проверить, были ли какие-либо ошибки мягких утверждений:

// Make a few checks that will not stop the test when failed...
await expect.soft(page.getByTestId('status')).toHaveText('Success');
await expect.soft(page.getByTestId('eta')).toHaveText('1 day');

// Avoid running further if there were soft assertion failures.
expect(test.info().errors).toHaveLength(0);

Обратите внимание, что мягкие утверждения работают только с исполнителем тестов Playwright.

Настройка собственного сообщения для expect​

Вы можете указать пользовательское сообщение expect в качестве второго аргумента функции expect, например:

await expect(page.getByText('Name'), 'should be logged in').toBeVisible();

Это сообщение будет отображаться в отчетах, как для прошедших, так и для не прошедших утверждений, предоставляя дополнительный контекст утверждению.

При прохождении утверждения вы можете увидеть успешный шаг примерно так:

✅ should be logged in    @example.spec.ts:18

При неудачном утверждении ошибка будет выглядеть так:

    Error: should be logged in

    Call log:
      - expect.toBeVisible with timeout 5000ms
      - waiting for "getByText('Name')"


      2 |
      3 | test('example test', async({ page }) => {
    > 4 |   await expect(page.getByText('Name'), 'should be logged in').toBeVisible();
        |                                                                  ^
      5 | });
      6 |

Мягкие утверждения также поддерживают пользовательские сообщения:

expect.soft(value, 'my soft assertion').toBe(56);

expect.configure​

Вы можете создать собственный экземпляр предварительно настроенного expect с собственными значениями по умолчанию, такими как timeout и soft.

const slowExpect = expect.configure({ timeout: 10000 });
await slowExpect(locator).toHaveText('Submit');

// Always do soft assertions.
const softExpect = expect.configure({ soft: true });
await softExpect(locator).toHaveText('Submit');

expect.poll​

Вы можете преобразовать любую синхронную expect в асинхронную, используя expect.poll.

Следующий метод будет повторять указанную функцию до тех пор, пока она не вернет HTTP-статус 200:

await expect.poll(async () => {
  const response = await page.request.get('https://api.example.com');
  return response.status();
}, {
  // Custom expect message for reporting, optional.
  message: 'make sure API eventually succeeds',
  // Poll for 10 seconds; defaults to 5 seconds. Pass 0 to disable timeout.
  timeout: 10000,
}).toBe(200);

Вы также можете указать пользовательские интервалы опроса:

await expect.poll(async () => {
  const response = await page.request.get('https://api.example.com');
  return response.status();
}, {
  // Probe, wait 1s, probe, wait 2s, probe, wait 10s, probe, wait 10s, probe
  // ... Defaults to [100, 250, 500, 1000].
  intervals: [1_000, 2_000, 10_000],
  timeout: 60_000
}).toBe(200);

expect.toPass​

Вы можете повторно выполнять блоки кода, пока они не пройдут успешно.

await expect(async () => {
  const response = await page.request.get('https://api.example.com');
  expect(response.status()).toBe(200);
}).toPass();

Вы также можете указать пользовательские значения тайм-аута и интервалов повторных попыток:

await expect(async () => {
  const response = await page.request.get('https://api.example.com');
  expect(response.status()).toBe(200);
}).toPass({
  // Probe, wait 1s, probe, wait 2s, probe, wait 10s, probe, wait 10s, probe
  // ... Defaults to [100, 250, 500, 1000].
  intervals: [1_000, 2_000, 10_000],
  timeout: 60_000
});

Обратите внимание, что по умолчанию toPass имеет тайм-аут 0 и не учитывает пользовательский тайм-аут expect.

Добавление пользовательских утверждений с помощью expect.extend​

Вы можете расширить утверждения Playwright, предоставив пользовательские соответствия. Эти соответствия будут доступны в объекте expect.

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

import { expect as baseExpect } from '@playwright/test';
import type { Page, Locator } from '@playwright/test';

export { test } from '@playwright/test';

export const expect = baseExpect.extend({
  async toHaveAmount(locator: Locator, expected: number, options?: { timeout?: number }) {
    const assertionName = 'toHaveAmount';
    let pass: boolean;
    let matcherResult: any;
    try {
      await baseExpect(locator).toHaveAttribute('data-amount', String(expected), options);
      pass = true;
    } catch (e: any) {
      matcherResult = e.matcherResult;
      pass = false;
    }

    const message = pass
      ? () => this.utils.matcherHint(assertionName, undefined, undefined, { isNot: this.isNot }) +
          '\n\n' +
          `Locator: ${locator}\n` +
          `Expected: not ${this.utils.printExpected(expected)}\n` +
          (matcherResult ? `Received: ${this.utils.printReceived(matcherResult.actual)}` : '')
      : () =>  this.utils.matcherHint(assertionName, undefined, undefined, { isNot: this.isNot }) +
          '\n\n' +
          `Locator: ${locator}\n` +
          `Expected: ${this.utils.printExpected(expected)}\n` +
          (matcherResult ? `Received: ${this.utils.printReceived(matcherResult.actual)}` : '');

    return {
      message,
      pass,
      name: assertionName,
      expected,
      actual: matcherResult?.actual,
    };
  },
});

Теперь мы можем использовать toHaveAmount в тесте.

import { test, expect } from './fixtures';

test('amount', async () => {
  await expect(page.locator('.cart')).toHaveAmount(4);
});

Совместимость с библиотекой expect​

примечание

Не путайте утверждения Playwright expect с библиотекой expect. Последняя не полностью интегрирована с исполнителем тестов Playwright, поэтому убедитесь, что используете собственные утверждения Playwright expect.

Комбинирование пользовательских утверждений из нескольких модулей​

Вы можете комбинировать пользовательские утверждения из нескольких файлов или модулей.

import { mergeTests, mergeExpects } from '@playwright/test';
import { test as dbTest, expect as dbExpect } from 'database-test-utils';
import { test as a11yTest, expect as a11yExpect } from 'a11y-test-utils';

export const expect = mergeExpects(dbExpect, a11yExpect);
export const test = mergeTests(dbTest, a11yTest);
import { test, expect } from './fixtures';

test('passes', async ({ database }) => {
  await expect(database).toHaveDatabaseUser('admin');
});

© 2024 Microsoft
Licensed under the Apache License, Version 2.0.
https://playwright.dev/docs/test-assertions

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API