airgun.widgets

Module Contents

Classes

SatSelect

Represent basic select element except our custom implementation remove

CheckboxWithAlert

Represent basic checkbox element, but able to handle alert message

RadioGroup

Classical radio buttons group widget

ToggleRadioGroup

Toggle buttons group widget when each button represented by radio

DateTime

Collection of date picker and two inputs for hours and minutes

DatePickerInput

Input for date, which opens calendar on click.

ItemsList

List with click-able elements. Part of MultiSelect or jQuery

AddRemoveItemsList

Similar to ItemsList widget except list elements can be selected only using 'Add'

ItemsListGroup

Similar to ItemsList widget ideology, but here we have group of items lists instead.

ItemsListReadOnly

List with click-able elements. Part of MultiSelect or jQuery

MultiSelect

Typical two-pane multiselect jQuery widget. Allows to move items from

PuppetClassesMultiSelect

Widget has different appearance than MultiSelect, because there are no actual panes,

ConfigGroupMultiSelect

Similar to the PuppetClassesMultiSelect widget except items lists has different

ActionsDropdown

List of actions, expandable via button with caret. Usually comes with

Pf4ActionsDropdown

PF4 version of actions dropdown with support for items description

ActionDropdownWithCheckbox

Custom drop down which contains the checkbox inside in drop down.

Search

Searchbar for table filtering

PF4Search

PF4 Searchbar for table filtering

SatVerticalNavigation

The Patternfly Vertical navigation.

SatFlashMessage

Satellite version of Patternfly alert. It doesn't contain <strong>

SatFlashMessages

Satellite version of Patternfly's alerts section. The only difference is

ValidationErrors

Widget for tracking all improperly filled inputs inside view, which are

ContextSelector

Base class for all UI objects.

FilteredDropdown

Drop-down element with filtering functionality

CustomParameter

Name-Value paired input elements which can be added, edited or removed.

ConfirmationDialog

Usual confirmation dialog with two buttons and close 'x' button in the

Pf4ConfirmationDialog

PF4 confirmation dialog with two buttons and close 'x' button in the

LCESelector

Group of checkboxes that goes in a line one after another. Usually used

LimitInput

Input for managing limits (e.g. Hosts limit). Consists of 'Unlimited'

TextInputHidden

Text input widget with content that may be hidden

EditableEntry

Usually represented by static field and edit button that transform

EditableEntrySelect

Should be used in case EditableEntry widget represented not by

EditableEntryCheckbox

Should be used in case EditableEntry widget represented not by

CheckboxGroup

A set of checkboxes of the same property type

EditableEntryMultiCheckbox

Should be used in case EditableEntry widget represented not by

TextInputsGroup

A set of text inputs

EditableLimitEntry

Should be used in case EditableEntry widget represented not by

EditableDateTime

Should be used in case EditableEntry widget represented not by

ReadOnlyEntry

Similar to EditableEntry and specific for the same page types, but cannot

ACEEditor

Default ace editor

Pagination

Represents Paginator widget that includes per page selector, First/Last/Next/Prev buttons

SatTablePagination

Paginator widget for use within SatTable.

SatTable

Satellite version of table.

SatSubscriptionsTable

Subscriptions table, which has extra preceding row for 'Repository Name'

SatTableWithoutHeaders

Applicable for every table in application that has no headers. Due logic of the Table

SatTableWithUnevenStructure

Applicable for every table in application that has uneven amount of

ProgressBar

Generic progress bar widget.

PublishPromoteProgressBar

Progress bar for Publish and Promote procedures. They contain status

PieChart

Default Pie Chart that can be found across application. At that moment

RemovableWidgetsItemsListView

A host for widgets list. Items that can be added or removed, mainly used in profile for

GenericRemovableWidgetItem

Generic Item widget (to be inherited) and to be used as Widget Item for

AutoCompleteTextInput

Autocomplete Search input field, We must remove the focus from this widget after fill to

ToggleButton

A simple toggle button that we can read/write it's state via the standard view functions

Link

A link representation that we can read/click via the standard view functions read/fill.

PopOverModalView

Popover-content UI widget which contains header, drop_down, input_box, or textarea and

PopOverWidget

Popover-content UI widget which contains header, drop_down, input_box, or textarea and

AuthSourceAggregateCard

This is a customizable card widget which has the title, count and kebab widget

Accordion

PF4 Accordion widget

BaseMultiSelect

Represents the Patternfly Multi Select.

InventoryBootstrapSwitch

Checkbox-like Switch control, representing On and Off state. But with

class airgun.widgets.SatSelect(parent, locator=None, id=None, name=None, logger=None)

Represent basic select element except our custom implementation remove html tags from select option values

SELECTED_OPTIONS_TEXT = Multiline-String
Show Value
1var result_arr = [];
2var opt_elements = arguments[0].selectedOptions;
3for(var i = 0; i < opt_elements.length; i++){
4    value = opt_elements[i].innerHTML;
5    parsed_value = value.replace(/<[^>]+>/gm, '');
6    result_arr.push(parsed_value);
7}
8return result_arr;
class airgun.widgets.CheckboxWithAlert(parent, name=None, id=None, locator=None, logger=None)

Represent basic checkbox element, but able to handle alert message which can appear after you perform action for that widget

fill(value)

Interactive objects like inputs, selects, checkboxes, et cetera should implement fill.

When you implement this method, it MUST ALWAYS return a boolean whether the value was changed. Otherwise it can break.

For actual filling, please use fill_with(). It offers richer interface for filling.

Returns

A boolean whether it changed the value or not.

class airgun.widgets.RadioGroup(parent, locator, logger=None)

Classical radio buttons group widget

Example html representation:

<div class="form-group ">
    <label>Protocol *</label>
<div class="col-md-4">
    <label class="radio-inline">
        <input type="radio" checked="checked" name="subnet[type]">IPv4
    </label>
    <label class="radio-inline">
        <input type="radio" name="subnet[type]">IPv6
    </label>

Locator example:

//div/label[input[@type='radio']][contains(., 'IPv4')]
LABELS = .//label[input[@type="radio"]]
BUTTON = .//input[@type="radio"]
property button_names

Return all radio group labels

_get_parent_label(name)

Get radio group label for specific button

property selected

Return name of a button that is currently selected in the group

select(name)

Select specific radio button in the group

read()

Wrap method according to architecture

fill(name)

Wrap method according to architecture

class airgun.widgets.ToggleRadioGroup(parent, locator, logger=None)

Toggle buttons group widget when each button represented by radio element

Example html representation:

<div class="form-group ">
    <div>
        <label>Template *</label>
    <div class="btn-group">
        <label class="btn btn-default btn-sm active">
           <input type="radio" name="options">Input
        </label>
        <label class="btn btn-default btn-sm">
           <input type="radio" name="options">Diff
        </label>

Locator example:

//div[@class='btn-group']
property selected

Return name of a button that is currently selected in the group

select(name)

Select specific radio button in the group

class airgun.widgets.DateTime(parent, logger=None, **kwargs)

Collection of date picker and two inputs for hours and minutes

Example html representation:

<div name="syncPlanForm">
    <div ... label="Start Date">
        <label for="startDate" class="ng-binding">Start Date</label>
        <input type="text" uib-datepicker-popup="" id="startDate" ...>
        <span class="input-group-btn">
            <button type="button" class="btn btn-default"...>
                <i class="fa fa-calendar"></i>
    <div ...label="Start Time">
        <label for="" class="ng-binding">Start Time</label>
            <div show-meridian="false" id="startTime" ...>
                <table...>
...

Locator example:

We don't need to pass locator here as widget seems has one structure
across all applications that use paternfly pattern
start_date
hours
minutes
fill(values)

Fills the widget accordingly to provided values.

Parameters

values – dict with keys start_date and/or hours, and/or minutes containing values that should be present in the fields

read()

Read current widget values and put them into the dict

Parameters

values – dict with key/value pairs for all widget fields

class airgun.widgets.DatePickerInput(parent, name=None, id=None, locator=None, logger=None)

Input for date, which opens calendar on click.

Example html representation:

<input type="date" uib-datepicker-popup="" ng-model="rule.start_date"
 ng-model-options="{timezone: 'UTC'}" is-open="date.startOpen"
 ng-click="openStartDate($event)">
    <div uib-datepicker-popup-wrap="" ng-model="date"
     ng-change="dateSelection(date)"
     template-url="uib/template/datepickerPopup/popup.html">
        <ul role="presentation" class="uib-datepicker-popup ..."
         ng-if="isOpen" ng-keydown="keydown($event)"
         ng-click="$event.stopPropagation()">
        ...
    </div>
    <span class="input-group-btn">
            <button class="btn btn-default" type="button"
             ng-click="openStartDate($event)">
                <i class="fa fa-calendar inline-icon"></i>
        </button>
    </span>

Locator example:

".//input[@ng-model='rule.start_date']"
CALENDAR_POPUP = ./parent::div/div[@ng-model='date']/ul[contains(@class, 'datepicker-popup')]
calendar_button
clear_button
done_button
property is_open

Bool value whether the calendar is opened or not

clear()

Clear input value. Opens calendar popup if it’s closed and pushes ‘Clear’ button.

close_calendar()

Closes calendar popup if it’s opened.

fill(value)

Custom fill which uses custom clear() and closes calendar popup after filling.

class airgun.widgets.ItemsList(parent, locator, logger=None)

List with click-able elements. Part of MultiSelect or jQuery drop-down.

Example html representation:

<ul class="ms-list" tabindex="-1">

Locator example:

//ul[@class='ms-list']
ITEM = ./li[not(contains(@style, 'display: none'))][normalize-space(.)='{}']
ITEMS = ./li[not(contains(@style, 'display: none'))]
read()

Return a list of strings representing elements in the ItemsList.

fill(value)

Clicks on element inside the list.

Parameters

value – string with element name

class airgun.widgets.AddRemoveItemsList(parent, locator, logger=None)

Similar to ItemsList widget except list elements can be selected only using ‘Add’ and ‘Remove’ buttons near each of it

Example html representation:

<ul class="config_group_group">
    <li id="config_group_1" class="config_group ">
        <span>
            <a onclick="expandClassList...">
        </span>
        <a onclick="addConfigGroup(this)">Add</a>
    </li>
</ul>

Locator example:

//ul[@id='selected_config_groups']
ITEM_BUTTON = ./li[not(contains(@style, 'display: none'))][contains(., '{}')]/a
ITEMS = ./li[not(contains(@style, 'display: none'))]/span/a
read()

Return a list of strings representing elements in the AddRemoveItemsList.

fill(value)

Clicks on whether Add or Remove button for necessary element from the list.

Parameters

value – string with element name

class airgun.widgets.ItemsListGroup(parent, locator, logger=None)

Similar to ItemsList widget ideology, but here we have group of items lists instead. Each item list element from such group is placed inside expandable section

Example html representation:

<ul class="puppetclass_group">
    <li>
        <a onclick="expandClassList...">
            stdlib
        </a>
        <ul id="pc_stdlib">
            <li class="puppetclass">
                <span>
                    <a...>stdlib</a>
                </span>

            </li>
            <li class="puppetclass ">
                <span>
                    <a...>stdlib::stages</a>
                </span>
        </li>
    </li>
</ul>

Locator example:

//div[contains(@class, 'available_classes')]/div[@class='row']
ITEM = ./div/ul/li/ul/li[not(contains(@style, 'display: none'))][normalize-space(.)='{}']/span/a
ITEMS = ./div/ul/li/ul/li[not(contains(@style, 'display: none'))]
EXPAND = ./div/ul/li/ul/li[not(contains(@style, 'display:...
read()

Each object should implement read so it is easy to get the value of such object.

When you implement this method, the exact return value is up to you but it MUST be consistent with what fill() takes.

fill(value)

Interactive objects like inputs, selects, checkboxes, et cetera should implement fill.

When you implement this method, it MUST ALWAYS return a boolean whether the value was changed. Otherwise it can break.

For actual filling, please use fill_with(). It offers richer interface for filling.

Returns

A boolean whether it changed the value or not.

class airgun.widgets.ItemsListReadOnly(parent, locator, logger=None)

List with click-able elements. Part of MultiSelect or jQuery drop-down.

Example html representation:

<ul class="ms-list" tabindex="-1">

Locator example:

//ul[@class='ms-list']
fill(value)

Clicks on element inside the list.

Parameters

value – string with element name

class airgun.widgets.MultiSelect(parent, locator=None, id=None, logger=None)

Typical two-pane multiselect jQuery widget. Allows to move items from list of unassigned entities to list of assigned ones and vice versa.

Examples on UI:

Hosts -> Architectures -> any -> Operating Systems
Hosts -> Operating Systems -> any -> Architectures

Example html representation:

<div class="ms-container" id="ms-operatingsystem_architecture_ids">

Locator examples:

//div[@id='ms-operatingsystem_architecture_ids']
id='ms-operatingsystem_architecture_ids'
filter
unassigned
assigned
fill(values)

Read current values, find the difference between current and passed ones and fills the widget accordingly.

Parameters

values – dict with keys assigned and/or unassigned, containing list of strings, representing item names

read()

Returns a dict with current lists values.

class airgun.widgets.PuppetClassesMultiSelect(parent, locator=None, id=None, logger=None)

Widget has different appearance than MultiSelect, because there are no actual panes, but logically it is the same. It looks like two lists of items and specific for puppet classes functionality. Allows to move items from list of ‘available’ entities to list of ‘included’ ones and vice versa. Named these lists as ‘assigned’ and ‘unassigned’ for proper inheritance.

Examples on UI::

Hosts -> Create Host -> Puppet Classes Configure -> Config Groups

Example html representation:

<div class="row">
    <div>
        <h3>Included Classes</h3>
        <ul id="selected_classes">
        </ul>
    </div>

    <div>
         <h3>Available Classes</h3>
         <ul class="puppetclass_group">
         </ul>
    </div>
</div>
Locator examples::

Usually it is empty locator, because it is impossible to build relative path

filter
assigned
unassigned
class airgun.widgets.ConfigGroupMultiSelect(parent, locator=None, id=None, logger=None)

Similar to the PuppetClassesMultiSelect widget except items lists has different appearance and there is no filter field for available classes. Usually specific for config group functionality.

filter
assigned
unassigned
class airgun.widgets.ActionsDropdown(parent, locator, logger=None)

List of actions, expandable via button with caret. Usually comes with button attached on left side, representing either most common action or hint like ‘Select Action’.

Example html representation:

<div class="btn-group dropdown" is-open="status.isOpen">
  <button type="button" class="btn btn-default" ...>
    <span><span >Select Action</span></span>
  </button>
  <button type="button" class="btn btn-default" ...>
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu dropdown-menu-right ng-scope" role="menu">
    <li role="menuitem"><a><span><span>Action1</span></span></a></li>
    <li role="menuitem"><a><span><span>Action2</span></span></a></li>
  </ul>
</div>

Locator example:

//div[contains(@class, 'dropdown')]
//div[contains(@class, 'btn-group')]
dropdown
pf4_drop_down
button
ITEMS_LOCATOR = .//ul/li/a
ITEM_LOCATOR = .//ul/li/a[normalize-space(.)="{}"]
property is_open

Checks whether dropdown list is open.

open()

Opens dropdown list

close()

Closes dropdown list

property items

Returns a list of all dropdown items as strings.

select(item)

Selects item from dropdown.

fill(item)

Selects action. Apart from dropdown also checks attached button label if present

read()

Returns a list of available actions.

class airgun.widgets.Pf4ActionsDropdown(parent, locator, logger=None)

PF4 version of actions dropdown with support for items description

Example html representation:

<div class="pf-c-dropdown pf-m-expanded" data-ouia-component-type="PF4/Dropdown">
  <div class="pf-c-dropdown__toggle pf-m-split-button pf-m-action">
      <button class="pf-c-dropdown__toggle-button">Schedule a job</button>
      <button class="pf-c-dropdown__toggle-button pf-m-secondary">
      </button>
  </div>
  <ul class="pf-c-dropdown__menu" role="menu">
      <li "role="menuitem"><a><div>Run Puppet Once</div></a></li>
      <li "role="menuitem"><a><div>Run OpenSCAP scan</div></a></li>
      <li "role="menuitem"><a><div>Run Ansible roles</div></a></li>
      <li "role="menuitem"><a><div>Enable web console</div></a></li>
  </ul>
</div>
button
dropdown
ITEMS_LOCATOR = .//ul[contains(@class, 'pf-c-dropdown__menu')]/li
ITEM_LOCATOR = .//ul/li[@role='menuitem' and contains(normalize-space(.), '{}')]
property is_open

Checks whether dropdown list is open.

property is_enabled

Check widget is enabled or not.

The logic behind is_enabled is WebElement property. If __locator__ not pointing to the expected WebElement, you can always override this.

Returns

bool

select(item)

Selects item from dropdown.

class airgun.widgets.ActionDropdownWithCheckbox(parent, locator, logger=None)

Custom drop down which contains the checkbox inside in drop down.

customize_check_box
fill(item)

select action from drop down list, after checking customize checkbox :param item: dictionary with values for ‘is_customize’ and ‘action’ keys.

class airgun.widgets.Search(parent, logger=None, **kwargs)

Searchbar for table filtering

ROOT = //div[contains(@class, "toolbar-pf-filter") or contains(@class, "title_filter")or...
search_field
search_button
clear_button
actions
fill(value)

Interactive objects like inputs, selects, checkboxes, et cetera should implement fill.

When you implement this method, it MUST ALWAYS return a boolean whether the value was changed. Otherwise it can break.

For actual filling, please use fill_with(). It offers richer interface for filling.

Returns

A boolean whether it changed the value or not.

read()

Each object should implement read so it is easy to get the value of such object.

When you implement this method, the exact return value is up to you but it MUST be consistent with what fill() takes.

clear()

Clears search field value and re-trigger search to remove all filters.

search(value)
class airgun.widgets.PF4Search(parent, logger=None, **kwargs)

PF4 Searchbar for table filtering

ROOT = //div[@role="combobox" or @aria-haspopup="listbox"]
search_field
clear_button
clear()

Clears search field value and re-trigger search to remove all filters.

search(value)
class airgun.widgets.SatVerticalNavigation(parent, locator, logger=None)

The Patternfly Vertical navigation.

CURRENTLY_SELECTED = .//li[contains(@class, "active")]/a/span
class airgun.widgets.SatFlashMessage(parent, logger=None, **kwargs)

Satellite version of Patternfly alert. It doesn’t contain <strong> tag and all the text is inside 2 <span>.

For more details, see Bugzilla #1566565.

Should not be used directly, only via class:SatFlashMessages.

Example html representation:

<div class="alert toast-pf alert-success alert-dismissable">
        <button ... type="button" class="close close-default">
            <span ... class="pficon pficon-close"></span></button>
        <span aria-hidden="true" class="pficon pficon-ok"></span>
        <span><span>Sample message</span></span></div>
</div>
TYPE_MAPPING
ROOT
TITLE_LOCATOR = .//h4[contains(@class, "alert__title")]
DISMISS_LOCATOR = .//div[contains(@class, "alert__action")]
ICON_LOCATOR = .//div[contains(@class, "alert__icon")]
DESCRIPTION_LOCATOR = .//div[contains(@class, "alert__description")]
property text

Return the message text of the notification.

class airgun.widgets.SatFlashMessages(parent, logger=None, **kwargs)

Satellite version of Patternfly’s alerts section. The only difference is overridden messages property which returns SatFlashMessage.

Example html representation:

<ul class="pf-c-alert-group pf-m-toast"><li>
<div class="pf-c-alert pf-m-success foreman-toast" aria-label="Success Alert"
    data-ouia-component-type="PF4/Alert" data-ouia-safe="true"
    data-ouia-component-id="OUIA-Generated-Alert-success-1">
    <div class="pf-c-alert__icon">

Locator example:

//ul[@class="pf-c-alert-group pf-m-toast"]/li/div[contains(@class, "pf-c-alert")]
ROOT = //ul[@class="pf-c-alert-group pf-m-toast"]
MSG_LOCATOR
msg_class
class airgun.widgets.ValidationErrors(parent, logger=None, **kwargs)

Widget for tracking all improperly filled inputs inside view, which are highlighted with red color and typically contain error message next to them.

Example html representation:

<div class="form-group has-error">
    <label class="..." for="name">DNS Domain *</label>
    <div class="col-md-4">
        <input ... type="text" name="domain[name]" id="domain_name">
        <span class="help-block"></span>
    </div>
    <span class="help-block help-inline">
        <span class="error-message">can't be blank</span>
    </span>
</div>

Locator example:

No locator accepted as widget should look through entire view.
ERROR_ELEMENTS = .//*[contains(@class,'has-error') and not(contains(@style,'display:none'))]
ERROR_MESSAGES = .//*[(contains(@class, 'alert base in fade alert-danger')or contains(@class,'error-msg-block')or...
property has_errors

Returns boolean value whether view has fields with invalid data or not.

property messages

Returns a list of all validation messages for improperly filled fields. Example: [“can’t be blank”]

assert_no_errors()

Assert current view has no validation messages, otherwise rise AssertionError.

read(*args, **kwargs)

Each object should implement read so it is easy to get the value of such object.

When you implement this method, the exact return value is up to you but it MUST be consistent with what fill() takes.

class airgun.widgets.ContextSelector(parent, logger=None, **kwargs)

Base class for all UI objects.

Does couple of things:

  • Ensures it gets instantiated with a browser or another widget as parent. If you create an instance in a class, it then creates a WidgetDescriptor which is then invoked on the instance and instantiates the widget with underlying browser.

  • Implements some basic interface for all widgets.

If you are inheriting from this class, you MUST ALWAYS ensure that the inherited class has an init that always takes the parent as the first argument. You can do that on your own, setting the parent as self.parent or you can do something like this:

def __init__(self, parent, arg1, arg2, logger=None):
    super(MyClass, self).__init__(parent, logger=logger)
    # or if you have somehow complex inheritance ...
    Widget.__init__(self, parent, logger=logger)
CURRENT_ORG
CURRENT_LOC
ORG_LOCATOR = //div[@id="organization-dropdown"]//li[button[contains(.,{})]]
LOC_LOCATOR = //div[@id="location-dropdown"]//li[button[contains(.,{})]]
select_org(org_name)
property current_org
select_loc(loc_name)
property current_loc
read()

As reading organization and location is not atomic operation: needs mouse moves, clicks, etc, and this widget is included in every view - calling airgun.views.common.BaseLoggedInView.read() for any view will trigger reading values of ContextSelector. Thus, to avoid significant performance degradation it should not be readable.

Use current_org() and current_loc() instead.

class airgun.widgets.FilteredDropdown(parent, id=None, locator=None, logger=None)

Drop-down element with filtering functionality

Example html representation:

<div class="select2-container form-control" id="s2id_subnet_boot_mode">

Locator example:

id=subnet_boot_mode
id=s2id_subnet_ipam
selected_value
open_filter
clear_filter
filter_criteria
filter_content
read()

Return drop-down selected item value

clear()

Clear currently selected value for drop-down

fill(value)

Select specific item from the drop-down

Parameters

value – string with item value

class airgun.widgets.CustomParameter(parent, **kwargs)

Name-Value paired input elements which can be added, edited or removed.

It is essentially a table with text input widgets on each row, with an “Add New Parameter” button on the same page.

Example html representation:

<table class="table" id="global_parameters_table">
    <tr class="fields " id="new_os_parameter_row">
        <input placeholder="Name" type="text" ... id="..._name">
        <textarea id="new_os_parameter_value" placeholder="Value" ...>

Locator example:

//input[@placeholder='Name']
//textarea[@placeholder='Value']
add_new_value
read()

Return a list of dictionaries. Each dictionary consists of name and value parameters

add(value)

Add single name/value parameter entry to the table.

Parameters

value – dict with format {‘name’: str, ‘value’: str}

remove(name)

Remove parameter entries from the table based on name.

Parameters

value – dict with format {‘name’: str, ‘value’: str}

fill(values)

Fill parameter entries. Existing values will be overwritten.

Updates name/value pairs if the name is already in the list.

If you desire to intentionally add a duplicate value, use self.add()

Parameters

values – either single dictionary of name and value, or list of name/value dictionaries

class airgun.widgets.ConfirmationDialog(parent, logger=None, **kwargs)

Usual confirmation dialog with two buttons and close ‘x’ button in the right corner. Has nothing in common with javascript alert, confirm or prompt pop-ups.

Example html representation:

<div class="modal-content">
    <button type="button" class="close" ... ng-click="cancel()">
    <div class="modal-footer ng-scope">
        <button class="btn btn-danger" ng-click="ok()">
        <button class="btn ..." ng-click="cancel()"...>

Locator example:

//div[@class='modal-content']
ROOT = .//div[@class='modal-content']
confirm_dialog
cancel_dialog
discard_dialog
_check_is_displayed(elem)

This is to check if dialog is displayed

confirm()

Clicks on the positive outcome button like ‘Remove’, ‘Ok’, ‘Yes’

cancel()

Clicks on the negative outcome button like ‘Cancel’ or ‘No’

read()

Widgets has no fields to read

class airgun.widgets.Pf4ConfirmationDialog(parent, logger=None, **kwargs)

PF4 confirmation dialog with two buttons and close ‘x’ button in the right corner.

ROOT = //div[@id="app-confirm-modal" or @data-ouia-component-type="PF4/ModalContent"]
confirm_dialog
cancel_dialog
discard_dialog
class airgun.widgets.LCESelector(parent, locator=None, logger=None)

Group of checkboxes that goes in a line one after another. Usually used to specify lifecycle environment

Example html representation:

<ul[@class='path-list']>
    <li class="path-list-item ng-scope"...>
        <label class="path-list-item-label...>
            <input type="checkbox"...>
    <li class="path-list-item ng-scope"...>
        <label class="path-list-item-label...>
            <input type="checkbox"...>

Locator example:

//ul[@class='path-list']
ROOT
LABELS = ./li/label[contains(@class, path-list-item-label)]
CHECKBOX = .//input[@ng-model="item.selected"][parent::label[contains(., "{}")]]
checkbox_selected(locator)

Identify whether specific checkbox is selected or not

select(locator, value)

Select or deselect checkbox depends on the value passed

read()

Return a dictionary where keys are lifecycle environment names and values are booleans whether they’re selected or not.

fill(value)

Assign value for specific checkbox from group

Parameters

value – dictionary that consist of single checkbox name and value that should be assigned to that checkbox

class airgun.widgets.LimitInput(parent, logger=None, **kwargs)

Input for managing limits (e.g. Hosts limit). Consists of ‘Unlimited’ checkbox and text input for specifying the limit, which is only visible if checkbox is unchecked.

Example html representation:

<input type="checkbox" name="limit"
 ng-model="activationKey.unlimited_hosts"...>

<input id="max_hosts" name="max_hosts"
 ng-model="activationKey.max_hosts"
 ng-required="!activationKey.unlimited_hosts" type="number" min="1"
 max="2147483648"...>

Locator example:

No locator accepted as widget consists of multiple other widgets in
different parts of DOM. Please use View's ``ROOT`` for proper isolation
if needed.
unlimited
limit
fill(value)

Handle ‘Unlimited’ checkbox before trying to fill text input.

Parameters

value – either ‘Unlimited’ (case insensitive) to select corresponding checkbox or value to fill text input with.

read()

Return either ‘Unlimited’ if corresponding checkbox is selected or text input value otherwise.

class airgun.widgets.TextInputHidden(parent, name=None, id=None, locator=None, logger=None)

Text input widget with content that may be hidden

read()

Each object should implement read so it is easy to get the value of such object.

When you implement this method, the exact return value is up to you but it MUST be consistent with what fill() takes.

class airgun.widgets.EditableEntry(parent, locator=None, name=None, logger=None)

Usually represented by static field and edit button that transform field into control to change field content to specific value. That control can have different appearances like textarea, input, select and etc. That widget is specific for entity edit pages.

Example html representation:

<dl>
    <dt>
    <dd>
        <form>
        ...
            <span class="fr" ng-hide="editMode || readonly"...>
            <span class="editable-value ng-binding">

Locator example:

//dt[contains(., 'test')]/following-sibling::dd/span
//dt[contains(., 'test')]/following-sibling::dd/input
edit_button
edit_field
save_button
cancel_button
entry_value
fill(value)

Fill widget with necessary value

Parameters

value – string with value that should be used for field update procedure

read()

Returns string with current widget value

class airgun.widgets.EditableEntrySelect(parent, locator=None, name=None, logger=None)

Should be used in case EditableEntry widget represented not by a field, but by select list.

edit_field
class airgun.widgets.EditableEntryCheckbox(parent, locator=None, name=None, logger=None)

Should be used in case EditableEntry widget represented not by a field, but by checkbox.

edit_field
class airgun.widgets.CheckboxGroup(parent, locator, logger=None)

A set of checkboxes of the same property type

ITEMS_LOCATOR = .//p
CHECKBOX_LOCATOR = .//p[normalize-space(.)="{}"]/input
checkboxes()
read()

Read values of checkboxes

fill(values)

Check or uncheck one of the checkboxes

Parameters

value – string with specification of fields’ values Example: value={‘details.addons’: {‘Test addon 1’: True, ‘Test addon 2’: False}}

class airgun.widgets.EditableEntryMultiCheckbox(parent, locator=None, name=None, logger=None)

Should be used in case EditableEntry widget represented not by a field, but by a set of checkboxes.

edit_field
class airgun.widgets.TextInputsGroup(parent, locator, logger=None)

A set of text inputs

FIELD_LABELS = .//div[contains(@id,"template-input-")]//label
TEXTINPUT_LOCATOR = .//div[contains(@id,"template-input-")]//label[normalize-space(.)="{}"]/following-sibling::div//input
labels()
textinputs()
read()

Read values of text inputs

fill(values)

Fill one of the text inputs

Parameters

value – string with specification of fields’ values Example: value={‘Hosts filter’: ‘name=host11.example.com’, ‘Errata filter’: ‘whatever’}

class airgun.widgets.EditableLimitEntry(parent, locator=None, name=None, logger=None)

Should be used in case EditableEntry widget represented not by a field, but by LimitInput widget.

edit_field
class airgun.widgets.EditableDateTime(parent, locator=None, name=None, logger=None)

Should be used in case EditableEntry widget represented not by a field, but by DateTime widget.

edit_field
class airgun.widgets.ReadOnlyEntry(parent, locator=None, name=None, logger=None)

Similar to EditableEntry and specific for the same page types, but cannot be modified.

Example html representation:

<dl>
    <dt>
    <dd>
        <form>
        ...
            <span class="ng-scope">No</span>

Locator example:

//dt[contains(., 'test')]/following-sibling::dd
//dt[contains(., 'test')]/following-sibling::dd/span
entry_value
BASE_LOCATOR = .//dt[contains(., '{}')]/following-sibling::dd[not(contains(@class, 'ng-hide'))][1]
read()

Returns string with current widget value

class airgun.widgets.ACEEditor(parent, logger=None)

Default ace editor

Example html representation:

<div id="editor-000" class="editor ace_editor ace-twilight ace_dark">
    <textarea class="ace_text-input"
    <div class="ace_gutter" style="display: none;">
        <div class="ace_layer ace_gutter-layer ace_folding-enabled">
    <div class="ace_scroller">
    <div class="ace_content">
        ...

Locator example:

There is no need to provide any locators to that widget
ROOT = //div[contains(@class, 'ace_editor')]
fill(value)

Fill widget with necessary value

Parameters

value – string with value that should be used for field update procedure

read()

Returns string with current widget value

class airgun.widgets.Pagination(parent, logger=None, **kwargs)

Represents Paginator widget that includes per page selector, First/Last/Next/Prev buttons and current page index/overall amount of pages. Mainly used with Table widget.

ROOT = .//form[contains(@class, 'content-view-pf-pagination')]
PER_PAGE_BUTTON_DROPDOWN = .//div[button[@id='pagination-row-dropdown']]
PER_PAGE_SELECT = .//select[contains(@ng-model, 'per_page')]
first_page_button
previous_page_button
next_page_button
last_page_button
page
pages
total_items
per_page()

Return the per page widget

property is_displayed

Check whether this Pagination widget exists and visible

_click_button(pager_button)

Click on the pager button if enabled.

first_page()

Goto first page by clicking on first page button

previous_page()

Goto previous page by clicking on previous page button

next_page()

Goto next page by clicking on next page button

last_page()

Goto last page by clicking on last page button

property current_page

Return the current page as integer value

property total_pages

Return the total available pages as integer value

read()

Read the basic sub widgets of this pagination widget

fill(values)

Fill sub widgets with the supplied values

class airgun.widgets.SatTablePagination(parent, logger=None, **kwargs)

Paginator widget for use within SatTable.

ROOT = //form[contains(@class, 'content-view-pf-pagination')]
class airgun.widgets.SatTable(parent, locator, column_widgets=None, assoc_column=None, rows_ignore_top=None, rows_ignore_bottom=None, top_ignore_fill=False, bottom_ignore_fill=False, logger=None)

Satellite version of table.

Includes a paginator sub-widget. If found, then the paginator is used to read all entries from the table.

If the table is empty, there might be only one column with an appropriate message in the table body, or it may have no columns or rows at all. This subclass handles both possibilities.

Example html representation:

<table bst-table="table" ...>
   <thead>
     <tr class="ng-scope">
       <th class="row-select"><input type="checkbox" ...></th>
       <th ng-click="table.sortBy(column)" ...>
        <span ...><span ...>Column Name</span></span><i ...></i></th>
       <th ng-click="table.sortBy(column)" ...>
        <span ...><span ...>Column Name</span></span><i ...></i></th>
     </tr>
   </thead>
   <tbody>
    <tr id="noRowsTr"><td colspan="9">
         <span data-block="no-rows-message" ...>
            <span class="ng-scope">Table is empty</span></span>
    </td></tr>
   </tbody>
 </table>

Locator example:

.//table
no_rows_message = .//td/span[contains(@data-block, 'no-rows-message') or contains(@data-block,...
tbody_row
pagination
property has_rows

Boolean value whether table contains some elements (rows) or is empty.

read()

Return empty list in case table is empty

_read_all()

Return all available table values with using pagination navigation.

class airgun.widgets.SatSubscriptionsTable(parent, locator, column_widgets=None, assoc_column=None, rows_ignore_top=None, rows_ignore_bottom=None, top_ignore_fill=False, bottom_ignore_fill=False, logger=None)

Subscriptions table, which has extra preceding row for ‘Repository Name’ column. It’s equal to satellite table in all other respects.

Example:

Following table cells:

TestSubscriptionName
1|0 out of Unlimited|Physical|Start_Date|End_Date|Support_Level
TestSubscriptionName2
1|0 out of Unlimited|Physical|Start_Date|End_Date|Support_Level

Will be transformed into:

TestSubscriptionName|1|0 out of Unlimited|Physical|Start_Date|...
TestSubscriptionName2|1|0 out of Unlimited|Physical|Start_Date|...

So, title rows will be removed in favor of extra column 'Repository
Name'.

Example html representation:

<table bst-table="table" ...>
 ...
 <tbody>
    <!-- ngRepeat: (name, subscriptions) in groupedSubscriptions -->
    ...
 </tbody>
</table>

Locator example:

.//table
title_rows
rows(*extra_filters, **filters)

Split list of all the rows into ‘content’ rows and ‘title’ rows. Return content rows only.

read()

Return content rows with 1 extra column ‘Repository Name’ in it.

class airgun.widgets.SatTableWithoutHeaders(parent, locator, column_widgets=None, assoc_column=None, rows_ignore_top=None, rows_ignore_bottom=None, top_ignore_fill=False, bottom_ignore_fill=False, logger=None)

Applicable for every table in application that has no headers. Due logic of the Table widget we have to explicitly specify custom headers. As we have no idea about the content and structure of the table in advance, we will dynamically name each column using simple - ‘column1’, ‘column2’, … ‘columnN’.

Example html representation:

<table>
    <tbody>
        <tr>
            <td>Name</td>
            <td>my_host</td>
            <td>my_new_host</td>
        </tr>
        <tr>
            <td>Arhitecture</td>
            <td>x32</td>
            <td>x64</td>
        </tr>
    </tbody>
</table>

Locator example:

//table[@id='audit_table']
ROWS = ./tbody/tr
COLUMNS = ./tbody/tr[1]/td
ROW_AT_INDEX = ./tbody/tr[{0}]
HEADER_IN_ROWS
HEADERS
property _is_header_in_body

Explicitly return False as there is no header row in this table.

headers()
class airgun.widgets.SatTableWithUnevenStructure(parent, locator, column_locator='.', logger=None)

Applicable for every table in application that has uneven amount of headers and columns(usually we talk about 1 header but 2 columns) We taking into account that all possible content rows are actually present in DOM, but some are ‘hidden’ using css class. Also we can specify what widget we expect in a second column (e.g. link or text)

Some examples where we can use current class: ‘Content Counts’ table present in every repository, containing amount of packages/source RPM’s/Errata/etc with links to corresponding details pages. ‘Properties’ table present in every host details page

Example html representation:

<table class="table table-striped table-bordered">
    <thead>
    <tr>
      <th colspan="2" ...>Content Type</th>
    </tr>
    </thead>

    <tbody>
    <tr ng-show="repository.content_type === 'yum'" class="ng-hide" style="">
      <!-- translate: --><td translate="" class="ng-scope" style="">Packages</td>
      <td class="align-center">
        <a ui-sref="product.repository.manage-content.packages(...)" class="ng-binding"
          href=".../repositories/<repo-id>/content/packages">
          0
        </a>
      </td>
    </tr>

    ...

    <tr ng-show="repository.content_type === 'docker'">
      <!-- translate: -->
        <td translate="" class="ng-scope" style="">Container Image Manifests</td>
      <td class="align-center">
        <a ui-sref="product.repository.manage-content.docker-manifests(...)"
          class="ng-binding"
          href=".../repositories/<repo-id>/content/content/docker_manifests">
          0
        </a>
      </td>
    </tr>
    ...
    </tbody>
</table>

Locator example:

.//table[//th[normalize-space(.)="Content Type"]]
//table[@id='properties_table']
read()

Returns a dict with {column1: column2} values, and only for rows which aren’t marked as hidden.

Example:

{
    'Packages': '1',
    'Package Groups': '0'
    'Status': 'OK'
    'Domain': 'domain_name'
}
class airgun.widgets.ProgressBar(parent, locator=None, logger=None)

Generic progress bar widget.

Example html representation:

<div class="progress ng-isolate-scope" type="success" ...>
  <div class="progress-bar progress-bar-success" aria-valuenow="0"
   aria-valuemin="0" aria-valuemax="100" aria-valuetext="0%" ...></div>
</div>

Locator example:

.//div[contains(@class, "progress progress-striped")]
PROGRESSBAR = .//div[contains(@class,"progress-bar")]
property is_active

Boolean value whether progress bar is active or not (stopped, pending or any other state).

property progress

String value with current flow rate in percent.

property is_completed

Boolean value whether progress bar is finished or not

wait_for_result(timeout=600, delay=1)

Waits for progress bar to finish. By default checks whether progress bar is completed every second for 10 minutes.

Parameters
  • timeout – integer value for timeout in seconds

  • delay – float value for delay between attempts in seconds

read()

Returns current progress.

class airgun.widgets.PublishPromoteProgressBar(parent, locator=None, logger=None)

Progress bar for Publish and Promote procedures. They contain status message and link to associated task. Also the progress is displayed slightly differently.

Example html representation:

<a ng-href="/foreman_tasks/tasks/71196" ng-hide="hideProgress(version)"
 href="/foreman_tasks/tasks/...71196">

  <div ng-class="{ active: taskInProgress(version) }"
   class="progress progress-striped">
    <div class="progress ng-isolate-scope" animate="false" ...>
    <div class="progress-bar" aria-valuenow="" aria-valuemin="0"
     aria-valuemax="100" aria-valuetext="%" ...></div></div>
  </div>
  Publishing and promoting to 1 environment.
</a>
<span ng-show="hideProgress(version)" ...>
  Published
  (2018-05-07 18:10:14 +0300)
</span>

Locator example:

.//div[contains(@class, "progress progress-striped")]
ROOT = .
TASK
MESSAGE
property is_completed

Boolean value whether progress bar is finished or not

read()

Returns message with either progress or result, depending on its status.

class airgun.widgets.PieChart(parent, locator, logger=None)

Default Pie Chart that can be found across application. At that moment only return values that displayed inside of the chart

chart_title_text
chart_title_value
read()

Return dictionary that contains chart title name as key and chart value as its value

class airgun.widgets.RemovableWidgetsItemsListView(parent, logger=None, **kwargs)

A host for widgets list. Items that can be added or removed, mainly used in profile for network interfaces, storage and job template.

Usage:

@View.nested
class resources(RemovableWidgetsItemsListView):
    ROOT = "//fieldset[@id='storage_volumes']"
    ITEMS = "./div/div[contains(@class, 'removable-item')]"
    ITEM_WIDGET_CLASS = ComputeResourceRHVProfileStorageItem
ITEMS = ./div[contains(@class, 'removable-item')]
ITEM_WIDGET_CLASS
ITEM_REMOVE_BUTTON_ATTR = remove_button
add_item_button
_get_item_locator(index)

Return the item locator located at index position

get_item_at_index(index)

Return the item widget instance at index

add_item()

Add an item by pressing the add_item button and return the item instance

remove_item(item)

Remove item widget by clicking on it’s remove button

remove_item_at_index(index)

Remove item at index

property items_length
property items

Return all the items widget instances

clear()

Remove all items if item remove button attribute defined.

read()

Read all items

fill(values)

Fill all items. :param values: A list of values to fill the item widgets with.

class airgun.widgets.GenericRemovableWidgetItem(parent, locator, logger=None)

Generic Item widget (to be inherited) and to be used as Widget Item for RemovableWidgetsItemsListView.

remove_button
context
read()

Each object should implement read so it is easy to get the value of such object.

When you implement this method, the exact return value is up to you but it MUST be consistent with what fill() takes.

fill(values)

Interactive objects like inputs, selects, checkboxes, et cetera should implement fill.

When you implement this method, it MUST ALWAYS return a boolean whether the value was changed. Otherwise it can break.

For actual filling, please use fill_with(). It offers richer interface for filling.

Returns

A boolean whether it changed the value or not.

class airgun.widgets.AutoCompleteTextInput(parent, name=None, id=None, locator=None, logger=None)

Autocomplete Search input field, We must remove the focus from this widget after fill to force the auto-completion list to be hidden. Since this is a react component, calling browser clear method directly on the field has no effect, thus we need to clear the field using the clear button attached to the input

clear_button
clear()

Clears search field value and re-trigger search to remove all filters.

fill(value)

Interactive objects like inputs, selects, checkboxes, et cetera should implement fill.

When you implement this method, it MUST ALWAYS return a boolean whether the value was changed. Otherwise it can break.

For actual filling, please use fill_with(). It offers richer interface for filling.

Returns

A boolean whether it changed the value or not.

class airgun.widgets.ToggleButton(parent, *text, locator=None, **kwargs)

A simple toggle button that we can read/write it’s state via the standard view functions read/fill

__locator__()
fill(value)

Interactive objects like inputs, selects, checkboxes, et cetera should implement fill.

When you implement this method, it MUST ALWAYS return a boolean whether the value was changed. Otherwise it can break.

For actual filling, please use fill_with(). It offers richer interface for filling.

Returns

A boolean whether it changed the value or not.

read()

Widget.read override, use text

A link representation that we can read/click via the standard view functions read/fill.

fill(value)

Interactive objects like inputs, selects, checkboxes, et cetera should implement fill.

When you implement this method, it MUST ALWAYS return a boolean whether the value was changed. Otherwise it can break.

For actual filling, please use fill_with(). It offers richer interface for filling.

Returns

A boolean whether it changed the value or not.

class airgun.widgets.PopOverModalView(parent, logger=None, **kwargs)

Popover-content UI widget which contains header, drop_down, input_box, or textarea and submit button. This is associated within a table.

Example html representation:

<div class="modal-content" role="document">
    <h4 class="modal-title">Update value for Connect by IP setting</h4>
    <form class="form-horizontal well">
        <select name="value" class="form-control">
            <option value="true">Yes</option>
            <option value="false">No</option>
        <div class="form-actions">
            <button type="submit" class="btn btn-primary">

<div class="modal-content" role="document">
    <h4 class="modal-title">Update value for Administrator email address setting</h4>
    <form class="form-horizontal well">
        <input name="value" class="form-control" value="root@rhts.example.com">
        <div class="form-actions">
            <button type="submit" class="btn btn-primary">

Locator example:

//div[contains(@class,'modal-content')]
ROOT = //div[contains(@class,'modal-content')]
header
input_box
textarea
drop_down
submit
class airgun.widgets.PopOverWidget(parent, logger=None, **kwargs)

Popover-content UI widget which contains header, drop_down, input_box, or textarea and submit button. This is associated within a table.

Locator example:

//div[contains(@class, 'editable-open')]
ROOT = .
column_value
pop_over_view
fill(item)

Selects value from drop_down if exist otherwise write into input_box or textarea

read()

read column updated value

class airgun.widgets.AuthSourceAggregateCard(parent, name, locator=None, action_title=None, logger=None)

This is a customizable card widget which has the title, count and kebab widget

Example html representation:

<div class="card-pf-body">
    <div class="dropdown pull-right dropdown-kebab-pf">
        <ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropupKebabRight2">
            <li><a href="/auth_source_externals/3/edit">Edit</a></li>
        </ul>
    </div>
    <h2 class="card-pf-title text-center">
            External
    </h2>
    <div class="card-pf-items text-center">
        <div class="card-pf-item">
            <span class="pficon pficon-users"></span>
            <span class="card-pf-item-text"><a href="">10</a></span>
        </div>
    </div>
</div>
ROOT
select_kebab
COUNT = .//span[@class='card-pf-item-text']
property count

Count of sources :return int: None if no count element is found, otherwise count of sources in the card

class airgun.widgets.Accordion(parent=None, id=None, locator=None, logger=None)

PF4 Accordion widget

ROOT
ITEMS = .//button[contains(@class, 'pf-c-accordion__toggle')]
ITEM = .//span[contains(normalize-space(.), '{}')]
items()
toggle(value)
class airgun.widgets.BaseMultiSelect(parent: widgetastic.types.ViewParent, component_id: Optional[str] = None, logger: Optional[logging.Logger] = None, component_type: Optional[str] = None)

Represents the Patternfly Multi Select.

https://www.patternfly.org/v4/documentation/react/components/select#multiple

BUTTON_LOCATOR = .//button[@aria-label="Options menu"]
OUIA_COMPONENT_TYPE = PF4/Select
item_select(items, close=True)

Opens the Dropdown and selects the desired items.

Parameters
  • items – Items to be selected

  • close – Close the dropdown when finished

fill(items)

Fills all the items.

Parameters

items – list containing what items to be selected

class airgun.widgets.InventoryBootstrapSwitch(parent, class_name, **kwargs)

Checkbox-like Switch control, representing On and Off state. But with fancy UI and without any <form> elements. There’s also BootstrapSwitch widget in widgetastic_patternfly, but we don’t inherit from it as it uses completely different HTML structure than this one (it has underlying <input>).

ON_TOGGLE = .//span[contains(@class, 'bootstrap-switch-handle-on')]
OFF_TOGGLE = .//span[contains(@class, 'bootstrap-switch-handle-off')]
ROOT
property selected
property _clickable_el

In automation, you need to click on exact toggle element to trigger action

Returns: selenium webelement

fill(value)

Interactive objects like inputs, selects, checkboxes, et cetera should implement fill.

When you implement this method, it MUST ALWAYS return a boolean whether the value was changed. Otherwise it can break.

For actual filling, please use fill_with(). It offers richer interface for filling.

Returns

A boolean whether it changed the value or not.

read()

Each object should implement read so it is easy to get the value of such object.

When you implement this method, the exact return value is up to you but it MUST be consistent with what fill() takes.