Skip to main content

pytest-selenium-enhancer is a plugin for pytest that provides enhanced webdriver functionality by dynamically adding methods to: - remote.webdriver.Webdriver - remote.webdriver.WebElement

It provides a set of commands to enable testing of WebComponents and Visual Regression Testing

Requirements

Following prerequisites are needed in order to use pytest-selenium-enhancer:

  • numpy

  • opencv-python >= 4.2.0.32

  • pillow >= 7.0.0

  • Python >= 3.7.5

  • pytest >= 5.3.0

  • pytest-variables >= 1.9.0

  • requests

  • selenium >= 3.141.0

Installation

To install pytest-selenium-enhancer:

pip install pytest-selenium-enhancer

Features and Usage

Custom Commands

Adding custom commands

Custom commands have to be added to the WebDriver and WebElement before they are used within the test project. List of built-in fixtures: .. code-block:

selenium_patcher
    # Adds the predefined CustomCommands to WebDriver and WebElement

To extend the browser instance with own set of commands, the decorator add_method is here to help. .. code-block:

@pytest.fixture(scope='session')
def my_custom_commands():
    @add_method(WebElement)
    def wait_and_click(self, timeout):
        """Waits for a given period of time then clicks the element
        """
        sleep(timeout)
        self.click()

To add the command to WebElement simply add the fixture as param to the browser function Example of usage for the built-in fixture selenium_patcher and your defined fixture my_custom_commands: .. code-block:

@pytest.fixture(scope="function")
def driver(variables, env_variables, selenium_patcher, my_custom_commands):
    from selenium import webdriver
    _driver = webdriver.Remote(
        command_executor='https://%s:%s@hub-cloud.browserstack.com/wd/hub'
                        % (env_variables.bs_username, env_variables.bs_key),
        desired_capabilities=variables['capabilities'])
    yield _driver
    _driver.close()

The plugin provides a set of custom commands to use for browser testing with pytest

Build in remote.Webdriver Custom Commands

shadow_find_element WebDriver

Returns an element of a DOM subtree by given selector

Usage .. code-block:

browser.shadow_find_element(selector)

Parameters .. csv-table:

:header: "Name", "Type", "Details"
:widths: 20, 30, 50

"selector", "(obj:CSS Selector)", "CSS Selector as described here_"

Example .. code-block:

browser.shadow_find_element('custom-login-component')
shadow_cascade_find_element WebDriver

Returns an element of a DOM subtree by given list of selectors

Usage .. code-block:

browser.shadow_cascade_find_element(selectors)

Parameters .. csv-table:

:header: "Name", "Type", "Details"
:widths: 20, 30, 50

"selectors", "(obj:CSS Selector), n (obj:CSS Selector)", "CSS Selectors as described here_"

Example .. code-block:

browser.shadow_cascade_find_element('custom-login-component', 'custom-login-form', 'custom-field')
shadow_find_elements WebDriver

Returns a list of elements of a DOM subtree by given of selector

Usage .. code-block:

browser.shadow_find_elements(selector)

Parameters .. csv-table:

:header: "Name", "Type", "Details"
:widths: 20, 30, 50

"selectors", "(obj:CSS Selector)", "CSS Selectors as described here_"

Example .. code-block:

browser.shadow_cascade_find_element('custom-login-component')
get_full_page_screenshot_as_base64 WebDriver
Gets full page screenshot of current page by automatically scroll the full width and height of the page

NOTE: Does not work for infinite scrolling pages

Usage .. code-block:

browser.get_full_page_screenshot_as_base64(elements_to_hide, device_offset)

Parameters .. csv-table:

:header: "Name", "Type", "Details"
:widths: 20, 30, 50

"elements_to_hide", "(obj)", "{'top': [sticky top elements that you want to hide after first horizontal scroll], 'all':[elements that you want to completely hide], 'bottom': [sticky bottom elements that you want to show only after first horizontal scroll]}"
"device_offset", "(int)", "iOS only. Used to define the height of the browser upper controls. Safari iOS browser controls are part of the screenshot taken by selenium so we want not to have them into a full page screenshot"

Example .. code-block:

elements_to_hide = {
    "start": [self.get_header()._banner] if self.page_name is 'home_page'] else [],
    "all": [],
    "end": [self.get_persistent_isi()._component_container]
}
browser.get_full_page_screenshot_as_base64(elements_to_hide, 284)
get_full_page_screenshot_as_png WebDriver
Gets full page screenshot of current page by automatically scroll the full width and height of the page

NOTE: Does not work for infinite scrolling pages

Usage .. code-block:

browser.get_full_page_screenshot_as_png(image_path, elements_to_hide, device_offset)

Parameters .. csv-table:

:header: "Name", "Type", "Details"
:widths: 20, 30, 50

"image_path", "(str)", "Full path of the location to where to save the screenshot"
"elements_to_hide", "(obj)", "{'top': [sticky top elements that you want to hide after first horizontal scroll], 'all':[elements that you want to completely hide], 'bottom': [sticky bottom elements that you want to show only after first horizontal scroll]}"
"device_offset", "(int)", "iOS only. Used to define the height of the browser upper controls. Safari iOS browser controls are part of the screenshot taken by selenium so we want not to have them into a full page screenshot"

Example .. code-block:

elements_to_hide = {
    "start": [self.get_header()._banner] if self.page_name is 'home_page'] else [],
    "all": [],
    "end": [self.get_persistent_isi()._component_container]
}
browser.get_full_page_screenshot_as_png(image_path, elements_to_hide, 284)

Build in remote.WebElement Custom Commands

shadow_find_element WebElement

Returns a child element of a DOM subtree by given selector

Usage .. code-block:

element.shadow_find_element(selector)

Parameters .. csv-table:

:header: "Name", "Type", "Details"
:widths: 20, 30, 50

"selector", "(obj:CSS Selector)", "CSS Selector as described here_"

Example .. code-block:

custom_login_component = browser.find_element_by_tag_name('custom-login-component')
custom_login_component.shadow_find_element('custom-login-component')
shadow_cascade_find_element WebElement

Returns a child element of a DOM subtree by given list of selectors

Usage .. code-block:

element.shadow_cascade_find_element(selectors)

Parameters .. csv-table:

:header: "Name", "Type", "Details"
:widths: 20, 30, 50

"selectors", "(obj:CSS Selector), n (obj:CSS Selector)", "CSS Selectors as described here_"

Example .. code-block:

custom_login_component = browser.find_element_by_tag_name('custom-login-component')
custom_login_component.shadow_cascade_find_element('custom-login-component', 'custom-login-form', 'custom-field')
shadow_find_elements WebElement

Returns a list of children elements of a DOM subtree by given of selector

Usage .. code-block:

element.shadow_find_elements(selector)

Parameters .. csv-table:

:header: "Name", "Type", "Details"
:widths: 20, 30, 50

"selectors", "(obj:CSS Selector)", "CSS Selectors as described here_"

Example .. code-block:

custom_login_component = browser.find_element_by_tag_name('custom-login-component')
custom_login_component.shadow_cascade_find_element('custom-login-component')

If you want to know more about WebComponents and ShadowRoot

NOTE: For the above examples, the following piece of HTML, as seen in Developer Tools, was considered: .. code-block:

<custom-login-component>
    #shadowRoot (open)
    <custom-login-form>
        #shadowRoot (open)
        <custom-field type="text">
            #shadowRoot (open)
            <input></input>
        </custom-field>
        <custom-field type="password">
            #shadowRoot (open)
            <input></input>
        </custom-field>
        <custom-button>Login
            #shadowRoot (open)
            <button></button>
        </custom-button>
    </custom-login-form>
</custom-login-component>

Custom Waits

wait_for_element_present

TODO

wait_for_element_visible

TODO

wait_for_element_not_visible

TODO

wait_for_element_clickable

TODO

wait_for_child_element_visible

TODO

wait_for_child_element_not_visible

TODO

wait_for_the_attribute_value

TODO

wait_for_the_attribute_contain_value

TODO

wait_until

TODO

Contributing

We welcome contributions.

To learn more, see Contributing

E2E testing is brought to you by BrowserStack.

BrowserStack

Resources

Metadata

Release files for pytest-selenium-enhancer 1.7.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pytest-selenium-enhancer 1.7.1
File Size Uploaded
pytest-selenium-enhancer-1.7.1.tar.gz 11.5 kB Details

Release files / pytest-selenium-enhancer-1.7.1.tar.gz

Download URL pytest-selenium-enhancer-1.7.1.tar.gz
Size 11.5 kB
Tags Source
SHA-256 checksum
How to use checksums
8c0628733a54b4ba7f02e9b8da83241746c48770e4fbdad36b98b142026c1c4c
BLAKE2b-256 checksum
How to use checksums
e369607d93a13307a1914042408a82abdc3dbffc01fd1d0d9fdf7a348a73cb0f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.7.1 importlib_metadata/4.8.2 pkginfo/1.8.2 requests/2.25.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.0

Release history Release notifications | RSS feed

This release

1.7.1 This release

1 release file

1.7.0

1 release file

1.6.2

1 release file

1.6.1

1 release file

1.6.0

1 release file

1.5.3

1 release file

1.5.2

1 release file

1.5.1

1 release file

1.5.0

1 release file

1.4.4

1 release file

1.4.3

1 release file

1.4.2

1 release file

1.4.1

1 release file

1.4.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page