Взаимодействие с элементами внутри фреймов

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

Работа с фреймами в Playwright

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

Получение фрейма по имени или ID

Самый простой способ — это получить фрейм по его имени или идентификатору. Playwright предоставляет метод frame(), который позволяет работать с фреймами через их атрибуты.

const frame = await page.frame({ name: 'frameName' });

В этом примере name — это атрибут name фрейма. Если фрейм имеет ID, то его можно получить через атрибут id.

Получение всех фреймов на странице

Если имя или ID фрейма неизвестны, можно получить все фреймы на странице и затем выбрать нужный. Для этого используется метод frames(), который возвращает массив всех фреймов на странице.

const frames = page.frames();
const myFrame = frames.find(f => f.url().includes('some-part-of-url'));

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

Взаимодействие с элементами внутри фрейма

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

Клик на элемент внутри фрейма

Для того чтобы кликнуть на элемент внутри фрейма, нужно использовать метод locator() фрейма. Например, если нужно кликнуть на кнопку с классом .submit-button внутри фрейма, код будет выглядеть так:

const button = await frame.locator('.submit-button');
await button.click();

Этот код находит кнопку внутри фрейма и выполняет клик.

Заполнение формы внутри фрейма

Заполнение формы внутри фрейма также не вызывает трудностей. Для этого можно использовать методы, такие как fill() или type(), в зависимости от того, нужно ли заполнять поле текстом или симулировать ввод с клавиатуры.

const input = await frame.locator('#username');
await input.fill('testuser');

Этот код заполняет поле с id username текстом “testuser” внутри фрейма.

Работа с элементами внутри вложенных фреймов

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

Для работы с элементами во вложенных фреймах сначала нужно получить доступ к верхнему фрейму, а затем к фрейму внутри него. Это можно сделать с помощью методов childFrames() и frame().

const topFrame = page.frame({ name: 'topFrame' });
const nestedFrame = await topFrame.frame({ name: 'nestedFrame' });
const button = await nestedFrame.locator('.button');
await button.click();

В этом примере мы сначала получаем верхний фрейм, а затем находим вложенный фрейм, после чего взаимодействуем с элементом внутри него.

Ожидания и тайм-ауты при работе с фреймами

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

Одним из важных методов является waitForSelector(). Он позволяет подождать, пока элемент внутри фрейма не появится.

await frame.waitForSelector('.submit-button');

Этот код заставит Playwright подождать, пока элемент с классом .submit-button не станет доступен внутри фрейма.

Работа с окнами и всплывающими фреймами

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

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

const [newPage] = await Promise.all([
  page.waitForEvent('popup'),
  page.locator('button#openModal').click(),
]);
await newPage.locator('.modal-button').click();

Этот код отслеживает открытие всплывающего окна при клике на кнопку с id openModal и выполняет действие внутри нового окна.

Обработка ошибок при работе с фреймами

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

try {
  const frame = await page.frame({ name: 'frameName' });
  const button = await frame.locator('.submit-button');
  await button.click();
} catch (error) {
  console.error('Ошибка при работе с фреймом:', error);
}

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

Заключение

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