airgun.widgets

Module Contents

class airgun.widgets.SatSelect

Bases: widgetastic.widget.Select

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

SELECTED_OPTIONS_TEXT
class airgun.widgets.CheckboxWithAlert

Bases: widgetastic.widget.Checkbox

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

fill(self, value)
class airgun.widgets.RadioGroup

Bases: widgetastic.widget.GenericLocatorWidget

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"]
button_names

Return all radio group labels

selected

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

_get_parent_label(self, name)

Get radio group label for specific button

select(self, name)

Select specific radio button in the group

read(self)

Wrap method according to architecture

fill(self, name)

Wrap method according to architecture

class airgun.widgets.ToggleRadioGroup

Bases: airgun.widgets.RadioGroup

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']
selected

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

select(self, name)

Select specific radio button in the group

class airgun.widgets.DateTime

Bases: widgetastic.widget.Widget

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(self, 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(self)

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

Bases: widgetastic.widget.TextInput

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
is_open

Bool value whether the calendar is opened or not

clear(self)

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

close_calendar(self)

Closes calendar popup if it’s opened.

fill(self, value)

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

class airgun.widgets.ItemsList

Bases: widgetastic.widget.GenericLocatorWidget

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(.)='%s']
ITEMS = ./li[not(contains(@style, 'display: none'))]
read(self)

Return a list of strings representing elements in the ItemsList.

fill(self, value)

Clicks on element inside the list.

Parameters:value – string with element name
class airgun.widgets.AddRemoveItemsList

Bases: widgetastic.widget.GenericLocatorWidget

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(., '%s')]/a
ITEMS = ./li[not(contains(@style, 'display: none'))]/span/a
read(self)

Return a list of strings representing elements in the AddRemoveItemsList.

fill(self, value)

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

Parameters:value – string with element name
class airgun.widgets.ItemsListGroup

Bases: widgetastic.widget.GenericLocatorWidget

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(.)='%s']/span/a
ITEMS = ./div/ul/li/ul/li[not(contains(@style, 'display: none'))]
EXPAND = ./div/ul/li/ul/li[not(contains(@style, 'display: none'))][normalize-space(.)='%s']/../preceding-sibling::a
read(self)
fill(self, value)
class airgun.widgets.ItemsListReadOnly

Bases: airgun.widgets.ItemsList

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

Bases: widgetastic.widget.GenericLocatorWidget

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(self, 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(self)

Returns a dict with current lists values.

class airgun.widgets.PuppetClassesMultiSelect

Bases: airgun.widgets.MultiSelect

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

Bases: airgun.widgets.MultiSelect

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

Bases: widgetastic.widget.GenericLocatorWidget

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
button
ITEMS_LOCATOR = .//ul/li/a
ITEM_LOCATOR = .//ul/li/a[normalize-space(.)="{}"]
is_open

Checks whether dropdown list is open.

items

Returns a list of all dropdown items as strings.

open(self)

Opens dropdown list

select(self, item)

Selects item from dropdown.

fill(self, item)

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

read(self)

Returns a list of available actions.

class airgun.widgets.ActionDropdownWithCheckbox

Bases: airgun.widgets.ActionsDropdown

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

customize_check_box
fill(self, 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

Bases: widgetastic.widget.Widget

Searchbar for table filtering

search_field
search_button
clear_button
actions
fill(self, value)
read(self)
clear(self)

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

search(self, value)
class airgun.widgets.SatVerticalNavigation

Bases: widgetastic_patternfly.VerticalNavigation

The Patternfly Vertical navigation.

CURRENTLY_SELECTED = .//li[contains(@class, "active")]/a/span
class airgun.widgets.SatFlashMessages

Bases: widgetastic_patternfly.FlashMessages

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

Example html representation:

<div class="toast-notifications-list-pf">
    <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>
</div>

Locator example:

//div[@class="toast-notifications-list-pf"]
messages
assert_no_error(self, ignore_messages=None)
dismiss(self)
class airgun.widgets.SatFlashMessage

Bases: widgetastic_patternfly.FlashMessage

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>
text
class airgun.widgets.ValidationErrors

Bases: widgetastic.widget.Widget

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,'error-msg-block') or contains(@class,'error-message') or contains(@class,'editable-error-block')) and not(contains(@style,'display:none'))]
has_errors

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

messages

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

assert_no_errors(self)

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

read(self, *args, **kwargs)
class airgun.widgets.ContextSelector

Bases: widgetastic.widget.Widget

CURRENT_ORG = //li[@id="organization-dropdown"]/a
CURRENT_LOC = //li[@id="location-dropdown"]/a
ORG_LOCATOR = //li[@id="organization-dropdown"]/ul/li/a[contains(.,{})]
LOC_LOCATOR = //li[@id="location-dropdown"]/ul/li/a[contains(.,{})]
current_org
current_loc
select_org(self, org_name)
select_loc(self, loc_name)
read(self)

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)

Bases: widgetastic.widget.GenericLocatorWidget

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(self)

Return drop-down selected item value

clear(self)

Clear currently selected value for drop-down

fill(self, value)

Select specific item from the drop-down

Parameters:value – string with item value
class airgun.widgets.CustomParameter(parent, locator=None, id=None, logger=None)

Bases: widgetastic.widget.Table

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(self)

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

add(self, value)

Add single name/value parameter entry to the table.

Parameters:value – dict with format {‘name’: str, ‘value’: str}
remove(self, name)

Remove parameter entries from the table based on name.

Parameters:value – dict with format {‘name’: str, ‘value’: str}
fill(self, 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

Bases: widgetastic.widget.Widget

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(self, elem)

This is to check if dialog is displayed

confirm(self)

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

cancel(self)

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

read(self)

Widgets has no fields to read

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

Bases: widgetastic.widget.GenericLocatorWidget

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(self, locator)

Identify whether specific checkbox is selected or not

select(self, locator, value)

Select or deselect checkbox depends on the value passed

read(self)

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

fill(self, 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

Bases: widgetastic.widget.Widget

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(self, 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(self)

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

class airgun.widgets.TextInputHidden

Bases: widgetastic.widget.TextInput

Text input widget with content that may be hidden

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

Bases: widgetastic.widget.GenericLocatorWidget

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(self, value)

Fill widget with necessary value

Parameters:value – string with value that should be used for field update procedure
read(self)

Returns string with current widget value

class airgun.widgets.EditableEntrySelect

Bases: airgun.widgets.EditableEntry

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

edit_field
class airgun.widgets.EditableEntryCheckbox

Bases: airgun.widgets.EditableEntry

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

edit_field
class airgun.widgets.CheckboxGroup

Bases: widgetastic.widget.GenericLocatorWidget

A set of checkboxes of the same property type

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

Read values of checkboxes

fill(self, 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

Bases: airgun.widgets.EditableEntry

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

edit_field
class airgun.widgets.TextInputsGroup

Bases: widgetastic.widget.GenericLocatorWidget

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(self)
textinputs(self)
read(self)

Read values of text inputs

fill(self, 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

Bases: airgun.widgets.EditableEntry

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

edit_field
class airgun.widgets.EditableDateTime

Bases: airgun.widgets.EditableEntry

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)

Bases: widgetastic.widget.GenericLocatorWidget

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(self)

Returns string with current widget value

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

Bases: widgetastic.widget.Widget

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(self, value)

Fill widget with necessary value

Parameters:value – string with value that should be used for field update procedure
read(self)

Returns string with current widget value

class airgun.widgets.Pagination

Bases: widgetastic.widget.Widget

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
is_displayed

Check whether this Pagination widget exists and visible

current_page

Return the current page as integer value

total_pages

Return the total available pages as integer value

per_page(self)

Return the per page widget

_click_button(self, pager_button)

Click on the pager button if enabled.

first_page(self)

Goto first page by clicking on first page button

previous_page(self)

Goto previous page by clicking on previous page button

next_page(self)

Goto next page by clicking on next page button

last_page(self)

Goto last page by clicking on last page button

read(self)

Read the basic sub widgets of this pagination widget

fill(self, values)

Fill sub widgets with the supplied values

class airgun.widgets.SatTable

Bases: widgetastic.widget.Table

DEPRECATED. Please use widgetastic.widget.Table instead.

Satellite version of table. Main difference - in case it’s empty, there might be just 1 column with appropriate message in table body or no columns and rows at all.

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, 'no-search-results-message')]
tbody_row
pagination
has_rows

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

read(self)

Return empty list in case table is empty

_read_all(self)

Return all available table values with using pagination navigation.

class airgun.widgets.SatSubscriptionsTable

Bases: airgun.widgets.SatTable

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(self, *extra_filters, **filters)

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

read(self)

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

class airgun.widgets.SatTableWithoutHeaders

Bases: widgetastic.widget.Table

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
_is_header_in_body

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

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

Bases: airgun.widgets.SatTable

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/puppet modules/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" ...><span ...>Content Type</span></th>
    </tr>
    </thead>

    <tbody>
    <tr ng-show="repository.content_type === 'yum'" class="ng-hide">
      <td><span>Packages</span></td>
      <td class="align-center">
        <a ui-sref="product.repository.manage-content.packages(...)"
         href=".../repositories/151/content/packages">
          0
        </a></td>
    </tr>

    ...

    <tr ng-show="repository.content_type === 'puppet'" class="">
      <td><span>Puppet Modules</span></td>
      <td class="align-center">
        <a ui-sref="product.repository.manage-content.puppet-module..."
         href=".../repositories/151/content/content/puppet_modules">
          2
        </a></td>
    </tr>
    ...
    </tbody>
</table>

Locator example:

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

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)

Bases: widgetastic.widget.GenericLocatorWidget

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")]
is_active

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

progress

String value with current flow rate in percent.

is_completed

Boolean value whether progress bar is finished or not

wait_for_result(self, 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(self)

Returns current progress.

class airgun.widgets.PublishPromoteProgressBar

Bases: airgun.widgets.ProgressBar

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
is_completed

Boolean value whether progress bar is finished or not

read(self)

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

class airgun.widgets.PieChart

Bases: widgetastic.widget.GenericLocatorWidget

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(self)

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

class airgun.widgets.RemovableWidgetsItemsListView

Bases: widgetastic.widget.View

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
items_length
items

Return all the items widget instances

_get_item_locator(self, index)

Return the item locator located at index position

get_item_at_index(self, index)

Return the item widget instance at index

add_item(self)

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

remove_item(self, item)

Remove item widget by clicking on it’s remove button

remove_item_at_index(self, index)

Remove item at index

clear(self)

Remove all items if item remove button attribute defined.

read(self)

Read all items

fill(self, values)

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

class airgun.widgets.GenericRemovableWidgetItem

Bases: widgetastic.widget.GenericLocatorWidget

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

remove_button
context
read(self)
fill(self, values)
class airgun.widgets.AutoCompleteTextInput

Bases: widgetastic.widget.TextInput

Autocomplete Search input field, We must remove the focus from this widget after fill to force the auto-completion list to be hidden.

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

Bases: widgetastic_patternfly.Button

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

__locator__(self)
fill(self, value)
read(self)

Bases: widgetastic.widget.Text

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

fill(self, value)
class airgun.widgets.PopOverWidget

Bases: widgetastic.widget.Widget

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:

<h3 class="popover-title">Authorize login delegation (Default: false)</h3>
    <form class="form-inline editableform" style="">
        <select class="form-control input-sm">
            <option value="0">No</option>
            <option value="1">Yes</option></select>
        <div class="editable-buttons">
            <button type="submit" class="btn btn-primary btn-sm editable-submit">

<h3 class="popover-title">Authorize login delegation auth ...(Default: Not set)</h3>
    <form class="form-inline editableform" style="">
        <input type="text" ...>
        <div class="editable-buttons">
            <button type="submit" class="btn btn-primary btn-sm editable-submit">

Locator example:

//div[contains(@class, 'editable-open')]
ROOT = .
column_value
header
input_box
textarea
drop_down
submit
fill(self, item)

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

read(self)

read column updated value