diff --git a/horizon/static/horizon/js/horizon.selenium.js b/horizon/static/horizon/js/horizon.selenium.js
new file mode 100644
index 0000000000..8d43526155
--- /dev/null
+++ b/horizon/static/horizon/js/horizon.selenium.js
@@ -0,0 +1,73 @@
+/* Copyright (c) 2015 Mirantis, Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License"); you may
+ not use this file except in compliance with the License. You may obtain
+ a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and limitations
+ under the License.
+*/
+
+/*
+ NOTE(tsufiev): the purpose of this code is to mark the titles of expanded
+ dashboards and panel groups with special 'selenium-active' class that
+ integration tests can use to understand what dashboard/panel group is
+ currently open (and whether or not it needs to click it to proceed to some
+ other dashboard/panel group). The need for this code arises from 2 facts:
+ * since https://review.openstack.org/#/c/209259/ sidebar's expand/collapse
+ behavior doesn't rely on JS code (pure CSS instead) - which is good;
+ * to match dashboard/panel group header _before_ the 'li.panel-collapse.in'
+ we need '!' selector which will be supported only in CSS4 (not going soon).
+ */
+horizon.selenium = {
+};
+
+horizon.addInitFunction(horizon.selenium.init = 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 $activeDashboard = $activeEntry.closest(dashboardLoc).toggleClass(activeCls);
+ var $activeGroup = $activeEntry.find(
+ 'li.nav-header.panel > ul.panel-collapse.in').closest(groupLoc).toggleClass(activeCls);
+
+ function toggleActiveDashboard($dashboard) {
+ if ($activeDashboard) {
+ $activeDashboard.toggleClass(activeCls);
+ }
+ if ($activeDashboard === $dashboard) {
+ $activeDashboard = null;
+ } else {
+ $activeDashboard = $dashboard.toggleClass(activeCls);
+ toggleActiveGroup($activeDashboard.find(groupLoc + ':eq(0)'));
+ }
+ }
+
+ function toggleActiveGroup($group) {
+ if ($group.length) {
+ if ($activeGroup) {
+ $activeGroup.toggleClass(activeCls);
+ }
+ if ($activeGroup === $group) {
+ $activeGroup = null;
+ } else {
+ $activeGroup = $group.toggleClass(activeCls);
+ }
+ }
+ }
+
+ $(document).on('click', dashboardLoc, function() {
+ toggleActiveDashboard($(this));
+ }).on('click', groupLoc, function(event) {
+ toggleActiveGroup($(this));
+ // prevent the event from toggling an active dashboard
+ event.stopPropagation();
+ });
+
+});
diff --git a/openstack_dashboard/templates/horizon/_scripts.html b/openstack_dashboard/templates/horizon/_scripts.html
index 7eab545702..2152af3ec1 100644
--- a/openstack_dashboard/templates/horizon/_scripts.html
+++ b/openstack_dashboard/templates/horizon/_scripts.html
@@ -37,6 +37,7 @@
+
diff --git a/openstack_dashboard/test/integration_tests/horizon.conf b/openstack_dashboard/test/integration_tests/horizon.conf
index 5a125cb341..79894a2b85 100644
--- a/openstack_dashboard/test/integration_tests/horizon.conf
+++ b/openstack_dashboard/test/integration_tests/horizon.conf
@@ -4,10 +4,10 @@
[dashboard]
# Where the dashboard can be found (string value)
-dashboard_url=http://localhost/
+dashboard_url=http://localhost/dashboard/
# Login page for the dashboard (string value)
-login_url=http://localhost/auth/login/
+login_url=http://localhost/dashboard/auth/login/
# Dashboard help page url (string value)
help_url=http://docs.openstack.org/
@@ -50,7 +50,7 @@ admin_password=secretadmin
# Whether is Sahara expected to be available (boolean
# value)
-sahara=True
+sahara=False
[scenario]
# ssh username for image file (string value)
diff --git a/openstack_dashboard/test/integration_tests/regions/bars.py b/openstack_dashboard/test/integration_tests/regions/bars.py
index ccd627dd28..4bde621e35 100644
--- a/openstack_dashboard/test/integration_tests/regions/bars.py
+++ b/openstack_dashboard/test/integration_tests/regions/bars.py
@@ -17,11 +17,12 @@ from openstack_dashboard.test.integration_tests.regions import menus
class TopBarRegion(baseregion.BaseRegion):
- _user_dropdown_menu_locator = (by.By.ID, 'profile_editor_switcher')
+ _user_dropdown_menu_locator = (by.By.CSS_SELECTOR,
+ '.nav.navbar-nav.navbar-right li.dropdown')
_openstack_brand_locator = (by.By.CSS_SELECTOR, 'a[href*="/home/"]')
_user_dropdown_project_locator = (by.By.CSS_SELECTOR,
- 'div.dropdown.context-selection')
+ 'li.dropdown.context-selection')
@property
def user(self):
diff --git a/openstack_dashboard/test/integration_tests/regions/menus.py b/openstack_dashboard/test/integration_tests/regions/menus.py
index 7b76101594..8e29320ba7 100644
--- a/openstack_dashboard/test/integration_tests/regions/menus.py
+++ b/openstack_dashboard/test/integration_tests/regions/menus.py
@@ -35,12 +35,20 @@ class NavigationAccordionRegion(baseregion.BaseRegion):
def project_bar(self):
return self._get_element(*self._project_bar_locator)
- _first_level_item_selected_locator = (by.By.CSS_SELECTOR, 'dt.active')
- _second_level_item_selected_locator = (by.By.CSS_SELECTOR, 'h4.active')
+ _first_level_item_selected_locator = (
+ by.By.CSS_SELECTOR, 'li.openstack-dashboard.selenium-active > a')
+ _second_level_item_selected_locator = (
+ by.By.CSS_SELECTOR, 'li.nav-header.selenium-active > a')
- _first_level_item_xpath_template = '//dt[contains(text(),\'%s\')]'
- _second_level_item_xpath_template = '//h4[contains(text(),\'%s\')]'
- _third_level_item_xpath_template = '//li/a[text()=\'%s\']'
+ _first_level_item_xpath_template = (
+ "//li[contains(concat('', @class, ''), 'openstack-dashboard') "
+ "and contains(., '%s')]/a")
+ _second_level_item_xpath_template = (
+ "//li[contains(concat('', @class, ''), 'nav-header') "
+ "and contains(., '%s')]/a")
+ _third_level_item_xpath_template = (
+ "//li[contains(concat('', @class, ''), 'openstack-panel') and "
+ "contains(., '%s')]/a")
def _get_first_level_item_locator(self, text):
return (by.By.XPATH,
diff --git a/openstack_dashboard/test/integration_tests/tests/test_floatingip.py b/openstack_dashboard/test/integration_tests/tests/test_floatingip.py
index b19e5ef356..4591a653b7 100644
--- a/openstack_dashboard/test/integration_tests/tests/test_floatingip.py
+++ b/openstack_dashboard/test/integration_tests/tests/test_floatingip.py
@@ -14,10 +14,8 @@
# under the License.
from openstack_dashboard.test.integration_tests import helpers
-from openstack_dashboard.test.integration_tests.tests import decorators
-@decorators.skip_because(bugs=["1467950"])
class TestFloatingip(helpers.TestCase):
"""Checks that the user is able to allocate/release floatingip."""
diff --git a/openstack_dashboard/test/integration_tests/tests/test_keypair.py b/openstack_dashboard/test/integration_tests/tests/test_keypair.py
index a4ada35a67..45783b19e9 100644
--- a/openstack_dashboard/test/integration_tests/tests/test_keypair.py
+++ b/openstack_dashboard/test/integration_tests/tests/test_keypair.py
@@ -14,10 +14,8 @@
# under the License.
from openstack_dashboard.test.integration_tests import helpers
-from openstack_dashboard.test.integration_tests.tests import decorators
-@decorators.skip_because(bugs=["1467950"])
class TestKeypair(helpers.TestCase):
"""Checks that the user is able to create/delete keypair."""
KEYPAIR_NAME = helpers.gen_random_resource_name("keypair")
diff --git a/openstack_dashboard/test/integration_tests/tests/test_user_create_delete.py b/openstack_dashboard/test/integration_tests/tests/test_user_create_delete.py
index 7f1c634173..9ae585ea81 100644
--- a/openstack_dashboard/test/integration_tests/tests/test_user_create_delete.py
+++ b/openstack_dashboard/test/integration_tests/tests/test_user_create_delete.py
@@ -11,10 +11,8 @@
# under the License.
from openstack_dashboard.test.integration_tests import helpers
-from openstack_dashboard.test.integration_tests.tests import decorators
-@decorators.skip_because(bugs=["1467950"])
class TestUser(helpers.AdminTestCase):
USER_NAME = helpers.gen_random_resource_name("user")