Robot’s Functionality

These are the functions which allow the robot to interact with the environment.

aiviro.BaseRobot

class aiviro.core.robots.BaseRobot(runner_manager: aiviro.core.robots.robot_base.T, config: GlobalConfig, pause: bool = False)

Robot for UI automation of various applications. This class cannot be instantiated by itself, it only provides base functionality for DynamicRobot and StaticRobot.

see_color(expected_color: aiviro.core.utils.search_objects.other.Color, assert_not: bool = False) None

Checks if color is on screen. It is used to determine if a certain color is present on the screen or in current working area.

Parameters
  • expected_color – The color we wish to examine.

  • assert_not – If set to True exception is thrown when the color is NOT present.

Raises

CheckCommandError – If check was not successful

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.see_color(aiviro.Color(255, 255, 255)) # white color is present no assert is triggered
>>> r.see_color(aiviro.Color(255, 0, 0)) # red color is not present assert is triggered
CheckCommandError: Expected color is not on screen
>>> r.see_color(aiviro.Color(255, 255, 255), True) # second parameter reverses exception triggers
CheckCommandError: Expected color is on screen
>>> r.see_color(aiviro.Color(255, 0, 0), True)
get_working_area() Optional[BoundBox]

Get currently set working-area.

Returns

BoundBox or None, representing current working-area

Example

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> with r.set_working_area(aiviro.Area(200, 300, 500, 600)):
...     wa_box = r.get_working_area()
set_working_area(area: Optional[SearchObjectArea], check_stability_outside: bool = False) AbstractContextManager

Defines a working area for the tester.

Working area is an area in which it is supposed to look for elements to interact with. Using a working area limits the scope of elements with which subsequent commands work with, making them more easily identifiable, reducing naming ambiguity and avoiding confusion other similar elements.

Parameters
  • area – Elements or Area which subsequent commands will work with.

  • check_stability_outside – If True, it checks screen stability outside the provided working area

Returns

Context manager which can be used with pythons with.

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> an_area = aiviro.Area(200, 400, 200, 400)
>>> r.set_working_area(an_area)  # Sets the working area according the variable.
>>> r.set_working_area(None)  # Reset the working area to default.
>>> with r.set_working_area(an_area) as wa: # Inside the with statement the working area is set.
...     print(wa)  # created area can be accessed via `as` statement
...     # Area(200, 400, 200, 400)
...     # some code ...
... # After the with block ends than the working are is reverted to previous state.
>>> with r.set_working_area(aiviro.BoundaryArea(
...     aiviro.Button("Login"),
...     aiviro.Button("Cancel"),
...     aiviro.boundary_type.EXCLUDE_FIRST.RIGHT_EDGE
... )) as wa:
...     # some code ...
set_working_area_by_boundaries(first_boundary: Optional[SearchObjectArea] = None, second_boundary: Optional[SearchObjectArea] = None, check_stability_outside: bool = False, method: aiviro.core.constants.ui_constants.BoundaryType = BoundaryType.DEFAULT) AbstractContextManager

Defines a working area for the tester based on an area computed from two boundaries.

Working area is an area in which it is supposed to look for elements to interact with. Using a working area limits the scope of elements with which subsequent commands work with, making them more easily identifiable, reducing naming ambiguity and avoiding confusion other similar elements.

Parameters
  • first_boundary – First boundary box area, from which the total working area is computed. Can be None but at least one boundary must be set.

  • second_boundary – Second boundary box area, from which the total working area is computed. Can be None but at least one boundary must be set.

  • check_stability_outside – If True, it checks screen stability outside the provided working area

  • method – Method how the working area is calculated. Default calculation creates box encasing both supplied boundary boxes. Other options can be found at BoundaryType

Returns

Context manager which can be used with pythons with.

Attention

This method is deprecated, and will be removed in future version.
Please use instead set_working_area() method with BoundaryArea search-object as argument.
set_working_area_by_grid(row_area: SearchObjectArea, col_area: SearchObjectArea, max_width: int = 0, max_height: int = 0, check_stability_outside: bool = False) AbstractContextManager

Defines a working area for the robot based on an area computed from two coordinate areas x and y.

Working area is an area in which it is supposed to look for elements to interact with. Using a working area limits the scope of elements with which subsequent commands work with, making them more easily identifiable, reducing naming ambiguity and avoiding confusion other similar elements.

Working area by grid should be mainly used for recognition in tables, forms or wherever you need to interact with information which is in a grid bounded by grid lines. If the table has no lines, or you want to use it on non-grid screen you need to set max_width and max_height in order to limit the lookup.

Parameters
  • row_area – Boundary box area for grid row.

  • col_area – Boundary box area for grid column.

  • max_width – Used to limit the size of the lookup for column width. Default=0 which covers the entire area of the column. Caution if the element has no distinct limits it can expand to the whole screen.

  • max_height – Used to limit the size of the lookup for row height. Default=0 which covers the entire area of the row. Caution if the element has no distinct limits it can expand to the entire screen.

  • check_stability_outside – If True, it checks screen stability outside the provided working area

Returns

Context manager which can be used with pythons with.

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> # Let's look on the website https://examples.bootstrap-table.com/#welcomes/from-data.html
>>> r.go_to_url("https://examples.bootstrap-table.com/#welcomes/from-data.html")
>>> # We want to get price for item 2, so we need to have column as `Item Price` and row as `Item 2`
>>> with r.set_working_area_by_grid(aiviro.Text("Item 2"),aiviro.Text("Item Price")):
...     result = r.get(aiviro.Text(""))
>>> print(result)
<BoundBox TEXT [1221, 414],[1236, 428] '$ 2'/>
>>> # If the table borders are not well-defined we need to use max_width and max_height
>>> r.go_to_url("https://getbootstrap.com/docs/4.0/content/tables/#examples")
>>> with r.set_working_area_by_grid(
...     aiviro.Text("Jacob", element_index=0),
...     aiviro.Text("Last", element_index=0),
...     max_width=150,
...     max_height=30,
... ):
...     result = r.get(aiviro.Text(""))
>>> print(result)
<BoundBox TEXT [800, 412],[861, 428] 'Thornton'/>
set_working_area_as_intersection(first_area: SearchObjectArea, second_area: SearchObjectArea, *areas: SearchObjectArea, check_stability_outside: bool = False) AbstractContextManager

Defines a working area for the tester which is computed as an intersection of the input objects.

Working area is an area in which it is supposed to look for elements to interact with. Using a working area limits the scope of elements with which subsequent commands work with, making them more easily identifiable, reducing naming ambiguity and avoiding confusion other similar elements.

Parameters
  • first_area – Area, from which the total intersection working area is computed.

  • second_area – Area, from which the total intersection working area is computed.

  • areas – List of additional areas, from which the total intersection working area is computed.

  • check_stability_outside – If True, it checks screen stability outside the provided working area

Returns

Context manager which can be used with pythons with.

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.set_working_area_as_intersection(aiviro.Button("Login"), aiviro.Button("Cancel"))
>>> r.set_working_area(None)  # Reset the working area to default.
>>> with r.set_working_area_as_intersection(aiviro.Button("Login"), aiviro.Button("Cancel")):
...     # After the with block ends the working area is reverted to previous state.
add_working_area_checkpoint(checkpoint_name: str, use_full_screen: bool = False, overwrite: bool = True) None

Save actual state of the display (screenshot) as working-area checkpoint by its name.

Parameters
  • checkpoint_name – Name of the checkpoint under which the screenshot will be saved.

  • use_full_screen – If True, full screen is used for checkpoint screenshot, even if working area is set

  • overwrite – If False, an exception will be raised if the checkpoint already exists.

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.add_working_area_checkpoint("submit-form")
>>> r.click(aiviro.Button("Submit"))
>>> # modal window opens
>>> with r.set_working_area_by_checkpoint("submit-form"):
...     r.click(aiviro.Button("OK"))  # click OK button in the modal window
set_working_area_by_checkpoint(checkpoint_name: str, use_full_screen: bool = False, check_stability_outside: bool = False) AbstractContextManager

Defines a working area for the tester which is computed as a difference between current image & checkpoint image. Several working-areas can be detected, always the closest one to the center of the display is selected.

Parameters
  • checkpoint_name – Name of the checkpoint to use for computing the area.

  • use_full_screen – If True, full screen is used for current image, even if working area is set

  • check_stability_outside – If True, it checks screen stability outside the provided working area

Returns

Context manager which can be used with pythons with.

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.add_working_area_checkpoint("submit-form")
>>> r.click(aiviro.Button("Submit"))
>>> # modal window opens
>>> with r.set_working_area_by_checkpoint("submit-form"):
...     r.click(aiviro.Button("OK"))  # click OK button in the modal window
limit_working_area(limit_element: SearchObjectArea, top: Optional[aiviro.core.constants.ui_constants.WorkingAreaLimit] = None, bottom: Optional[aiviro.core.constants.ui_constants.WorkingAreaLimit] = None, left: Optional[aiviro.core.constants.ui_constants.WorkingAreaLimit] = None, right: Optional[aiviro.core.constants.ui_constants.WorkingAreaLimit] = None, check_stability_outside: bool = False) AbstractContextManager

Limits the currently set working-area, based on the provided options.

Parameters
  • limit_element – Object based on which area is limited.

  • top – If set to MIN, y_min from limit_object is used as top border of working-area. If set to MAX, y_max from limit_object is used. If None, top border stays unchanged.

  • bottom – If set to MAX, y_max from limit_object is used as bottom border of working-area. If set to MIN, y_min from limit_object is used. If None, bottom border stays unchanged.

  • left – If set to MIN, x_min from limit_object is used as left border of working-area. If set to MAX, x_max from limit_object is used. If None, left border stays unchanged.

  • right – If set to MAX, x_min from limit_object is used as right border of working-area. If set to MIN, x_min from limit_object is used. If None, right border stays unchanged.

  • check_stability_outside – If True, it checks screen stability outside the provided working area

Returns

Context manager which can be used with pythons with.

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.add_working_area_checkpoint("submit-form")
>>> r.click(aiviro.Button("Submit"))
>>> # modal window opens
>>> with r.set_working_area_by_checkpoint("submit-form"):
...     # limit working-area
...     with r.limit_working_area(
...         aiviro.Text('Limiting Text'),
...         right=aiviro.working_area_limit.MAX
...     ):
...         r.click(aiviro.Button("OK"))  # click OK button in the modal window
get_display_info() Area

Get size of the current display.

Returns

Area representing dimensions of the screen

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> # some code
>>> display_info = r.get_display_info()
>>> r.add_mask(
...     aiviro.Area(
...         0,
...         display_info.height - 30,
...         display_info.width,
...         display_info.height
...     )
... )
>>> # some code
get(*elements: SearchObjectArea, ignore_exception: bool = False, exception_to_raise: CUSTOM_EXCEPTION_TYPE = None) ManyListBoxOrListBoxOrBox

Gets elements from the current screen.

Parameters
  • elements – Elements to be searched for

  • ignore_exception – If True, SearchObjectError will not be thrown and method will return None

  • exception_to_raise – If set, it will be raised instead of SearchObjectError

Returns

Bounding boxes of the elements found in the screen

Example

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> bxs = r.get(aiviro.Text("Home"), aiviro.Text("Contact"), aiviro.Text("Blog"))
[BoundBox<'Home'>, BoundBox<'Contact'>, BoundBox<'Blog'>]
get_by_scroll(*elements: SearchObjectArea, scroll_function: Union[Callable[[], None], aiviro.core.constants.ui_constants.ScrollOption] = ScrollOption.MOUSE_DOWN, scroll_speed: int = 4, max_scrolls: int = 20, wait_between_scrolls: int = 0, exception_to_raise: Optional[Union[Type[Exception], Exception]] = None) ManyListBoxOrListBoxOrBox

Scrolls the screen down using supplied functions until it finds all elements. All supplied elements must be found on screen or this function ends with an exception

Parameters
  • elements – Elements to be searched for.

  • scroll_function – Scroll function which will be used when scrolling. For options are ScrollOption. You can also supply your own function which moves the screen. See examples.

  • scroll_speed – When using mouse scroll function how many “clicks” should be done each scroll.

  • max_scrolls – Maximum number of scrolling attempts.

  • wait_between_scrolls – Maximum number of seconds to wait for an element to appear. Used when application is slower than the scroll function.

  • exception_to_raise – If set, it will be raised instead of SearchObjectError

Raises

ScrollEndException – This exception is thrown when the screen isn’t changing anymore (could be end of document) or when the maximum scrolling attempts are reached.

Returns

Bounding boxes of the elements found in the screen.

Example

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> # Standard scroll down with default parameters
>>> r.get_by_scroll(aiviro.Text("Home"), aiviro.Text("Contact"), aiviro.Text("Blog"))
[BoundBox<'Home'>, BoundBox<'Contact'>, BoundBox<'Blog'>]
>>> # Scroll up instead of down
>>> r.get_by_scroll(aiviro.Text("Home"), scroll_function=aiviro.scroll_option.MOUSE_UP)
[BoundBox<'Home'>]
>>> # Scroll with own function using down-arrow
>>> def scroll_with_arrow():
...     r.key_press(aiviro.key.DOWN_ARROW)
...
>>> r.get_by_scroll(aiviro.Text("Home"), scroll_function=scroll_with_arrow)
[BoundBox<'Home'>]
>>> # The same function using lambda expression
>>> r.get_by_scroll(aiviro.Text("Home"), scroll_function=lambda: r.key_press(aiviro.key.DOWN_ARROW))
[BoundBox<'Home'>]

See also

get()

disable_cross_validation(enable: bool = False) AbstractContextManager

Disable cross-validation service, when looking for the UI elements.

Returns

Context manager which can be used with pythons with.

Example

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> with r.disable_cross_validation():
...     r.click(aiviro.Button("Animated Button"))
get_stable_screen() ndarray

Returns stable screenshot of the current display in opencv format (Blue, Green, Red channels)

get_current_screen() ndarray

Returns screenshot of the current display in opencv format (Blue, Green, Red channels)

set_animation_timeout(timeout: Optional[int]) AbstractContextManager

Sets a timeout for checking animations. If execution time exceeds this value then it will be interrupted and continue with current screen even if it is animating.

Parameters

timeout – Maximum number of seconds before interrupting the animation waiting. If None infinite waiting time. This is default value.

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.set_animation_timeout(20)  # if the screen is animating, wait 20 sec before proceeding further
>>> r.set_animation_timeout(0)   # wait 0 seconds for animation
>>> r.set_animation_timeout(None)  # wait until animation finished (can be infinite)
>>> with r.set_animation_timeout(10):
...     # some code
...     # in this block wait 10 sec on animation
get_animation_timeout() Optional[int]

Returns number of seconds to wait for changing screen to stabilize. If ‘None’ it’s infinite waiting time.

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.get_animation_timeout()
10
check_are_inside(*elements: SearchObjectArea, container: SearchObjectArea, strict: bool = False, assert_not: bool = False) List[BoundBox]

Check if all ‘elements’ are inside ‘container’. Method works like an assert statement.

Parameters
  • elements – List of bound boxes

  • container – Element representing container

  • strict – If True, every element must be at least 1 pixel smaller than ‘container’, in every direction

  • assert_not – If True, method check is tested in not statement. Reverse logic of the assert statement

Raises

CheckCommandError – If check was not successful

Returns

List of bound_boxes found in current screen, last box is the container

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.check_are_inside(aiviro.Text("Username"), container=aiviro.Input("Username"))
>>> r.check_are_inside(
...     aiviro.Input("Username"), aiviro.Input("Password"), container=aiviro.Area(0, 600, 200, 400)
... )
CheckCommandError ...
>>> r.check_are_inside(
...     aiviro.Input("Username"), aiviro.Input("Password"),
...     container=aiviro.Area(0, 600, 200, 400), assert_not=True
... )
check_are_similar_size(*elements: SearchObjectArea, max_delta_x: int, max_delta_y: int, assert_not: bool = False) ListBoxOrBox

Check if every element from ‘elements’ have similar size. Method works like an assert statement.

Parameters
  • elements – List of search objects

  • max_delta_x – Maximal difference in width between any element

  • max_delta_y – Maximal difference in height between any element

  • assert_not – If True, method check is tested in not statement

Raises

CheckCommandError – If check was not successful

Returns

List of bound_boxes found in current screen

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.check_are_similar_size(aiviro.Input("Username"), aiviro.Input("Password"))
>>> r.check_are_similar_size(aiviro.Input("Username"), aiviro.Input("Password"), assert_not=True)
CheckCommandError ...
check_have_size(*elements: SearchObjectArea, height: int, width: int, tolerance: int = 0, assert_not: bool = False) ListBoxOrBox

Check if ‘elements’ have expected ‘height’ & ‘width’. Method works like an assert statement.

Parameters
  • elements – List of search objects

  • height – Expected height

  • width – Expected width

  • tolerance – Maximal permitted deviation from height & width in pixel

  • assert_not – If True, method check is tested in not statement

Raises

CheckCommandError – If check was not successful

Returns

List of bound_boxes found in current screen

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.check_have_size(aiviro.Input("Username"), height=50, width=100) # Input is 55px so assert is thrown
CheckCommandError ...
>>> r.check_have_size(aiviro.Input("Username"), height=55, width=100)
>>> r.check_have_size(aiviro.Input("Username"), height=50, width=100, tolerance=5)
>>> r.check_have_size(aiviro.Input("Username"), height=50, width=100, tolerance=5, assert_not=True)
CheckCommandError ...
check_have_aspect_ratio(*elements: SearchObjectArea, expected_ratio: float, tolerance: float = 0, assert_not: bool = False) ListBoxOrBox

Check if ‘elements’ has expected width/height ‘expected_ratio’. Method works like an assert statement.

Parameters
  • elements – List of search objects

  • expected_ratio – Expected ratio of “width / height”

  • tolerance – Ratio must be in range <expected_ratio * (1 - tolerance); expected_ratio * (1 + tolerance)>

  • assert_not – If True, method check is tested in not statement

Raises

CheckCommandError – If check was not successful

Returns

List of bound_boxes found in current screen

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.check_have_aspect_ratio(aiviro.Input("Username"), expected_ratio=3) # Real ratio is 3.5
CheckCommandError ...
>>> r.check_have_aspect_ratio(aiviro.Input("Username"), expected_ratio=3.5)
>>> r.check_have_aspect_ratio(aiviro.Input("Username"), expected_ratio=3, tolerance=0.2)
>>> r.check_have_aspect_ratio(aiviro.Input("Username"), expected_ratio=3.5, assert_not=True)
CheckCommandError ...
check_are_in_column(*elements: SearchObjectArea, anchor: aiviro.core.constants.ui_constants.LayoutAnchor, tolerance: int = 0, assert_not: bool = False) ListBoxOrBox

Check if ‘elements’ are aligned vertically in one column. Method works like an assert statement.

Parameters
  • elements – List of search objects

  • anchor – See LayoutAnchor for possible options

  • tolerance – Maximal permitted deviation from alignment

  • assert_not – If True, method check is tested in not statement

Raises

CheckCommandError – If check was not successful

Returns

List of bound_boxes

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> label1 = aiviro.Text("Text 1") # check if labels are in same column
>>> label2 = aiviro.Text("Text 2")
>>> label3 = aiviro.Text("Text 3")
>>> r.check_are_in_column(label1, label2, label3, anchor=aiviro.layout_anchor.LEFT, tolerance=5)
check_are_in_row(*elements: SearchObjectArea, anchor: aiviro.core.constants.ui_constants.LayoutAnchor, tolerance: int = 0, assert_not: bool = False) ListBoxOrBox

Check if ‘elements’ are aligned horizontally in one row. Method works like an assert statement.

Parameters
  • elements – List of search objects

  • anchor – See LayoutAnchor for possible options

  • tolerance – Maximal permitted deviation from alignment

  • assert_not – If True, method check is tested in not statement

Raises

CheckCommandError – If check was not successful

Returns

List of bound_boxes

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> label1 = aiviro.Text("Text 1") # Check if labels are in same row
>>> label2 = aiviro.Text("Text 2")
>>> label3 = aiviro.Text("Text 3")
>>> r.check_are_in_row(label1, label2, label3, anchor=aiviro.layout_anchor.BOTH, tolerance=5)
check_are_in_columns(*elements: SearchObjectArea, number_of_columns: int, max_delta_x: int, tolerance: int = 0, assert_not: bool = False) ListBoxOrBox

Check if ‘elements’ can be spaced in a specified number of columns, by center point. Method works like an assert statement.

Parameters
  • elements – List of search objects

  • number_of_columns – Number of columns

  • max_delta_x – Maximum empty space between columns (overlap when negative)

  • tolerance – Maximum difference in x-axis coordinate among elements in one row

  • assert_not – If True, method check is tested in not statement

Raises

CheckCommandError – If check was not successful

Returns

List of bound_boxes

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> label1 = aiviro.Text("Text 11") # check if labels are only in two columns
>>> label2 = aiviro.Text("Text 12")
>>> label3 = aiviro.Text("Text 21")
>>> label4 = aiviro.Text("Text 22")
>>> r.check_are_in_columns(
...     label1, label2, label3, label4,
...     number_of_columns=2,
...     tolerance=5
... )
check_are_in_rows(*elements: SearchObjectArea, number_of_rows: int, max_delta_y: int, tolerance: int = 0, assert_not: bool = False) ListBoxOrBox

Check if ‘elements’ can be spaced in a specified number of rows, by center point. Method works like an assert statement.

Parameters
  • elements – List of search objects

  • number_of_rows – Number of rows

  • max_delta_y – Maximum empty space between rows (overlap when negative)

  • tolerance – Maximum difference in y-axis coordinate among elements in one row

  • assert_not – If True, method check is tested in not statement

Raises

CheckCommandError – If check was not successful

Returns

List of bound_boxes

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> label1 = aiviro.Text("Text 11") # check if labels are only in two rows
>>> label2 = aiviro.Text("Text 12")
>>> label3 = aiviro.Text("Text 21")
>>> label4 = aiviro.Text("Text 22")
>>> r.check_are_in_rows(
...     label1, label2, label3, label4,
...     number_of_columns=2,
...     tolerance=5
... )
check_are_in_grid(*elements: SearchObjectArea, number_of_rows: int, number_of_columns: int, max_delta_x: int, max_delta_y: int, tolerance: int = 0, assert_not: bool = False) ListBoxOrBox

Check if ‘elements’ can be spaced in a specific number of rows & columns, by center point. Method works like an assert statement.

Parameters
  • elements – List of search objects

  • number_of_rows – Number of rows

  • number_of_columns – Number of columns

  • max_delta_x – Maximum empty space between columns (overlap when negative)

  • max_delta_y – Maximum empty space between rows (overlap when negative)

  • tolerance – Maximum difference in coordinates among column/row elements

  • assert_not – If True, method check is tested in not statement

Raises

CheckCommandError – If check was not successful

Returns

List of bound_boxes

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> label1 = aiviro.Text("Text 11") # check if labels are in 2x2 grid
>>> label2 = aiviro.Text("Text 12")
>>> label3 = aiviro.Text("Text 21")
>>> label4 = aiviro.Text("Text 22")
>>> r.check_are_in_grid(
...     label1, label2, label3, label4,
...     number_of_rows=2,
...     number_of_columns=2,
...     tolerance=5
... )
check_is_positioned(element: SearchObjectArea, reference: SearchObjectArea, direction_type: aiviro.core.constants.ui_constants.LayoutPositions, comparison_mode: aiviro.core.constants.ui_constants.LayoutComparisonMode = LayoutComparisonMode.WHOLE, assert_not: bool = False) List[BoundBox]

Check if ‘element’ is in specified direction ‘direction_type’ of ‘reference’ element. Method works like an assert statement.

Parameters
  • element – Element to be checked

  • reference – Element to be checked against

  • direction_type – Position of ‘element’ considering to ‘reference’. See LayoutPositions for possible options

  • comparison_mode – Type of determination. See LayoutComparisonMode for possible options

  • assert_not – If True, method check is tested in not statement

Raises

CheckCommandError – If check was not successful

Returns

List of two bound-boxes, element & reference bounding box

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> label1 = aiviro.Text("Text 1") # check if label1 is above of label2
>>> label2 = aiviro.Text("Text 2")
>>> r.check_is_positioned(label1, label2, aiviro.layout_positions.IS_ABOVE)
check_are_within_distance(first_element: SearchObjectArea, second_element: SearchObjectArea, max_delta_x: int, max_delta_y: int, comparison_mode: aiviro.core.constants.ui_constants.LayoutComparisonMode = LayoutComparisonMode.EXTREME, assert_not: bool = False) List[BoundBox]

Check if between ‘first’ and ‘second’ is at most ‘dx’ and ‘dy’ in their respective dimensions. Method works like an assert statement.

Parameters
  • first_element – First search object

  • second_element – Second search object

  • max_delta_x – Maximal permitted distance on x-axis

  • max_delta_y – Maximal permitted distance on y-axis

  • comparison_mode – Type of determination. See LayoutComparisonMode for possible options

  • assert_not – If True, method check is tested in not statement

Raises

CheckCommandError – If check was not successful

Returns

List of two bound-boxes, first & second element

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> label1 = aiviro.Text("Text 1") # check if label 1 is at most 200 px away from label 2
>>> label2 = aiviro.Text("Text 2")
>>> r.check_are_within_distance(label1, label2, 200, 0)
check_are_intersecting(*elements: SearchObjectArea, assert_not: bool = False, strict: bool = False) ListBoxOrBox

Check if at least two of the ‘elements’ intersect. Method works like an assert statement.

Parameters
  • elements – List of search objects

  • assert_not – If True, method check is tested in not statement

  • strict – If True, boxes cannot touch their borders

Raises

CheckCommandError – If check was not successful

Returns

List of bound_boxes

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> form_box = aiviro.Area(0, 500, 200, 780) # area containing label1 and label2
>>> label1 = aiviro.Text("Text 1")
>>> label2 = aiviro.Text("Text 2")
>>> r.check_are_intersecting(label1, label2)
CheckCommandError ...
>>> r.check_are_intersecting(label1, label2, assert_not=True)
>>> r.check_are_intersecting(label1, form_box)
check_elements_color(*elements: SearchObjectArea, expected_color: aiviro.core.utils.search_objects.other.Color, assert_not: bool = False) ListBoxOrBox

Check if dominant color in ‘element’ is ‘element_color’. Method works like an assert statement.

Parameters
  • elements – List of search objects

  • expected_color – Dominant color of elements

  • assert_not – If True, method check is tested in not statement

Raises

CheckCommandError – If check was not successful

Returns

List of bound_boxes

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.check_elements_color(
...     aiviro.Button("Login Now"),
...     expected_color=aiviro.Color(75, 0, 206)
... )
emit_image_logger_buffer(number_of_images_to_emit: Optional[int] = None, save_locally: bool = False, upload: bool = False, include_files: Optional[List[str]] = None) Optional[ZipSnapshot]

Method to emits images from image-buffer into the log-folder and upload them to Aiviro-Dashboard.

Parameters
  • number_of_images_to_emit – Number of images to emit, if None whole buffer will be emitted.

  • save_locally – If True, images are saved locally into log-folder

  • upload – If True, ZipSnaphost will be automatically uploaded to Aiviro-Dashboard

  • include_files – Additional files which will be included with emitted buffer

Returns

ZipSnaphost, for uploading files to aiviro-dashboard

Example

>>> import aiviro
>>> r = aiviro.create_web_robot(headless=True)
>>> r.go_to_url("https://my-website.com")
>>> # check if website/application is fully loaded
>>> if not r.wait_for(aiviro.Text("Welcome!"), ignore_timeout_exception=True):
...     # website wasn't fully loaded, we would like to log what robot sees
...     r.emit_image_logger_buffer(upload=True)
>>> r.close()
>>> import aiviro
>>> r = aiviro.create_web_robot(headless=True)
>>> r.go_to_url("https://my-website.com")
>>> if not r.wait_for(aiviro.Text("Welcome!"), ignore_timeout_exception=True):
...     # command will return ImageLogSnapshot object, and the images are not uploaded yet
...     log_snapshot = r.emit_image_logger_buffer()
...     # some code for downloading additional files which we want to include in log_snapshot
...     # add file & upload all files to Aiviro-Dashboard
...     log_snapshot.add_file('path/to/file/additional-log.txt').upload()
create_gif_from_buffer(number_of_images: Optional[int] = None, save_locally: bool = False, upload: bool = False) Optional[GifSnapshot]

Method to creates gif from images currently in the image-buffer. The image can be stored locally inside log-folder or be uploaded to Aiviro-Dashboard.

Parameters
  • number_of_images – Number of images that will be used for gif, if None the entire buffer will be used.

  • save_locally – If True, the gif is created and saved locally into log-folder

  • upload – If True, the created gif will be automatically uploaded to Aiviro-Dashboard.

Returns

GifSnapshot, if upload was not set to True, otherwise it returns None. If the GifSnapshot is returned then you can add more images to the gif and upload/save them.

Example

>>> import aiviro
>>> r = aiviro.create_web_robot(headless=True)
>>> r.go_to_url("https://my-website.com")
>>> # check if website/application is fully loaded
>>> if not r.wait_for(aiviro.Text("Welcome!"), ignore_timeout_exception=True):
...     # website wasn't fully loaded, we would like to log what robot sees
...     r.create_gif_from_buffer(upload=True)
>>> r.close()
>>> import aiviro
>>> r = aiviro.create_web_robot(headless=True)
>>> r.go_to_url("https://my-website.com")
>>> if not r.wait_for(aiviro.Text("Welcome!"), ignore_timeout_exception=True):
...     # command will return GifSnapshot object, and the gif is not uploaded yet
...     gif_snapshot = r.create_gif_from_buffer()
...     # do some fallback code
...     # add current state
...     gif_snapshot.add_image(r.get_current_screen())
...     # upload it to dashboard
...     gif_snapshot.upload()
>>> r.close()
add_mask(mask: SearchObjectArea, color: aiviro.core.utils.search_objects.other.Color = <Color RGBA (0, 0, 0, 1.0)/>, mask_group: str = '') AbstractContextManager

Adds screen mask which covers parts of screen. Useful if we want to ignore some parts of the screen.

Parameters
  • mask – Element or area of the mask

  • color – Which color should be used to fill the element

  • mask_group – Name of the group into which the mask belongs. If not set, default group is used

Returns

Context manager which can be used in with block

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.add_mask(aiviro.BoundaryArea(aiviro.Text("top-b"), aiviro.Text("bottom-b")))
>>> # some code
>>> r.clear_screen_masks()
>>> with r.add_mask(aiviro.CustomBox(aiviro.Input("Username"), 10, 10, 10, 10)):
...     # some code
add_mask_by_boundaries(upper_boundary: SearchObjectArea, lower_boundary: SearchObjectArea, color: aiviro.core.utils.search_objects.other.Color = <Color RGBA (0, 0, 0, 1.0)/>) AbstractContextManager

Adds screen mask which covers parts of screen. Useful if we want to ignore some parts of the screen.

Parameters
  • upper_boundary – Left-upper element or area of the mask

  • lower_boundary – Right-lower element or area of the mask

  • color – Which color should be used to fill the element

Returns

Context manager which can be used in with block

Attention

This method is deprecated, and will be removed in future version.
Please use instead add_mask() method with BoundaryArea search-object as argument.
add_mask_by_margin(search_object: SearchObjectArea, top: int = 0, right: int = 0, bottom: int = 0, left: int = 0, color: aiviro.core.utils.search_objects.other.Color = <Color RGBA (0, 0, 0, 1.0)/>) AbstractContextManager

Adds screen mask which covers parts of screen extended by margin. Useful if we want to ignore some parts of the screen.

Parameters
  • search_object – Element or area of the mask

  • top – Rop margin

  • right – Right margin

  • bottom – Bottom margin

  • left – Left margin

  • color – Which color should be used to fill the element

Returns

Context manager which can be used in with block

Attention

This method is deprecated, and will be removed in future version.
Please use instead add_mask() method with CustomBox search-object as argument.
add_mask_by_display(search_object: SearchObjectArea, to_top: bool = False, to_right: bool = False, to_bottom: bool = False, to_left: bool = False, include_object: bool = True, color: aiviro.core.utils.search_objects.other.Color = <Color RGBA (0, 0, 0, 1.0)/>, mask_group: str = '') AbstractContextManager

Adds screen mask which covers parts of screen extended to screen border(-s). Useful if we want to ignore some parts of the screen.

Parameters
  • search_object – Element or area of the mask

  • to_top – If True extends mask to top border of the screen

  • to_right – If True extends mask to right border of the screen

  • to_bottom – If True extends mask to bottom border of the screen

  • to_left – If True extends mask to left border of the screen

  • include_object – If True the search_object is covered by mask

  • color – Which color should be used to fill the element

  • mask_group – Name of the group into which the mask belongs. If not set, default group is used

Returns

Context manager which can be used in with block

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.add_mask_by_display(aiviro.Input("Username"), True, True, True, True, True)
>>> # some code
>>> r.clear_screen_masks()
>>> with r.add_mask_by_display(aiviro.Input("Username"), True, True, True, True, True):
...     # some code
clear_screen_masks(mask_groups: Union[str, List[str]] = '') AbstractContextManager

Clears screen masks.

Parameters

mask_groups – Names of mask’s groups to remove. If not set, only masks in default group are removed.

Returns

Context manager which can be used in with statement

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.add_mask(aiviro.Input("Username"), mask_group="static")
>>> r.add_mask(aiviro.Area(0, 200, 300, 456))
>>> # some code
>>> r.clear_screen_masks()  # doesn't remove 'static' masks, only default ones
>>> r.clear_screen_masks('static')  # removes only 'static' masks
add_mask_windows_taskbar(size_pixels: int = 40, position: str = 'bottom', mask_group: str = '_windows') AbstractContextManager

Covers windows taskbar with a screen mask.

Parameters
  • size_pixels – Size of the taskbar in pixels

  • position – Position of the taskbar, supported are ‘top’, ‘bottom’, ‘left’ and ‘right’

  • mask_group – Group into which mask is added

Example

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> r.add_mask_windows_taskbar()
see(*elements: SearchObjectArea, assert_not: bool = False, exception_to_raise: CUSTOM_EXCEPTION_TYPE = None) ManyListBoxOrListBoxOrBox

Checks if provided elements are present on screen

Parameters
  • elements – Elements to be checked

  • assert_not – If True, method check is tested in not statement

  • exception_to_raise – If set, it will be raised instead of SearchObjectError

Raises

CheckCommandError – If the element is not seen and assert_not is set to False. Or if the element is seen and assert_not is set to True.

Returns

Bounding boxes of the checked elements

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> try:
...     r.see(aiviro.Button("Login"))
...     # proceed to log-in
... except aiviro.CheckCommandError:
...     # already logged in
see_any_element(types: Optional[Union[List[aiviro.core.constants.ui_constants.UIElementType], aiviro.core.constants.ui_constants.UIElementType]] = None, exclude_texts: Optional[List[str]] = None) bool

The tester will check if any element is present on screen.

Parameters
  • types – Optional elements types which to seek.

  • exclude_texts – Optional ignore elements which have given texts.

Returns

True if any element (including text) is present on screen and False otherwise

set_as_stream_source()

Sets the current streaming image to this robot

property streaming_url: Optional[str]

Returns the current streaming url. If streaming is not enabled None is returned instead.

aiviro.DynamicRobot

class aiviro.core.robots.DynamicRobot(runner_manager: aiviro.core.robots.robot_base.T, config: GlobalConfig, pause: bool = False)

Robot containing dynamic functionality, it cannot be instantiated by itself. You need to use one of the concrete implementations, as RDPRobot, WebRobot, DesktopRobot. Has the same methods as the BaseRobot.

click(*elements: SearchObjectArea, offset_x: int = 0, offset_y: int = 0, hold_button: bool = False, skip_waiting: bool = False, move_away: bool = False) None

Left-clicks the supplied elements.

Parameters
  • elements – Elements to click on

  • offset_x – Offset in x-axis

  • offset_y – Offset in y-axis

  • hold_button – If True, it holds the mouse button after click, default False (only click)

  • skip_waiting – If True, waiting for unstable screen, after click, will be skipped

  • move_away – If True, it moves away to empty space after click

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.click(aiviro.Button("Push"))  # click in the center of the button element
>>> r.click(aiviro.Button("Push"), offset_x=20)  # click 20 px to the right of the center
>>> r.click(aiviro.Button("Push"), offset_y=20)  # click 20 px below the center
>>> # click the checkbox element and after the button element
>>> r.click(aiviro.CheckBox("Option 1"), aiviro.Button("Push"))
release(skip_waiting: bool = False) None

Release pressed mouse button.

Parameters

skip_waiting – If True, waiting for unstable screen, after click, will be skipped

Example

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> r.click(aiviro.Button("Hold"), hold_button=True)  # press left mouse button and hold it down
>>> r.move(aiviro.Text("Release Area"))
>>> r.release()  # release the mouse button
double_click(*elements: SearchObjectArea, offset_x: int = 0, offset_y: int = 0, skip_waiting: bool = False, move_away: bool = False) None

Double-clicks the supplied elements.

Parameters
  • elements – Elements to click on

  • offset_x – Offset in x-axis

  • offset_y – Offset in y-axis

  • skip_waiting – If True, waiting for unstable screen, after click, will be skipped

  • move_away – If True, it moves away to empty space after double click

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.double_click(aiviro.Button("Push"))  # double-click in the center of the button element
>>> r.double_click(aiviro.Button("Push"), offset_x=20)  # double-click 20 px to the right from the center
>>> r.double_click(aiviro.Button("Push"), offset_y=20)  # double-click 20 px below the center
>>> # double-click the checkbox element and after the button element
>>> r.double_click(aiviro.CheckBox("Option 1"), aiviro.Button("Push"))
right_click(*elements: SearchObjectArea, offset_x: int = 0, offset_y: int = 0, skip_waiting: bool = False, move_away: bool = False) None

Right-clicks the supplied elements.

Parameters
  • elements – Elements to click on

  • offset_x – Offset in x-axis

  • offset_y – Offset in y-axis

  • skip_waiting – If True, waiting for unstable screen, after click, will be skipped

  • move_away – If True, it moves away to empty space after right click

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.right_click(aiviro.Button("Push"))  # right-click in the center of the button element
>>> r.right_click(aiviro.Button("Push"), offset_x=20)  # right-click 20 px to the right from the center
>>> r.right_click(aiviro.Button("Push"), offset_y=20)  # right-click 20 px below the center
>>> # right-click the checkbox element and after the button element
>>> r.right_click(aiviro.CheckBox("Option 1"), aiviro.Button("Push"))
move(*elements: SearchObjectArea, offset_x: int = 0, offset_y: int = 0, skip_waiting: bool = False) None

Moves the mouse on the given elements.

Parameters
  • elements – Elements to be moved on

  • offset_x – Offset in x-axis

  • offset_y – Offset in y-axis

  • skip_waiting – If True, waiting for unstable screen, after click, will be skipped

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.move(aiviro.Button("Push"))  # move the mouse in the center of the button element
>>> r.move(aiviro.Button("Push"), offset_x=20)  # move the mouse 20 px to the right from the center
>>> r.move(aiviro.Button("Push"), offset_y=20)  # move the mouse 20 px below the center
>>> # move the mouse the checkbox element and after the button element
>>> r.move(aiviro.CheckBox("Option 1"), aiviro.Button("Push"))
move_away()

Moves the mouse to a space which is not occupied by elements

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.move(aiviro.Button("Push"))  # move the mouse in the center of the button element
>>> r.move_away()  # moves the mouse away from the button and other elements
drag(start: SearchObjectArea, end: SearchObjectArea, skip_waiting: bool = False) None

Drags from one element to another

Parameters
  • start – Beginning element to drag from

  • end – End element to drag to

  • skip_waiting – If True, waiting for unstable screen, after click, will be skipped

Example

>>> import aiviro
>>> r = aiviro.create_web_robot(headless=True)
>>> r.drag(aiviro.Text("Start position"), aiviro.Text("End position"))
clear_and_type(element: SearchObjectArea, text_to_type: Union[str, aiviro.core.utils.secret.Secret], skip_waiting: bool = False, sensitive_data: bool = False) None

Clears the selected elements and types text into it.

Parameters
  • element – Element which will be cleared and typed into

  • text_to_type – Text which will be typed

  • skip_waiting – If True, waiting for unstable screen, after click, will be skipped

  • sensitive_data – If True, text_to_type argument will be hidden in logs

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.clear_and_type(aiviro.Input("Username"), "Example")
clear_text(element: SearchObjectArea, skip_waiting: bool = False) None

Clears the selected elements.

Parameters
  • element – Element which will be cleared

  • skip_waiting – If True, waiting for unstable screen, after click, will be skipped

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.clear_text(aiviro.Input("Username"))
type_text(element: SearchObjectArea, text_to_type: Union[str, aiviro.core.utils.secret.Secret], skip_waiting: bool = False, sensitive_data: bool = False) None
type_text(text_to_type: Union[str, aiviro.core.utils.secret.Secret], skip_waiting: bool = False, sensitive_data: bool = False) None

Types text into supplied element or in current context

Parameters
  • element – Element which will be typed into

  • text_to_type – Text to be typed

  • skip_waiting – If True, waiting for unstable screen, after action, will be skipped

  • sensitive_data – If True, text_to_type argument will be hidden in logs

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.type_text(aiviro.Input("Message"), "Example text")
>>> r.type_text("Example text")
key_press(key: BaseKey, skip_waiting: bool = False) None

Press key method is just a wrapper for the key_hold_down() and key_release(). It simulates pressing a key down and then releasing it up.

Parameters
  • key – Key to press, see BaseKey

  • skip_waiting – If True, waiting for unstable screen, after action, will be skipped

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.key_press(aiviro.key.KEY_A)
key_hold_down(key: BaseKey, skip_waiting: bool = False) None

Simulates pressing a key down, but not releasing it.

This function should be used only with modifier keys, which are shift, alt, ctrl.

Parameters
  • key – Key to hold down, see BaseKey

  • skip_waiting – If True, waiting for unstable screen, after action, will be skipped

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.key_hold_down(aiviro.key.LEFT_CONTROL)
key_release(key: BaseKey, skip_waiting: bool = False) None

Simulates releasing key up, mostly used after key_hold_down() method.

This function should be used only with modifier keys, which are shift, alt, ctrl.

Parameters
  • key – Key to release up, see BaseKey

  • skip_waiting – If True, waiting for unstable screen, after action, will be skipped

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.key_release(aiviro.key.LEFT_CONTROL)
key_shortcut(*keys: BaseKey, skip_waiting: bool = False) None

Keys will be pressed down in order, and then released in reverse order.

Parameters
  • keys – List of keys to press, see BaseKey

  • skip_waiting – If True, waiting for unstable screen, after action, will be skipped

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> r.key_shortcut(aiviro.key.LEFT_CONTROL.KEY_A)
scroll_up(scroll_n_times: int = 1, skip_waiting: bool = False) None

Uses mouse scroll wheel keys to scroll up.

Parameters
  • scroll_n_times – Number of times to scroll up

  • skip_waiting – If True, waiting for unstable screen, after action, will be skipped

Example

>>> import aiviro
>>> r = aiviro.create_web_robot(headless=True)
>>> # some code
>>> r.scroll_up(30)
>>> r.click(aiviro.Button("Continue"))
scroll_down(scroll_n_times: int = 1, skip_waiting: bool = False) None

Uses mouse scroll wheel keys to scroll down.

Parameters
  • scroll_n_times – Number of times to scroll down.

  • skip_waiting – If True, waiting for unstable screen, after action, will be skipped

Example

>>> import aiviro
>>> r = aiviro.create_web_robot(headless=True)
>>> # code to fill out the form
>>> r.scroll_down(30)
>>> r.click(aiviro.Button("Submit"))
wait_for(*elements: SearchObjectArea, timeout: int = 60, ignore_timeout_exception: bool = False, exception_to_raise: CUSTOM_EXCEPTION_TYPE = None) ManyListBoxOrListBoxOrBox

Waits for all elements to be on the screen.

Parameters
  • elements – Elements to check the presence of

  • timeout – Maximum time to wait, for elements to appear

  • ignore_timeout_exception – If True, SearchObjectError will not be thrown and method will return None

  • exception_to_raise – If set, it will be raised instead of SearchObjectError

Returns

Bounding boxes of found elements

Raises

SearchObjectError – If waiting for an element has exceeded the set timeout

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
>>> button = r.wait_for(aiviro.Button("Signup for nothing here"))
>>> r.click(button)
>>> # some other code
>>> if r.wait_for(aiviro.Text("Username"), ignore_timeout_exception=True):
...     r.type_text(aiviro.Input("Password"), "******", sensitive_data=True)
... else:
...     r.click(aiviro.Button("Close"))
wait_until_disappear(*elements: SearchObjectArea, timeout: int = 30, ignore_timeout_exception: bool = False, exception_to_raise: CUSTOM_EXCEPTION_TYPE = None) ManyListBoxOrListBoxOrBox

Wait until all elements disappear from the screen.

Parameters
  • elements – Elements to disappear

  • timeout – Maximum time to wait, for elements to disappear

  • ignore_timeout_exception – If True, SearchObjectError will not be thrown

  • exception_to_raise – If set, it will be raised instead of SearchObjectError

Returns

Bounding boxes of found elements

Raises

SearchObjectError – If waiting for elements to disappear has exceeded the set timeout

Example

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> # open some app, open modal-window
>>> r.click(aiviro.Button("OK"))  # submit modal-window
>>> # wait until modal-window will disappear
>>> r.wait_until_disappear(aiviro.Button("OK"), aiviro.Button("Cancel"))

aiviro.RDPRobot

class aiviro.core.robots.RDPRobot(runner_manager: aiviro.core.robots.robot_base.T, config: GlobalConfig, pause: bool = False)

Robot for UI automation of remote desktop applications using the RDP protocol. Has the same methods as the DynamicRobot

Example

>>> import aiviro
>>> r = aiviro.create_rdp_robot("<ip-address>", "<username>", "<password>", "<domain>")
start_process(name: Union[str, aiviro.core.utils.secret.Secret], args: Optional[List[Union[str, aiviro.core.utils.secret.Secret]]] = None, timeout: int = 15, as_admin: bool = False, use_likely_area: bool = False, sleep_time: int = 0, sensitive_data: bool = False) None

Starts a process on the system this robot is running on.

Parameters
  • name – Path or name of the executable

  • args – Arguments the executable should be launched with

  • timeout – Timeout in which should the run window be found

  • as_admin – Start this command as admin.

  • use_likely_area – If True, it uses area in which is more likely to find “Run” window.

  • sleep_time – Implicit sleep between sub-commands execution

  • sensitive_data – If True, typed text will be hidden in logs

Example

>>> import aiviro, time
>>> r = aiviro.create_rdp_robot()
>>> time.sleep(2) # it is important to wait till rdp is fully ready
>>> r.start_process("chrome", ["--incognito"])
>>> r.wait_for(
...     aiviro.Image("helper_images/chrome_incognito_icon.png")
... )
>>> r.key_shortcut(aiviro.key.LEFT_ALT.F4)
>>> r.close()
get_clipboard_text() str

Returns current text from the clipboard. Expects some text was copied on the RDP machine.

set_clipboard_text(value: str) None

Sets clipboard text to value specified in parameter. You can paste this value on the RDP machine.

Parameters

value – Value which will be set to the clipboard

transfer_files_to_guests_clipboard(file_path: str, paste: bool = False, blocking: bool = False, timeout: int = 600) None

Transfer file or directory from a local(host) machine to remote(guest’s) clipboard.

Warning

Because of limitations of RDP procotol you will not be notified when a Windows GUI prompt will be shown. This will block your script for the duration of timeout. So if using this option make sure you don’t overwrite some files.

Parameters
  • file_path – Path to the file or directory to be transfered

  • paste – If True it’ll call Ctrl+V, after the transfer, at guest’s machine

  • blocking – Waits for transfer finish of all files to the client.

  • timeout – Timeout for blocking option. Default 10 minutes.

Raises

TimeoutError – Only occurs when blocking is enabled. If the copy time exceeds timeout(large file) or if Windows GUI prompt which needs resolving is shown.

Example

>>> import aiviro, time
>>> r = aiviro.create_rdp_robot()
>>> time.sleep(2) # it is important to wait till rdp is fully ready
>>> # code to navigate robot to some folder on remote machine
>>> r.transfer_files_to_guests_clipboard("file/you/want/to/be/loaded/in/clipboard.txt")
>>> r.key_shortcut(aiviro.key.LEFT_CONTROL.KEY_V) # paste the file into the folder
>>> # The same command without the need to trigger the shortcut
>>> r.transfer_files_to_guests_clipboard("file/you/want/to/be/loaded/in/clipboard.txt", paste=True)
>>> # you can also copy the file via windows context options:
>>> r.transfer_files_to_guests_clipboard("file/you/want/to/be/loaded/in/clipboard.txt")
>>> window = ... # find window which you want to copy files to
>>> r.right_click(window) # open context dialog
>>> r.click(aiviro.Text("Paste")) # select paste from the dialog
>>> r.close()
wait_for_clipboard_file_transfer(timeout: int = 600) None

Waits for transfer finish of all files to the client

Warning

Because of limitations of RDP procotol you will not be notified when a Windows GUI prompt is shown. This will block your script for the duration of timeout. So if using this method make sure you don’t overwrite some files.

Parameters

timeout – Timeout for waiting. Default 10 minutes.

Raises

TimeoutError – If the copy time exceeds timeout(large file) or if Windows GUI prompt which needs resolving is shown.

Example

>>> import aiviro, time
>>> r = aiviro.create_rdp_robot()
>>> time.sleep(2) # it is important to wait till rdp is fully ready
... # navigate robot to some folder on remote machine
>>> r.transfer_files_to_guests_clipboard("file/you/want/to/be/loaded/in/clipboard.txt")
>>> r.key_shortcut(aiviro.key.LEFT_CONTROL.KEY_V) # paste the file into the folder
>>> try:
...     r.wait_for_clipboard_file_transfer() # waiting for file transfer to finish
... except TimeoutError:
...     # After 10 minutes (default)
...     # Too large file was transferred and timeout expired
...     # Or file with the same is already in client and a GUI window about overwrite is shown.
>>> r.close()
transfer_files_from_guests_clipboard(folder_path: str, copy: bool = False) List[str]

Transfer files from remote(guest’s) clipboard to local directory.

Parameters
  • folder_path – Path to the directory to be saved to

  • copy – If True it’ll call Ctrl+C, before the transfer, at guest’s machine

Returns

List of paths which had been loaded

Example

>>> import aiviro, time
>>> r = aiviro.create_rdp_robot()
>>> time.sleep(2) # it is important to wait till rdp is fully ready
>>> # code to navigate robot to some folder on remote machine
>>> r.click(aiviro.Text("somefile.txt"))  # you must select which files you want to copy
>>> r.key_shortcut(aiviro.key.LEFT_CONTROL.KEY_C) # copy the file into clipboard
>>> r.transfer_files_from_guests_clipboard("some/local/dir/")
["some/local/dir/somefile.txt"]
>>> r.close()

aiviro.WebRobot

class aiviro.core.robots.WebRobot(runner_manager: aiviro.core.robots.robot_base.T, config: GlobalConfig, pause: bool = False)

Robot for UI automation of web applications. Has the same methods as the DynamicRobot

Example

>>> import aiviro
>>> r = aiviro.create_web_robot()
go_to_url(url: str) None

Switches the web browser to specified url.

Parameters

url – Url address of the site you want to visit

get_current_url() str

Returns current url

go_to_url_in_new_tab(url: str) None

Opens the web browser to specified url in a new tab.

Parameters

url – Url address of the site you want to visit

switch_tab(tab_id: int) contextlib.AbstractContextManager

Switches tabs in the web browser.

Parameters

tab_id – Tab identification to which you want to switch.

Returns

Context manager which can be used in with statement.

close_tab()

Close currently open tab

aiviro.DesktopRobot

class aiviro.core.robots.DesktopRobot(runner_manager: aiviro.core.robots.robot_base.T, config: GlobalConfig, pause: bool = False)

Robot for UI automation of desktop applications. Has the same methods as the DynamicRobot

Example

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
start_process(name: str, args: Optional[List[str]] = None, keep_alive: bool = False) int

Starts a process on the system this robot is running on.

Parameters
  • name – Path or name of the executable

  • args – Arguments the executable should be launched with

  • keep_alive – If True, this process won’t terminate after the script ends

Returns

Process identification number which can be used to access the process

Example

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> firefox_id = r.start_process("firefox")
>>> r.wait_for(aiviro.Text("Mozilla Firefox"))
>>> r.see(aiviro.Text("youtube"))
>>> r.terminate_process(firefox_id)
terminate_process(ppid: int) None

Terminates a started process on the system this robot is running on. By calling this method, also process which was set with argument keep_alive = True will terminate.

Parameters

ppid – Identification number of the process

Example

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> firefox_id = r.start_process("firefox")
>>> r.wait_for(aiviro.Text("Mozilla Firefox"))
>>> r.see(aiviro.Text("youtube"))
>>> r.terminate_process(firefox_id)

See also

start_process()

switch_display(display_id: int) contextlib.AbstractContextManager

Switches the current working display to the one specified with this argument.

Parameters

display_id – Id of the display you want to switch to.

Returns

Context manager which can be used in with statement

get_clipboard_text() str

Returns current text from the clipboard.

set_clipboard_text(value: str) None

Sets clipboard text to value specified in parameter.

Parameters

value – Value to set into the clipboard

aiviro.StaticRobot

class aiviro.core.robots.StaticRobot(runner_manager: aiviro.core.robots.robot_base.T, config: GlobalConfig, pause: bool = False)

Robot for UI automation of static images. Has the same methods as the BaseRobot

Example

>>> import aiviro
>>> r = aiviro.create_static_robot()
get(*elements: SearchObjectArea, screen: Optional[ndarray] = None, ignore_exception: bool = False, exception_to_raise: CUSTOM_EXCEPTION_TYPE = None) ManyListBoxOrListBoxOrBox

Gets elements from the current screen.

Parameters
  • elements – Elements to be searched for

  • screen – Finding elements in described screen. If None it uses current screen

  • ignore_exception – If True, SearchObjectError will not be thrown and method will return None

  • exception_to_raise – If set, it will be raised instead of SearchObjectError

Returns

Bounding boxes of the elements found in the screen.

Example

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> bxs = r.get(aiviro.Text("Home"), aiviro.Text("Contact"), aiviro.Text("Blog"))
[BoundBox<'Home'>, BoundBox<'Contact'>, BoundBox<'Blog'>]
>>> image = ... # Load image from disk or from other sources.
>>> bxs = r.get(aiviro.Text("Home"), aiviro.Text("Contact"), aiviro.Text("Blog"), screen=image)
[BoundBox<'Home'>, BoundBox<'Contact'>, BoundBox<'Blog'>]
set_image(screen: ndarray) None

Sets the current image of the robot to this image.

Parameters

screen – The screen that will be set as current screen.

aiviro.modules.pdf.PDFRobot

class aiviro.modules.pdf.PDFRobot(manager: aiviro.core.services.runner_service.static_runner_manager.StaticRunnerManager, config: aiviro.core.utils.global_config.GlobalConfig, pdf_file: Optional[PathType] = None, timeout: int = 30, dpi: int = 200, poppler_path: Optional[PathType] = None, only_digital: bool = False)

Robot for parsing PDF files. Utilizes PDF embedded text from supplied file if available. Has the same methods as the StaticRobot

Example

>>> from aiviro.modules.pdf import create_pdf_robot
>>> r = create_pdf_robot().parse("path/to/file.pdf", skip_chars=["_"])
>>> r = r.add_file("path/to/file_2.pdf", skip_chars=["_"])  # switch to MultiPDFRobot
register_pdf_changed_subscriber(subscriber: Callable[[], None]) None

Registers method that should be notified when pdf-robot loads or set new pdf-file.

Parameters

subscriber – Method to call for notifying another object

parse(pdf_file: PathType, skip_chars: Optional[List[str]] = None, strategy: Optional[aiviro.modules.pdf.common.CharFallbackStrategy] = None, page_id: int = 0, only_digital: bool = False) PDFRobot

Utilizes digital PDF text extraction or if not available use OCR.

Parameters
  • pdf_file – Path to a PDF file this robot should be reading.

  • skip_chars – Chars which should be skipped. Usually used when the PDF isn’t well-formed _ characters for lines overlap into words.

  • strategy – Fallback strategy for characters which could not be recognized by digital text extraction. Default strategy is recognizing by OCR when digital extraction fails to recognize a character.

  • page_id – Sets the page automatically after parsing the file, equivalent of calling set_page() method

  • only_digital – If True, only PDF file which can be read digitally is processed. File where OCR would have to be used is skipped

add_file(pdf_file: PathType, skip_chars: Optional[List[str]] = None, strategy: Optional[aiviro.modules.pdf.common.CharFallbackStrategy] = None, page_id: int = 0, only_digital: bool = False) MultiPDFRobot

Loads another pdf-file into robot. It switches PDFRobot for MultiPDFRobot to store information about several files in one robot. See PDFRobot.parse() for arguments description.

Returns

Instance of MultiPDFRobot

Example

>>> from aiviro.modules.pdf import create_pdf_robot
>>> r = create_pdf_robot("path/to/file.pdf")
>>> multi_r = r.add_file("path/to/file_2.pdf")
set_page(page_id: int) None

Sets current page.

Parameters

page_id – Page index to set as current page

Raises

IndexError – If page index is out of bounds

property current_page: int

Returns page index of currently set page.

property number_of_pages: int

Returns number of pages from the supplied pdf.

switch_to_ocr() contextlib.AbstractContextManager

Switches text recognition method to OCR.

Returns

Context manager for scoped based switching.

Example

>>> from aiviro.modules.pdf import create_pdf_robot
>>> r = create_pdf_robot("path/to/file.pdf")
>>> r.switch_to_ocr() # Switches text recognition to OCR
>>> with r.switch_to_ocr(): # Switches text recognition to OCR in the following scope
...     r.get(...)
switch_to_pdf_text() contextlib.AbstractContextManager

Switches text recognition method to text extracted from PDF.

Raises

ValueError – If the PDF could not be extracted.

Returns

Context manager for scoped based switching.

Example

>>> from aiviro.modules.pdf import create_pdf_robot
>>> r = create_pdf_robot("path/to/file.pdf")
>>> r.switch_to_pdf_text() # Switches text recognition to PDF text
>>> with r.switch_to_pdf_text(): # Switches text recognition to PDF text in the following scope
...     r.get(...)
property is_digital: bool

Returns True if at least one page of the source PDF is digitally readable

add_text(text: str, x: int, y: int, font: aiviro.modules.pdf.fonts.PDFTextFonts = PDFTextFonts.TIMES_ROMAN, size: int = 12) None

Adds text to the current PDF file on the current page.

Parameters
  • text – Text that should be added to the PDF file.

  • x – x-coordinate where to add the text.

  • y – y-coordinate where to add the text.

  • font – which font to use.

  • size – how large should the text be.

Raises

PDFTextAdditionError – If there was an error during the text addition.

Example

>>> import aiviro
>>> from aiviro.modules.pdf import create_pdf_robot, PDFTextFonts
>>> r = create_pdf_robot("path/to/file.pdf")
>>> r.add_text(
>>>    text="Hello World",
>>>    x=150,
>>>    y=150,
>>>    font=PDFTextFonts.TIMES_ROMAN,
>>>    size=20
>>> )
>>> r.see(aiviro.Text("Hello World"))
...
add_image(image: PathType, x: int, y: int, width: Optional[int] = None, height: Optional[int] = None, preserve_ratio: bool = True) None

Adds image to the current PDF file on the current page.

Parameters
  • image – Path to the image file which should be added to the PDF.

  • x – x-coordinate where to add the image.

  • y – y-coordinate where to add the image.

  • width – Width to which the image should be resized.

  • height – Height to which the image should be resized.

  • preserve_ratio – Option whether to keep aspect ratio of the image. If the width and height are not None, the method creates a frame of the given size and adds the image to it’s center while maintaining the aspect ratio.

Raises

PDFImageAdditionError – If there was an error during the image addition.

Example

>>> import aiviro
>>> from aiviro.modules.pdf import create_pdf_robot
>>> r = create_pdf_robot("path/to/file.pdf")
>>> r.add_image(
>>>    image="path/to/img.png",
>>>    x=150,
>>>    y=150,
>>>    preserve_ratio=True
>>> )
>>> r.get(aiviro.Image("path/to/img.png"))
...
save(path: PathType) None

Saves the current PDF file to the given path.

Parameters

path – Path where the PDF file should be saved.

Raises

PDFError – If no PDF has been loaded and parsed yet.

Example

>>> from aiviro.modules.pdf import create_pdf_robot
>>> r = create_pdf_robot("path/to/file.pdf")
>>> r.save("/path/where/to/save.pdf") # Saves the file 'file.pdf' to the given path
...

aiviro.modules.pdf.MultiPDFRobot

class aiviro.modules.pdf.MultiPDFRobot(manager: aiviro.core.services.runner_service.static_runner_manager.StaticRunnerManager, config: aiviro.core.utils.global_config.GlobalConfig, pdf_files: Sequence[PathType], timeout: int = 30, dpi: int = 200, poppler_path: Optional[PathType] = None, only_digital: bool = False)

Robot for parsing a bulk of PDF files. Utilizes PDF embedded text from supplied file if available. Has the same methods as the PDFRobot

Example

>>> from aiviro.modules.pdf import create_pdf_robot
>>> r = create_pdf_robot(
...     [
...         "path/to/pdf_1.pdf"
...         "path/to/pdf_2.pdf"
...         "path/to/pdf_3.pdf"
...         "path/to/pdf_4.pdf"
...     ]
... )
>>> r.add_file("path/to/pdf_5.pdf", skip_chars=["_"])  # parse additional file
parse(pdf_file: PathType, skip_chars: Optional[List[str]] = None, strategy: Optional[aiviro.modules.pdf.common.CharFallbackStrategy] = None, page_id: int = 0, only_digital: bool = False) MultiPDFRobot

Utilizes digital PDF text extraction or if not available use OCR.

Parameters
  • pdf_file – Path to a PDF file this robot should be reading.

  • skip_chars – Chars which should be skipped. Usually used when the PDF isn’t well-formed _ characters for lines overlap into words.

  • strategy – Fallback strategy for characters which could not be recognized by digital text extraction. Default strategy is recognizing by OCR when digital extraction fails to recognize a character.

  • page_id – Sets the page automatically after parsing the file, equivalent of calling set_page() method

  • only_digital – If True, only PDF file which can be read digitally is processed. File where OCR would have to be used is skipped

add_file(pdf_file: PathType, skip_chars: Optional[List[str]] = None, strategy: Optional[aiviro.modules.pdf.common.CharFallbackStrategy] = None, page_id: int = 0, only_digital: bool = False) MultiPDFRobot

Loads another pdf-file into robot. See MultiPDFRobot.parse() for arguments description.

Returns

Instance of MultiPDFRobot

Example

>>> from aiviro.modules.pdf import create_pdf_robot
>>> r = create_pdf_robot(["path/to/file_1.pdf", "path/to/file_2.pdf"])
>>> r.add_file("path/to/file_3.pdf")
property loaded_files: List[str]

Returns names of loaded PDF files.

set_pdf(file_name: str, page_id: int = 0) None

Sets current file to work with and current page.

Parameters
  • file_name – Name of the parsed file to set

  • page_id – Page index to set as current page

Raises

IndexError – If page index is out of bounds

Example

>>> import aiviro
>>> from aiviro.modules.pdf import create_pdf_robot
>>> r = create_pdf_robot(["path/file1.pdf", "path/file2.pdf"])
>>> r.set_pdf("file1.pdf")
>>> r.get(aiviro.Text("Invoice"))