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 theget()
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 thetext
attribute of componentx
, and componentx
doesn’t have atext
attribute defined for it, thenx
gets its WebElement and gets thetext
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 toTrue
.- Attributes:
- _locator (
tuple
ofstr
): 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.
- _locator (
-
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 theget()
method.
-
iframe_ancestor
¶ First ancestor
PageComponent
that is of typeIframe
.Walk up through the
PageComponent
’s ancestors, checking for one that is of typeIframe
. If one is found, return it. If none are found, returnNone
.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 aNoSuchElementException
is raised, then the element is not present, andFalse
is returned. Otherwise,True
is returned. Only aNoSuchElementException
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 thePageComponent
may have been overridden which might cause a reference toself._el
to not actually make a reference to theWebElement
itself. Making a call tois_displayed
should trigger any new behavior for theWebElement
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.
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.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 thetext
attribute of componentx
, and componentx
doesn’t have atext
attribute defined for it, thenx
gets its WebElement and gets thetext
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 toTrue
.- Attributes:
- _locator (
tuple
ofstr
): 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.
- _locator (
-
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 theget()
method.
-
iframe_ancestor
¶ First ancestor
PageComponent
that is of typeIframe
.Walk up through the
PageComponent
’s ancestors, checking for one that is of typeIframe
. If one is found, return it. If none are found, returnNone
.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 aNoSuchElementException
is raised, then the element is not present, andFalse
is returned. Otherwise,True
is returned. Only aNoSuchElementException
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 thePageComponent
may have been overridden which might cause a reference toself._el
to not actually make a reference to theWebElement
itself. Making a call tois_displayed
should trigger any new behavior for theWebElement
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.
-
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, theState
object will check their results and returnTrue
if all passed, orFalse
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 theirself.add_problem
method, which theState
object will check through theirself.get_problems
method once it has used all of its expected attributes. The expected attributes can also just raise anAssertionError
in theircompare
method, and theState
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 throughself.get_report()
, so they can all be reported as one failure. This is meant for pytest to access during itspytest_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 aget_report_messages
method, and will add whatever it returns to the list of report messages for thisState
. It expects alist
/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 associatedExpectedAttribute
, there will be a line showing theExpectedAttribute
’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.
-