diff --git a/openstack_dashboard/test/integration_tests/regions/baseregion.py b/openstack_dashboard/test/integration_tests/regions/baseregion.py index 0b7be6ed23..f6362be6d2 100644 --- a/openstack_dashboard/test/integration_tests/regions/baseregion.py +++ b/openstack_dashboard/test/integration_tests/regions/baseregion.py @@ -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 diff --git a/openstack_dashboard/test/integration_tests/regions/forms.py b/openstack_dashboard/test/integration_tests/regions/forms.py index ba9dfd1e46..2f1c42d2d8 100644 --- a/openstack_dashboard/test/integration_tests/regions/forms.py +++ b/openstack_dashboard/test/integration_tests/regions/forms.py @@ -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. diff --git a/openstack_dashboard/test/integration_tests/regions/menus.py b/openstack_dashboard/test/integration_tests/regions/menus.py index 02921a58fb..744d1a0a16 100644 --- a/openstack_dashboard/test/integration_tests/regions/menus.py +++ b/openstack_dashboard/test/integration_tests/regions/menus.py @@ -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()