Многие команды и компании используют глобальную настройку для входа в приложение и последующего использования этой настройки для тестов, которые должны выполняться в авторизованном состоянии. Однако у такого подхода есть несколько важных ограничений. Например, при использовании глобальной настройки вы не видите трейсы для этапа настройки тестов, и этот этап настройки не отображается в HTML-отчёте. Кроме того, глобальная настройка не поддерживает использование фикстур.

Решить эту проблему помогут проектные зависимости.

Что такое проектные зависимости?

Проектные зависимости — это более гибкий способ выполнения глобальной настройки. Чтобы один проект зависел от другого, создаётся отдельный проект в конфигурации Playwright для тестов настройки, где каждый тест будет шагом процедуры настройки.

Каждый раз, когда вы запускаете тесты из основного проекта, сначала будут выполнены тесты из проекта настройки.

// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
  projects: [
    {
      name: 'setup',
      testMatch: '**/*.setup.ts',
    },
    {
      name: 'basic',
      dependencies: ['setup'],
    },
  ],
});

При использовании зависимостей HTML-отчёт покажет тесты настройки, средство просмотра трейсов запишет трейсы процесса настройки, а с помощью инспектора вы сможете просмотреть DOM-снимок трейсов тестов установки. Также вы сможете использовать фикстуры.

Последовательность выполнения

Сначала будут выполнены тесты из проекта 'setup', а затем тесты из проектов 'chromium', 'webkit' и 'firefox' будут запущены параллельно, после завершения всех тестов в проекте setup.

chrome, firefox and safari project that depend on a setup project
Проекты chrome, firefox и safari, зависящие от проекта setup

Что произойдёт, если зависимость не сработает?

В следующем примере показан проект 'e2e tests', который зависит как от проекта 'Browser Login', так и от проекта 'Database'. Проекты 'Browser Login' и 'Database' будут выполняться параллельно. Однако, поскольку проект 'Database' завершился с ошибкой, проект 'e2e tests' не будет запущен, поскольку он зависит от успешного выполнения как 'Browser Login', так и 'Database'.

e2e tests project that depends on browser login project and database project
Проект e2e-тестов, который зависит от проекта авторизации и проекта базы данных

Пример зависимости

Playwright запускает тесты в изолированных средах, называемых контекстами браузера. Каждый тест выполняется независимо от других тестов. Это означает, что у каждого теста есть собственное локальное хранилище, сессионное хранилище, куки и так далее. Однако тесты могут использовать storageState, которое содержит куки и снимок локального хранилища, полученные из других тестов, чтобы запускать их в авторизованном состоянии.

Давайте рассмотрим пример использования зависимостей для глобальной настройки, которая входит в Википедию и сохраняет состояние хранилища, чтобы все тесты из проекта e2e запускались в авторизованном состоянии.

Для начала установите Playwright с помощью CLI или расширения для VS Code. Затем вы можете изменить конфигурационный файл, создать авторизационный тест и e2e тест, который запускается в авторизованном состоянии, используя состояние хранилища.

Настройка проекта настройки

Начните с создания базового файла playwright.config.ts или модифицируйте уже существующий. Необходимые параметры — это testDir, который указывает на директорию, где вы хотите хранить тесты, и projects, которая определяет, какие проекты (projects) вы хотите запускать.

Проект — это логическая группа тестов, которые запускаются с использованием одной и той же конфигурации. Первый проект, который вам нужен, называется 'setup', и с помощью testMatch вы можете отфильтровать все файлы, которые заканчиваются на setup.ts, чтобы запускались только эти тесты при выполнении проекта 'setup'.

// playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
  testDir: './tests',

  projects: [
    {
      name: 'setup',
      testMatch: '**/*.setup.ts',
    },
  ],
});

Создайте тест для входа в систему

Далее создайте login.setup.ts. Чтобы было проще понять, что это тест настройки, можно импортировать test as setup, и тогда при написании теста вместо слова test можно будет использовать слово setup.

Цель состоит в том, чтобы создать тест, который выполняет вход в Википедию и проверяет, что пользователь авторизован. Вы можете использовать генератор тестов Playwright либо из расширения для VS Code, либо с помощью CLI — чтобы открыть инспектор Playwright и сгенерировать код, нажав на кнопку «Войти» и заполнив имя пользователя и пароль. Затем вы можете добавить утверждение, которое проверит, что после входа в систему отображается опция 'Personal Tools'.

Если у вас ещё нет имени пользователя или пароля, вы можете быстро создать учётную запись и затем использовать свои учётные данные, чтобы убедиться, что тесты работают.

// login.setup.ts
import { test as setup, expect } from '@playwright/test';

setup('do login', async ({ page }) => {
  await page.goto('https://en.wikipedia.org');
  await page.getByRole('link', { name: 'Log in' }).click();
  await page.getByPlaceholder('Enter your username').fill('your_username');
  await page.getByPlaceholder('Enter your password').fill('your_password');
  await page.getByRole('button', { name: 'Log in' }).click();

  await expect(page.getByRole('button', { name: 'Personal tools' })).toBeVisible();
});

Использование переменных окружения (env)

Чтобы обеспечить безопасность ваших имени пользователя и пароля, вы можете хранить их как переменные .env и обращаться к ним в тестах через process.env.USERNAME! и process.env.PASSWORD!

// login.setup.ts
import { test as setup, expect } from '@playwright/test';

setup('do login', async ({ page }) => {
  await page.goto('https://en.wikipedia.org');
  await page.getByRole('link', { name: 'Log in' }).click();
  await page.getByPlaceholder('Enter your username').fill(process.env.USERNAME!);
  await page.getByPlaceholder('Enter your password').fill(process.env.PASSWORD!);
  await page.getByRole('button', { name: 'Log in' }).click();

  await expect(page.getByRole('button', { name: 'Personal tools' })).toBeVisible();
});

Не забудьте установить пакет dotenv из npm.

npm i dotenvnpm i dotenvnpm i dotenv

После установки пакета импортируйте его в конфигурацию Playwright с помощью require('dotenv').config();, чтобы получить доступ к переменным из .env.

// playwright.config.ts
import { defineConfig } from '@playwright/test';
require('dotenv').config();

export default defineConfig({
  testDir: './tests',

  projects: [
    {
      name: 'setup',
      testMatch: '**/*.setup.ts',
    },
    {
      name: 'e2e tests',
      dependencies: ['setup'],
    },
  ],
});

Затем создайте файл .env и добавьте в него имя пользователя и пароль. Не забудьте добавить этот файл в .gitignore, чтобы конфиденциальные данные не попали в CI.

USERNAME: your_username
PASSWORD: your_password

При работе с CI вы можете использовать секреты GitHub. Создайте секреты в настройках репозитория, а затем добавьте переменные окружения в рабочий процесс GitHub Actions, который был создан при установке Playwright.

env: 
  USERNAME: ${{secrets.USERNAME}}
  PASSWORD: ${{secrets.PASSWORD}}

Создание проекта e2e tests

Создайте проект e2e tests logged in. Этот проект будет зависеть от проекта 'setup' и будет соответствовать всем тестовым фалам, которые заканчиваются на loggedin.spec.ts.

// playwright.config.ts
import { defineConfig } from '@playwright/test';
require('dotenv').config();

export default defineConfig({
  testDir: './tests',

  projects: [
    {
      name: 'setup',
      testMatch: '**/*.setup.ts',
    },
    {
      name: 'e2e tests logged in',
      testMatch: '**/*loggedin.spec.ts',
      dependencies: ['setup'],
    },
  ],
});

Добавление состояния хранилища

Проект настройки записывает состояние хранилища в файл 'auth.json' в папке .auth внутри папки playwright. При этом экспортируется константа STORAGE_STATE для использования местоположения файла хранилища между проектами.

Далее вам нужно указать тесту использовать созданную переменную STORAGE_STATE в качестве значения для storageStage. Эта переменная возвращает состояние хранилища для контекста браузера и содержит текущие cookie-файлы и снимок локального хранилища.

// playwright.config.ts
import { defineConfig } from '@playwright/test';
import path from 'path';
require('dotenv').config();

export const STORAGE_STATE = path.join(__dirname, 'playwright/.auth/user.json');

export default defineConfig({
  testDir: './tests',

  projects: [
    {
      name: 'setup',
      testMatch: '**/*.setup.ts',
    },
    {
      name: 'e2e tests logged in',
      testMatch: '**/*loggedin.spec.ts',
      dependencies: ['setup'],
      use: {
        storageState: STORAGE_STATE,
      },
    },
  ],
});

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

// login.setup.ts
import { test as setup, expect } from '@playwright/test';
import { STORAGE_STATE } from '../playwright.config';

setup('do login', async ({ page }) => {
  await page.goto('https://en.wikipedia.org');
  await page.getByRole('link', { name: 'Log in' }).click();
  await page.getByPlaceholder('Enter your username').fill('TestingLogin');
  await page.getByPlaceholder('Enter your password').fill('e2etests');
  await page.getByRole('button', { name: 'Log in' }).click();

  await expect(page.getByRole('button', { name: 'Personal tools' })).toBeVisible();

  await page.context().storageState({ path: STORAGE_STATE });
});

Создание e2e тестов 

Создайте несколько e2e-тестов, которые продолжат тестирование приложения в авторизованном состоянии. При запуске всех тестов в файле настройка будет выполнена только один раз, а второй тест начнётся уже в авторизованном состоянии, поскольку в конфигурационном файле указано значение storageState.

// e2e-loggedin.spec.ts
import { test, expect } from '@playwright/test';

test.beforeEach(async ({ page }) => {
  await page.goto('https://en.wikipedia.org');
});

test('menu', async ({ page }) => {
  await page.getByRole('link', { name: 'TestingLogin' }).click();
  await expect(page.getByRole('heading', { name: /TestingLogin/i })).toBeVisible();
  await page.getByRole('link', { name: /alerts/i  }).click();
  await page.getByText('Alerts', { exact: true }).click();
  await page.getByRole('button', { name: /notice/i  }).click();
  await page.getByText('Notices').click();
  await page.getByRole('link', { name: /watchlist/i  }).click();
})

test('logs user out', async ({ page }) => {
  await page.getByRole('button', { name: /Personal tools/i }).check();
  await page.getByRole('link', { name:  /Log out/i }).click();
  await expect(page.getByRole('heading', { name: /Log out/i })).toBeVisible();
  await expect(page.getByRole('link', { name: 'Log in', exact: true })).toBeVisible();
})

Настройка baseURL

Если вы используете один и тот же URL для 'setup' и 'e2e' тестов, вы можете настроить baseURL в файле playwright.config.ts. Установка baseURL позволяет использовать page.goto('/') в ваших тестах, что ускоряет написание кода, снижает вероятность опечаток и упрощает управление URL в случае его изменения в будущем.

// playwright.config.ts
import { defineConfig } from '@playwright/test';
import path from 'path';
require('dotenv').config();

export const STORAGE_STATE = path.join(__dirname, 'playwright/.auth/user.json');

export default defineConfig({
  testDir: './tests',

  use: {
    baseURL: 'https://en.wikipedia.org',
  },

  projects: [
    {
      name: 'setup',
      testMatch: '**/*.setup.ts',
    },
    {
      name: 'e2e tests logged in',
      dependencies: ['setup'],
      use: {
        storageState: STORAGE_STATE,
      },
    },
  ],
});

После этого вы можете использовать символ / вместо 'https://en.wikipedia.org' в команде page.goto для всех последующих тестов, включая тест 'setup', который вы создали.

// e2e-loggedin.spec.ts
import { test, expect } from '@playwright/test';

test.beforeEach(async ({ page }) => {
  await page.goto('/');
});

//...

Настройка HTML Reporter

Если в конфигурации Playwright это ещё не настроено, то следующим шагом будет добавление HTML Reporter в файл playwright.config.ts для создания HTML-отчётов для ваших тестов. Вы также можете настроить количество повторных запусков (retries) для CI, установить значение fullyParallel в true и настроить запись трейсов при первой повторной попытке неудачного теста.

// playwright.config.ts
import { defineConfig } from '@playwright/test';
import path from 'path';
require('dotenv').config();

export const STORAGE_STATE = path.join(__dirname, 'playwright/.auth/user.json');

export default defineConfig({
  testDir: './tests',
  // Configure the reporter
  reporter: ['html'],
  // Retry on CI only
  retries: process.env.CI ? 2 : 0,
  // Run tests in files in parallel
  fullyParallel: true,

  use: {
    baseURL: 'https://en.wikipedia.org',
    // run traces on the first retry of a failed test
    trace: 'on-first-retry',
  },

  projects: [
    {
      name: 'setup',
      testMatch: '**/*.setup.ts',
    },
    {
      name: 'e2e tests logged in',
      dependencies: ['setup'],
      use: {
        storageState: STORAGE_STATE,
      },
    },
  ],
});

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

// playwright.config.ts
import { defineConfig } from '@playwright/test';
import path from 'path';
require('dotenv').config();

export const STORAGE_STATE = path.join(__dirname, 'playwright/.auth/user.json');

export default defineConfig({
  testDir: './tests',
  // Configure the reporter
  reporter: ['html'],
  // Retry on CI only
  retries: process.env.CI ? 2 : 0,
  // Run tests in files in parallel
  fullyParallel: true,

  use: {
    baseURL: 'https://en.wikipedia.org',
    // run traces on the first retry of a failed test
    trace: 'on-first-retry',
  },

  projects: [
    {
      name: 'setup',
      testMatch: '**/*.setup.ts',
    },
    {
      name: 'e2e tests logged in',
      dependencies: ['setup'],
      use: {
        storageState: STORAGE_STATE,
      },
    },
    {
      name: 'e2e tests',
      testIgnore: ['**/*loggedin.spec.ts', '**/*.setup.ts'],
    },
  ],
});

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

Просмотр HTML-отчёта и трейсов

Теперь вы можете запускать тесты из CLI с флагом --trace on, чтобы увидеть полный отчёт о тестах, включая проекты 'setup' и 'e2e tests logged in', а также просмотреть трейсы каждого из них.

npx playwright test --trace on

После выполнения тестов вы увидите в CLI, что два теста прошли, и сможете выполнить команду для открытия HTML-отчёта.

npx playwright show-report

Эта команда откроет HTML-отчёт Playwright, в котором будут показаны ваши два проекта: проект 'setup', содержащий тест входа в систему, и проект 'e2e tests logged in', содержащий тест для меню и тест выхода из системы.

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

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

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

Заключение

Использование зависимостей между проектами значительно упрощает глобальную настройку с готовыми HTML-отчётами и трейсами процесса настройки.


Больше актуальных навыков по тестированию, в том числе автоматизации, вы можете получить в рамках практических онлайн-курсов от экспертов отрасли.

Также всех тестировщиков приглашаем на открытый урок 17 октября «Способы организации тестовой модели». На занятии поговорим о том, что из себя представляет хорошая тестовая модель, способы ее организации. Кроме того, обсудим плюсы и минусы применения разных подходов. Записаться можно по ссылке.

Комментарии (0)