Add TabbedFormRegion to Integration tests

* TabbedFormRegion - that should be used for forms that are divided into tabs,
  the manipulation with the form is then the same as with the regular Form
  region, tabs are switched automatically

* TabbedMenuRegion - support for another type of menu, that is for
  example located in certain forms or under the Project/Compute/access
  & security page

* Also _default_src_locator is added to BaseRegion class, that makes it
  possible for every component to have its own default locator, so it is
  not necessary to specify region source element all over again

Partially implements blueprint: selenium-integration-testing

Change-Id: If302385d7d0f8b84512e710fbd70cdbd5bcdffea
This commit is contained in:
Tomas Novacik 2014-10-01 14:55:04 +02:00 committed by Tomáš Nováčik
parent bace1f573f
commit e3e25a6e8b
3 changed files with 74 additions and 2 deletions

View File

@ -16,6 +16,7 @@ from openstack_dashboard.test.integration_tests import basewebobject
class BaseRegion(basewebobject.BaseWebObject):
"""Base class for region module
* there is necessity to override some basic methods for obtaining elements
as in content of regions it is required to do relative searches
@ -24,12 +25,21 @@ class BaseRegion(basewebobject.BaseWebObject):
src_elem is WebElement its usage is different.
* this does not mean that self.src_elem cannot be self.driver
"""
"""
_default_src_locator = None
# private methods
def __init__(self, driver, conf, src_elem=None):
super(BaseRegion, self).__init__(driver, conf)
if src_elem is None and self._default_src_locator:
# fake self.src_elem must be set up in
# order self._get_element work
self.src_elem = driver
src_elem = self._get_element(*self._default_src_locator)
self.src_elem = src_elem or driver
# variable for storing names of dynamic properties and
# associated 'getters' - meaning method that are supplying
# regions or web elements

View File

@ -16,6 +16,7 @@ import selenium.webdriver.support.ui as Support
from openstack_dashboard.test.integration_tests.regions import baseregion
from openstack_dashboard.test.integration_tests.regions import exceptions
from openstack_dashboard.test.integration_tests.regions import menus
class FieldFactory(baseregion.BaseRegion):
@ -67,6 +68,9 @@ class BaseFormFieldRegion(baseregion.BaseRegion):
classes = self.driver.get_attribute('class')
return 'required' in classes
def is_displayed(self):
return self.element.is_displayed()
class CheckBoxFormFieldRegion(BaseFormFieldRegion):
"""Checkbox field."""
@ -145,6 +149,9 @@ class SelectFormFieldRegion(BaseFormFieldRegion):
_element_locator = (by.By.CSS_SELECTOR, 'div > select')
def is_displayed(self):
return self.element._el.is_displayed()
@property
def element(self):
select = self._get_element(*self._element_locator)
@ -209,7 +216,7 @@ class FormRegion(BaseFormRegion):
# private methods
def __init__(self, driver, conf, src_elem, form_field_names):
super(self.__class__, self).__init__(driver, conf, src_elem)
super(FormRegion, self).__init__(driver, conf, src_elem)
self.form_field_names = form_field_names
self._init_form_fields()
@ -247,6 +254,52 @@ class FormRegion(BaseFormRegion):
return self._get_form_fields()
class TabbedFormRegion(FormRegion):
"""Forms that are divided with tabs.
As example is taken form under the
the Project/Network/Networks/Create Network, on initialization form needs
to have form field names divided into tuples, that represents the tabs
and the fields located under them.
Usage:
form_field_names = (("network_name", "admin_state"),
("create_subnet", "subnet_name", "network_address",
"ip_version", "gateway_ip", "disable_gateway"),
("enable_dhcp", "allocation_pools", "dns_name_servers",
"host_routes"))
form = TabbedFormRegion(self.conf, self.driver, None, form_field_names)
form.network_name.text = "test_network_name"
"""
_submit_locator = (by.By.CSS_SELECTOR, '*.btn.btn-primary[type=submit]')
_side_info_locator = (by.By.CSS_SELECTOR, "td.help_text")
_fields_locator = (by.By.CSS_SELECTOR, "div.form-group")
class GetFieldsMethod(object):
def __init__(self, get_fields_method, tab_index, switch_tab_method):
self.get_fields = get_fields_method
self.tab_index = tab_index
self.switch_to_tab = switch_tab_method
def __call__(self, *args, **kwargs):
self.switch_to_tab(self.tab_index)
return [field for field in self.get_fields()
if field.is_displayed()]
@property
def tabs(self):
return menus.TabbedMenuRegion(self.driver, self.conf)
def _init_form_fields(self):
for index, tab_names in enumerate(self.form_field_names):
get_fields = self.GetFieldsMethod(self._get_form_fields, index,
self.tabs.switch_to)
self._init_dynamic_properties(tab_names, get_fields)
class DateFormRegion(BaseFormRegion):
"""Form that queries data to table that is regularly below the form,
typical example is located on Project/Compute/Overview page.

View File

@ -182,3 +182,12 @@ class UserDropDownMenuRegion(DropDownMenuRegion):
def click_on_logout(self):
self.open()
self.logout_link.click()
class TabbedMenuRegion(baseregion.BaseRegion):
_tab_locator = (by.By.CSS_SELECTOR, 'li')
_default_src_locator = (by.By.CSS_SELECTOR, 'ul.nav-tabs')
def switch_to(self, index=0):
self._get_elements(*self._tab_locator)[index].click()