murano-dashboard/muranodashboard/tests/functional/base.py

263 lines
10 KiB
Python

import json
import logging
import sys
import urlparse
from glanceclient import client as gclient
from keystoneclient.v2_0 import client as ksclient
from muranoclient import client as mclient
from selenium.common import exceptions as exc
from selenium import webdriver
import selenium.webdriver.common.by as by
from selenium.webdriver.support.ui import WebDriverWait
import testtools
import config.config as cfg
from muranodashboard.tests.functional import consts
from muranodashboard.tests.functional import utils
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
log.addHandler(logging.StreamHandler())
if sys.version_info >= (2, 7):
class BaseDeps(testtools.TestCase):
pass
else:
# Define asserts for python26
import unittest2
class BaseDeps(testtools.TestCase,
unittest2.TestCase):
pass
class OrderedMethodMixin(object):
__metaclass__ = utils.OrderedMethodMetaclass
class UITestCase(OrderedMethodMixin, BaseDeps):
@classmethod
def setUpClass(cls):
cls.keystone_client = ksclient.Client(username=cfg.common.user,
password=cfg.common.password,
tenant_name=cfg.common.tenant,
auth_url=cfg.common.keystone_url)
cls.murano_client = mclient.Client(
'1', endpoint=cfg.common.murano_url,
token=cls.keystone_client.auth_token)
cls.url_prefix = urlparse.urlparse(cfg.common.horizon_url).path or ''
def setUp(self):
super(UITestCase, self).setUp()
self.driver = webdriver.Firefox()
self.driver.maximize_window()
self.driver.get(cfg.common.horizon_url + '/')
self.driver.implicitly_wait(30)
self.log_in()
def tearDown(self):
super(UITestCase, self).tearDown()
self.driver.quit()
for env in self.murano_client.environments.list():
self.murano_client.environments.delete(env.id)
def log_in(self):
self.fill_field(by.By.ID, 'id_username', cfg.common.user)
self.fill_field(by.By.ID, 'id_password', cfg.common.password)
self.driver.find_element_by_xpath("//button[@type='submit']").click()
self.driver.find_element_by_xpath(consts.Murano).click()
def fill_field(self, by_find, field, value):
self.driver.find_element(by=by_find, value=field).clear()
self.driver.find_element(by=by_find, value=field).send_keys(value)
def get_element_id(self, el_name):
path = self.driver.find_element_by_xpath(
".//*[@data-display='{0}']".format(el_name)).get_attribute("id")
return path.split('__')[-1]
def select_and_click_action_for_app(self, action, app):
self.driver.find_element_by_xpath(
"//*[@href='{0}/murano/catalog/{1}/{2}']".format(self.url_prefix,
action,
app)).click()
def go_to_submenu(self, link):
self.driver.find_element_by_partial_link_text(
'{0}'.format(link)).click()
def check_panel_is_present(self, panel_name):
self.assertIn(panel_name,
self.driver.find_element_by_xpath(
".//*[@class='page-header']").text)
def navigate_to(self, menu):
self.driver.find_element_by_xpath(getattr(consts, menu)).click()
def select_from_list(self, list_name, value):
self.driver.find_element_by_xpath(
"//select[@name='{0}']/option[text()='{1}']".
format(list_name, value)).click()
def check_element_on_page(self, method, value):
try:
self.driver.find_element(method, value)
except (exc.NoSuchElementException, exc.ElementNotVisibleException):
self.fail("Element {0} is not preset on the page".format(value))
def check_element_not_on_page(self, method, value):
self.driver.implicitly_wait(2)
present = True
try:
self.driver.find_element(method, value)
except (exc.NoSuchElementException, exc.ElementNotVisibleException):
present = False
self.assertFalse(present, "Element {0} is preset on the page"
" while it should't".format(value))
self.driver.implicitly_wait(30)
def create_environment(self, env_name):
self.driver.find_element_by_id(
'murano__action_CreateEnvironment').click()
self.fill_field(by.By.ID, 'id_name', env_name)
self.driver.find_element_by_xpath(consts.InputSubmit).click()
WebDriverWait(self.driver, 10).until(lambda s: s.find_element(
by.By.LINK_TEXT, 'Add Component').is_displayed())
class PackageBase(UITestCase):
@classmethod
def setUpClass(cls):
super(PackageBase, cls).setUpClass()
cls.mockapp_id = utils.upload_app_package(
cls.murano_client,
"MockApp",
{"categories": ["Web"], "tags": ["tag"]})
cls.postgre_id = utils.upload_app_package(
cls.murano_client,
"PostgreSQL",
{"categories": ["Databases"], "tags": ["tag"]})
@classmethod
def tearDownClass(cls):
super(PackageBase, cls).tearDownClass()
cls.murano_client.packages.delete(cls.mockapp_id)
cls.murano_client.packages.delete(cls.postgre_id)
class ImageTestCase(PackageBase):
@classmethod
def setUpClass(cls):
super(ImageTestCase, cls).setUpClass()
glance_endpoint = cls.keystone_client.service_catalog.url_for(
service_type='image', endpoint_type='publicURL')
cls.glance = gclient.Client('1', endpoint=glance_endpoint,
token=cls.keystone_client.auth_token)
cls.image = cls.upload_image()
@classmethod
def tearDownClass(cls):
super(ImageTestCase, cls).tearDownClass()
cls.glance.images.delete(cls.image.id)
@classmethod
def upload_image(cls):
try:
property = {'murano_image_info': json.dumps({'title': 'New Image',
'type': 'linux'})}
image = cls.glance.images.create(name='TestImage',
disk_format='qcow2',
size=0,
is_public=True,
properties=property)
except Exception as e:
log.exception("Unable to create or update image in Glance")
raise e
return image
def select_and_click_element(self, element):
self.driver.find_element_by_xpath(
".//*[@value = '{0}']".format(element)).click()
class EnvironmentTestCase(UITestCase):
def delete_environment(self, env_name):
self.select_action_for_environment(env_name, 'delete')
self.driver.find_element_by_xpath(consts.ConfirmDeletion).click()
def edit_environment(self, old_name, new_name):
self.select_action_for_environment(old_name, 'edit')
self.fill_field(by.By.ID, 'id_name', new_name)
self.driver.find_element_by_xpath(consts.InputSubmit).click()
def select_action_for_environment(self, env_name, action):
element_id = self.get_element_id(env_name)
more_button = consts.More.format(element_id)
self.driver.find_element_by_xpath(more_button).click()
self.driver.find_element_by_id(
"murano__row_{0}__action_{1}".format(element_id, action)).click()
class FieldsTestCase(PackageBase):
def check_error_message_is_present(self, error_message):
self.driver.find_element_by_xpath(consts.ButtonSubmit).click()
self.driver.find_element_by_xpath(
'//span[@class="help-inline"]'
'[contains(text(), "{0}")]'.format(error_message))
def check_error_message_is_absent(self, error_message):
self.driver.find_element_by_xpath(consts.ButtonSubmit).click()
self.driver.implicitly_wait(2)
try:
self.driver.find_element_by_xpath(
'//span[@class="help-inline"]'
'[contains(text(), "{0}")]'.format(error_message))
except (exc.NoSuchElementException, exc.ElementNotVisibleException):
log.info("Message {0} is not"
" present on the page".format(error_message))
self.driver.implicitly_wait(30)
class ApplicationTestCase(ImageTestCase):
def delete_component(self, component_name):
component_id = self.get_element_id(component_name)
self.driver.find_element_by_id(
'services__row_{0}__action_delete'.format(component_id)).click()
self.driver.find_element_by_link_text('Delete Component').click()
def select_action_for_package(self, package, action):
package_id = self.get_element_id(package)
if action == 'more':
self.driver.find_element_by_xpath(
".//*[@id='packages__row__{0}']/td[6]/div/a[2]".
format(package_id)).click()
WebDriverWait(self.driver, 10).until(lambda s: s.find_element(
by.By.XPATH,
".//*[@id='packages__row_{0}__action_download_package']".
format(package_id)).is_displayed())
else:
self.driver.find_element_by_xpath(
".//*[@id='packages__row_{0}__action_{1}']".
format(package_id, action)).click()
def check_package_parameter(self, package, column, value):
package_id = self.get_element_id(package)
result = self.driver.find_element_by_xpath(
".//*[@id='packages__row__{0}']/td[{1}]".
format(package_id, column)).text
if result == value:
return True
else:
return False
def modify_package(self, param, value):
self.fill_field(by.By.ID, 'id_{0}'.format(param), value)
self.driver.find_element_by_xpath(consts.InputSubmit).click()
self.driver.refresh()