Package: pytest-selenium-enhancer
pytest-selenium-enhancer is a plugin forpytestthat provides enhanced webdriver functionality by dynamically
adding methods to:
- remote.webdriver.Webdriver
- remote.webdriver.WebElementIt provides a set of commands to enable testing ofWebComponentsand Visual Regression TestingTable of ContentsRequirementsInstallationFeatures and UsageCustom CommandsAdding custom commandsBuild in remote.Webdriver Custom Commandsshadow_find_element WebDrivershadow_cascade_find_element WebDrivershadow_find_elements WebDriverget_full_page_screenshot_as_base64 WebDriverget_full_page_screenshot_as_png WebDriverBuild in remote.WebElement Custom Commandsshadow_find_element WebElementshadow_cascade_find_element WebElementshadow_find_elements WebElementCustom Waitswait_for_element_presentwait_for_element_visiblewait_for_element_not_visiblewait_for_element_clickablewait_for_child_element_visiblewait_for_child_element_not_visiblewait_for_the_attribute_valuewait_for_the_attribute_contain_valuewait_untilContributingResourcesRequirementsFollowing prerequisites are needed in order to use pytest-selenium-enhancer:numpyopencv-python >= 4.2.0.32pillow >= 7.0.0Python >= 3.7.5pytest >= 5.3.0pytest-variables >= 1.9.0requestsselenium >= 3.141.0InstallationTo install pytest-selenium-enhancer:pip install pytest-selenium-enhancerFeatures and UsageCustom CommandsAdding custom commandsCustom 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 WebElementTo extend the browser instance with own set of commands, the decoratoradd_methodis 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 fixtureselenium_patcherand your defined fixturemy_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 withpytestBuild in remote.Webdriver Custom Commandsshadow_find_element WebDriverReturns an element of a DOM subtree by given selectorUsage.. 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 WebDriverReturns an element of a DOM subtree by given list of selectorsUsage.. 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 WebDriverReturns a list of elements of a DOM subtree by given of selectorUsage.. 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 WebDriverGets full page screenshot of current page by automatically scroll the full width and height of the pageNOTE:Does not work for infinite scrolling pagesUsage.. 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 WebDriverGets full page screenshot of current page by automatically scroll the full width and height of the pageNOTE:Does not work for infinite scrolling pagesUsage.. 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 Commandsshadow_find_element WebElementReturns a child element of a DOM subtree by given selectorUsage.. 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 WebElementReturns a child element of a DOM subtree by given list of selectorsUsage.. 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 WebElementReturns a list of children elements of a DOM subtree by given of selectorUsage.. 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 aboutWebComponentsandShadowRootNOTE:For the above examples, the following piece of HTML, as seen inDeveloper 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 Waitswait_for_element_presentTODOwait_for_element_visibleTODOwait_for_element_not_visibleTODOwait_for_element_clickableTODOwait_for_child_element_visibleTODOwait_for_child_element_not_visibleTODOwait_for_the_attribute_valueTODOwait_for_the_attribute_contain_valueTODOwait_untilTODOContributingWe welcome contributions.To learn more, seeContributingE2E testing is brought to you byBrowserStack.ResourcesRelease NotesIssue TrackerCode