PyPCOM package

Subpackages

Submodules

pypcom.component module

This module just contains the base class for components.

pypcom.component.CssProperties[source]

CSS properties.

Lookups can be defined manually for nuanced control over what is returned, but if not defined manually, the attribute being looked up will be passed as a string to the value_of_css_property method of the manager class’s WebElement. If the property’s name can’t be treated as a Python variable name, the name can be passed as a string to the get() method.

class pypcom.component.PageComponent[source]

Bases: object

The base class for all page components.

This is the class that all page components should inherit from. Components are meant to represent a specific element on a page, and aren’t a direct reference to the WebElement itself. Instead, an attempt to get the WebElement is only ever made if a reference is made to an attribute of the component that it doesn’t have defined itself (see __getattr__ for details).

If a reference is made to an attribute of the component that the component doesn’t have, then the component’s _locator attribute is used to get the WebElement, and the attribute lookup is deferred to the WebElement. For example, if a reference is made to the text attribute of component x, and component x doesn’t have a text attribute defined for it, then x gets its WebElement and gets the text attribute of it.

If the component has no _locator attribute, an exception is raised stating that the component cannot be referenced as an element without one.

If the WebElement can’t be found, an exception is raised stating so.

If the WebElement is found, but it doesn’t have the attribute initially referenced, then an exception is raised stating that the component (not the WebElement) doesn’t have that attribute. All WebElements have a static set of attributes, so it’s assumed that any referenced attributes that aren’t part of that set are meant to be defined for that component, and if the lookup for it failed in this way, it was because it wasn’t properly defined in the component’s class.

Components must be descriptors of their owner pages’/components’ classes. They can be made to be subcomponents of other components to create a tree of ownership, accessed through dot-notation. If a component is a manager of another component, it can still have its own _locator, which allows it to be treated as an element.

For example, a ‘username’ component could belong to a ‘login_form’ component, and the ‘login_form’ component could belong to the page. In order to reference the ‘username’ component, you would say:

page.login_form.username

If you want to find the WebElement of the PageComponent by searching from its parent component’s element, give the component the _find_from_parent attribute and set it to True.

Attributes:
_locator (tuple of str): The locator method and value to
find the WebElement.
driver (WebDriver): WebDriver to be used for element lookups and page
interactions.
_parent (PageComponent): The instance of the manager class for this
component.
_find_from_parent (bool): Whether or not to used the parent
component’s element as the jumping off point to find the element from.
css

CSS properties.

Lookups can be defined manually for nuanced control over what is returned, but if not defined manually, the attribute being looked up will be passed as a string to the value_of_css_property method of the manager class’s WebElement. If the property’s name can’t be treated as a Python variable name, the name can be passed as a string to the get() method.

iframe_ancestor

First ancestor PageComponent that is of type Iframe.

Walk up through the PageComponent’s ancestors, checking for one that is of type Iframe. If one is found, return it. If none are found, return None.

This also caches the ancestor the first time it’s searched for (as it shouldn’t be changing), which will speed up further references to it.

is_present()[source]

Query the element to find if it is present or not.

Make a call to is_displayed to force a lookup of the element. If a NoSuchElementException is raised, then the element is not present, and False is returned. Otherwise, True is returned. Only a NoSuchElementException is checked for so that other exceptions can still be raised as they shoud be.

A call to is_displayed is made, because some behavior of the PageComponent may have been overridden which might cause a reference to self._el to not actually make a reference to the WebElement itself. Making a call to is_displayed should trigger any new behavior for the WebElement lookup if this is the case, but will also work if the standard behavior hasn’t been overridden.

possible_iframe_context(**kwds)[source]

Context manager for interacting with elements possibly in an iframe.

This is used to automatically handle switching the focus to an iframe before some actions are done, and then switching back to the default content frame (page) once those actions are completed.

This was made specifically for performing the repetitive task of managing switching focus to an iframe and back. This was also made to make sure that, should an exception be raised, focus is switched back to the default content without interferring with how the exception is handled, and without having to put a bunch of try/except/finally blocks everywhere.

remove_from_dom()[source]

Remove the element from the DOM.

wait_until(condition, timeout=10, **kwargs)[source]

Wait for up to the allotted time until the condition is met.

Args:
condition (str): The condition to be met. timout (int): The maximum number of seconds to wait before failing.
wait_until_not(condition, timeout=10, **kwargs)[source]

Wait for up to the allotted time until the condition is not met.

Args:
condition (str): The condition to not be met. timout (int): The maximum number of seconds to wait before failing.

pypcom.expected_conditions module

Custom expected conditions to wait for.

When using the wait_until or wait_until_not methods, if a certain condition can not be checked for with the standard set of expected conditions from Selenium, custom conditions and how to check for them should be defined here.

pypcom.expected_conditions.clickable(component, **kwargs)[source]
pypcom.expected_conditions.present(component, **kwargs)[source]
pypcom.expected_conditions.visible(component, **kwargs)[source]

pypcom.page module

This module just contains the base class for pages.

class pypcom.page.Page(driver)[source]

Bases: object

The base class for all pages.

This is the class that all pages should inherit from. Components of a page should be descriptors of the page’s class. Components that belong to other components should not be included as descriptors for the page’s class. For example, a ‘username’ component should be a descriptor for a ‘login_form’ component, and the ‘login_form’ component should be a descriptor of the page, so the ‘username’ component shouldn’t be a descriptor of the page as well.

Attributes:
driver (WebDriver): WebDriver to be used for element lookups and page
interactions.

Module contents

class pypcom.Page(driver)[source]

Bases: object

The base class for all pages.

This is the class that all pages should inherit from. Components of a page should be descriptors of the page’s class. Components that belong to other components should not be included as descriptors for the page’s class. For example, a ‘username’ component should be a descriptor for a ‘login_form’ component, and the ‘login_form’ component should be a descriptor of the page, so the ‘username’ component shouldn’t be a descriptor of the page as well.

Attributes:
driver (WebDriver): WebDriver to be used for element lookups and page
interactions.
class pypcom.PageComponent[source]

Bases: object

The base class for all page components.

This is the class that all page components should inherit from. Components are meant to represent a specific element on a page, and aren’t a direct reference to the WebElement itself. Instead, an attempt to get the WebElement is only ever made if a reference is made to an attribute of the component that it doesn’t have defined itself (see __getattr__ for details).

If a reference is made to an attribute of the component that the component doesn’t have, then the component’s _locator attribute is used to get the WebElement, and the attribute lookup is deferred to the WebElement. For example, if a reference is made to the text attribute of component x, and component x doesn’t have a text attribute defined for it, then x gets its WebElement and gets the text attribute of it.

If the component has no _locator attribute, an exception is raised stating that the component cannot be referenced as an element without one.

If the WebElement can’t be found, an exception is raised stating so.

If the WebElement is found, but it doesn’t have the attribute initially referenced, then an exception is raised stating that the component (not the WebElement) doesn’t have that attribute. All WebElements have a static set of attributes, so it’s assumed that any referenced attributes that aren’t part of that set are meant to be defined for that component, and if the lookup for it failed in this way, it was because it wasn’t properly defined in the component’s class.

Components must be descriptors of their owner pages’/components’ classes. They can be made to be subcomponents of other components to create a tree of ownership, accessed through dot-notation. If a component is a manager of another component, it can still have its own _locator, which allows it to be treated as an element.

For example, a ‘username’ component could belong to a ‘login_form’ component, and the ‘login_form’ component could belong to the page. In order to reference the ‘username’ component, you would say:

page.login_form.username

If you want to find the WebElement of the PageComponent by searching from its parent component’s element, give the component the _find_from_parent attribute and set it to True.

Attributes:
_locator (tuple of str): The locator method and value to
find the WebElement.
driver (WebDriver): WebDriver to be used for element lookups and page
interactions.
_parent (PageComponent): The instance of the manager class for this
component.
_find_from_parent (bool): Whether or not to used the parent
component’s element as the jumping off point to find the element from.
css

CSS properties.

Lookups can be defined manually for nuanced control over what is returned, but if not defined manually, the attribute being looked up will be passed as a string to the value_of_css_property method of the manager class’s WebElement. If the property’s name can’t be treated as a Python variable name, the name can be passed as a string to the get() method.

iframe_ancestor

First ancestor PageComponent that is of type Iframe.

Walk up through the PageComponent’s ancestors, checking for one that is of type Iframe. If one is found, return it. If none are found, return None.

This also caches the ancestor the first time it’s searched for (as it shouldn’t be changing), which will speed up further references to it.

is_present()[source]

Query the element to find if it is present or not.

Make a call to is_displayed to force a lookup of the element. If a NoSuchElementException is raised, then the element is not present, and False is returned. Otherwise, True is returned. Only a NoSuchElementException is checked for so that other exceptions can still be raised as they shoud be.

A call to is_displayed is made, because some behavior of the PageComponent may have been overridden which might cause a reference to self._el to not actually make a reference to the WebElement itself. Making a call to is_displayed should trigger any new behavior for the WebElement lookup if this is the case, but will also work if the standard behavior hasn’t been overridden.

possible_iframe_context(**kwds)[source]

Context manager for interacting with elements possibly in an iframe.

This is used to automatically handle switching the focus to an iframe before some actions are done, and then switching back to the default content frame (page) once those actions are completed.

This was made specifically for performing the repetitive task of managing switching focus to an iframe and back. This was also made to make sure that, should an exception be raised, focus is switched back to the default content without interferring with how the exception is handled, and without having to put a bunch of try/except/finally blocks everywhere.

remove_from_dom()[source]

Remove the element from the DOM.

wait_until(condition, timeout=10, **kwargs)[source]

Wait for up to the allotted time until the condition is met.

Args:
condition (str): The condition to be met. timout (int): The maximum number of seconds to wait before failing.
wait_until_not(condition, timeout=10, **kwargs)[source]

Wait for up to the allotted time until the condition is not met.

Args:
condition (str): The condition to not be met. timout (int): The maximum number of seconds to wait before failing.
pypcom.PC

alias of pypcom.component.PageComponent

class pypcom.State(*expected_attributes)[source]

Bases: object

The expected state of the object being checked.

Instances of this class can be created with multiple expected attributes to be checked against the test subject object all at once when compared through __eq__. For each expected attribute that is passed, each will be utilized even if others had problems. When all are used, the State object will check their results and return True if all passed, or False if any had a problem.

Each expected attribute is responsible for handling the logic for how to compare against the test subject. If they find a problem, they are responsible for storing that problem in their self._problems list through their self.add_problem method, which the State object will check through their self.get_problems method once it has used all of its expected attributes. The expected attributes can also just raise an AssertionError in their compare method, and the State object will catch it and include it in the reported problems.

When the State has all the reported problems, it will bundle them up into a readable string accessed through self.get_report(), so they can all be reported as one failure. This is meant for pytest to access during its pytest_assertrepr_compare hook, so that a readable representation of the failure can be provided.

Here’s an example of how it can be used:

def test_my_component(self, page):
    assert page.component.my_form.my_input == State(
        IsPresent(),
        IsDisplayed(),
        IsEnabled(),
        TagName("input"),
        Type("text"),
    )
add_problems_of_attr(attr)[source]

Grab and store the reported problems of the ExpectedAttribute.

These will be used later to generate a proper failure message for pytest to show in its output. This structure helps make iteration and truthy evaluation easier.

Args:
attr (obj): The ExpectedAttribute to pull the problems from.
get_pytest_failure_report_messages()[source]

Get a list of all the report messages from all the problems.

This is designed to be flexible, so that custom problems, or custom ways for ExpectedAttribute to report their problems can easily be made.

For ExpectedAttribute objects, this will look for a get_report_messages method, and will add whatever it returns to the list of report messages for this State. It expects a list/tuple of strings, but can handle a single string. If it doesn’t have such a method, this will just look at each problem associated with it.

get_pytest_failure_report_repr()[source]

Get the failure report repr for pytest to display in its output.

Run through all the stored problems and their associated ExpectedAttribute``s, and buld the failure message that ``pytest will show in its output. For each problem of each associated ExpectedAttribute, there will be a line showing the ExpectedAttribute’s name and the problem’s message. For example:

Comparing AboutLink State:
    Text: "Contact Us" != "About Us"
    Href: "https://mysite.com/contact" != "https://mysite.com/about"

This is designed to allow flexibility in what shows up in the failure message.