airgun.widgets
¶
Module Contents¶
Classes¶
Represent basic select element except our custom implementation remove |
|
Represent basic checkbox element, but able to handle alert message |
|
Classical radio buttons group widget |
|
Toggle buttons group widget when each button represented by radio |
|
Collection of date picker and two inputs for hours and minutes |
|
Input for date, which opens calendar on click. |
|
List with click-able elements. Part of |
|
Similar to ItemsList widget except list elements can be selected only using 'Add' |
|
Similar to ItemsList widget ideology, but here we have group of items lists instead. |
|
List with click-able elements. Part of |
|
Typical two-pane multiselect jQuery widget. Allows to move items from |
|
Widget has different appearance than MultiSelect, because there are no actual panes, |
|
Similar to the PuppetClassesMultiSelect widget except items lists has different |
|
List of actions, expandable via button with caret. Usually comes with |
|
PF4 version of actions dropdown with support for items description |
|
Custom drop down which contains the checkbox inside in drop down. |
|
Searchbar for table filtering |
|
PF4 Searchbar for table filtering |
|
The Patternfly Vertical navigation. |
|
Satellite version of Patternfly alert. It doesn't contain |
|
Satellite version of Patternfly's alerts section. The only difference is |
|
Widget for tracking all improperly filled inputs inside view, which are |
|
Base class for all UI objects. |
|
Drop-down element with filtering functionality |
|
Name-Value paired input elements which can be added, edited or removed. |
|
Usual confirmation dialog with two buttons and close 'x' button in the |
|
PF4 confirmation dialog with two buttons and close 'x' button in the |
|
Group of checkboxes that goes in a line one after another. Usually used |
|
Input for managing limits (e.g. Hosts limit). Consists of 'Unlimited' |
|
Text input widget with content that may be hidden |
|
Usually represented by static field and edit button that transform |
|
Should be used in case |
|
Should be used in case |
|
A set of checkboxes of the same property type |
|
Should be used in case |
|
A set of text inputs |
|
Should be used in case |
|
Should be used in case |
|
Similar to EditableEntry and specific for the same page types, but cannot |
|
Default ace editor |
|
Represents Paginator widget that includes per page selector, First/Last/Next/Prev buttons |
|
Paginator widget for use within SatTable. |
|
Satellite version of table. |
|
Subscriptions table, which has extra preceding row for 'Repository Name' |
|
Applicable for every table in application that has no headers. Due logic of the Table |
|
Applicable for every table in application that has uneven amount of |
|
Generic progress bar widget. |
|
Progress bar for Publish and Promote procedures. They contain status |
|
Default Pie Chart that can be found across application. At that moment |
|
A host for widgets list. Items that can be added or removed, mainly used in profile for |
|
Generic Item widget (to be inherited) and to be used as Widget Item for |
|
Autocomplete Search input field, We must remove the focus from this widget after fill to |
|
A simple toggle button that we can read/write it's state via the standard view functions |
|
A link representation that we can read/click via the standard view functions read/fill. |
|
Popover-content UI widget which contains header, drop_down, input_box, or textarea and |
|
Popover-content UI widget which contains header, drop_down, input_box, or textarea and |
|
This is a customizable card widget which has the title, count and kebab widget |
|
PF4 Accordion widget |
|
Represents the Patternfly Multi Select. |
|
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/orhours
, and/orminutes
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.
- 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'))]¶
- 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 ofassigned
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/orunassigned
, 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
- 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)¶
The Patternfly Vertical navigation.
- 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 returnsSatFlashMessage
.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 asself.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 ofContextSelector
. Thus, to avoid significant performance degradation it should not be readable.Use
current_org()
andcurrent_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 byLimitInput
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 byDateTime
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
- class airgun.widgets.Link(parent, locator, logger=None)¶
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.