Проблема
Процесс поиска элементов на веб-странице, не использующей Shadow DOM, достаточно прост. Попытка найти элементы на веб-странице, которая действительно использует Shadow DOM, - это еще одна проблема!
Проблема в том, что библиотеки WebDriver изначально не поддерживают теневые элементы DOM из коробки, поэтому, если вы используете предоставленные вызовы функций для поиска элементов, они потерпят неудачу.
Пример веб-страницы
Типичным примером веб-страницы, используемой для демонстрации использования теневой модели DOM, является страница загрузок Google Chrome:
На этом экране есть три теневых корня, которые называются «менеджер загрузок», «список загрузок» и «элемент загрузок». Имена берутся из тега, указанного выше каждого теневого корня, выделенного красным.
Решение
Часть 1. Используйте JavaScript
Распространенным решением для работы с тем, что не поддерживается WebDriver, является использование JavaScript через функцию WebDriver ExecuteScript.
На высоком уровне нам нужно:
- Найдите теневой корень элемента
- Найдите элемент в этом теневом корне
Приступим к первому шагу. Нам нужно циклически перемещаться по теневым корневым элементам, чтобы добраться до желаемого уровня исходного кода html. Лучший способ сделать это в коде:
Чтобы немного пояснить:
- Мы отправляем массив теневых корневых имен
- Мы перебираем массив, чтобы добраться до нужного нам теневого корня. Для этого мы запускаем Javascript для доступа к переменной shadowRoot текущего элемента.
- После того, как мы перебрали все предоставленные теневые корни, мы возвращаем элемент как IWebElement.
Часть 2. Как определить список используемых селекторов
Самая сложная часть всего этого - как узнать, какие селекторы отправлять в FindShadowRootElement ()?
Лучший способ узнать, что отправлять, - использовать Инструменты разработчика Chrome и проверить элемент. Например, на изображении страницы загрузок Chrome выше, если мы проверим значок «X» msi-файла узла, вы получите:
Как видим, выделена кнопка с идентификатором «удалить». Важной частью является ленточный список элементов под ней. Я развернул ленту, чтобы показать, что я имею в виду:
Нас интересуют имена, которые появляются перед записями «# shadow-root», «downloads-manager» и «downloads-item». В этом случае имена теневого корня выглядят так, как они появляются в исходном HTML-коде, но, как я выяснил, это не всегда так, поэтому рекомендуется использовать ленту элементов Chrome для помощи.
Часть 3. Найдите элемент и управляйте им
Затем мы можем использовать нашу функцию FindShadowRootElement, передавая наш строковый массив селекторов таким образом:
Теперь у нас есть доступ к теневому корню, мы можем искать в нем элемент, который хотим использовать, используя любую стратегию, которую мы предпочитаем. Затем мы можем манипулировать найденным элементом обычным способом, например, щелкнув значок «X»:
И наконец…
Отличный способ использовать функцию FindShadowRootElement - сделать ее доступной, как если бы она была частью API WebDriver, путем написания метода расширения. Подробнее о том, как это сделать, читайте в моем рассказе Расширения C # WebDriver.