Fix dropdowns sometimes not opening in integration tests

Since most probable cause of dropdowns not opening intermittently is
Bootstrap initialization code not having enough time to complete
before test tries to open dropdown, make test wait a specified timeout
before clicking it (by means of setting a CSS class after that
timeout, which test in turn waits before clicking the dropdown).

Closes-Bug: #1594926
Change-Id: I32625caa4433f4af0de72c94b61e85ab4e16b1f9
This commit is contained in:
Timur Sufiev
2016-06-15 23:44:50 +03:00
parent 268e44b349
commit fe04af039f
3 changed files with 32 additions and 11 deletions

View File

@@ -25,13 +25,20 @@
we need '!' selector which will be supported only in CSS4 (not going soon).
*/
horizon.selenium = {
ACTIVE_CLS: 'selenium-active',
ACTIVATION_DELAY: 1000
};
horizon.addInitFunction(horizon.selenium.init = function() {
horizon.selenium.initSideBarHelpers();
horizon.selenium.initDropdownHelpers();
});
horizon.selenium.initSideBarHelpers = function() {
var $activeEntry = $('li.openstack-dashboard.active > ul.panel-collapse.in');
var dashboardLoc = 'li.openstack-dashboard';
var groupLoc = 'li.nav-header.panel';
var activeCls = 'selenium-active';
var activeCls = horizon.selenium.ACTIVE_CLS;
var $activeDashboard = $activeEntry.closest(dashboardLoc).toggleClass(activeCls);
var $activeGroup = $activeEntry.find(
@@ -69,5 +76,11 @@ horizon.addInitFunction(horizon.selenium.init = function() {
// prevent the event from toggling an active dashboard
event.stopPropagation();
});
};
});
horizon.selenium.initDropdownHelpers = function() {
var dropdownLoc = '.dropdown';
window.setTimeout(function() {
$(document).find(dropdownLoc).toggleClass(horizon.selenium.ACTIVE_CLS, true);
}, horizon.selenium.ACTIVATION_DELAY);
};

View File

@@ -18,12 +18,11 @@ from openstack_dashboard.test.integration_tests.regions import menus
class TopBarRegion(baseregion.BaseRegion):
_user_dropdown_menu_locator = (by.By.CSS_SELECTOR,
'.nav.navbar-nav.navbar-right li.dropdown')
'.nav.navbar-nav.navbar-right')
_openstack_brand_locator = (by.By.CSS_SELECTOR, 'a[href*="/home/"]')
_user_dropdown_project_locator = (
by.By.CSS_SELECTOR,
'.navbar-collapse > ul.navbar-nav:first-child li.dropdown')
by.By.CSS_SELECTOR, '.navbar-collapse > ul.navbar-nav:first-child')
_header_locator = (by.By.CSS_SELECTOR, 'nav.navbar-fixed-top')
MATERIAL_THEME_CLASS = 'material-header'

View File

@@ -182,8 +182,8 @@ class DropDownMenuRegion(baseregion.BaseRegion):
_menu_container_locator = (by.By.CSS_SELECTOR, 'ul.dropdown-menu')
_menu_items_locator = (by.By.CSS_SELECTOR,
'ul.dropdown-menu > li > *')
_menu_first_child_locator = (by.By.CSS_SELECTOR,
'a[data-toggle="dropdown"]')
_dropdown_locator = (by.By.CSS_SELECTOR, '.dropdown')
_active_cls = 'selenium-active'
@property
def menu_items(self):
@@ -198,7 +198,19 @@ class DropDownMenuRegion(baseregion.BaseRegion):
def open(self):
"""Opens menu by clicking on the first child of the source element."""
if self.is_open() is False:
self._get_element(*self._menu_first_child_locator).click()
dropdown = self._get_element(*self._dropdown_locator)
# NOTE(tsufiev): there is an issue with clicking dropdowns too fast
# after page has been loaded - the Bootstrap constructors haven't
# completed yet, so the dropdown never opens in that case. Avoid
# this by waiting for a specific class to appear, which is set in
# horizon.selenium.js for dropdowns after a timeout passes
def predicate(d):
classes = dropdown.get_attribute('class').split()
return self._active_cls in classes
self._wait_until(predicate)
dropdown.click()
self._wait_till_element_visible(self._menu_container_locator)
@@ -206,7 +218,6 @@ class UserDropDownMenuRegion(DropDownMenuRegion):
"""Drop down menu located in the right side of the topbar,
contains links to settings and help.
"""
_menu_first_child_locator = (by.By.CSS_SELECTOR, '*')
_settings_link_locator = (by.By.CSS_SELECTOR,
'a[href*="/settings/"]')
_help_link_locator = (by.By.CSS_SELECTOR,
@@ -260,8 +271,6 @@ class TabbedMenuRegion(baseregion.BaseRegion):
class ProjectDropDownRegion(DropDownMenuRegion):
_menu_first_child_locator = (by.By.CSS_SELECTOR, '*')
_menu_items_locator = (
by.By.CSS_SELECTOR, 'ul.context-selection li > a')