Move out integration tests scaffolds from Horizon production code
The main idea of this change is to not include into Horizon production code little helper features we need Horizon to have in gating so Selenium integration tests could easily navigate through it. Closes-Bug: #1560467 Change-Id: Ib0c973932260ddfe7f1d2cf9fdab7bbbfe298bea
This commit is contained in:
parent
caa5e91059
commit
408e358f79
@ -301,6 +301,11 @@ which also contains instructions on how to run the tests. To make integration
|
|||||||
tests more understandable and maintainable, the Page Object pattern is used
|
tests more understandable and maintainable, the Page Object pattern is used
|
||||||
throughout them.
|
throughout them.
|
||||||
|
|
||||||
|
.. warning:: To enable integration tests support before running them, please
|
||||||
|
copy openstack_dashboard/local/local_settings.d/_20_integration_tests_scaffolds.py.example
|
||||||
|
to openstack_dashboard/local/local_settings.d/_20_integration_tests_scaffolds.py
|
||||||
|
and then run ./manage.py collectstatic --clear && ./manage.py compress.
|
||||||
|
|
||||||
Horizon repository also provides two shell `scripts`_, which are executed in
|
Horizon repository also provides two shell `scripts`_, which are executed in
|
||||||
pre_test_hook and post_test_hook respectively. Pre hook is generally used for
|
pre_test_hook and post_test_hook respectively. Pre hook is generally used for
|
||||||
modifying test environment, while post hook is used for running actual
|
modifying test environment, while post hook is used for running actual
|
||||||
@ -662,6 +667,10 @@ Customizing tests to a specific gate environment
|
|||||||
in `devstack-vm-gate-wrap.sh`_ script will be already cloned by the moment
|
in `devstack-vm-gate-wrap.sh`_ script will be already cloned by the moment
|
||||||
pre hook is executed. So the natural use for it is to customize some Horizon
|
pre hook is executed. So the natural use for it is to customize some Horizon
|
||||||
settings before they are used in operations like compressing statics etc.
|
settings before they are used in operations like compressing statics etc.
|
||||||
|
That is how it is actually used now: it sets settings variable
|
||||||
|
`INTEGRATION_TESTS_SUPPORT` to `True`, so all the support code for integration
|
||||||
|
tests is included into Horizon static assets. If this variable was set to
|
||||||
|
`False`, we would not be able to run integration tests.
|
||||||
|
|
||||||
* Post hook is executed after Devstack is deployed, so integration tests
|
* Post hook is executed after Devstack is deployed, so integration tests
|
||||||
themselves are run inside that hook, as well as various test artifacts
|
themselves are run inside that hook, as well as various test artifacts
|
||||||
@ -676,7 +685,9 @@ Customizing tests to a specific gate environment
|
|||||||
Writing integration tests for Horizon plugins
|
Writing integration tests for Horizon plugins
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
There are 2 possible setups when running integration tests for Horizon plugins.
|
First, for more details on writing a Horizon plugin please refer to
|
||||||
|
:doc:`../tutorials/plugin`. Second, there are 2 possible setups when running
|
||||||
|
integration tests for Horizon plugins.
|
||||||
|
|
||||||
The first setup, which is suggested to be used in gate of \*-dashboard plugins
|
The first setup, which is suggested to be used in gate of \*-dashboard plugins
|
||||||
is to get horizon as a dependency of a plugin and then run integration tests
|
is to get horizon as a dependency of a plugin and then run integration tests
|
||||||
|
@ -46,5 +46,8 @@ HORIZON_CONFIG = {
|
|||||||
'password_autocomplete': 'off',
|
'password_autocomplete': 'off',
|
||||||
|
|
||||||
# Enable or disable simplified floating IP address management.
|
# Enable or disable simplified floating IP address management.
|
||||||
'simple_ip_management': True
|
'simple_ip_management': True,
|
||||||
|
|
||||||
|
'integration_tests_support':
|
||||||
|
getattr(settings, 'INTEGRATION_TESTS_SUPPORT', False)
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import logging
|
|||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.core import exceptions as core_exceptions
|
from django.core import exceptions as core_exceptions
|
||||||
from django.core import urlresolvers
|
from django.core import urlresolvers
|
||||||
from django import forms
|
from django import forms
|
||||||
@ -433,10 +434,11 @@ class Column(html.HTMLElement):
|
|||||||
except urlresolvers.NoReverseMatch:
|
except urlresolvers.NoReverseMatch:
|
||||||
return self.link
|
return self.link
|
||||||
|
|
||||||
def get_default_attrs(self):
|
if getattr(settings, 'INTEGRATION_TESTS_SUPPORT', False):
|
||||||
attrs = super(Column, self).get_default_attrs()
|
def get_default_attrs(self):
|
||||||
attrs.update({'data-selenium': self.name})
|
attrs = super(Column, self).get_default_attrs()
|
||||||
return attrs
|
attrs.update({'data-selenium': self.name})
|
||||||
|
return attrs
|
||||||
|
|
||||||
def get_summation(self):
|
def get_summation(self):
|
||||||
"""Returns the summary value for the data in this column if a
|
"""Returns the summary value for the data in this column if a
|
||||||
@ -665,7 +667,8 @@ class Cell(html.HTMLElement):
|
|||||||
if len(data) > column.truncate:
|
if len(data) > column.truncate:
|
||||||
self.attrs['data-toggle'] = 'tooltip'
|
self.attrs['data-toggle'] = 'tooltip'
|
||||||
self.attrs['title'] = data
|
self.attrs['title'] = data
|
||||||
self.attrs['data-selenium'] = data
|
if getattr(settings, 'INTEGRATION_TESTS_SUPPORT', False):
|
||||||
|
self.attrs['data-selenium'] = data
|
||||||
self.data = self.get_data(datum, column, row)
|
self.data = self.get_data(datum, column, row)
|
||||||
|
|
||||||
def get_data(self, datum, column, row):
|
def get_data(self, datum, column, row):
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
{% block modal-body %}
|
{% block modal-body %}
|
||||||
<ul class="nav nav-pills selenium-nav-region{% if workflow.wizard %} wizard-tabs{% endif %}" role="tablist">
|
<ul class="nav nav-pills{% if HORIZON_CONFIG.integration_tests_support %} selenium-nav-region{% endif %}{% if workflow.wizard %} wizard-tabs{% endif %}" role="tablist">
|
||||||
{% for step in workflow.steps %}
|
{% for step in workflow.steps %}
|
||||||
<li class="{% if entry_point == step.slug %}active{% endif %}{% if step.has_errors %} error{% endif %}{% if step.has_required_fields %} required{% endif %}">
|
<li class="{% if entry_point == step.slug %}active{% endif %}{% if step.has_errors %} error{% endif %}{% if step.has_required_fields %} required{% endif %}">
|
||||||
<a href="#{{ step.get_id }}" data-toggle="tab" data-target="#{{ step.get_id }}">
|
<a href="#{{ step.get_id }}" data-toggle="tab" data-target="#{{ step.get_id }}">
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
# Enable both Launch Instance wizards for the sake of testing
|
# Enable both Launch Instance wizards for the sake of testing
|
||||||
LAUNCH_INSTANCE_LEGACY_ENABLED = True
|
LAUNCH_INSTANCE_LEGACY_ENABLED = True
|
||||||
LAUNCH_INSTANCE_NG_ENABLED = True
|
LAUNCH_INSTANCE_NG_ENABLED = True
|
||||||
|
|
||||||
|
# Provide a global setting for switching on/off various integration tests
|
||||||
|
# scaffolds
|
||||||
|
INTEGRATION_TESTS_SUPPORT = True
|
||||||
|
HORIZON_CONFIG['integration_tests_support'] = INTEGRATION_TESTS_SUPPORT
|
||||||
|
@ -52,6 +52,7 @@ MEDIA_ROOT = None
|
|||||||
MEDIA_URL = None
|
MEDIA_URL = None
|
||||||
STATIC_ROOT = None
|
STATIC_ROOT = None
|
||||||
STATIC_URL = None
|
STATIC_URL = None
|
||||||
|
INTEGRATION_TESTS_SUPPORT = False
|
||||||
|
|
||||||
ROOT_URLCONF = 'openstack_dashboard.urls'
|
ROOT_URLCONF = 'openstack_dashboard.urls'
|
||||||
|
|
||||||
@ -73,7 +74,8 @@ HORIZON_CONFIG = {
|
|||||||
'js_files': [],
|
'js_files': [],
|
||||||
'js_spec_files': [],
|
'js_spec_files': [],
|
||||||
'external_templates': [],
|
'external_templates': [],
|
||||||
'plugins': []
|
'plugins': [],
|
||||||
|
'integration_tests_support': INTEGRATION_TESTS_SUPPORT
|
||||||
}
|
}
|
||||||
|
|
||||||
# Set to True to allow users to upload images to glance via Horizon server.
|
# Set to True to allow users to upload images to glance via Horizon server.
|
||||||
|
@ -38,7 +38,9 @@
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
horizon.modals.MODAL_BACKDROP = "{% firstof HORIZON_CONFIG.modal_backdrop 'static' %}";
|
horizon.modals.MODAL_BACKDROP = "{% firstof HORIZON_CONFIG.modal_backdrop 'static' %}";
|
||||||
</script>
|
</script>
|
||||||
|
{% if HORIZON_CONFIG.integration_tests_support %}
|
||||||
<script src='{{ STATIC_URL }}horizon/js/horizon.selenium.js'></script>
|
<script src='{{ STATIC_URL }}horizon/js/horizon.selenium.js'></script>
|
||||||
|
{% endif %}
|
||||||
<script src='{{ STATIC_URL }}horizon/js/horizon.quota.js'></script>
|
<script src='{{ STATIC_URL }}horizon/js/horizon.quota.js'></script>
|
||||||
<script src='{{ STATIC_URL }}horizon/js/horizon.tables.js'></script>
|
<script src='{{ STATIC_URL }}horizon/js/horizon.tables.js'></script>
|
||||||
<script src='{{ STATIC_URL }}horizon/js/horizon.tables_inline_edit.js'></script>
|
<script src='{{ STATIC_URL }}horizon/js/horizon.tables_inline_edit.js'></script>
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Added new setting INTEGRATION_TESTS_SUPPORT, default value
|
||||||
|
is `False`. This value is used when running `manage.py compress`
|
||||||
|
command, so by default all static assets and html classes used
|
||||||
|
by integration tests are removed from Horizon production build.
|
||||||
|
Integration tests gate job sets this variable to `True` and
|
||||||
|
recompresses static assets.
|
Loading…
Reference in New Issue
Block a user