Фреймы и iframes часто используются в веб-приложениях для изоляции контента или внедрения сторонних виджетов. В автоматизированном тестировании взаимодействие с ними требует специального подхода, поскольку элементы внутри фрейма находятся в отдельном DOM-контексте. Protractor предоставляет удобные механизмы для работы с фреймами через WebDriver API.
Для взаимодействия с элементами внутри фрейма необходимо сначала
переключить контекст выполнения. Protractor использует метод
browser.switchTo().frame():
// По индексу фрейма
browser.switchTo().frame(0);
// По WebElement
let frameElement = element(by.css('iframe#myFrame'));
browser.switchTo().frame(frameElement.getWebElement());
// По имени или ID фрейма
browser.switchTo().frame('frameName');
Особенности:
0.WebElement предпочтительно, когда фрейм
имеет динамический ID или имя.После завершения работы с фреймом необходимо вернуть контекст на основную страницу:
browser.switchTo().defaultContent();
Если требуется вернуться на родительский фрейм из вложенного:
browser.switchTo().parentFrame();
Важно: без возврата к основному контенту попытки
взаимодействия с элементами вне фрейма приведут к ошибкам
NoSuchElementError.
После переключения на фрейм можно использовать стандартные методы поиска элементов:
let buttonInsideFrame = element(by.css('button.submit'));
buttonInsideFrame.click();
let inputField = element(by.model('user.name'));
inputField.sendKeys('Тест');
Все команды поиска element и element.all
будут локализованы в текущем фрейме.
Если фреймы вложены друг в друга, переключение выполняется последовательно:
// Переключение на внешний фрейм
let outerFrame = element(by.css('iframe#outer'));
browser.switchTo().frame(outerFrame.getWebElement());
// Переключение на внутренний фрейм
let innerFrame = element(by.css('iframe#inner'));
browser.switchTo().frame(innerFrame.getWebElement());
// Доступ к элементам внутри внутреннего фрейма
element(by.css('button.save')).click();
// Возврат на внешний фрейм
browser.switchTo().parentFrame();
// Возврат к основному контенту
browser.switchTo().defaultContent();
Иногда фреймы загружаются асинхронно, и поиск их элементов сразу
после загрузки страницы приводит к ошибкам. В таких случаях используется
ожидание с ExpectedConditions:
let EC = protractor.ExpectedConditions;
let dynamicFrame = element(by.css('iframe.dynamic'));
browser.wait(EC.presenceOf(dynamicFrame), 5000, 'Фрейм не загрузился');
browser.switchTo().frame(dynamicFrame.getWebElement());
Использование ожиданий обеспечивает стабильность тестов при работе с динамическими страницами.
it('должен заполнить форму внутри фрейма', async () => {
let mainFrame = element(by.id('mainFrame'));
await browser.wait(protractor.ExpectedConditions.presenceOf(mainFrame), 5000);
await browser.switchTo().frame(mainFrame.getWebElement());
let usernameInput = element(by.name('username'));
await usernameInput.sendKeys('user123');
let submitButton = element(by.css('.submit-btn'));
await submitButton.click();
await browser.switchTo().defaultContent();
});
Этот пример демонстрирует корректное использование ожиданий, переключение на фрейм и возврат к основному контенту, что обеспечивает надежное выполнение теста даже на динамических страницах.
browser.switchTo().frame() и
browser.switchTo().defaultContent() — основные методы для
работы с фреймами.Эффективное использование этих механизмов позволяет создавать стабильные и масштабируемые тесты для сложных веб-приложений с фреймами.