Проблема

Процесс поиска элементов на веб-странице, не использующей Shadow DOM, достаточно прост. Попытка найти элементы на веб-странице, которая действительно использует Shadow DOM, - это еще одна проблема!

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

Пример веб-страницы

Типичным примером веб-страницы, используемой для демонстрации использования теневой модели DOM, является страница загрузок Google Chrome:

На этом экране есть три теневых корня, которые называются «менеджер загрузок», «список загрузок» и «элемент загрузок». Имена берутся из тега, указанного выше каждого теневого корня, выделенного красным.

Решение

Часть 1. Используйте JavaScript

Распространенным решением для работы с тем, что не поддерживается WebDriver, является использование JavaScript через функцию WebDriver ExecuteScript.

На высоком уровне нам нужно:

  1. Найдите теневой корень элемента
  2. Найдите элемент в этом теневом корне

Приступим к первому шагу. Нам нужно циклически перемещаться по теневым корневым элементам, чтобы добраться до желаемого уровня исходного кода 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.