pyshadow
Selenium plugin to manage multi level shadow DOM elements on web page.
Shadow DOM:
Shadow DOM is a web standard that offers component style and markup encapsulation. It is a critically important piece of the Web Components story as it ensures that a component will work in any environment even if other CSS or JavaScript is at play on the page.
Custom HTML Tags:
Custom HTML tags can't be directly identified with selenium tools. Using this plugin you can handle any custom HTML tags.
Problem Statement:
- You have already developed your web-based automation framework in java selenium. Your frontend application uses Polymer that uses shadow dom. Selenium doesn't provide any way to deal with shadow-dom elements.
- Your application page contains custom HTML tags that can't be identified directly using selenium.
Solution:
You can use this plugin by adding jar file or by including maven dependency in your java selenium project.
How it works:
Methods:
find_element(str css_selector) : use this method if want single element from DOM
find_elements(str css_selector) : use this if you want to find all elements from DOM
find_element(object parent, str css_selector) : use this if you want to find a single elements from parent object DOM
find_elements(object parent, str css_selector) : use this if you want to find all elements from parent object DOM
set_implicit_wait(int seconds) : use this method for implicit wait
set_explicit_wait(int seconds, int polling_time) raise Exception : use this method for explicit wait
get_shadow_element(object parent,str css_selector) : use this if you want to find a single element from parent DOM
get_all_shadow_element(object parent, str css_selector) : use this if you want to find all elements from parent DOM
get_parent_element(object element) : use this to get the parent element if web element.
get_child_elements(object parent) : use this to get all the child elements of parent element.
get_sibling_elements(object element) : use this to get all adjacent (sibling) elements.
get_sibling_element(object element, str css_selector) : use this to get adjacent(sibling) element using css selector.
get_next_sibling_element(object element) : use this to get next adjacent(sibling) element.
get_previous_sibling_element(object element) : use this to get previous adjacent(sibling) element..
is_visible(object element) : use this if you want to find visibility of element
is_checked(object element) : use this if you want to check if checkbox is selected
is_disabled(object element) : use this if you want to check if element is disabled
get_attribute(object element, str attribute) : use this if you want to get attribute like aria-selected and other custom attributes of elements.
select_checkbox(str label) : use this to select checkbox element using label.
select_checkbox(object parent, str label) : use this to select checkbox element using label.
select_radio(str label) : use this to select radio element using label.
select_radio(object parent, str label) : use this to select radio element from parent DOM using label.
select_dropdown(str label) : use this to select dropdown list item using label (use this if only one dropdown is present or loaded on UI).
select_dropdown(object parent, str label) : use this to select dropdown list item from parent DOM using label.
scroll_to(object element) : use this to scroll to web element.
Installing
Maven
pip install pyshadow
Examples
Importing modules and calling methods from webdriver and pyshadow:
from selenium import webdriver
from pyshadow.main import Shadow
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(ChromeDriverManager().install())
shadow = Shadow(driver)
Selecting one element:
For element <paper-tab title="Settings">, you can use this code in your framework to grab the paper-tab element Object. The code below returns element based on CSS selector:
...
element = shadow.find_element("paper-tab[title='Settings']")
text = element.text
Selecting elements:
For element that resides under a shadow-root dom element <input class="employee_input">, you can use this code in your framework to grab the paper-tab element Object.
...
elements = shadow.find_elements("input[title='The name of the employee']")
for content in elements:
text = content.text
After this, you can do the handle of content for your case.
Selecting nested elements under shadow-root
For html tag that resides under a shadow-root dom element ex:
<properties-page id="settingsPage">
<textarea id="textarea">
</properties-page>
You can use this code in your framework to grab the textarea element Object.
...
element = shadow.find_element("properties-page#settingsPage>textarea#textarea")
text = element.text
Tips
You can set de selector CSS or Xpath in variables and call in pyshadow methods.
Sometimes you should select elements before, to select the target element, for example:
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a href="#">HTML</a></li>
<li><a href="#">CSS</a></li>
<li><a href="#">JavaScript</a></li>
</ul>
</div>
To select all elements in dropdown, you can do:
...
elements = shadow.find_elements("div[class='dropdown']>ul[class='dropdown-menu']")
for content in elements:
text = content.text
Wait: Implicit and Explicit
If you want to use wait to synchronize your scripts then you should use the implicit or explicit wait feature.
-
For Implicit wait, you can use shadow.set_implicit_wait(int seconds) method.
-
For Explicit wait, you can use shadow.set_explicit_wait(int seconds, int pollingTime) method.
-
In Implicit wait, the driver will wait for at least n seconds as set in shadow.set_implicit_wait(n).
-
In Explicit wait, the driver will wait for at max n seconds as set in shadow.set_implicit_wait(n,m). In between driver will check for presence of WebElement every m seconds.
Note: > is used to combine multi level dom structure. So you can combine 5 levels of dom. If you want some more level modify the script and ready to rock.
Documentation Link
Metadata
Release files for pyshadow 0.0.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pyshadow-0.0.6.tar.gz | 19.7 kB | Without provenance | Details for pyshadow-0.0.6.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pyshadow-0.0.6-py3-none-any.whl | Python 3 | none | any | Details for pyshadow-0.0.6-py3-none-any.whl |
Total release size: 35.7 kB
Release files / pyshadow-0.0.6.tar.gz
| Download URL | pyshadow-0.0.6.tar.gz |
|---|---|
| Size | 19.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
16fbad34aa58e546a9e60ae8ece9517e01ab90f1e41a1bb128bb2c2a707ff9fe
|
|
BLAKE2b-256 checksum How to use checksums |
6e78e6a2dcafd237c8e409f6607d145ed026975376d0e2c018f30a2cc30418d6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / pyshadow-0.0.6-py3-none-any.whl
| Download URL | pyshadow-0.0.6-py3-none-any.whl |
|---|---|
| Size | 16.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cceb2cc17e3c3ce063e2ae69e2b1c83e41f71a54656cb6ac6b15b4f7ab3ba601
|
|
BLAKE2b-256 checksum How to use checksums |
070b73203765829ad5ac75c7c76ad7bf06f585f9cd099cf2a073c3ec6b51ca42
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Security for pyshadow 0.0.6
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.