Модификация запросов и ответов

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

Перехват запросов

Перехват запросов в Playwright осуществляется с помощью API page.route(). Этот метод позволяет задать правило для перехвата определенных сетевых запросов. При вызове page.route() можно указать фильтр URL или регулярное выражение, а также обработчик, который будет вызываться при совпадении запроса с фильтром.

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

const { test, expect } = require('@playwright/test');

test('Перехват и модификация запросов', async ({ page }) => {
  // Перехватываем все запросы, которые идут на сайт example.com
  await page.route('**/example.com/**', (route, request) => {
    console.log('Запрос:', request.url());
    route.continue(); // продолжаем запрос без изменений
  });

  await page.goto('https://example.com');
});

В данном примере используется метод page.route(), который позволяет перехватывать все запросы, адресованные на домен example.com. Внутри обработчика можно анализировать сам запрос, его параметры и, при необходимости, изменять его.

Модификация запросов

Для модификации запроса используется метод route.continue() с дополнительными параметрами. Он позволяет изменять заголовки, тело запроса или метод запроса.

Пример модификации запросов

const { test, expect } = require('@playwright/test');

test('Модификация заголовков запроса', async ({ page }) => {
  await page.route('**/example.com/**', (route, request) => {
    const modifiedHeaders = {
      ...request.headers(),
      'Authorization': 'Bearer my_token'
    };

    route.continue({
      headers: modifiedHeaders
    });
  });

  await page.goto('https://example.com');
});

В этом примере добавляется заголовок Authorization ко всем запросам, направляемым на example.com. Это может быть полезно для тестирования авторизации или передачи секретных ключей.

Модификация ответов

Помимо изменения запросов, Playwright также позволяет модифицировать ответы, получаемые от сервера. Для этого используется метод route.fulfill(), который позволяет заменить содержимое ответа, его заголовки или код статуса.

Пример модификации ответа

const { test, expect } = require('@playwright/test');

test('Модификация тела ответа', async ({ page }) => {
  await page.route('**/example.com/api/data', async (route, request) => {
    const response = await route.continue();
    const body = await response.body();

    // Модифицируем тело ответа
    const modifiedBody = JSON.stringify({
      ...JSON.parse(body.toString()),
      customKey: 'customValue'
    });

    route.fulfill({
      status: 200,
      body: modifiedBody,
      headers: {
        'Content-Type': 'application/json'
      }
    });
  });

  await page.goto('https://example.com');
});

Здесь, после того как ответ был получен, его тело модифицируется добавлением нового ключа customKey в JSON. Также возможно изменять заголовки и статус ответа, что полезно для тестирования различных состояний ответа от сервера.

Ответ с ошибкой

Иногда нужно тестировать поведение приложения при ошибках сети или недоступности сервера. Для этого можно искусственно генерировать ошибки в ответах с помощью метода route.abort(). Этот метод позволяет отменить запрос с заданным статусом ошибки.

Пример ответа с ошибкой

const { test, expect } = require('@playwright/test');

test('Искусственная ошибка ответа', async ({ page }) => {
  await page.route('**/example.com/api/data', (route) => {
    route.abort('failed'); // Запрос будет отменен с ошибкой
  });

  await page.goto('https://example.com');
});

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

Параллельная модификация нескольких запросов

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

Пример параллельной модификации

const { test, expect } = require('@playwright/test');

test('Перехват и модификация нескольких запросов', async ({ page }) => {
  await page.route('**/api/data1', (route, request) => {
    route.continue({
      headers: {
        ...request.headers(),
        'X-Custom-Header': 'value1'
      }
    });
  });

  await page.route('**/api/data2', (route, request) => {
    route.continue({
      headers: {
        ...request.headers(),
        'X-Custom-Header': 'value2'
      }
    });
  });

  await page.goto('https://example.com');
});

Здесь для разных URL устанавливаются разные заголовки, что позволяет легко тестировать сложные сценарии с несколькими сетевыми запросами.

Завершение работы с перехватами

После того как запросы были перехвачены и обработаны, необходимо завершить работу с маршрутизацией с помощью метода page.unroute(). Этот метод удаляет все обработчики для указанных маршрутов и возвращает страницу в исходное состояние.

Пример завершения перехвата

const { test, expect } = require('@playwright/test');

test('Завершение перехвата запросов', async ({ page }) => {
  const routeHandler = (route) => route.continue();

  await page.route('**/example.com/**', routeHandler);

  // Ожидаем, что запросы перехватываются
  await page.goto('https://example.com');

  // Убираем перехват
  await page.unroute('**/example.com/**', routeHandler);

  // Теперь запросы на example.com не будут перехватываться
  await page.goto('https://example.com');
});

Метод page.unroute() позволяет удалить обработчик маршрута и вернуться к стандартному поведению без перехвата.

Заключение

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