Skip to content

#

This is the latest development version

Some features documented on this page may not yet be available in the published stable version.

All = Collection module-attribute #

AllElements = Collection module-attribute #

R = TypeVar('R') module-attribute #

Assertable #

Bases: ABC

should(condition) abstractmethod #

Collection #

Bases: _WaitingConfiguredEntity, Iterable[Element]

_locator = locator instance-attribute #

cached: Collection property #

even property #

A human-readable alias to [1::2], i.e. filtering collection to have only even elements

first: Element property #

A human-readable alias to .element(0) or [0]

odd property #

A human-readable alias to [::2], i.e. filtering collection to have only odd elements

second: Element property #

A human-readable alias to .element(1) or [1]

shadow_roots: Collection property #

all(selector) #

Returns a collection of all elements found be selector inside each element of self

An alias to collection.collected(lambda its: its.all(selector)).

Example#

Given html::

<table>
  <tr class="row">
    <td class="cell">A1</td><td class="cell">A2</td>
  </tr>
  <tr class="row">
    <td class="cell">B1</td><td class="cell">B2</td>
  </tr>
</table>

Then::

browser.all('.row').all('.cell')).should(have.texts('A1', 'A2', 'B1', 'B2'))

all_first(selector) #

Returns a collection of each first element found be selector inside each element of self

An alias to collection.collected(lambda its: its.element(selector)). Not same as collection.all(selector).first that is same as collection.first.element(selector)

Example#

Given html::

<table>
  <tr class="row">
    <td class="cell">A1</td><td class="cell">A2</td>
  </tr>
  <tr class="row">
    <td class="cell">B1</td><td class="cell">B2</td>
  </tr>
</table>

Then::

browser.all('.row').all_first('.cell')).should(have.texts('A1', 'B1'))

by(condition) #

by_their(selector, condition) #

Returns elements from collection that have inner/relative element, found by selector and matching condition.

Is a shortcut for collection.by(lambda element: condition(element.element(selector)).

Example (straightforward)#

GIVEN html elements somewhere in DOM:: .result .result-title .result-url .result-snippet

THEN::

browser.all('.result')                .by_their('.result-title', have.text('Selene'))                .should(have.size(3))

is similar to::

browser.all('.result')                .by_their(lambda it: have.text(text)(it.element('.result-title')))                .should(have.size(3))
Example (PageObject)#

GIVEN html elements somewhere in DOM:: .result .result-title .result-url .result-snippet

AND::

results = browser.all('.result')
class Result:
    def __init__(self, element):
        self.element = element
        self.title = self.element.element('.result-title')
        self.url = self.element.element('.result-url')
# ...

THEN::

results.by_their(lambda it: Result(it).title, have.text(text))                .should(have.size(3))

is similar to::

results.by_their(lambda it: have.text(text)(Result(it).title))                .should(have.size(3))

collected(finder) #

element(index) #

element_by(condition) #

element_by_its(selector, condition) #

Returns element from collection that has inner/relative element found by selector and matching condition. Is a shortcut for collection.element_by(lambda its: condition(its.element(selector)).

Example (straightforward)#

GIVEN html elements somewhere in DOM::

.result
    .result-title
    .result-url
    .result-snippet

THEN::

browser.all('.result')                .element_by_its('.result-title', have.text(text))                .element('.result-url').click()

... is a shortcut for::

browser.all('.result')                .element_by(lambda its: have.text(text)(its.element('.result-title')))                .element('.result-url').click()
Example (PageObject)#

GIVEN html elements somewhere in DOM::

.result
    .result-title
    .result-url
    .result-snippet

AND::

results = browser.all('.result')
class Result:
    def __init__(self, element):
        self.element = element
        self.title = self.element.element('.result-title')
        self.url = self.element.element('.result-url')

THEN::

Result(results.element_by_its(lambda it: Result(it).title, have.text(text)))                .url.click()

is a shortcut for::

Result(results.element_by(lambda it: have.text(text)(Result(it).title)))                .url.click()
# ...

filtered_by(condition) #

from_(start) #

locate() #

sliced(start=None, stop=None, step=1) #

to(stop) #

with_(config=None, **config_as_kwargs) #

Element #

Bases: _LocatableEntity[WebElement], _WaitingConfiguredEntity

_actual_not_overlapped_webelement property #

cached: Element property #

frame_context: _FrameContext property #

A context manager to work with frames (iframes). Has an additional decorator to adapt context manager to step-methods when implementing a PageObject pattern. Partially serves as entity similar to Element allowing to find element or collection inside frame.

Technically it's a shortcut to _FrameContext(element) and also is pretty similar to element.get(_FrameContext) query. Find more details in the _FrameContext docs.

shadow_root: _ElementsContext property #

wait: Wait[Element] property #

_actual_visible_webelement_and_maybe_its_cover(center_x_offset=0, center_y_offset=0) #

_log_webelement_outer_html_for(element) staticmethod #

all(css_or_xpath_or_by) #

clear() #

Clears the text in a text-like field element.

Can be customized via config.wait_for_no_overlap_found_by_js

click(*, xoffset=0, yoffset=0) #

Just a normal click with optional offset:)

By default, if not offset is asked, will wait till the element is not covered by any other element like overlays, because this is a pure Selenium WebDriver behavior.

If you start specifying offsets, then, if you still want to wait for no overlap, you should explicitly ask for it via setting to True the config.wait_for_no_overlap_found_by_js.

If you want to simulate a click via JS, by turning on the config.click_by_js, then unless #566 issue is resolved, you can't wait for no overlap. After you can use something like: browser.element('#save').should(be.not_overlapped).with_(click_by_js=True).click()

context_click() #

Context clicks (aka right-click to open a popup menu) on the element.

Can be customized via config.wait_for_no_overlap_found_by_js.

copy() #

Sends «copy» OS-based keys shortcut.

See more at command.copy, that can be also applied on a "browser" level, without specifying the exact element to send shortcut to.

See also "all scenarios to work with clipboard"

double_click() #

Double clicks on the element.

Can be customized via config.wait_for_no_overlap_found_by_js.

drag_and_drop_by_offset(x, y) #

Drags the element by the offset.

Currently, cannot be customized via config.drag_and_drop_by_js (wait for #568).

See more at command.drag_and_drop_by_offset.

drag_and_drop_to(target, /, *, _assert_location_changed=False) #

Drags the element to the target element.

Can be customized via config.drag_and_drop_by_js. Though turning the config flag on will disable the _assert_location_changed feature (wait for #567).

See more at command.drag_and_drop_to. See also command.js.drag_and_drop_to.

drop_file(path) #

Simulates via JS: drops file by absolute path to the element (self). Usually is needed as a workaround for cases where there is no input[type=file] available to send_keys with path to the file. Prefer the send_keys method if possible. See also #569

See more at command.js.drop_file.

element(css_or_xpath_or_by) #

execute_script(script_on_self, *arguments) #

Executes JS script on self as webelement.

The script can use predefined parameters: - element and self are aliases to this element handle, i.e. self.locate() or self(). - arguments are accessible from the script with same order and indexing as they are provided to the method

Examples:

browser.element('[id^=google_ads]').execute_script('element.remove()')
# OR
browser.element('[id^=google_ads]').execute_script('self.remove()')
'''
# are shortcuts to
browser.execute_script('arguments[0].remove()', browser.element('[id^=google_ads]')())
'''
browser.element('input').execute_script('element.value=arguments[0]', 'new value')
# OR
browser.element('input').execute_script('self.value=arguments[0]', 'new value')
'''
# are shortcuts to
browser.execute_script('arguments[0].value=arguments[1]', browser.element('input').locate(), 'new value')
'''

hover() #

Hovers over the element.

Can be customized via config.wait_for_no_overlap_found_by_js.

locate() #

paste(text=None) #

Sends «paste» OS-based keys shortcut.

If text argument is provided, will copy it to clipboard before sending the keys shortuct.

See more at command.paste, that can be also applied on a "browser" level, without specifying the exact element to send shortcut to.

See also "all scenarios to work with clipboard"

press(*keys) #

Simulates pressing keys on the element. A human readable alternative to pure Selenium's send_keys method.

Can be customized via config.wait_for_no_overlap_found_by_js.

press_enter() #

press_escape() #

press_sequentially(text) #

Presses each key (letter) in text sequentially to the element.

See more at command.press_sequentially.

press_tab() #

s(css_or_xpath_or_by) #

A JQuery-like alias (~ $) to Element.element(selector_or_by).

scroll_to_bottom() #

Simulates via JS: scrolls to an element so the bottom of the element will be aligned to the bottom of the visible area of the scrollable ancestor.

See also command.scroll_into_view.

scroll_to_center() #

Simulates via JS: scrolls to an element so the center of the element will be aligned to the center of the scrollable ancestor.

See also command.scroll_into_view.

scroll_to_top() #

Simulates via JS: scrolls to an element so the top of the element will be aligned to the top of the visible area of the scrollable ancestor.

See also command.scroll_into_view.

select_all() #

Sends «select all» keys shortcut as ctrl+a for Win/Linux or cmd+a for mac.

See more at command.select_all, that can be also applied on a "browser" level, without specifying the exact element to send shortcut to.

Has no "by_js" version so far (see #572)

send_keys(*value) #

To be used for more low level operations like «uploading files», etc. To simulate normal input of keys by user when typing - consider using Element.type(self, text) that has additional customizaton to wait for the element to be not overlapped by other elements.

set(value) #

Sounds similar to Element.set_value(self, value), but considered to be used in broader context. For example, a use can say «Set gender radio to Male» but will hardly say «Set gender radio to value Male». Now imagine, on your project you have custom html implementation of radio buttons, and want to teach selene to set such radio-button controls – you can do this via Element.set(self, value) method, after monkey-patching it according to your behavior;)

set_value(value) #

ss(css_or_xpath_or_by) #

A JQuery-like alias (~ $$) to Element.all(selector_or_by).

submit() #

Submits a form-like element.

Can be customized via config.wait_for_no_overlap_found_by_js.

type(text) #

Simulates typing text into a text-like field element. A human readable alternative to pure Selenium's send_keys method.

Will wait till the element is not covered by any other element like overlays, if config.wait_for_no_overlap_found_by_js is set to True.

with_(config=None, **config_as_kwargs) #

_ElementsContext #

Bases: _LocatableEntity[_SearchContext], _WaitingConfiguredEntity

An Element-like class that serves as pure context for search elements inside via element(selector_or_by) or all(selector_or_by) methods

cached: _ElementsContext property #

wait: Wait[_ElementsContext] property #

all(selector_or_by) #

element(selector_or_by) #

locate() #

with_(config=None, **config_as_kwargs) #

_FrameContext #

A context manager to work with frames (iframes). Has an additional decorator to adapt context manager to step-methods when implementing a PageObject pattern.

Partially serves as entity similar to Element allowing to find element or collection inside frame and work with them with implicit automatic "switch into context" before any action and "switch out" after it. But this ability may reduce performance in case of "too much of actions" inside a frame. In such cases, it's better to use explicit context manager.

Note

There is a query.frame_context alias to this class, because it can be used as "pseudo-query": element.get(query.frame_context).

This context manager is already built into selene.web.Element entity, That's why in the majority of examples below you will see element.frame_context instead of _FrameContext(element) or element.get(_FrameContext).

Laziness on query application#

On element.get(query.frame_context) (or element.frame_context) it actually just wraps an element into context manager and so is lazy, i.e. you can store result of such query into a variable even before opening a browser and use it later. Thus, unlike for other queries, there is no difference between using the query directly as query.frame_context(element) or via get method as element.get(query.frame_context).

The "lazy result" of the query is also a "lazy search context" similar to Element entity – it allows to find elements or collections inside the frame by using self.element(selector) or self.all(selector) methods. This allows the easiest and most implicit way to work with frames in Selene without bothering about switching to the frame and back:

Example: Using as "search context" with fully implicit frame management#
from selene import browser, command, have, query
...
# iframe = _FrameContext(browser.element('#editor-iframe'))
# OR:
# iframe = query.frame_context(browser.element('#editor-iframe'))
# OR:
# iframe = browser.element('#editor-iframe').get(_FrameContext)
# OR:
# iframe = browser.element('#editor-iframe').get(query.frame_context)
# OR:
iframe = browser.element('#editor-iframe').frame_context
iframe.all('strong').should(have.size(0))
iframe.element('.textarea').type('Hello, World!').perform(command.select_all)
browser.element('#toolbar').element('#bold').click()
iframe.all('strong').should(have.size(1))

Warning

But be aware that such syntax will force to switch to the frame and back for each command executed on element or collection of elements inside the frame. This might result in slower tests if you have a lot of commands to be executed all together inside the frame.

Tip

We recommend to stay YAGNI and use this "frame like an element context" syntax by default, but when you notice performance drawbacks, consider choosing an explicit way to work with frame context as a context manager passed to with statement or as a decorator within applied to step-methods of PageObject as described below.

Laziness ends on with statement#

On passing the "lazy result" of the query to with statement it actually transforms from "lazy query" into "actual command", that performs an action on the entity – the action of switching to the element's frame with the corresponding implicit waiting.

On exiting the with statement it switches back to the default content, without any additional implicit waiting. This behavior might change in the future, and some waiting might be added.

Example: Straightforward usage of the frame context (in with statement):#

from selene import browser, query, command, have

toolbar = browser.element('.tox-toolbar__primary')
text_area_frame = browser.element('.tox-edit-area__iframe')
# the following var will only work if used after the switch to the frame ↙️
text_area = browser.element('#tinymce')  # ❗️ inside the frame

browser.open('https://the-internet.herokuapp.com/iframe')

with text_area_frame.frame_context:
    text_area.perform(command.select_all)

toolbar.element('[title=Bold]').click()

with text_area_frame.frame_context:
    text_area.element('p').should(
        have.js_property('innerHTML').value(
            '<strong>Your content goes here.</strong>'
        )
    )

Example: Usage utilizing the lazy nature of the frame context (in with statement)#

from selene import browser, query, command, have

toolbar = browser.element('.tox-toolbar__primary')
text_area_frame = browser.element('.tox-edit-area__iframe')
text_area_frame_context = text_area_frame.frame_context  # 💡↙️
# the following var will only work if used after the switch to the frame
text_area = browser.element('#tinymce')  # ❗️ inside the frame

browser.open('https://the-internet.herokuapp.com/iframe')

with text_area_frame_context:  # ⬅️
    text_area.perform(command.select_all)

toolbar.element('[title=Bold]').click()

with text_area_frame_context:  # ⬅️
    text_area.element('p').should(
        have.js_property('innerHTML').value(
            '<strong>Your content goes here.</strong>'
        )
    )

Example: Usage utilizing the lazy nature of the query without get method:#

Since the query application is fully lazy (laziness ends only on with statement), you can use it directly, without get method:

from selene import browser, query, command, have

toolbar = browser.element('.tox-toolbar__primary')
text_area_frame = browser.element('.tox-edit-area__iframe')
# text_area_frame_context = _FrameContext(text_area_frame)
# OR:
text_area_frame_context = query.frame_context(text_area_frame)  # 💡↙️
# the following var will only work if used after the switch to the frame
text_area = browser.element('#tinymce')

browser.open('https://the-internet.herokuapp.com/iframe')

with text_area_frame_context:  # ⬅️
    text_area.perform(command.select_all)

toolbar.element('[title=Bold]').click()

with text_area_frame_context:  # ⬅️
    text_area.element('p').should(
        have.js_property('innerHTML').value(
            '<strong>Your content goes here.</strong>'
        )
    )

Example: Nested with statements for nested frames#

from selene import browser, have, query, be

# GIVEN opened browser
browser.open('https://the-internet.herokuapp.com/nested_frames')

# WHEN
with browser.element('[name=frame-top]').frame_context:
    with browser.element('[name=frame-middle]').frame_context:
        browser.element(
            '#content',
            # THEN
        ).should(have.exact_text('MIDDLE'))
    # AND
    browser.element('[name=frame-right]').should(be.visible)

Example: Usage utilizing the within decorator for PageObjects:#

See example at within section.

_container = element instance-attribute #

within = decorator class-attribute instance-attribute #

An alias to decorator

Example of usage:

from selene import browser, command, have, query


def teardown_function():
    browser.quit()


class WYSIWYG:
    toolbar = browser.element('.tox-toolbar__primary')
    text_area_frame = browser.element('.tox-edit-area__iframe').frame_context  # 💡⬇️
    text_area = browser.element('#tinymce')

    def open(self):
        browser.open('https://the-internet.herokuapp.com/iframe')
        return self

    def set_bold(self):
        self.toolbar.element('[title=Bold]').click()
        return self

    @text_area_frame.within  # ⬅️
    def should_have_text_html(self, text_html):
        self.text_area.should(have.js_property('innerHTML').value(text_html))
        return self

    @text_area_frame.within  # ⬅️
    def select_all_text(self):
        self.text_area.perform(command.select_all)
        return self

    @text_area_frame.within  # ⬅️
    def reset_to(self, text):
        self.text_area.perform(command.select_all).type(text)
        return self


def test_page_object_steps_within_frame_context():
    wysiwyg = WYSIWYG().open()

    wysiwyg.should_have_text_html(
        '<p>Your content goes here.</p>',
    ).select_all_text().set_bold().should_have_text_html(
        '<p><strong>Your content goes here.</strong></p>',
    )

    wysiwyg.reset_to('New content').should_have_text_html(
        '<p><strong>New content</strong></p>',
    )

all(selector) #

Allows to search for all elements by selector inside the frame context with implicit switching to the frame and back for each method execution.

Is lazy, i.e. does not switch to the frame immediately on calling this method, and so can be stored in a variable and used later.

Parameters:

  • selector (str | Tuple[str, str]) –

    css or xpath as string or classic selenium tuple-like locator, e.g. ('css selector', '.some-class') or (By.CSS_SELECTOR, '.some-class')

Warning

Same "potential performance drawbacks" warning is applied here as for element method.

decorator(func) #

A decorator to mark a function as a step within context manager

See example of usage at within section.

element(selector) #

Allows to search for a first element by selector inside the frame context with implicit switching to the frame and back for each method execution.

Is lazy, i.e. does not switch to the frame immediately on calling this method, and so can be stored in a variable and used later.

Parameters:

  • selector (str | Tuple[str, str]) –

    css or xpath as string or classic selenium tuple-like locator, e.g. ('css selector', '.some-class') or (By.CSS_SELECTOR, '.some-class')

Warning

By adding implicit switching to the frame and back for each command executed on entity, it makes the usage of such entity slower in case of a lot of commands to be executed all together inside the frame.

It becomes especially important in case of nested frames. In such cases, if you use entity.get(query.frame_context) over query.frame_context(entity) or entity.frame_context then try to keep turned on the option: config._disable_wait_decorator_on_get_query That will help to avoid re-switching at least on get calls.

If you notice performance drawbacks, consider choosing an explicit way to work with frame context as a context manager passed to with statement.

_SearchContext #

Bases: Protocol

find_element(by, value=None) #

find_elements(by, value=None) #