Одной из ключевых особенностей Playwright является возможность создания множества контекстов в одном тесте. Это позволяет изолировать состояние между тестами, что критически важно при работе с веб-приложениями, требующими работы с несколькими сессиями, профилями или вкладками одновременно. В данной главе рассмотрим, как эффективно использовать изоляцию состояния между контекстами для повышения стабильности и гибкости тестов.
Контекст в Playwright представляет собой независимую среду для взаимодействия с браузером. Каждый контекст может содержать свои cookies, локальное хранилище (localStorage), сессионные данные и другие ресурсы, что делает его идеальным для работы с многими параллельными сессиями.
Создание новых контекстов позволяет тестировать различные сценарии, где требуется, чтобы состояния, такие как аутентификация или данные сессий, не пересекались между контекстами. Это важно для:
Чтобы создать новый контекст в Playwright, необходимо воспользоваться
методом browser.newContext(). Это позволит изолировать все
данные, связанные с данным контекстом, от остальных.
Пример создания контекста:
const { webkit } = require('playwright'); // или другой браузер, например, chromium или firefox
(async () => {
const browser = await webkit.launch();
// Создание контекста
const context1 = await browser.newContext();
const context2 = await browser.newContext();
// Создание страниц в контекстах
const page1 = await context1.newPage();
const page2 = await context2.newPage();
// Действия с page1 и page2, которые не будут влиять друг на друга
await page1.goto('https://example.com');
await page2.goto('https://example.org');
// Закрытие браузера
await browser.close();
})();
Каждый контекст работает независимо, и данные, например cookies или локальное хранилище, не пересекаются между контекстами.
Один из основных случаев использования изоляции контекстов — это работа с cookies и сессионными данными. Если необходимо выполнить тесты с несколькими пользователями, которые логируются в приложение с разными учетными записями, использование нескольких контекстов позволит избежать перезаписывания cookies.
Пример использования нескольких контекстов для проверки авторизации с разными учетными записями:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
// Контекст для первого пользователя
const context1 = await browser.newContext();
const page1 = await context1.newPage();
await page1.goto('https://example.com/login');
await page1.fill('#username', 'user1');
await page1.fill('#password', 'password1');
await page1.click('button[type="submit"]');
// Контекст для второго пользователя
const context2 = await browser.newContext();
const page2 = await context2.newPage();
await page2.goto('https://example.com/login');
await page2.fill('#username', 'user2');
await page2.fill('#password', 'password2');
await page2.click('button[type="submit"]');
// Действия с обоими пользователями, не влияющие друг на друга
await page1.goto('https://example.com/dashboard');
await page2.goto('https://example.com/dashboard');
await browser.close();
})();
В этом примере каждый контекст создаёт свою собственную сессию с независимыми cookies, что позволяет им авторизоваться с разными учетными записями.
Важной особенностью контекстов является их способность изолировать
данные локального хранилища (localStorage) и сессионного
хранилища (sessionStorage). Это необходимо, например, когда
требуется протестировать, как приложение ведет себя при изменении этих
данных в разных контекстах.
Пример работы с локальным хранилищем в разных контекстах:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
// Контекст для первого пользователя
const context1 = await browser.newContext();
const page1 = await context1.newPage();
await page1.goto('https://example.com');
await page1.evaluate(() => {
localStorage.setItem('user_data', JSON.stringify({ user: 'user1' }));
});
// Контекст для второго пользователя
const context2 = await browser.newContext();
const page2 = await context2.newPage();
await page2.goto('https://example.com');
await page2.evaluate(() => {
localStorage.setItem('user_data', JSON.stringify({ user: 'user2' }));
});
// Проверка изоляции
const user1Data = await page1.evaluate(() => {
return localStorage.getItem('user_data');
});
const user2Data = await page2.evaluate(() => {
return localStorage.getItem('user_data');
});
console.log(user1Data); // {"user": "user1"}
console.log(user2Data); // {"user": "user2"}
await browser.close();
})();
В этом примере, несмотря на то что оба контекста обращаются к одному и тому же сайту, данные в локальном хранилище изолированы, и каждый контекст имеет собственную запись.
Одной из распространенных задач является тестирование многозадачных сценариев, где важно взаимодействие нескольких пользователей в реальном времени. Например, два пользователя могут одновременно обновлять страницу или делать какие-то действия, которые должны быть обработаны одновременно. В таких случаях контексты позволяют не только эмулировать одновременные действия, но и проверять корректность работы приложения в условиях многозадачности.
Пример:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
// Контекст для первого пользователя
const context1 = await browser.newContext();
const page1 = await context1.newPage();
await page1.goto('https://example.com/chat');
await page1.fill('#message', 'Привет, как дела?');
await page1.click('#send');
// Контекст для второго пользователя
const context2 = await browser.newContext();
const page2 = await context2.newPage();
await page2.goto('https://example.com/chat');
await page2.fill('#message', 'Все хорошо, а у тебя?');
await page2.click('#send');
// Проверка сообщений на обеих страницах
const messages1 = await page1.locator('.messages').allTextContents();
const messages2 = await page2.locator('.messages').allTextContents();
console.log(messages1); // ['Привет, как дела?']
console.log(messages2); // ['Все хорошо, а у тебя?']
await browser.close();
})();
Таким образом, использование контекстов позволяет создавать независимые и изолированные сессии для множества пользователей, что идеально подходит для тестирования многозадачных и многопользовательских сценариев.
Изоляция состояния между контекстами является важным инструментом при тестировании веб-приложений с использованием Playwright. Она позволяет создавать независимые сессии для различных пользователей, эмулировать параллельные действия и работать с изолированными данными, такими как cookies, localStorage и sessionStorage. Правильное использование контекстов помогает повысить точность и надежность тестов, а также облегчить тестирование сложных многозадачных и многопользовательских сценариев.