From fe04af039f369bfeb71ca2c51301dde5711ca20b Mon Sep 17 00:00:00 2001 From: Timur Sufiev Date: Wed, 15 Jun 2016 23:44:50 +0300 Subject: [PATCH] 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 --- horizon/static/horizon/js/horizon.selenium.js | 17 +++++++++++++-- .../test/integration_tests/regions/bars.py | 5 ++--- .../test/integration_tests/regions/menus.py | 21 +++++++++++++------ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/horizon/static/horizon/js/horizon.selenium.js b/horizon/static/horizon/js/horizon.selenium.js index 8d43526155..506a62899c 100644 --- a/horizon/static/horizon/js/horizon.selenium.js +++ b/horizon/static/horizon/js/horizon.selenium.js @@ -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); +}; \ No newline at end of file diff --git a/openstack_dashboard/test/integration_tests/regions/bars.py b/openstack_dashboard/test/integration_tests/regions/bars.py index 11a7376aeb..201a75cd5f 100644 --- a/openstack_dashboard/test/integration_tests/regions/bars.py +++ b/openstack_dashboard/test/integration_tests/regions/bars.py @@ -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' diff --git a/openstack_dashboard/test/integration_tests/regions/menus.py b/openstack_dashboard/test/integration_tests/regions/menus.py index fe8135cdd2..3e4c13c303 100644 --- a/openstack_dashboard/test/integration_tests/regions/menus.py +++ b/openstack_dashboard/test/integration_tests/regions/menus.py @@ -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')