Проблемът

Процесът на намиране на елементи в уеб страница, която не използва Shadow DOM, е достатъчно ясен. Опитът да се намерят елементи в уеб страница, която наистина използва Shadow DOM, е още един котел за риба!

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

Примерна уеб страница

Често срещана примерна уеб страница, използвана за демонстриране на използването на DOM в сянка, е страницата за изтегляния на Google Chrome:

На този екран има три корена в сянка, наречени „мениджър на изтегляния“, „списък на изтегляния“ и „елемент на изтегляния“. Имената идват от етикета, посочен над всеки shadow-root, очертан в червено.

Решението

Част 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, предавайки нашия низов масив от селектори по следния начин:

Сега имаме достъп до shadow root, можем да търсим в него елемента, който искаме да използваме, като използваме каквато стратегия предпочитаме. След това можем да манипулираме елемента, който сме намерили, по нормалния начин, например да щракнем върху иконата „X“:

И накрая...

Чудесен начин да използвате функцията FindShadowRootElement е да я имате достъпна, сякаш е част от API на WebDriver, като напишете метод за разширение. Допълнителни подробности как да направите това в моята история C# WebDriver Extensions