Переключение между страницами

Работа с несколькими страницами в браузере является неотъемлемой частью тестирования и автоматизации в Puppeteer. Этот инструмент предоставляет мощные возможности для взаимодействия с веб-страницами и элементами внутри них, включая операции по переключению между несколькими страницами или вкладками. Рассмотрим, как управлять страницами, открывать новые, переключаться между ними и выполнять действия на каждой.

Основные понятия

Puppeteer работает с объектами типа Page, представляющими собой отдельные страницы в браузере. Каждая вкладка или окно браузера является отдельной страницей. Взаимодействие с несколькими страницами требует точного управления этими объектами. Для этого Puppeteer предоставляет методы для открытия новых вкладок, переключения между ними, а также управления контекстом текущей страницы.

Открытие новой страницы

Для открытия новой страницы в Puppeteer используется метод browser.newPage(). Этот метод возвращает объект Page, который можно использовать для взаимодействия с новой вкладкой браузера.

Пример:

const browser = await puppeteer.launch(); const page1 = await
browser.newPage(); // Открытие первой страницы await page1.goto(&

Если необходимо открыть несколько вкладок, можно вызывать newPage() столько раз, сколько необходимо:

const page2 = await browser.newPage(); // Открытие второй страницы
await page2.goto('https://example.org');

Каждый вызов newPage() создаёт новую страницу, с которой можно работать независимо от других.

Переключение между страницами

Чтобы взаимодействовать с конкретной страницей, нужно ссылаться на объект Page, который является текущим контекстом для всех операций. Puppeteer не предоставляет явного метода для «переключения» между страницами, так как каждая страница — это отдельный объект, с которым можно работать напрямую.

Пример взаимодействия с несколькими страницами:

const page1 = await browser.newPage();
const page2 = await browser.newPage();

await page1.goto('https://example.com');
await page2.goto('https://example.org');

// Ожидание загрузки элементов на первой странице
await page1.waitForSelector('#element1');

// Ожидание загрузки элементов на второй странице
await page2.waitForSelector('#element2');

Здесь каждая страница может использоваться независимо, и все операции (например, переходы по URL или взаимодействие с элементами) выполняются в контексте конкретной страницы.

Работа с вкладками

В Puppeteer каждое новое окно или вкладка браузера создаются как отдельные объекты Page. Однако иногда необходимо работать с несколькими вкладками одновременно и синхронизировать действия между ними. Для этого можно использовать Promise.all() для параллельного выполнения нескольких действий.

Пример:

const page1 = await browser.newPage();
const page2 = await browser.newPage();

await Promise.all([
  page1.goto('https://example.com'),
  page2.goto('https://example.org')
]);

await Promise.all([
  page1.waitForSelector('#element1'),
  page2.waitForSelector('#element2')
]);

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

Работа с контекстами

В некоторых случаях необходимо работать с несколькими вкладками в рамках одного контекста браузера. В таких ситуациях можно использовать методы для управления контекстом. Например, Puppeteer позволяет работать с несколькими окнами в режиме инкогнито, каждый из которых будет иметь свои cookies, localStorage и другие данные.

const browser = await puppeteer.launch();
const context1 = await browser.createIncognitoBrowserContext(); // Создание контекста инкогнито
const page1 = await context1.newPage();
await page1.goto('https://example.com');

Контекст позволяет изолировать вкладки друг от друга, что полезно для выполнения тестов с независимыми данными.

Закрытие страниц

После выполнения операций с определённой страницей важно не забывать её закрывать. Для этого используется метод page.close(). Это освобождает ресурсы и предотвращает утечку памяти.

Пример:

await page1.close(); // Закрытие первой страницы
await page2.close(); // Закрытие второй страницы

Переключение между окнами

Если необходимо работать с окнами браузера, то Puppeteer предоставляет возможность переключаться между окнами с помощью метода browser.pages(). Этот метод возвращает список всех открытых страниц, и можно выбрать ту, с которой требуется взаимодействовать.

Пример:

const pages = await browser.pages();
const page3 = pages[0]; // Выбираем первую открытую страницу
await page3.goto('https://new-url.com');

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

Управление вкладками в многозадачных приложениях

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

Пример:

const page1 = await browser.newPage();
const page2 = await browser.newPage();

await page1.goto('https://messenger.com');
await page2.goto('https://another-chat.com');

// Получение данных из чатов
const message1 = await page1.$eval('.message', el => el.textContent);
const message2 = await page2.$eval('.message', el => el.textContent);

// Выводим сообщения из разных чатов
console.log(message1);
console.log(message2);

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

Переключение между фреймами

Веб-страницы могут содержать внутри себя фреймы (iframe), которые также требуют особого подхода для взаимодействия. Чтобы работать с элементами внутри фрейма, необходимо получить доступ к этому фрейму через метод page.frames(). После этого можно манипулировать содержимым внутри фрейма так же, как и с обычной страницей.

Пример:

const page = await browser.newPage();
await page.goto('https://example.com');

// Получаем все фреймы на странице
const frames = await page.frames();
const iframe = frames.find(f => f.name() === 'iframe-name');

// Взаимодействуем с элементами внутри фрейма
await iframe.click('#button');

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

Заключение

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