Вопрос или проблема
Проще говоря, по какой-то причине сайт, с которым я работаю, настроил этот раздел ввода следующим образом:
<iframe title="parentIframe">
#document (https://www.website.com)
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<div id="root">
<div id="firstDiv">
... //iframe внутри произвольного количества div
<iframe title="firstChildIframe">
#document (https://www.website.com/subsite1)
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<input name="firstInput" />
</body>
</html>
</iframe>
...
</div>
<div id="secondDiv">
...
<iframe title="secondChildIframe">
#document (https://www.website.com/subsite2)
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<input name="secondInput" />
</body>
</html>
</iframe>
...
</div>
<div id="thirdDiv">
...
<iframe title="thirdChildIframe">
#document (https://www.website.com/subsite3)
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<input name="thirdInput" />
</body>
</html>
</iframe>
...
</div>
</div>
</body>
</html>
</iframe>
Для автоматизированного тестирования мы используем какой-то форк webdriver с nodeJS, и я наткнулся на стену.
Я пытался использовать this.focusFrame()
и browser.switchToFrame()
с //iframe[@title="____ChildIframe"]
и iframe[title="____ChildIframe"]
, оба из которых работают в строке поиска Inspect/Elements в Chrome, но я не могу найти способ заставить это работать.
Оказавшись внутри родительского iframe с помощью this.focusFrame('//iframe[@title="parentIframe"]')
, тестировщик остается зависшим и ничего не делает, вероятно, ищет первый дочерний iframe в цикле и никогда его не находит. Я не знаю, чего мне не хватает. Возможно, поскольку содержимое iFrame загружается на другом сайте или является частью другого HTML, тестировщик не знает, что делать? Что я упускаю?
Спасибо за вашу помощь!
Ответ или решение
Для доступа к iFrame внутри другого iFrame с использованием WebDriver и JavaScript в Node.js необходимо учитывать несколько ключевых моментов, которые могут влиять на успешное переключение между фреймами. Ваша проблема может быть вызвана неправильной последовательностью команд или отсутствием необходимого времени для загрузки элементов. Давайте рассмотрим этот процесс шаг за шагом.
Шаги для доступа к iFrame внутри другого iFrame
-
Инициализация WebDriver: Убедитесь, что вы правильно инициализировали WebDriver и указали нужный браузер. Пример для Chrome:
const { Builder } = require('selenium-webdriver'); const chrome = require('selenium-webdriver/chrome'); let driver = new Builder() .forBrowser('chrome') .setChromeOptions(new chrome.Options()) .build();
-
Навигация к родительскому iFrame: Сначала необходимо переключиться на родительский iFrame. Используйте метод
switchTo()
для этого:await driver.get('https://www.website.com'); // Перейдите на страницу await driver.switchTo().frame(driver.findElement({ xpath: '//iframe[@title="parentIframe"]' }));
-
Ожидание загрузки содержимого: Перед переключением на дочерний iFrame убедитесь, что содержимое загружено. Можно использовать WebDriverWait для ожидания видимости элемента:
const { WebDriverWait, until } = require('selenium-webdriver'); let wait = new WebDriverWait(driver, 10000); // Блок ожидания на 10 секунд await wait.until(until.elementLocated({ xpath: '//iframe[@title="firstChildIframe"]' }));
-
Переключение на дочерний iFrame: Теперь можно переключиться на нужный дочерний iFrame:
await driver.switchTo().frame(driver.findElement({ xpath: '//iframe[@title="firstChildIframe"]' }));
-
Взаимодействие с элементами внутри дочернего iFrame: После успешного переключения вы можете взаимодействовать с элементами, например, вводить текст в поле:
await driver.findElement({ name: 'firstInput' }).sendKeys('Ваш текст здесь');
-
Возвращение к родительскому iFrame: После завершения работы с дочерними iFrame рекомендуется вернуться к родительскому iFrame, чтобы при необходимости иметь возможность переключиться на другие дочерние iFrame:
await driver.switchTo().parentFrame(); // Возвращение к родительскому фрейму
-
Обработка ошибок и оптимизация: Убедитесь, что ваш код обрабатывает возможные исключения, а также добавляет соответствующие задержки или ожидания, чтобы избежать застревания в цикле.
Важные моменты
- Асинхронный код: Убедитесь, что вы используете асинхронные функции правильно, и не забывайте о
await
в нужных местах, чтобы разрешить промисы. - Загрузка контента: Иногда элементы могут загружаться с задержкой. Использование ожиданий (waits) поможет предотвратить многие проблемы.
- Кросс-доменные ограничения: Если контенты загружены с других доменов, убедитесь, что нет ограничений по кросс-доменной политике (CORS), так как это может вызывать проблемы с доступом к содержимому.
Следуя этим шагам, вы сможете успешно получить доступ к элементам внутри iFrame, находящихся внутри другого iFrame с использованием WebDriver в Node.js. Если после выполнения этих действий проблема сохраняется, рассмотрите возможность детального изучения консоли разработчика браузера для выявления возможных ошибок.