Move UI tests to main repo

Change-Id: I185969eb59922b98f8a7ca8a6b0f44a822ce927e
This commit is contained in:
NastyaUrlapova 2014-02-17 18:16:48 +04:00
parent 0b9ba969d1
commit be6199ef1f
38 changed files with 4016 additions and 2 deletions

View File

@ -1,4 +1,4 @@
# Copyright 2013 Mirantis, Inc.
# Copyright 2014 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

38
fuelweb_ui_test/.gitignore vendored Normal file
View File

@ -0,0 +1,38 @@
*.py[cod]
# C extensions
*.so
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
nosetests.xml
# Translations
*.mo
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
# IDEA
.idea

24
fuelweb_ui_test/README.md Normal file
View File

@ -0,0 +1,24 @@
fuelweb-test
============
# Setting up virtual test machine
Steps to set up a virtual machine for running fuelweb selenium tests:
* Create virtual machine with Ubuntu desktop OS. VM should have internet connection.
* install java OpenJDK runtime environment.
* Turn the VM into jenkins node
* Install “git”
* “git clone https://github.com/stackforge/fuel-web.git” repository. It will be required in next step (command “cd nailgun” is about folder in this repository)
* Install “postgresql” and “pip”, setup python virtual environement and install python packages. Follow instructions at https://github.com/stackforge/fuel-web/blob/master/docs/develop/env.rst#setup-for-nailgun-unit-tests Steps #2 - #5.
* Install NodeJS. Follow instructions in step #1 at https://github.com/stackforge/fuel-web/blob/master/docs/develop/env.rst#setup-for-web-ui-tests.
* Try to run fuel-web in fake-ui mode. Follow steps #1 - #3 at https://github.com/stackforge/fuel-web/blob/master/docs/develop/env.rst#running-nailgun-in-fake-mode . Try to navigate to http://localhost:8000
* Install Chrome web browser.
* Download latest version of Chrome driver from http://chromedriver.storage.googleapis.com/index.html and extract it to home folder at the VM
* “git clone https://github.com/Mirantis/fuelweb-test.git” Checkout a stable branch
* activate fuel virtual environment “workon fuel”
* install pip packages “pip install -r fuelweb-test/requirements.txt“
* Try to run selenium tests (fake-ui should be launched).
* workon fuel
* export PYTHONPATH=$PYTHONPATH:[path to /fuel-web/nailgun]
* nosetests fuelweb-test.tests

View File

@ -0,0 +1,13 @@
# Copyright 2013 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.

View File

@ -0,0 +1,39 @@
from selenium import webdriver
from selenium.webdriver import DesiredCapabilities
from fuelweb_ui_test.settings import BROWSER
from fuelweb_ui_test.settings import CHROME_EXECUTABLE_PATH
from fuelweb_ui_test.settings import SELENIUM_IMPLICIT_WAIT
driver = None
def start_driver(browser=None):
browser = browser or BROWSER
def start_chrome():
return webdriver.Chrome(
executable_path=CHROME_EXECUTABLE_PATH,
desired_capabilities=DesiredCapabilities.CHROME)
def start_firefox():
return webdriver.Firefox()
def start_iexplore():
return webdriver.Ie()
global driver
if browser == "iexplore":
driver = start_iexplore()
elif browser == "chrome":
driver = start_chrome()
elif browser == "firefox":
driver = start_firefox()
#driver.set_window_size(1024, 768)
driver.maximize_window()
driver.implicitly_wait(SELENIUM_IMPLICIT_WAIT)
return driver
def quit_driver():
driver.quit()

View File

@ -0,0 +1,13 @@
import browser
from fuelweb_ui_test.settings import SELENIUM_IMPLICIT_WAIT
def implicit_wait(wait_time):
def wrapper(func):
def wrapped(*args, **kwargs):
browser.driver.implicitly_wait(wait_time)
result = func(*args, **kwargs)
browser.driver.implicitly_wait(SELENIUM_IMPLICIT_WAIT)
return result
return wrapped
return wrapper

View File

View File

@ -0,0 +1,28 @@
from pageobjects.base import PageObject
from pageobjects.base import Popup
class Actions(PageObject):
@property
def name(self):
return self.parent.\
find_element_by_css_selector('.rename-cluster-form input')
@property
def rename(self):
return self.parent.\
find_element_by_css_selector('button.apply-name-btn')
@property
def delete(self):
return self.parent.\
find_element_by_css_selector('button.delete-cluster-btn')
class DeleteEnvironmentPopup(Popup):
@property
def delete(self):
return self.parent.\
find_element_by_css_selector('button.remove-cluster-btn')

View File

@ -0,0 +1,104 @@
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import StaleElementReferenceException
from selenium.webdriver.support.wait import WebDriverWait
import browser
import time
class PageObject:
XPATH_RADIO = '//div[@class="custom-tumbler" ' \
'and input[@type="radio" and @name="{}" and @value="{}"]]'
XPATH_CHECKBOX = \
'//div[@class="custom-tumbler" ' \
'and input[@type="checkbox" and @name="{}"]]'
def __init__(self, parent=None):
self.parent = parent or browser.driver
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
pass
@staticmethod
def wait_until_moving(element, timeout=10):
class Move:
def __init__(self, elem):
self.element = elem
self.location = elem.location
def __call__(self, *args, **kwargs):
loc = element.location
res = self.location['x'] == loc['x'] \
and self.location['y'] == loc['y']
self.location = loc
return res
wait = WebDriverWait(browser.driver, timeout)
wait.until(Move(element))
@staticmethod
def wait_until_exists(element, timeout=10):
wait = WebDriverWait(browser.driver, timeout)
try:
wait.until(lambda driver: not element.is_displayed())
except StaleElementReferenceException:
pass
@staticmethod
def wait_element(page_object, attribute, timeout=10):
class El:
def __init__(self, page_object, attribute):
self.page_object = page_object
self.attribute = attribute
def __call__(self, *args, **kwargs):
try:
getattr(self.page_object, attribute)
return True
except NoSuchElementException:
return False
wait = WebDriverWait(browser.driver, timeout)
wait.until(El(page_object, attribute))
class Popup(PageObject):
def __init__(self):
element = browser.driver.find_element_by_css_selector('div.modal')
PageObject.__init__(self, element)
time.sleep(0.5)
#PageObject.wait_until_moving(self.parent)
def wait_until_exists(self):
try:
PageObject.wait_until_exists(
browser.driver.
find_element_by_css_selector('div.modal-backdrop'))
except NoSuchElementException:
pass
@property
def close_cross(self):
return self.parent.find_element_by_css_selector('.close')
@property
def header(self):
return self.parent.find_element_by_css_selector('.modal-header > h3')
class ConfirmPopup(Popup):
TEXT = 'Settings were modified but not saved'
@property
def stay_on_page(self):
return self.parent.find_element_by_css_selector('.btn-return')
@property
def leave_page(self):
return self.parent.find_element_by_css_selector('.proceed-btn')

View File

@ -0,0 +1,175 @@
from selenium.webdriver.support.select import Select
from pageobjects.base import PageObject
from pageobjects.base import Popup
class Environments(PageObject):
@property
def create_cluster_box(self):
return self.parent.find_element_by_css_selector('div.create-cluster')
@property
def create_cluster_boxes(self):
return self.parent.find_elements_by_css_selector('a.clusterbox')
class RedhatAccountPopup(Popup):
@property
def license_rhsm(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('license-type', 'rhsm'))
@property
def license_rhn(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('license-type', 'rhn'))
@property
def redhat_username(self):
return self.parent.find_element_by_name('username')
@property
def redhat_password(self):
return self.parent.find_element_by_name('password')
@property
def redhat_satellite(self):
return self.parent.find_element_by_name('satellite')
@property
def redhat_activation_key(self):
return self.parent.find_element_by_name('activation_key')
@property
def apply(self):
return self.parent.\
find_element_by_css_selector('button.btn-os-download')
class Wizard(Popup, RedhatAccountPopup):
@property
def name(self):
return self.parent.find_element_by_name('name')
@property
def release(self):
return Select(self.parent.find_element_by_name('release'))
@property
def next(self):
return self.parent.find_element_by_css_selector('button.next-pane-btn')
@property
def create(self):
return self.parent.find_element_by_css_selector('button.finish-btn')
@property
def cancel(self):
return self.parent.\
find_element_by_css_selector('button.btn[data-dismiss=modal]')
@property
def prev(self):
return self.parent.find_element_by_css_selector('button.prev-pane-btn')
@property
def mode_multinode(self):
return self.parent.\
find_element_by_xpath(self.XPATH_RADIO.format('mode', 'multinode'))
@property
def mode_ha_compact(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('mode', 'ha_compact'))
@property
def hypervisor_kvm(self):
return self.parent.\
find_element_by_xpath(self.XPATH_RADIO.format('hypervisor', 'kvm'))
@property
def hypervisor_qemu(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('hypervisor', 'qemu'))
@property
def network_nova(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('manager', 'nova-network'))
@property
def network_neutron_gre(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('manager', 'neutron-gre'))
@property
def network_neutron_vlan(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('manager', 'neutron-vlan'))
@property
def storage_cinder_default(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('cinder', 'default'))
@property
def storage_cinder_ceph(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('cinder', 'ceph'))
@property
def storage_glance_default(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('glance', 'default'))
@property
def storage_glance_ceph(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('glance', 'ceph'))
@property
def install_savanna(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_CHECKBOX.format('savanna'))
@property
def install_murano(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_CHECKBOX.format('murano'))
@property
def install_ceilometer(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_CHECKBOX.format('ceilometer'))
class DeployChangesPopup(Popup):
@property
def deploy(self):
return self.parent.\
find_element_by_css_selector('.start-deployment-btn')
class DiscardChangesPopup(Popup):
@property
def discard(self):
return self.parent.find_element_by_css_selector('.discard-btn')

View File

@ -0,0 +1,58 @@
import browser
from decorators import implicit_wait
from pageobjects.base import PageObject
class Header(PageObject):
@property
def logo(self):
return self.parent.find_element_by_css_selector('div.logo')
@property
def environments(self):
return self.parent.\
find_element_by_css_selector('.navigation-bar-ul '
'a[href$=clusters]')
@property
def releases(self):
return self.parent.\
find_element_by_css_selector('.navigation-bar-ul '
'a[href$=releases]')
@property
def support(self):
return self.parent.\
find_element_by_css_selector('.navigation-bar-ul a[href$=support]')
@property
def breadcrumb(self):
return self.parent.find_element_by_css_selector('.breadcrumb')
@property
def total_nodes(self):
return self.parent.\
find_element_by_css_selector('div.total-nodes-count')
@property
def unallocated_nodes(self):
return self.parent.\
find_element_by_css_selector('div.unallocated-nodes-count')
class TaskResultAlert(PageObject):
@implicit_wait(60)
def __init__(self):
element = browser.driver.\
find_element_by_css_selector('div.task-result')
PageObject.__init__(self, element)
@property
def close(self):
return self.parent.find_element_by_css_selector('button.close')
@property
def header(self):
return self.parent.find_element_by_css_selector('h4')

View File

@ -0,0 +1,203 @@
import browser
from decorators import implicit_wait
from pageobjects.base import PageObject
from selenium.webdriver.support.select import Select
class Networks(PageObject):
@property
def flatdhcp_manager(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('net-manager', 'FlatDHCPManager'))
@property
def vlan_manager(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('net-manager', 'VlanManager'))
@property
def segmentation_type(self):
return self.parent.\
find_element_by_css_selector('span.network-segment-type')
@property
def public(self):
return Network('Public')
@property
def floating(self):
return Network('Floating')
@property
def management(self):
return Network('Management')
@property
def storage(self):
return Network('Storage')
@property
def fixed(self):
return Network('VM (Fixed)')
@property
def neutron(self):
return NeutronParameters()
@property
def dns1(self):
return self.parent.\
find_element_by_css_selector('.nameservers-row input[name=range0]')
@property
def dns2(self):
return self.parent.\
find_element_by_css_selector('.nameservers-row input[name=range1]')
@property
@implicit_wait(20)
def verification_alert(self):
return self.parent.\
find_element_by_css_selector('.verification-control .alert')
@property
def verify_networks(self):
return self.parent.\
find_element_by_xpath('//button[text()="Verify Networks"]')
@property
def cancel_changes(self):
return self.parent.\
find_element_by_xpath('//button[text()="Cancel Changes"]')
@property
def save_settings(self):
return self.parent.\
find_element_by_xpath('//button[text()="Save Settings"]')
class Network(PageObject):
XPATH_PARAMETER = './/div[contains(@class,"network-attribute") and ' \
'div[contains(@class,"parameter-name")]="{}"]'
XPATH_PARAMETER_RANGES = \
XPATH_PARAMETER + \
'/div[@class="ip-ranges-rows"]/div[contains(@class,"range-row")]'
def __init__(self, name):
el = browser.driver.\
find_element_by_xpath('//div[legend="{}"]'.format(name))
PageObject.__init__(self, el)
@property
def ip_ranges(self):
elements = self.parent.find_elements_by_xpath(
self.XPATH_PARAMETER_RANGES.format('IP Range'))
return [IpRange(el) for el in elements]
@property
def vlan_tagging(self):
return self.parent.find_element_by_css_selector('div.custom-tumbler')
@property
def vlan_id(self):
return self.parent.\
find_element_by_css_selector('input[name$=vlan_start]')
@property
def vlan_end(self):
return self.parent.\
find_element_by_css_selector('input[name$=vlan_end]')
@property
def netmask(self):
return self.parent.\
find_element_by_css_selector('input[name$=netmask]')
@property
def gateway(self):
return self.parent.\
find_element_by_css_selector('input[name$=gateway]')
@property
def cidr(self):
return self.parent.find_element_by_css_selector('input[name$=cidr]')
@property
def number_of_networks(self):
return self.parent.find_element_by_css_selector('input[name$=amount]')
@property
def network_size(self):
return Select(
self.parent.
find_element_by_css_selector('select[name$=network_size]'))
class NeutronParameters(PageObject):
def __init__(self):
el = browser.driver.\
find_element_by_css_selector('div.neutron-parameters')
PageObject.__init__(self, el)
@property
def id_start(self):
return self.parent.find_element_by_css_selector('input[name=id0]')
@property
def id_end(self):
return self.parent.find_element_by_css_selector('input[name=id1]')
@property
def base_mac(self):
return self.parent.find_element_by_css_selector('input[name=base_mac]')
@property
def floating_start(self):
return self.parent.\
find_element_by_css_selector('.floating-row input[name=range0]')
@property
def floating_end(self):
return self.parent.\
find_element_by_css_selector('.floating-row input[name=range1]')
@property
def cidr(self):
return self.parent.find_element_by_css_selector('input[name=cidr-int]')
@property
def gateway(self):
return self.parent.find_element_by_css_selector('input[name=gateway]')
@property
def nameserver0(self):
return self.parent.\
find_element_by_css_selector('.nameservers-row input[name=range0]')
@property
def nameserver1(self):
return self.parent.\
find_element_by_css_selector('.nameservers-row input[name=range1]')
class IpRange(PageObject):
@property
def start(self):
return self.parent.find_element_by_css_selector('input[name=range0]')
@property
def end(self):
return self.parent.find_element_by_css_selector('input[name=range1]')
@property
def icon_plus(self):
return self.parent.find_element_by_css_selector('button.ip-ranges-add')
@property
def icon_minus(self):
return self.parent.\
find_element_by_css_selector('button.ip-ranges-delete')

View File

@ -0,0 +1,121 @@
from pageobjects.base import PageObject
from pageobjects.settings import SettingsFooter
class DisksSettings(PageObject, SettingsFooter):
@property
def disks(self):
elements = self.parent.\
find_elements_by_css_selector('div.node-disks > div')
return [Disk(el) for el in elements]
class Disk(PageObject):
XPATH_INFORMATION_ITEM = './/div[@class="disk-map-details-item" and ' \
'div[@class="disk-map-details-name"]="{}"]' \
'/div[@class="disk-map-details-parameter"]'
def __init__(self, element):
PageObject.__init__(self, element)
@property
def volume_os(self):
return Volume(self.parent.find_element_by_css_selector(
'div.volume-group.os > .toggle-volume'))
@property
def volume_image(self):
return Volume(self.parent.find_element_by_css_selector(
'div.volume-group.image > .toggle-volume'))
@property
def volume_storage(self):
return Volume(self.parent.find_element_by_css_selector(
'div.volume-group.vm > .toggle-volume'))
@property
def volume_unallocated(self):
return Volume(self.parent.find_element_by_css_selector(
'div.volume-group.unallocated > .toggle-volume'))
@property
def volume_group_os(self):
return VolumeGroup(self.parent.find_element_by_css_selector(
'div.volume-group-box[data-volume=os]'
))
@property
def volume_group_image(self):
return VolumeGroup(self.parent.find_element_by_css_selector(
'div.volume-group-box[data-volume=image]'
))
@property
def volume_group_storage(self):
return VolumeGroup(self.parent.find_element_by_css_selector(
'div.volume-group-box[data-volume=vm]'
))
@property
def details_panel(self):
return self.parent.find_element_by_css_selector('.disk-map-details')
@property
def name(self):
return self.parent.find_element_by_xpath(
self.XPATH_INFORMATION_ITEM.format('name'))
@property
def model(self):
return self.parent.find_element_by_xpath(
self.XPATH_INFORMATION_ITEM.format('model'))
@property
def disk(self):
return self.parent.find_element_by_xpath(
self.XPATH_INFORMATION_ITEM.format('disk'))
@property
def size(self):
return self.parent.find_element_by_xpath(
self.XPATH_INFORMATION_ITEM.format('size'))
class Volume(PageObject):
def __init__(self, element):
PageObject.__init__(self, element)
@property
def name(self):
return self.parent.find_element_by_css_selector('.volume-group-name')
@property
def size(self):
return self.parent.find_element_by_css_selector('.volume-group-size')
@property
def close_cross(self):
return self.parent.\
find_element_by_xpath('./../div[contains(@class, "close-btn")]')
class VolumeGroup(PageObject):
def __init__(self, element):
PageObject.__init__(self, element)
@property
def name(self):
return self.parent.\
find_element_by_css_selector('.volume-group-box-name')
@property
def use_all(self):
return self.parent.find_element_by_css_selector('.use-all-allowed')
@property
def input(self):
return self.parent.find_element_by_tag_name('input')

View File

@ -0,0 +1,32 @@
from pageobjects.base import PageObject
from pageobjects.settings import SettingsFooter
class InterfacesSettings(PageObject, SettingsFooter):
@property
def interfaces(self):
elements = self.parent.\
find_elements_by_css_selector('.physical-network-box')
return [Interface(e) for e in elements]
class Interface(PageObject):
def __init__(self, element):
PageObject.__init__(self, element)
@property
def info(self):
return self.parent.find_element_by_css_selector('.network-info-box')
@property
def networks_box(self):
return self.parent.find_element_by_css_selector('.logical-network-box')
@property
def networks(self):
elements = self.parent.\
find_elements_by_css_selector('.logical-network-item')
return {el.find_element_by_css_selector('.name').text.lower(): el
for el in elements}

View File

@ -0,0 +1,176 @@
from selenium.webdriver.support.select import Select
from pageobjects.base import PageObject
from pageobjects.base import Popup
class Nodes(PageObject):
@property
def info_icon(self):
return self.parent.find_element_by_css_selector('i.icon-info-circled')
@property
def env_name(self):
return self.parent.\
find_element_by_css_selector('span.btn-cluster-details')
@property
def deploy_changes(self):
return self.parent.find_element_by_css_selector('button.deploy-btn')
@property
def discard_changes(self):
return self.parent.find_element_by_css_selector('button.rollback')
@property
def progress_deployment(self):
return self.parent.find_element_by_css_selector('.progress-deploy')
@property
def env_details(self):
return self.parent.find_element_by_css_selector('ul.cluster-details')
@property
def group_by(self):
return Select(
self.parent.find_element_by_css_selector('select[name=grouping]'))
@property
def add_nodes(self):
return self.parent.find_element_by_css_selector('button.btn-add-nodes')
@property
def delete_nodes(self):
return self.parent.\
find_element_by_css_selector('button.btn-delete-nodes')
@property
def edit_roles(self):
return self.parent.\
find_element_by_css_selector('button.btn-edit-nodes')
@property
def configure_interfaces(self):
return self.parent.\
find_element_by_css_selector('button.btn-configure-interfaces')
@property
def apply_changes(self):
return self.parent.find_element_by_css_selector('button.btn-apply')
@property
def configure_disks(self):
return self.parent.\
find_element_by_css_selector('button.btn-configure-disks')
@property
def nodes(self):
elements = self.parent.find_elements_by_css_selector('.node-container')
return [NodeContainer(el) for el in elements]
@property
def nodes_discovered(self):
elements = self.parent.\
find_elements_by_css_selector('.node-container.discover')
return [NodeContainer(el) for el in elements]
@property
def nodes_offline(self):
elements = self.parent.\
find_elements_by_css_selector('.node-container.node-offline')
return [NodeContainer(el) for el in elements]
@property
def nodes_error(self):
elements = self.parent.\
find_elements_by_css_selector('.node-container.error')
return [NodeContainer(el) for el in elements]
@property
def select_all(self):
return self.parent.\
find_element_by_css_selector('[name=select-nodes-common]')
@property
def select_all_in_group(self):
return self.parent.\
find_elements_by_css_selector('[name=select-node-group]')
@property
def node_groups(self):
elements = self.parent.find_elements_by_css_selector('.node-groups')
return [Nodes(el) for el in elements]
class NodeContainer(PageObject):
@property
def name(self):
return self.parent.find_element_by_css_selector('div.name > p')
@property
def name_input(self):
return self.parent.find_element_by_css_selector('div.name > input')
@property
def checkbox(self):
return self.parent.find_element_by_css_selector('div.node-checkbox')
@property
def roles(self):
return self.parent.find_element_by_css_selector('div.role-list')
@property
def details(self):
return self.parent.find_element_by_css_selector('.node-details')
@property
def status(self):
return self.parent.find_element_by_css_selector('.node-status-label')
class RolesPanel(PageObject):
XPATH_ROLE = '//label[contains(., "{}")]/input'
@property
def controller(self):
return self.parent.\
find_element_by_xpath(self.XPATH_ROLE.format('Controller'))
@property
def compute(self):
return self.parent.\
find_element_by_xpath(self.XPATH_ROLE.format('Compute'))
@property
def cinder(self):
return self.parent.\
find_element_by_xpath(self.XPATH_ROLE.format('Cinder'))
@property
def ceph_osd(self):
return self.parent.\
find_element_by_xpath(self.XPATH_ROLE.format('Ceph OSD'))
class NodeInfo(Popup):
@property
def edit_networks(self):
return self.parent.find_element_by_css_selector('.btn-edit-networks')
@property
def edit_disks(self):
return self.parent.find_element_by_css_selector('.btn-edit-disks')
@property
def close(self):
return self.parent.find_element_by_css_selector('.node-modal-close')
class DeleteNodePopup(Popup):
@property
def delete(self):
return self.parent.find_element_by_css_selector('.btn-delete')

View File

@ -0,0 +1,36 @@
from pageobjects.base import PageObject
class Releases(PageObject):
@property
def dict(self):
elements = self.parent.\
find_elements_by_css_selector('div.table-releases-box tbody > tr')
return {Release(el).name.text: Release(el) for el in elements}
@property
def rhel_setup(self):
return self.parent.find_element_by_css_selector('.btn-rhel-setup')
class Release(PageObject):
def __init__(self, element):
PageObject.__init__(self, parent=element)
@property
def name(self):
return self.parent.find_element_by_css_selector('.release-name')
@property
def version(self):
return self.parent.find_element_by_css_selector('.release-version')
@property
def status(self):
return self.parent.find_element_by_css_selector('.release-status')
@property
def download_progress(self):
return self.parent.find_element_by_css_selector('.download_progress')

View File

@ -0,0 +1,192 @@
from pageobjects.base import PageObject
class SettingsFooter(PageObject):
@property
def back_to_node_list(self):
return self.parent.\
find_element_by_xpath('//button[text()="Back To Node List"]')
@property
def load_defaults(self):
return self.parent.\
find_element_by_xpath('//button[text()="Load Defaults"]')
@property
def cancel_changes(self):
return self.parent.\
find_element_by_xpath('//button[text()="Cancel Changes"]')
@property
def save_settings(self):
return self.parent.\
find_element_by_xpath('//button[text()="Save Settings"]')
@property
def apply(self):
return self.parent.find_element_by_xpath('//button[text()="Apply"]')
class Settings(PageObject, SettingsFooter):
@property
def username(self):
return self.parent.find_element_by_name('user')
@property
def password(self):
return self.parent.find_element_by_name('password')
@property
def show_password(self):
return self.parent.\
find_element_by_xpath('//div[input[@name="password"]]/span')
@property
def tenant(self):
return self.parent.find_element_by_name('tenant')
@property
def email(self):
return self.parent.find_element_by_name('email')
@property
def install_savanna(self):
return self.parent.\
find_element_by_xpath(self.XPATH_CHECKBOX.format('savanna'))
@property
def install_murano(self):
return self.parent.\
find_element_by_xpath(self.XPATH_CHECKBOX.format('murano'))
@property
def install_ceilometer(self):
return self.parent.\
find_element_by_xpath(self.XPATH_CHECKBOX.format('ceilometer'))
@property
def debug(self):
return self.parent.\
find_element_by_xpath(self.XPATH_CHECKBOX.format('debug'))
@property
def hypervisor_kvm(self):
return self.parent.\
find_element_by_xpath(self.XPATH_RADIO.format('libvirt_type',
'kvm'))
@property
def hypervisor_qemu(self):
return self.parent.\
find_element_by_xpath(self.XPATH_RADIO.format('libvirt_type',
'qemu'))
@property
def assign_ip(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_CHECKBOX.format('auto_assign_floating_ip'))
@property
def filter_scheduler(self):
return self.parent.find_element_by_xpath(
self.XPATH_RADIO.format(
'compute_scheduler_driver',
'nova.scheduler.filter_scheduler.FilterScheduler'))
@property
def simple_scheduler(self):
return self.parent.find_element_by_xpath(
self.XPATH_RADIO.format(
'compute_scheduler_driver',
'nova.scheduler.simple.SimpleScheduler'))
@property
def vlan_splinters(self):
return self.parent.\
find_element_by_xpath(self.XPATH_CHECKBOX.format('vlan_splinters'))
@property
def vlan_splinters_disabled(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('vlan_splinters', 'disabled'))
@property
def vlan_splinters_soft(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('vlan_splinters', 'soft'))
@property
def vlan_splinters_hard(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_RADIO.format('vlan_splinters', 'hard'))
@property
def use_cow_images(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_CHECKBOX.format('use_cow_images'))
@property
def start_guests(self):
return self.parent.\
find_element_by_xpath(
self.XPATH_CHECKBOX.format('start_guests_on_host_boot'))
@property
def auth_key(self):
return self.parent.find_element_by_name('auth_key')
@property
def syslog_server(self):
return self.parent.find_element_by_name('syslog_server')
@property
def syslog_port(self):
return self.parent.find_element_by_name('syslog_port')
@property
def syslog_udp(self):
return self.parent.find_element_by_xpath(
self.XPATH_RADIO.format(
'syslog_transport', 'udp'))
@property
def syslog_tcp(self):
return self.parent.find_element_by_xpath(
self.XPATH_RADIO.format(
'syslog_transport', 'tcp'))
@property
def cinder_for_volumes(self):
return self.parent.\
find_element_by_xpath(self.XPATH_CHECKBOX.format('volumes_lvm'))
@property
def ceph_for_volumes(self):
return self.parent.\
find_element_by_xpath(self.XPATH_CHECKBOX.format('volumes_ceph'))
@property
def ceph_for_images(self):
return self.parent.\
find_element_by_xpath(self.XPATH_CHECKBOX.format('images_ceph'))
@property
def ceph_ephemeral(self):
return self.parent.\
find_element_by_xpath(self.XPATH_CHECKBOX.format('ephemeral_ceph'))
@property
def ceph_rados_gw(self):
return self.parent.\
find_element_by_xpath(self.XPATH_CHECKBOX.format('objects_ceph'))
@property
def ceph_factor(self):
return self.parent.find_element_by_name('osd_pool_size')

View File

@ -0,0 +1,25 @@
from pageobjects.base import PageObject
class Support(PageObject):
@property
def register_fuel(self):
return self.parent.find_element_by_link_text('Register Fuel')
@property
def contact_support(self):
return self.parent.find_element_by_link_text('Contact Support')
@property
def generate_snapshot(self):
return self.parent.find_element_by_css_selector('button.download-logs')
@property
def download_snapshot(self):
return self.parent.\
find_element_by_css_selector('span.donwload-logs-link > a')
@property
def view_capacity_audit(self):
return self.parent.find_element_by_link_text('View Capacity Audit')

View File

@ -0,0 +1,36 @@
from pageobjects.base import PageObject
class Tabs(PageObject):
XPATH_TAB = '//ul/li/a[div/text()="{}"]'
@property
def nodes(self):
return self.parent.\
find_element_by_xpath(self.XPATH_TAB.format('Nodes'))
@property
def networks(self):
return self.parent.\
find_element_by_xpath(self.XPATH_TAB.format('Networks'))
@property
def settings(self):
return self.parent.\
find_element_by_xpath(self.XPATH_TAB.format('Settings'))
@property
def logs(self):
return self.parent.\
find_element_by_xpath(self.XPATH_TAB.format('Logs'))
@property
def health_check(self):
return self.parent.\
find_element_by_xpath(self.XPATH_TAB.format('Health Check'))
@property
def actions(self):
return self.parent.\
find_element_by_xpath(self.XPATH_TAB.format('Actions'))

View File

@ -0,0 +1 @@
selenium

View File

@ -0,0 +1,39 @@
import os
import re
BROWSER = os.environ.get('BROWSER', 'firefox')
# download it here http://chromedriver.storage.googleapis.com/index.html
CHROME_EXECUTABLE_PATH = \
os.environ.get('CHROME_EXECUTABLE_PATH', '/usr/bin/google-chrome')
NAILGUN_FOLDER = os.environ.get('NAILGUN_FOLDER')
FOLDER_SCREEN_EXPECTED = os.environ.get(
'FOLDER_SCREEN_EXPECTED', '/home/nfedotov/testscreens/expected')
FOLDER_SCREEN_CURRENT = os.environ.get(
'FOLDER_SCREEN_CURRENT', '/home/nfedotov/testscreens/current')
OPENSTACK_RELEASE_CENTOS = os.environ.get(
'OPENSTACK_RELEASE_CENTOS', 'Havana on CentOS 6.4 (2013.2.1)')
OPENSTACK_RELEASE_REDHAT = os.environ.get(
'OPENSTACK_RELEASE_REDHAT', 'RHOS 3.0 for RHEL 6.4 (2013.1.2)')
OPENSTACK_RELEASE_UBUNTU = os.environ.get(
'OPENSTACK_RELEASE_UBUNTU', 'Havana on Ubuntu 12.04 (2013.2.1)')
REDHAT_USERNAME = os.environ.get('REDHAT_USERNAME', 'rheltest')
REDHAT_PASSWORD = os.environ.get('REDHAT_PASSWORD', 'password')
REDHAT_SATELLITE = os.environ.get('REDHAT_SATELLITE', 'satellite.example.com')
REDHAT_ACTIVATION_KEY = os.environ.get(
'REDHAT_ACTIVATION_KEY', '1234567890')
openstack_name = lambda release: re.sub('\s\\(.*?\\)$', '', release)
OPENSTACK_CENTOS = openstack_name(OPENSTACK_RELEASE_CENTOS)
OPENSTACK_REDHAT = openstack_name(OPENSTACK_RELEASE_REDHAT)
OPENSTACK_UBUNTU = openstack_name(OPENSTACK_RELEASE_UBUNTU)
NAILGUN_FIXTURES = os.environ.get('NAILGUN_FIXTURES', '')
URL_HOME = os.environ.get('URL_HOME', 'http://localhost:8000/')
SELENIUM_IMPLICIT_WAIT = os.environ.get('SELENIUM_IMPLICIT_WAIT', 10)

View File

View File

@ -0,0 +1,91 @@
import base64
from io import BytesIO
from unittest import TestCase
from PIL import Image
import operator
import math
import time
from selenium.common.exceptions import NoSuchElementException
import browser
from pageobjects.header import Header
from fuelweb_ui_test.settings import FOLDER_SCREEN_CURRENT
from fuelweb_ui_test.settings import FOLDER_SCREEN_EXPECTED
from fuelweb_ui_test.settings import NAILGUN_FIXTURES
from fuelweb_ui_test.settings import URL_HOME
class BaseTestCase(TestCase):
@classmethod
def setUpClass(cls):
browser.start_driver()
cls.clear_nailgun_database()
@classmethod
def tearDownClass(cls):
browser.quit_driver()
def setUp(self):
self.get_home()
@staticmethod
def get_home():
for i in range(5):
try:
browser.driver.get(URL_HOME)
Header().logo.is_displayed()
browser.driver.execute_script('jQuery.fx.off = true')
browser.driver.execute_script('''
$('head').append(
'<style type="text/css">
* {
-webkit-transition-duration: 0.00000001s !
important;
-moz-transition: 0.00000001s !important;
transition-duration: 0.00000001s !important;
}
</style>')
'''.replace('\n', ''))
break
except NoSuchElementException:
pass
@staticmethod
def refresh():
for i in range(5):
try:
browser.driver.refresh()
time.sleep(0.5)
Header().logo.is_displayed()
break
except NoSuchElementException:
pass
@staticmethod
def clear_nailgun_database():
from nailgun.db import dropdb
from nailgun.db import syncdb
from nailgun.db.sqlalchemy import fixman
dropdb()
syncdb()
fixman.upload_fixtures()
for fixture in NAILGUN_FIXTURES.split(':'):
if fixture == '':
continue
with open(fixture, "r") as fileobj:
fixman.upload_fixture(fileobj)
def assert_screen(self, name):
img_exp = Image.open('{}/{}.png'.format(FOLDER_SCREEN_EXPECTED, name))
img_cur_base64 = browser.driver.get_screenshot_as_base64()
img_cur = Image.open(BytesIO(base64.decodestring(img_cur_base64)))
img_cur.save('{}/{}.png'.format(FOLDER_SCREEN_CURRENT, name))
h1 = img_exp.histogram()
h2 = img_cur.histogram()
rms = math.sqrt(
reduce(operator.add,
map(lambda a, b: (a - b) ** 2, h1, h2)) / len(h1))
self.assertNotEqual(rms == 0, 'Screen valid')

View File

@ -0,0 +1,79 @@
import time
from pageobjects.environments import Environments
from pageobjects.environments import Wizard
from pageobjects.environments import DeployChangesPopup
from pageobjects.header import TaskResultAlert
from pageobjects.nodes import Nodes, RolesPanel
from tests.base import BaseTestCase
from fuelweb_ui_test.settings import OPENSTACK_CENTOS
from fuelweb_ui_test.settings import OPENSTACK_RELEASE_CENTOS
class Environment:
@staticmethod
def simple_flat(name=OPENSTACK_CENTOS,
release=OPENSTACK_RELEASE_CENTOS):
BaseTestCase.get_home()
Environments().create_cluster_box.click()
with Wizard() as w:
w.name.send_keys(name)
w.release.select_by_visible_text(release)
for i in range(6):
w.next.click()
w.create.click()
w.wait_until_exists()
@staticmethod
def ha_flat(name=OPENSTACK_CENTOS,
release=OPENSTACK_RELEASE_CENTOS):
BaseTestCase.get_home()
Environments().create_cluster_box.click()
with Wizard() as w:
w.name.send_keys(name)
w.release.select_by_visible_text(release)
w.next.click()
w.mode_ha_compact.click()
for i in range(5):
w.next.click()
w.create.click()
w.wait_until_exists()
@staticmethod
def simple_neutron_gre(name=OPENSTACK_CENTOS,
release=OPENSTACK_RELEASE_CENTOS):
BaseTestCase.get_home()
Environments().create_cluster_box.click()
with Wizard() as w:
w.name.send_keys(name)
w.release.select_by_visible_text(release)
for i in range(3):
w.next.click()
w.network_neutron_gre.click()
for i in range(3):
w.next.click()
w.create.click()
w.wait_until_exists()
@staticmethod
def deploy_nodes(controllers=0, computes=0, cinders=0, cephs=0):
def add(role, amount):
if amount < 1:
return
Nodes().add_nodes.click()
time.sleep(1)
for i in range(amount):
Nodes().nodes_discovered[i].checkbox.click()
getattr(RolesPanel(), role).click()
Nodes().apply_changes.click()
time.sleep(1)
add('controller', controllers)
add('compute', computes)
add('cinder', cinders)
add('ceph_osd', cephs)
time.sleep(1)
Nodes().deploy_changes.click()
DeployChangesPopup().deploy.click()
TaskResultAlert().close.click()

View File

@ -0,0 +1,312 @@
import time
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys
from pageobjects.environments import Environments
from pageobjects.header import Header
from pageobjects.nodes import Nodes, NodeInfo, RolesPanel
from pageobjects.tabs import Tabs
from tests import preconditions
from tests.base import BaseTestCase
from tests.test_roles import ROLE_CONTROLLER, ROLE_CEPH, ROLE_CINDER
class TestNodesAddPage(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
preconditions.Environment.simple_flat()
def setUp(self):
BaseTestCase.setUp(self)
Environments().create_cluster_boxes[0].click()
Nodes().add_nodes.click()
time.sleep(1)
def test_discovered_nodes_enabled(self):
with Nodes()as n:
for node in n.nodes_discovered:
self.assertTrue(
node.checkbox.
find_element_by_tag_name('input').is_enabled(),
'Node enabled')
def test_offline_nodes_disabled(self):
with Nodes()as n:
for node in n.nodes_offline:
self.assertFalse(
node.checkbox.
find_element_by_tag_name('input').is_enabled(),
'Node disabled')
def test_error_nodes_disabled(self):
with Nodes()as n:
for node in n.nodes_error:
self.assertFalse(
node.checkbox.
find_element_by_tag_name('input').is_enabled(),
'Node disabled')
def test_select_all(self):
with Nodes()as n:
n.select_all.click()
for selects in n.select_all_in_group:
self.assertTrue(selects.is_selected(),
'Select all in group is selected')
for node in n.nodes_discovered:
self.assertTrue(
node.checkbox.
find_element_by_tag_name('input').is_selected(),
'Discovered node is selected')
for node in n.nodes_offline:
self.assertFalse(
node.checkbox.
find_element_by_tag_name('input').is_selected(),
'Offline node is not selected')
for node in n.nodes_error:
self.assertFalse(
node.checkbox.
find_element_by_tag_name('input').is_selected(),
'Error node is not selected')
def test_select_all_in_group(self):
with Nodes()as n:
for i, group in enumerate(n.node_groups):
group.select_all_in_group[0].click()
for node in group.nodes_discovered:
self.assertTrue(
node.checkbox.find_element_by_tag_name('input').
is_selected(),
'Discovered node is selected')
self.assertTrue(
n.select_all.is_selected(), '"Select all" is checked')
def test_select_all_selecting_nodes_one_by_one(self):
with Nodes()as n:
for i, group in enumerate(n.node_groups):
for node in group.nodes_discovered:
node.checkbox.click()
self.assertTrue(
group.select_all_in_group[0].is_selected(),
'"Select all in group" is checked')
self.assertTrue(
n.select_all.is_selected(), '"Select all" is checked')
def test_selecting_nodes_clicking_them_discovered(self):
with Nodes()as n:
for node in n.nodes_discovered:
node.parent.click()
self.assertTrue(
node.checkbox.
find_element_by_tag_name('input').is_selected(),
'Discovered node is selected')
def test_selecting_nodes_clicking_them_offline(self):
with Nodes()as n:
for node in n.nodes_offline:
node.parent.click()
self.assertFalse(
node.checkbox.
find_element_by_tag_name('input').is_selected(),
'Offline node is not selected')
def test_selecting_nodes_clicking_them_error(self):
with Nodes()as n:
for node in n.nodes_error:
node.parent.click()
self.assertFalse(
node.checkbox.
find_element_by_tag_name('input').is_selected(),
'Error node is not selected')
def test_node_info_popup(self):
def test_popup(node):
node.details.click()
with NodeInfo() as details:
self.assertEqual(
node.name.text, details.header.text,
'Node name')
details.close.click()
details.wait_until_exists()
with Nodes()as n:
test_popup(n.nodes_discovered[0])
test_popup(n.nodes_offline[0])
test_popup(n.nodes_error[0])
def test_renaming_node(self):
name = 'new node name'
with Nodes()as n:
old_name = n.nodes_discovered[0].name.text
n.nodes_discovered[0].name.click()
self.assertTrue(
n.nodes_discovered[0].name_input.is_displayed(),
'input visible')
n.nodes_discovered[0].name_input.send_keys(name)
n.nodes_discovered[0].parent.click()
self.assertRaises(
NoSuchElementException, getattr, n.nodes_discovered[0],
'name_input')
self.assertEqual(
old_name, n.nodes_discovered[0].name.text,
'Node has old name')
n.nodes_discovered[0].name.click()
n.nodes_discovered[0].name_input.send_keys(name)
n.nodes_discovered[0].name_input.send_keys(Keys.ENTER)
time.sleep(2)
self.assertEqual(
name, Nodes().nodes_discovered[0].name.text,
'New node name')
class TestAddingNodes(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
def setUp(self):
BaseTestCase.clear_nailgun_database()
preconditions.Environment.simple_flat()
BaseTestCase.setUp(self)
Environments().create_cluster_boxes[0].click()
Nodes().add_nodes.click()
time.sleep(1)
def test_adding_node_single_role(self):
name = Nodes().nodes_discovered[0].name.text
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().controller.click()
Nodes().apply_changes.click()
time.sleep(1)
with Nodes() as n:
self.assertTrue(n.env_name.is_displayed())
self.assertEqual(len(n.nodes), 1, 'Nodes amount')
self.assertEqual(n.nodes[0].name.text, name, 'Node name')
self.assertIn(ROLE_CONTROLLER, n.nodes[0].roles.text, 'Node role')
def test_adding_node_multiple_roles(self):
Nodes().nodes_discovered[0].checkbox.click()
with RolesPanel() as r:
r.controller.click()
r.cinder.click()
r.ceph_osd.click()
Nodes().apply_changes.click()
time.sleep(1)
with Nodes() as n:
self.assertTrue(n.env_name.is_displayed())
self.assertIn(ROLE_CONTROLLER, n.nodes[0].roles.text,
'Node first role')
self.assertIn(ROLE_CINDER, n.nodes[0].roles.text,
'Node second role')
self.assertIn(ROLE_CEPH, n.nodes[0].roles.text,
'Node third role')
def test_edit_role_add_new_role(self):
# Add node with controller role
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().controller.click()
Nodes().apply_changes.click()
time.sleep(1)
# Add cinder role
with Nodes() as n:
n.nodes[0].checkbox.click()
n.edit_roles.click()
RolesPanel().cinder.click()
Nodes().apply_changes.click()
time.sleep(1)
with Nodes() as n:
self.assertIn(ROLE_CONTROLLER, n.nodes[0].roles.text,
'Controller role')
self.assertIn(ROLE_CINDER, n.nodes[0].roles.text,
'Cinder role')
def test_edit_role_change_role(self):
# Add node with controller role
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().controller.click()
Nodes().apply_changes.click()
time.sleep(1)
# Remove controller, Add cinder and ceph-osd roles
with Nodes() as n:
n.nodes[0].checkbox.click()
n.edit_roles.click()
with RolesPanel() as r:
r.controller.click()
r.cinder.click()
r.ceph_osd.click()
Nodes().apply_changes.click()
time.sleep(1)
with Nodes() as n:
self.assertNotIn(ROLE_CONTROLLER, n.nodes[0].roles.text,
'Controller role has been removed')
self.assertIn(ROLE_CINDER, n.nodes[0].roles.text,
'Cinder role')
self.assertIn(ROLE_CEPH, n.nodes[0].roles.text,
'Ceph-osd role')
def test_unallocated_nodes_counter(self):
initial = int(Header().unallocated_nodes.text)
discovered = len(Nodes().nodes_discovered)
Tabs().nodes.click()
for i in range(discovered):
Nodes().add_nodes.click()
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().compute.click()
Nodes().apply_changes.click()
time.sleep(1)
self.assertEqual(
str(initial - i - 1), Header().unallocated_nodes.text,
'Unallocated nodes amount')
class TestGroupBy(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
BaseTestCase.get_home()
preconditions.Environment().simple_flat()
Environments().create_cluster_boxes[0].click()
# Add controller
Nodes().add_nodes.click()
time.sleep(1)
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().controller.click()
Nodes().apply_changes.click()
time.sleep(1)
# Add other discovered nodes as compute
Nodes().add_nodes.click()
time.sleep(1)
for n in Nodes().nodes_discovered:
n.checkbox.click()
RolesPanel().compute.click()
Nodes().apply_changes.click()
def setUp(self):
BaseTestCase.setUp(self)
Environments().create_cluster_boxes[0].click()
def _test_group_by(self, group_by, nodes_in_groups):
with Nodes() as n:
n.group_by.select_by_visible_text(group_by)
time.sleep(1)
self.assertEqual(
len(nodes_in_groups), len(n.node_groups), 'Groups amount')
for i, group in enumerate(n.node_groups):
self.assertEqual(
nodes_in_groups[i], len(group.nodes),
'Group #{0} has {1} nodes'.format(i, nodes_in_groups[i]))
def test_group_by_roles(self):
self._test_group_by('Roles', [1, 5])
def test_group_by_hardware_info(self):
self._test_group_by('Hardware Info', [1, 1, 2, 1, 1])
def test_group_by_roles_and_hardware_info(self):
self._test_group_by('Roles and hardware info', [1, 2, 1, 1, 1])

View File

@ -0,0 +1,216 @@
import random
import time
from pageobjects.base import ConfirmPopup
from pageobjects.environments import Environments
from pageobjects.node_disks_settings import DisksSettings
from pageobjects.nodes import Nodes
from pageobjects.nodes import RolesPanel
from pageobjects.nodes import NodeInfo
from pageobjects.tabs import Tabs
from tests import preconditions
from tests.base import BaseTestCase
class TestConfigureDisks(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
preconditions.Environment.simple_flat()
Environments().create_cluster_boxes[0].click()
Nodes().add_nodes.click()
time.sleep(1)
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().controller.click()
Nodes().apply_changes.click()
def setUp(self):
BaseTestCase.setUp(self)
Environments().create_cluster_boxes[0].click()
Nodes().nodes[0].details.click()
NodeInfo().edit_disks.click()
time.sleep(1)
def test_volume_animation(self):
with DisksSettings() as s:
s.disks[0].volume_os.parent.click()
time.sleep(1)
self.assertTrue(
s.disks[0].details_panel.is_displayed(),
'details panel is expanded')
s.disks[0].volume_os.parent.click()
time.sleep(1)
self.assertFalse(
s.disks[0].details_panel.is_displayed(),
'details panel is expanded')
def test_remove_volume_cross(self):
with DisksSettings() as s:
s.disks[0].volume_image.parent.click()
time.sleep(1)
s.disks[0].volume_image.close_cross.click()
self.assertFalse(
s.disks[0].volume_image.close_cross.is_displayed(),
'Image volume has been removed')
self.assertEqual(
'0',
s.disks[0].volume_group_image.input.get_attribute('value'),
'image volume size is 0')
def test_use_all_allowed(self):
with DisksSettings() as s:
s.disks[1].volume_image.parent.click()
time.sleep(1)
s.disks[1].volume_image.close_cross.click()
unallocated = s.disks[1].volume_unallocated.size.text
s.disks[1].volume_group_os.use_all.click()
self.assertEqual(
unallocated, s.disks[1].volume_os.size.text,
'Base system uses all allowed space'
)
s.disks[1].volume_os.close_cross.click()
s.disks[1].volume_group_image.use_all.click()
self.assertEqual(
unallocated, s.disks[1].volume_image.size.text,
'Image storage uses all allowed space'
)
def test_type_volume_size(self):
values = [random.randint(100000, 200000) for i in range(3)]
with DisksSettings() as s:
s.disks[0].volume_image.parent.click()
time.sleep(1)
for v in values:
s.disks[0].volume_group_image.input.clear()
s.disks[0].volume_group_image.input.send_keys(v)
time.sleep(0.5)
exp = '{0:.1f} GB'.format((float(v) / 1024))
cur = s.disks[0].volume_image.size.text
self.assertEqual(
exp, cur,
'Volume size. exp: {0} ({1}), cur {2}'.format(exp, v, cur))
def test_save_load_defaults(self):
default = None
value = random.randint(60000, 80000)
with DisksSettings() as s:
s.disks[0].volume_image.parent.click()
time.sleep(1)
default = s.disks[0].\
volume_group_image.input.get_attribute('value')
s.disks[0].volume_group_image.input.\
clear()
s.disks[0].volume_group_image.input.\
send_keys(value)
s.apply.click()
time.sleep(1)
self.refresh()
with DisksSettings() as s:
time.sleep(2)
self.assertEqual(
"{:,}".format(value),
s.disks[0].volume_group_image.input.get_attribute('value'),
'New value has been saved'
)
s.load_defaults.click()
time.sleep(1)
self.assertEqual(
default,
s.disks[0].volume_group_image.input.get_attribute('value'),
'default value has been restored'
)
def test_cancel_changes(self):
with DisksSettings() as s:
s.disks[0].volume_image.parent.click()
time.sleep(1)
default = s.disks[0].\
volume_group_image.input.get_attribute('value')
s.disks[0].volume_group_image.input.\
clear()
s.disks[0].volume_group_image.input.\
send_keys(random.randint(60000, 80000))
s.cancel_changes.click()
time.sleep(1)
self.assertEqual(
default,
s.disks[0].volume_group_image.input.get_attribute('value'),
'default value has been restored'
)
def test_confirm_if_back_to_list(self):
with DisksSettings() as s:
s.disks[0].volume_image.parent.click()
time.sleep(1)
s.disks[0].volume_group_image.input.\
clear()
s.disks[0].volume_group_image.input.\
send_keys('0')
s.back_to_node_list.click()
with ConfirmPopup() as p:
p.stay_on_page.click()
p.wait_until_exists()
self.assertEqual(
'0', s.disks[0].volume_group_image.
input.get_attribute('value'), 'Value is not changed')
s.back_to_node_list.click()
with ConfirmPopup() as p:
p.leave_page.click()
p.wait_until_exists()
time.sleep(1)
self.assertTrue(
Nodes().add_nodes.is_displayed(),
'Backed to nodes page. Add Nodes button is displayed')
def test_configure_disks_of_several_nodes(self):
values = [random.randint(100000, 500000) for i in range(4)]
# Go back to nodes page
Tabs().nodes.click()
time.sleep(1)
# Add second node
Nodes().add_nodes.click()
time.sleep(1)
Nodes().select_all_in_group[1].click()
RolesPanel().compute.click()
Nodes().apply_changes.click()
time.sleep(1)
# change volumes size
with Nodes() as n:
n.select_all_in_group[1].click()
n.configure_disks.click()
time.sleep(1)
with DisksSettings() as s:
for i, v in enumerate(values):
s.disks[i].volume_storage.parent.click()
time.sleep(1)
s.disks[i].volume_group_storage.input.\
clear()
s.disks[i].volume_group_storage.input.\
send_keys(v)
s.apply.click()
time.sleep(1)
for i in range(1, 3):
# Go to nodes page
Tabs().nodes.click()
time.sleep(1)
# Verify disks settings of each node
Nodes().nodes[i].details.click()
NodeInfo().edit_disks.click()
time.sleep(1)
for j, v in enumerate(values):
self.assertEqual(
"{:,}".format(v),
s.disks[j].
volume_group_storage.input.get_attribute('value'),
'Image volume size of disk {0} of node {0} is correct'.
format(j, i))

View File

@ -0,0 +1,281 @@
import random
import time
from selenium.webdriver import ActionChains
import browser
from pageobjects.environments import Environments
from pageobjects.networks import Networks
from pageobjects.node_interfaces_settings import InterfacesSettings
from pageobjects.nodes import Nodes
from pageobjects.nodes import RolesPanel
from pageobjects.nodes import NodeInfo
from pageobjects.tabs import Tabs
from tests import preconditions
from tests.base import BaseTestCase
class TestConfigureNetworksPage(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
preconditions.Environment.simple_flat()
Environments().create_cluster_boxes[0].click()
Nodes().add_nodes.click()
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().controller.click()
Nodes().apply_changes.click()
time.sleep(1)
def setUp(self):
BaseTestCase.setUp(self)
Environments().create_cluster_boxes[0].click()
Nodes().nodes[0].details.click()
NodeInfo().edit_networks.click()
def test_drag_and_drop(self):
with InterfacesSettings() as s:
ActionChains(browser.driver).drag_and_drop(
s.interfaces[0].networks['storage'],
s.interfaces[1].networks_box).perform()
ActionChains(browser.driver).drag_and_drop(
s.interfaces[0].networks['management'],
s.interfaces[2].networks_box).perform()
ActionChains(browser.driver).drag_and_drop(
s.interfaces[0].networks['vm (fixed)'],
s.interfaces[2].networks_box).perform()
self.assertIn(
'storage', s.interfaces[1].networks,
'storage at eht1')
self.assertIn(
'management', s.interfaces[2].networks,
'management at eht2')
self.assertIn(
'vm (fixed)', s.interfaces[2].networks,
'vm (fixed) at eht2')
def test_public_floating_grouped(self):
with InterfacesSettings() as s:
ActionChains(browser.driver).drag_and_drop(
s.interfaces[0].networks['public'],
s.interfaces[1].networks_box).perform()
self.assertIn(
'floating', s.interfaces[1].networks,
'Floating has been moved')
ActionChains(browser.driver).drag_and_drop(
s.interfaces[1].networks['floating'],
s.interfaces[2].networks_box).perform()
self.assertIn(
'public', s.interfaces[2].networks,
'Public has been moved')
def test_admin_pxe_is_not_dragable(self):
with InterfacesSettings() as s:
ActionChains(browser.driver).drag_and_drop(
s.interfaces[2].networks['admin (pxe)'],
s.interfaces[0].networks_box).perform()
self.assertNotIn(
'admin (pxe)', s.interfaces[1].networks,
'admin (pxe) has not been moved')
def test_two_untagged_on_interface(self):
error = 'Untagged networks can not be assigned to one interface'
with InterfacesSettings() as s:
ActionChains(browser.driver).drag_and_drop(
s.interfaces[0].networks['public'],
s.interfaces[2].networks_box).perform()
self.assertIn(
'nodrag', s.interfaces[2].parent.get_attribute('class'),
'Red border')
self.assertIn(
error, s.interfaces[2].
parent.find_element_by_xpath('./..').text,
'Error message is displayed'
)
self.assertFalse(s.apply.is_enabled(), 'Apply disabled')
ActionChains(browser.driver).drag_and_drop(
s.interfaces[2].networks['public'],
s.interfaces[1].networks_box).perform()
self.assertNotIn(
'nodrag', s.interfaces[2].parent.get_attribute('class'),
'Red border')
self.assertNotIn(
error, s.interfaces[2].
parent.find_element_by_xpath('./..').text,
'Error message is displayed'
)
self.assertTrue(s.apply.is_enabled(), 'Apply enabled')
def test_cancel_changes(self):
with InterfacesSettings() as s:
ActionChains(browser.driver).drag_and_drop(
s.interfaces[0].networks['public'],
s.interfaces[1].networks_box).perform()
ActionChains(browser.driver).drag_and_drop(
s.interfaces[0].networks['storage'],
s.interfaces[2].networks_box).perform()
s.cancel_changes.click()
time.sleep(1)
self.assertIn(
'storage', s.interfaces[0].networks,
'storage at eht0')
self.assertIn(
'public', s.interfaces[0].networks,
'public at eht0')
self.assertIn(
'floating', s.interfaces[0].networks,
'floating at eht0')
class TestConfigureNetworks(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
def setUp(self):
BaseTestCase.clear_nailgun_database()
BaseTestCase.setUp(self)
preconditions.Environment.simple_flat()
Environments().create_cluster_boxes[0].click()
Nodes().add_nodes.click()
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().controller.click()
Nodes().apply_changes.click()
time.sleep(1)
Nodes().nodes[0].details.click()
NodeInfo().edit_networks.click()
def test_save_load_defaults(self):
with InterfacesSettings() as s:
ActionChains(browser.driver).drag_and_drop(
s.interfaces[0].networks['public'],
s.interfaces[1].networks_box).perform()
ActionChains(browser.driver).drag_and_drop(
s.interfaces[0].networks['storage'],
s.interfaces[2].networks_box).perform()
s.apply.click()
time.sleep(1)
self.refresh()
with InterfacesSettings() as s:
self.assertIn(
'storage', s.interfaces[2].networks,
'storage at eht2')
self.assertIn(
'public', s.interfaces[1].networks,
'public at eht1')
self.assertIn(
'floating', s.interfaces[1].networks,
'floating at eht1')
s.load_defaults.click()
time.sleep(1)
self.assertIn(
'storage', s.interfaces[0].networks,
'storage at eht0')
self.assertIn(
'public', s.interfaces[0].networks,
'public at eht0')
self.assertIn(
'floating', s.interfaces[0].networks,
'floating at eht0')
def test_configure_interfaces_of_several_nodes(self):
# Go back to nodes page
Tabs().nodes.click()
# Add second node
Nodes().add_nodes.click()
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().compute.click()
Nodes().apply_changes.click()
time.sleep(1)
# rearrange interfaces
with Nodes() as n:
n.select_all.click()
n.configure_interfaces.click()
with InterfacesSettings() as s:
ActionChains(browser.driver).drag_and_drop(
s.interfaces[0].networks['public'],
s.interfaces[1].networks_box).perform()
ActionChains(browser.driver).drag_and_drop(
s.interfaces[0].networks['management'],
s.interfaces[1].networks_box).perform()
ActionChains(browser.driver).drag_and_drop(
s.interfaces[0].networks['storage'],
s.interfaces[2].networks_box).perform()
s.apply.click()
time.sleep(1)
for i in range(2):
# Go to nodes page
Tabs().nodes.click()
# Verify interfaces settings of each node
Nodes().nodes[i].details.click()
NodeInfo().edit_networks.click()
self.assertIn(
'public', s.interfaces[1].networks,
'public at eht1. Node #{0}'.format(i))
self.assertIn(
'management', s.interfaces[1].networks,
'management at eht1. Node #{0}'.format(i))
self.assertIn(
'storage', s.interfaces[2].networks,
'storage at eht2. Node #{0}'.format(i))
def test_vlan_id_labels_visibility(self):
label = 'VLAN ID'
Tabs().networks.click()
with Networks() as n:
n.management.vlan_tagging.click()
n.storage.vlan_tagging.click()
n.fixed.vlan_tagging.click()
n.save_settings.click()
time.sleep(1)
Tabs().nodes.click()
Nodes().nodes[0].details.click()
NodeInfo().edit_networks.click()
with InterfacesSettings() as s:
self.assertNotIn(
label, s.interfaces[0].networks['storage'].text,
'vlan id is visible. Storage network')
self.assertNotIn(
label, s.interfaces[0].networks['management'].text,
'vlan id is visible. Management network')
self.assertNotIn(
label, s.interfaces[0].networks['vm (fixed)'].text,
'vlan id is visible. VM (Fixed) network')
def test_vlan_id_values(self):
label = 'VLAN ID: {0}'
vlans = [random.randint(110, 200) for i in range(3)]
Tabs().networks.click()
with Networks() as n:
n.management.vlan_id.clear()
n.management.vlan_id.send_keys(vlans[0])
n.storage.vlan_id.clear()
n.storage.vlan_id.send_keys(vlans[1])
n.fixed.vlan_id.clear()
n.fixed.vlan_id.send_keys(vlans[2])
n.save_settings.click()
time.sleep(1)
Tabs().nodes.click()
Nodes().nodes[0].details.click()
NodeInfo().edit_networks.click()
with InterfacesSettings() as s:
self.assertIn(
label.format(vlans[0]),
s.interfaces[0].networks['management'].text,
'vlan id is correct. Management network')
self.assertIn(
label.format(vlans[1]),
s.interfaces[0].networks['storage'].text,
'vlan id is correct. Storage network')
self.assertIn(
label.format(vlans[2]),
s.interfaces[0].networks['vm (fixed)'].text,
'vlan id is correct. VM (Fixed) network')

View File

@ -0,0 +1,133 @@
import time
from selenium.webdriver import ActionChains
import browser
from pageobjects.environments import Environments, DeployChangesPopup
from pageobjects.header import TaskResultAlert
from pageobjects.node_disks_settings import DisksSettings
from pageobjects.node_interfaces_settings import InterfacesSettings
from pageobjects.nodes import Nodes, RolesPanel, DeleteNodePopup, NodeInfo
from tests import preconditions
from tests.base import BaseTestCase
class TestDeploy(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
def setUp(self):
BaseTestCase.clear_nailgun_database()
BaseTestCase.setUp(self)
preconditions.Environment.simple_flat()
Environments().create_cluster_boxes[0].click()
time.sleep(1)
def test_add_nodes(self):
Nodes().add_nodes.click()
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().controller.click()
Nodes().apply_changes.click()
time.sleep(2)
Nodes().add_nodes.click()
time.sleep(1)
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().compute.click()
Nodes().apply_changes.click()
time.sleep(1)
for node in Nodes().nodes:
self.assertEqual(
'pending addition', node.status.text.lower(),
'Node status is Pending Addition')
Nodes().deploy_changes.click()
DeployChangesPopup().deploy.click()
TaskResultAlert().close.click()
with Nodes() as n:
self.assertEqual(2, len(n.nodes), 'Nodes amount')
for node in n.nodes:
self.assertEqual('ready', node.status.text.lower(),
'Node status is READY')
def test_delete_node(self):
self.test_add_nodes()
with Nodes() as n:
n.nodes[1].checkbox.click()
n.delete_nodes.click()
with DeleteNodePopup() as p:
p.delete.click()
p.wait_until_exists()
time.sleep(1)
self.assertEqual(
'pending deletion', Nodes().nodes[1].status.text.lower(),
'Node status is Pending Deletion')
Nodes().deploy_changes.click()
DeployChangesPopup().deploy.click()
TaskResultAlert().close.click()
with Nodes() as n:
self.assertEqual(1, len(n.nodes), 'Nodes amount')
for node in n.nodes:
self.assertEqual('ready', node.status.text.lower(),
'Node status is READY')
def test_node_configure_networks_is_readonly(self):
Nodes().add_nodes.click()
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().controller.click()
Nodes().apply_changes.click()
time.sleep(2)
Nodes().deploy_changes.click()
DeployChangesPopup().deploy.click()
time.sleep(1)
Nodes().nodes[0].details.click()
NodeInfo().edit_networks.click()
with InterfacesSettings() as s:
ActionChains(browser.driver).drag_and_drop(
s.interfaces[0].networks['storage'],
s.interfaces[1].networks_box).perform()
time.sleep(1)
self.assertNotIn(
'storage', s.interfaces[1].networks,
'storage at eht1')
self.assertFalse(s.apply.is_enabled(), 'Apply is disabled')
self.assertFalse(s.load_defaults.is_enabled(),
'Load defaults is disabled')
self.assertFalse(s.cancel_changes.is_enabled(),
'Cancel changes is disabled')
def test_node_configure_disks_is_readonly(self):
Nodes().add_nodes.click()
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().controller.click()
Nodes().apply_changes.click()
time.sleep(2)
Nodes().deploy_changes.click()
DeployChangesPopup().deploy.click()
time.sleep(1)
Nodes().nodes[0].details.click()
NodeInfo().edit_disks.click()
time.sleep(1)
with DisksSettings() as s:
for i in range(2):
self.assertFalse(
s.disks[i].volume_group_os.input.is_enabled(),
'Base system input is disabled at disk #{0}'.format(i))
self.assertFalse(
s.disks[i].volume_group_image.input.is_enabled(),
'Image storage input is disabled at disk #{0}'.format(i))
self.assertFalse(s.apply.is_enabled(), 'Apply is disabled')
self.assertFalse(s.load_defaults.is_enabled(),
'Load defaults is disabled')
self.assertFalse(s.cancel_changes.is_enabled(),
'Cancel changes is disabled')

View File

@ -0,0 +1,50 @@
import time
from pageobjects.environments import Environments, DiscardChangesPopup
from pageobjects.nodes import Nodes, RolesPanel, DeleteNodePopup
from tests import preconditions
from tests.base import BaseTestCase
class TestDiscardEnvironmentChanges(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
def setUp(self):
BaseTestCase.clear_nailgun_database()
BaseTestCase.setUp(self)
preconditions.Environment.simple_flat()
Environments().create_cluster_boxes[0].click()
time.sleep(1)
preconditions.Environment().deploy_nodes(1, 2)
def _discard_changes(self):
Nodes().discard_changes.click()
with DiscardChangesPopup() as p:
p.discard.click()
p.wait_until_exists()
time.sleep(2)
self.assertEqual(3, len(Nodes().nodes), 'Nodes amount')
for node in Nodes().nodes:
self.assertEqual('ready', node.status.text.lower(),
'Node status is READY')
def test_discard_adding_node(self):
Nodes().add_nodes.click()
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().compute.click()
Nodes().apply_changes.click()
time.sleep(1)
self._discard_changes()
def test_discard_deleting_node(self):
with Nodes() as n:
n.nodes[1].checkbox.click()
n.delete_nodes.click()
with DeleteNodePopup() as p:
p.delete.click()
p.wait_until_exists()
time.sleep(1)
self._discard_changes()

View File

@ -0,0 +1,189 @@
import time
import random
from pageobjects.environments import Environments
from pageobjects.environments import Wizard
from pageobjects.settings import Settings
from pageobjects.tabs import Tabs
from tests.base import BaseTestCase
from fuelweb_ui_test.settings import OPENSTACK_CENTOS
from fuelweb_ui_test.settings import OPENSTACK_RELEASE_CENTOS
class BaseClass(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
cls.get_home()
Environments().create_cluster_box.click()
with Wizard() as w:
w.name.send_keys(OPENSTACK_CENTOS)
w.release.select_by_visible_text(OPENSTACK_RELEASE_CENTOS)
for i in range(3):
w.next.click()
w.network_neutron_gre.click()
for i in range(3):
w.next.click()
w.create.click()
w.wait_until_exists()
def setUp(self):
BaseTestCase.setUp(self)
Environments().create_cluster_boxes[0].click()
Tabs().settings.click()
def _test_text_field(self, text_field, value):
def_value = None
with Settings() as s:
def_value = getattr(s, text_field).get_attribute('value')
getattr(s, text_field).clear()
getattr(s, text_field).send_keys(value)
s.save_settings.click()
time.sleep(1)
self.refresh()
with Settings() as s:
self.assertEqual(getattr(s, text_field).get_attribute('value'),
value)
s.load_defaults.click()
time.sleep(1)
self.assertEqual(
getattr(s, text_field).get_attribute('value'), def_value,
"load defaults value")
def _test_tumbler_field(self, tumbler_field):
def_value = None
with Settings() as s:
def_value = getattr(s, tumbler_field).\
find_element_by_tag_name('input').is_selected()
getattr(s, tumbler_field).click()
s.save_settings.click()
time.sleep(1)
self.refresh()
with Settings() as s:
self.assertEqual(
getattr(s, tumbler_field).
find_element_by_tag_name('input').is_selected(), not def_value)
s.load_defaults.click()
time.sleep(1)
self.assertEqual(
getattr(s, tumbler_field).
find_element_by_tag_name('input').is_selected(), def_value,
"load defaults value")
def _test_radio_group(self, radios):
radios.reverse()
for radio in radios:
with Settings() as s:
getattr(s, radio).click()
s.save_settings.click()
time.sleep(1)
self.refresh()
self.assertTrue(
getattr(Settings(), radio).
find_element_by_tag_name('input').is_selected())
# Set group to not default state
random_radio = radios[random.randint(0, len(radios) - 2)]
with Settings() as s:
getattr(s, random_radio).click()
s.load_defaults.click()
time.sleep(1)
self.assertTrue(
getattr(s, radios[-1]).
find_element_by_tag_name('input').is_selected(),
"load defaults value")
class TestAccess(BaseClass):
def test_username(self):
self._test_text_field('username', 'newname')
def test_password(self):
self._test_text_field('password', 'newpassword')
def test_password_show(self):
with Settings() as s:
s.show_password.click()
self.assertEqual(s.password.get_attribute('type'), 'text')
s.show_password.click()
self.assertEqual(s.password.get_attribute('type'), 'password')
def test_tenant(self):
self._test_text_field('tenant', 'newtenant')
def test_email(self):
self._test_text_field('email', 'newemail@example.org')
class TestAdditionalComponents(BaseClass):
def test_savanna(self):
self._test_tumbler_field('install_savanna')
def test_murano(self):
self._test_tumbler_field('install_murano')
def test_ceilometer(self):
self._test_tumbler_field('install_ceilometer')
class TestCommon(BaseClass):
def test_debug(self):
self._test_tumbler_field('debug')
def test_hypervisor_type(self):
self._test_radio_group(['hypervisor_qemu', 'hypervisor_kvm'])
def test_assign_ip(self):
self._test_tumbler_field('assign_ip')
def test_scheduler_driver(self):
self._test_radio_group(['filter_scheduler', 'simple_scheduler'])
def test_vlan_splinters(self):
self._test_radio_group(
['vlan_splinters_disabled',
'vlan_splinters_soft',
'vlan_splinters_hard'])
def test_use_cow_images(self):
self._test_tumbler_field('use_cow_images')
def test_start_guests(self):
self._test_tumbler_field('start_guests')
def test_auth_key(self):
self._test_text_field('auth_key', 'newauthkey')
class TestSyslog(BaseClass):
def test_hostname(self):
self._test_text_field('syslog_server', 'newsyslog_server')
def test_port(self):
self._test_text_field('syslog_port', '8000')
def test_syslog_protocol(self):
self._test_radio_group(['syslog_udp', 'syslog_tcp'])
class TestStorage(BaseClass):
def test_cinder_for_volumes(self):
self._test_tumbler_field('cinder_for_volumes')
def test_ceph_for_volumes(self):
self._test_tumbler_field('ceph_for_volumes')
def test_ceph_for_images(self):
self._test_tumbler_field('ceph_for_images')
def test_ceph_ephemeral(self):
self._test_tumbler_field('ceph_ephemeral')
def test_ceph_rados_gw(self):
self._test_tumbler_field('ceph_rados_gw')
def test_ceph_factor(self):
self._test_text_field('ceph_factor', '10')

View File

@ -0,0 +1,313 @@
import time
from pageobjects.base import PageObject
from pageobjects.environments import Environments, Wizard
from pageobjects.header import Header
from pageobjects.releases import Releases
from tests.base import BaseTestCase
from fuelweb_ui_test.settings import OPENSTACK_RELEASE_CENTOS
from fuelweb_ui_test.settings import OPENSTACK_RELEASE_UBUNTU
from fuelweb_ui_test.settings import OPENSTACK_RELEASE_REDHAT
from fuelweb_ui_test.settings import REDHAT_USERNAME
from fuelweb_ui_test.settings import REDHAT_PASSWORD
from fuelweb_ui_test.settings import OPENSTACK_REDHAT
from fuelweb_ui_test.settings import REDHAT_SATELLITE
from fuelweb_ui_test.settings import REDHAT_ACTIVATION_KEY
class TestEnvWizard(BaseTestCase):
def setUp(self):
BaseTestCase.setUp(self)
Environments().create_cluster_box.click()
def test_name_field(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_RELEASE_CENTOS)
w.next.click()
w.prev.click()
self.assertEqual(w.name.get_attribute('value'),
OPENSTACK_RELEASE_CENTOS)
w.name.clear()
w.next.click()
self.assertIn(
'Environment name cannot be empty',
w.name.find_element_by_xpath('..').text)
def test_name_exists(self):
name = 'test name'
with Wizard() as w:
w.name.send_keys(name)
for i in range(6):
w.next.click()
w.create.click()
w.wait_until_exists()
Environments().create_cluster_box.click()
with Wizard() as w:
w.name.send_keys(name)
w.next.click()
time.sleep(1)
self.assertIn('Environment with name "{}" already exists'.
format(name),
w.name.find_element_by_xpath('..').text)
def test_release_field(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_RELEASE_UBUNTU)
w.release.select_by_visible_text(OPENSTACK_RELEASE_UBUNTU)
w.next.click()
w.prev.click()
self.assertEqual(w.release.first_selected_option.text,
OPENSTACK_RELEASE_UBUNTU)
def test_rhel_empty_form(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_RELEASE_REDHAT)
w.release.select_by_visible_text(OPENSTACK_RELEASE_REDHAT)
w.next.click()
self.assertIn('Invalid username',
w.redhat_username.find_element_by_xpath('..').text)
self.assertIn('Invalid password',
w.redhat_password.find_element_by_xpath('..').text)
w.license_rhn.click()
w.next.click()
self.assertIn('Invalid username',
w.redhat_username.find_element_by_xpath('..').text)
self.assertIn('Invalid password',
w.redhat_password.find_element_by_xpath('..').text)
self.assertIn(
'Only valid fully qualified domain name is allowed for the '
'hostname field',
w.redhat_satellite.find_element_by_xpath('..').text)
self.assertIn(
'Invalid activation key',
w.redhat_activation_key.find_element_by_xpath('..').text)
def test_rhel_form(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_RELEASE_REDHAT)
w.release.select_by_visible_text(OPENSTACK_RELEASE_REDHAT)
self.assertTrue(w.license_rhsm.is_displayed())
self.assertTrue(w.license_rhn.is_displayed())
self.assertTrue(w.redhat_username.is_displayed())
self.assertTrue(w.redhat_password.is_displayed())
w.license_rhn.click()
self.assertTrue(w.redhat_satellite.is_displayed())
self.assertTrue(w.redhat_activation_key.is_displayed())
w.license_rhsm.click()
self.assertFalse(w.redhat_satellite.is_displayed())
self.assertFalse(w.redhat_activation_key.is_displayed())
def test_mode_radios(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_RELEASE_UBUNTU)
w.release.select_by_visible_text(OPENSTACK_RELEASE_UBUNTU)
w.next.click()
w.mode_ha_compact.click()
w.next.click()
w.prev.click()
self.assertTrue(
w.mode_ha_compact.
find_element_by_tag_name('input').is_selected())
self.assertFalse(
w.mode_multinode.
find_element_by_tag_name('input').is_selected())
def test_hypervisor_radios(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_RELEASE_UBUNTU)
w.release.select_by_visible_text(OPENSTACK_RELEASE_UBUNTU)
w.next.click()
w.next.click()
w.hypervisor_qemu.click()
w.next.click()
w.prev.click()
self.assertTrue(
w.hypervisor_qemu.find_element_by_tag_name('input').
is_selected())
self.assertFalse(
w.hypervisor_kvm.find_element_by_tag_name('input').
is_selected())
def test_network_radios(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_RELEASE_UBUNTU)
w.release.select_by_visible_text(OPENSTACK_RELEASE_UBUNTU)
w.next.click()
w.next.click()
w.next.click()
w.network_neutron_gre.click()
w.next.click()
w.prev.click()
self.assertFalse(
w.network_nova.find_element_by_tag_name('input').
is_selected())
self.assertTrue(
w.network_neutron_gre.find_element_by_tag_name('input').
is_selected())
self.assertFalse(
w.network_neutron_vlan.find_element_by_tag_name('input').
is_selected())
w.network_neutron_vlan.click()
self.assertFalse(
w.network_nova.find_element_by_tag_name('input').is_selected())
self.assertFalse(
w.network_neutron_gre.find_element_by_tag_name('input').
is_selected())
self.assertTrue(
w.network_neutron_vlan.find_element_by_tag_name('input').
is_selected())
def test_storage_radios(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_RELEASE_UBUNTU)
w.release.select_by_visible_text(OPENSTACK_RELEASE_UBUNTU)
w.next.click()
w.next.click()
w.next.click()
w.next.click()
w.storage_cinder_ceph.click()
w.storage_glance_ceph.click()
w.next.click()
w.prev.click()
self.assertFalse(
w.storage_cinder_default.find_element_by_tag_name('input').
is_selected())
self.assertTrue(
w.storage_cinder_ceph.find_element_by_tag_name('input').
is_selected())
self.assertFalse(
w.storage_glance_default.find_element_by_tag_name('input').
is_selected())
self.assertTrue(
w.storage_glance_ceph.find_element_by_tag_name('input').
is_selected())
def test_services_checkboxes(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_RELEASE_UBUNTU)
w.release.select_by_visible_text(OPENSTACK_RELEASE_UBUNTU)
w.next.click()
w.next.click()
w.next.click()
w.network_neutron_gre.click()
w.next.click()
w.next.click()
w.install_savanna.click()
w.install_murano.click()
w.install_ceilometer.click()
w.next.click()
w.prev.click()
self.assertTrue(
w.install_savanna.find_element_by_tag_name('input').
is_selected())
self.assertTrue(
w.install_murano.find_element_by_tag_name('input').
is_selected())
self.assertTrue(
w.install_ceilometer.find_element_by_tag_name('input').
is_selected())
def test_cancel_button(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_RELEASE_UBUNTU)
w.release.select_by_visible_text(OPENSTACK_RELEASE_UBUNTU)
w.next.click()
w.mode_ha_compact.click()
w.next.click()
w.hypervisor_kvm.click()
w.next.click()
w.network_neutron_gre.click()
w.next.click()
w.storage_cinder_ceph.click()
w.storage_glance_ceph.click()
w.next.click()
w.install_savanna.click()
w.install_murano.click()
w.next.click()
w.cancel.click()
PageObject.wait_until_exists(w.parent)
Environments().create_cluster_box.click()
with Wizard() as w:
self.assertEqual(w.name.get_attribute('value'), '')
self.assertEqual(w.release.first_selected_option.text,
OPENSTACK_RELEASE_CENTOS)
w.name.send_keys(OPENSTACK_RELEASE_UBUNTU)
w.next.click()
self.assertTrue(
w.mode_multinode.find_element_by_tag_name('input').
is_selected())
w.next.click()
self.assertTrue(
w.hypervisor_qemu.find_element_by_tag_name('input').
is_selected())
w.next.click()
self.assertTrue(
w.network_nova.find_element_by_tag_name('input').
is_selected())
w.next.click()
self.assertTrue(
w.storage_cinder_default.find_element_by_tag_name('input').
is_selected())
self.assertTrue(
w.storage_glance_default.find_element_by_tag_name('input').
is_selected())
w.next.click()
self.assertFalse(
w.install_savanna.find_element_by_tag_name('input').
is_selected())
self.assertFalse(
w.install_murano.find_element_by_tag_name('input').
is_selected())
class TestEnvWizardRedHat(BaseTestCase):
def setUp(self):
BaseTestCase.clear_nailgun_database()
BaseTestCase.setUp(self)
Environments().create_cluster_box.click()
def test_rhsm(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_RELEASE_REDHAT)
w.release.select_by_visible_text(OPENSTACK_RELEASE_REDHAT)
w.license_rhsm.click()
w.redhat_username.send_keys(REDHAT_USERNAME)
w.redhat_password.send_keys(REDHAT_PASSWORD)
for i in range(6):
w.next.click()
w.create.click()
w.wait_until_exists()
Header().releases.click()
with Releases() as r:
PageObject.wait_until_exists(
r.dict[OPENSTACK_REDHAT].download_progress, timeout=20)
self.assertEqual(
'Active', r.dict[OPENSTACK_REDHAT].status.text,
'RHOS status is active')
def test_rhn_satellite(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_RELEASE_REDHAT)
w.release.select_by_visible_text(OPENSTACK_RELEASE_REDHAT)
w.license_rhn.click()
w.redhat_username.send_keys(REDHAT_USERNAME)
w.redhat_password.send_keys(REDHAT_PASSWORD)
w.redhat_satellite.send_keys(REDHAT_SATELLITE)
w.redhat_activation_key.send_keys(REDHAT_ACTIVATION_KEY)
for i in range(6):
w.next.click()
w.create.click()
w.wait_until_exists()
Header().releases.click()
with Releases() as r:
PageObject.wait_until_exists(
r.dict[OPENSTACK_REDHAT].download_progress, timeout=20)
self.assertEqual(
'Active', r.dict[OPENSTACK_REDHAT].status.text,
'RHOS status is active')

View File

@ -0,0 +1,207 @@
from pageobjects.environments import Environments, Wizard
from pageobjects.networks import Networks, NeutronParameters
from pageobjects.nodes import Nodes
from pageobjects.settings import Settings
from pageobjects.tabs import Tabs
from tests.base import BaseTestCase
from fuelweb_ui_test.settings import OPENSTACK_CENTOS
from fuelweb_ui_test.settings import OPENSTACK_RELEASE_CENTOS
class TestEnvironment(BaseTestCase):
def setUp(self):
self.clear_nailgun_database()
BaseTestCase.setUp(self)
Environments().create_cluster_box.click()
def test_default_settings(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_CENTOS)
w.release.select_by_visible_text(OPENSTACK_RELEASE_CENTOS)
for i in range(6):
w.next.click()
w.create.click()
w.wait_until_exists()
cb = Environments().create_cluster_boxes[0]
self.assertIn(OPENSTACK_CENTOS, cb.text)
cb.click()
with Nodes() as n:
self.assertEqual(n.env_name.text, OPENSTACK_CENTOS)
n.info_icon.click()
self.assertIn('display: block;',
n.env_details.get_attribute('style'))
self.assertIn(OPENSTACK_CENTOS, n.env_details.text)
self.assertIn('New', n.env_details.text)
self.assertIn('Multi-node', n.env_details.text)
self.assertNotIn('with HA', n.env_details.text)
n.info_icon.click()
self.assertIn('display: none;',
n.env_details.get_attribute('style'))
Tabs().networks.click()
with Networks() as n:
self.assertTrue(
n.flatdhcp_manager.find_element_by_tag_name('input').
is_selected())
Tabs().settings.click()
with Settings() as s:
self.assertFalse(
s.install_savanna.find_element_by_tag_name('input').
is_selected())
self.assertFalse(
s.install_murano.find_element_by_tag_name('input').
is_selected())
self.assertFalse(
s.install_ceilometer.find_element_by_tag_name('input').
is_selected())
self.assertTrue(
s.hypervisor_qemu.find_element_by_tag_name('input').
is_selected())
pass
def test_ha_mode(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_CENTOS)
w.release.select_by_visible_text(OPENSTACK_RELEASE_CENTOS)
w.next.click()
w.mode_ha_compact.click()
for i in range(5):
w.next.click()
w.create.click()
w.wait_until_exists()
cb = Environments().create_cluster_boxes[0]
cb.click()
with Nodes() as n:
self.assertEqual(n.env_name.text, OPENSTACK_CENTOS)
n.info_icon.click()
self.assertIn(OPENSTACK_CENTOS, n.env_details.text)
self.assertIn('Multi-node with HA', n.env_details.text)
def test_hypervisor_kvm(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_CENTOS)
w.release.select_by_visible_text(OPENSTACK_RELEASE_CENTOS)
w.next.click()
w.next.click()
w.hypervisor_kvm.click()
for i in range(4):
w.next.click()
w.create.click()
w.wait_until_exists()
cb = Environments().create_cluster_boxes[0]
cb.click()
Tabs().settings.click()
with Settings() as s:
self.assertTrue(
s.hypervisor_kvm.find_element_by_tag_name('input').
is_selected())
def test_neutron_gre(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_CENTOS)
w.release.select_by_visible_text(OPENSTACK_RELEASE_CENTOS)
for i in range(3):
w.next.click()
w.network_neutron_gre.click()
for i in range(3):
w.next.click()
w.create.click()
w.wait_until_exists()
cb = Environments().create_cluster_boxes[0]
cb.click()
Tabs().networks.click()
with Networks() as n:
self.assertEqual(n.segmentation_type.text,
'Neutron with gre segmentation')
self.assertTrue(NeutronParameters().parent.is_displayed())
def test_neutron_vlan(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_CENTOS)
w.release.select_by_visible_text(OPENSTACK_RELEASE_CENTOS)
for i in range(3):
w.next.click()
w.network_neutron_vlan.click()
for i in range(3):
w.next.click()
w.create.click()
w.wait_until_exists()
cb = Environments().create_cluster_boxes[0]
cb.click()
Tabs().networks.click()
with Networks() as n:
self.assertEqual(n.segmentation_type.text,
'Neutron with vlan segmentation')
self.assertTrue(NeutronParameters().parent.is_displayed())
def test_storage_ceph(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_CENTOS)
w.release.select_by_visible_text(OPENSTACK_RELEASE_CENTOS)
for i in range(4):
w.next.click()
w.storage_cinder_ceph.click()
w.storage_glance_ceph.click()
w.next.click()
w.next.click()
w.create.click()
w.wait_until_exists()
cb = Environments().create_cluster_boxes[0]
cb.click()
Tabs().settings.click()
with Settings() as s:
self.assertTrue(
s.cinder_for_volumes.find_element_by_tag_name('input').
is_selected())
self.assertTrue(
s.ceph_for_volumes.find_element_by_tag_name('input').
is_selected())
self.assertTrue(
s.ceph_for_images.find_element_by_tag_name('input').
is_selected())
self.assertFalse(
s.ceph_rados_gw.find_element_by_tag_name('input').
is_selected())
def test_services(self):
with Wizard() as w:
w.name.send_keys(OPENSTACK_CENTOS)
w.release.select_by_visible_text(OPENSTACK_RELEASE_CENTOS)
for i in range(3):
w.next.click()
w.network_neutron_gre.click()
w.next.click()
w.next.click()
w.install_savanna.click()
w.install_murano.click()
w.install_ceilometer.click()
w.next.click()
w.create.click()
w.wait_until_exists()
cb = Environments().create_cluster_boxes[0]
cb.click()
Tabs().settings.click()
with Settings() as s:
self.assertTrue(
s.install_savanna.find_element_by_tag_name('input').
is_selected())
self.assertTrue(
s.install_murano.find_element_by_tag_name('input').
is_selected())
self.assertTrue(
s.install_ceilometer.find_element_by_tag_name('input').
is_selected())

View File

@ -0,0 +1,40 @@
import time
from pageobjects.actions import Actions, DeleteEnvironmentPopup
from pageobjects.environments import Environments
from pageobjects.nodes import Nodes
from pageobjects.tabs import Tabs
from tests import preconditions
from tests.base import BaseTestCase
class TestEnvironmentActions(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
def setUp(self):
BaseTestCase.clear_nailgun_database()
preconditions.Environment.simple_flat()
Environments().create_cluster_boxes[0].click()
Tabs().actions.click()
def test_rename(self):
value = 'Happy environment'
with Actions() as a:
a.name.clear()
a.name.send_keys(value)
a.rename.click()
time.sleep(1)
Tabs().nodes.click()
self.assertEqual(value, Nodes().env_name.text,
'Environment has been renamed')
def test_delete(self):
with Actions() as a:
a.delete.click()
DeleteEnvironmentPopup().delete.click()
time.sleep(1)
self.assertEqual(
0, len(Environments().create_cluster_boxes),
'Environment has been deleted')

View File

@ -0,0 +1,449 @@
import time
from pageobjects.environments import Environments
from pageobjects.networks import Networks
from pageobjects.nodes import Nodes, RolesPanel
from pageobjects.tabs import Tabs
from tests.base import BaseTestCase
import preconditions
RANGES = [
['172.16.0.3', '172.16.0.10'],
['172.16.0.20', '172.16.0.50'],
['172.16.0.128', '172.16.0.140'],
['172.16.0.158', '172.16.0.165']
]
class SimpleFlatNetworks(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
preconditions.Environment.simple_flat()
def setUp(self):
BaseTestCase.setUp(self)
Environments().create_cluster_boxes[0].click()
Tabs().networks.click()
time.sleep(1)
def _assert_save_cancel_disabled(self):
self.assertFalse(Networks().save_settings.is_enabled(),
'Save settings is disabled')
self.assertFalse(Networks().cancel_changes.is_enabled(),
'Cancel changes is disabled')
def _assert_save_verify_disabled(self):
self.assertFalse(Networks().save_settings.is_enabled(),
'Save settings is disabled')
self.assertFalse(Networks().verify_networks.is_enabled(),
'Verify networks is disabled')
def _save_settings(self):
Networks().save_settings.click()
time.sleep(1)
self._assert_save_cancel_disabled()
self.refresh()
def _test_ranges_plus_icon(self, network):
with getattr(Networks(), network) as n:
n.ip_ranges[0].icon_plus.click()
self.assertEqual(len(n.ip_ranges), 2, 'Plus icon. row 1')
n.ip_ranges[1].icon_plus.click()
self.assertEqual(len(n.ip_ranges), 3, 'Plus icon. row 2')
n.ip_ranges[1].start.send_keys(RANGES[0][0])
n.ip_ranges[1].end.send_keys(RANGES[0][1])
n.ip_ranges[0].icon_plus.click()
self.assertEqual(len(n.ip_ranges), 4, 'Plus icon. row 1')
self.assertEqual(n.ip_ranges[1].start.get_attribute('value'), '')
self.assertEqual(n.ip_ranges[1].end.get_attribute('value'), '')
self.assertEqual(n.ip_ranges[2].start.get_attribute('value'),
RANGES[0][0])
self.assertEqual(n.ip_ranges[2].end.get_attribute('value'),
RANGES[0][1])
def _test_ranges_minus_icon(self, network):
with getattr(Networks(), network) as n:
for i in range(3):
n.ip_ranges[i].icon_plus.click()
n.ip_ranges[3].icon_minus.click()
self.assertEqual(len(n.ip_ranges), 3, 'Minus icon. last row')
n.ip_ranges[2].start.send_keys(RANGES[0][0])
n.ip_ranges[2].end.send_keys(RANGES[0][1])
n.ip_ranges[1].icon_minus.click()
self.assertEqual(len(n.ip_ranges), 2, 'Minus icon. second row')
self.assertEqual(n.ip_ranges[1].start.get_attribute('value'),
RANGES[0][0])
self.assertEqual(n.ip_ranges[1].end.get_attribute('value'),
RANGES[0][1])
def _test_ranges(self, network, values):
with getattr(Networks(), network) as n:
n.ip_ranges[0].icon_plus.click()
n.ip_ranges[0].start.clear()
n.ip_ranges[0].start.send_keys(values[0][0])
n.ip_ranges[0].end.clear()
n.ip_ranges[0].end.send_keys(values[0][1])
n.ip_ranges[1].start.send_keys(values[1][0])
n.ip_ranges[1].end.send_keys(values[1][1])
self._save_settings()
with getattr(Networks(), network) as n:
self.assertEqual(n.ip_ranges[0].start.get_attribute('value'),
values[0][0])
self.assertEqual(n.ip_ranges[0].end.get_attribute('value'),
values[0][1])
self.assertEqual(n.ip_ranges[1].start.get_attribute('value'),
values[1][0])
self.assertEqual(n.ip_ranges[1].end.get_attribute('value'),
values[1][1])
n.ip_ranges[0].start.clear()
n.ip_ranges[0].start.send_keys(' ')
self.assertIn('Invalid IP range start',
n.ip_ranges[0].start.
find_element_by_xpath('../../..').text)
n.ip_ranges[1].end.clear()
n.ip_ranges[1].end.send_keys(' ')
self.assertIn('Invalid IP range end',
n.ip_ranges[1].end.
find_element_by_xpath('../../..').text)
def _test_use_vlan_tagging(self, network, vlan_id, initial_value=False):
def assert_on():
with getattr(Networks(), network) as n:
self.assertTrue(
n.vlan_tagging.
find_element_by_tag_name('input').is_selected(),
'use vlan tagging is turned on')
self.assertEqual(n.vlan_id.get_attribute('value'), vlan_id,
'vlan id value')
def assert_off():
with getattr(Networks(), network) as n:
self.assertFalse(
n.vlan_tagging.
find_element_by_tag_name('input').is_selected(),
'use vlan tagging is turned off')
self.assertFalse(n.vlan_id.is_displayed(),
'vlan id input is not visible')
def turn_on():
with getattr(Networks(), network) as n:
n.vlan_tagging.click()
self.assertTrue(n.vlan_id.is_displayed(),
'vlan id input is visible')
n.vlan_id.send_keys(vlan_id)
time.sleep(0.5)
self._save_settings()
assert_on()
with getattr(Networks(), network) as n:
n.vlan_id.clear()
n.vlan_id.send_keys(' ')
self.assertIn('Invalid VLAN ID',
n.vlan_id.find_element_by_xpath('../../..').text)
self._assert_save_verify_disabled()
def turn_off():
with getattr(Networks(), network) as n:
n.vlan_tagging.click()
self.assertFalse(n.vlan_id.is_displayed(),
'vlan id input is not visible')
time.sleep(0.5)
self._save_settings()
assert_off()
if initial_value:
turn_off()
turn_on()
else:
turn_on()
turn_off()
def _test_text_field(self, network, field, value):
with getattr(Networks(), network) as n:
getattr(n, field).clear()
getattr(n, field).send_keys(value)
self._save_settings()
with getattr(Networks(), network) as n:
self.assertEqual(
getattr(n, field).get_attribute('value'), value,
'New value')
getattr(n, field).clear()
getattr(n, field).send_keys(' ')
self.assertIn('Invalid',
getattr(n, field).
find_element_by_xpath('../../..').text)
self._assert_save_verify_disabled()
Networks().cancel_changes.click()
time.sleep(1)
with getattr(Networks(), network) as n:
self.assertEqual(
getattr(n, field).get_attribute('value'), value,
"cancel changes")
def _test_select_field(self, network, field, value):
with getattr(Networks(), network) as n:
getattr(n, field).select_by_visible_text(value)
self._save_settings()
with getattr(Networks(), network) as n:
self.assertEqual(
getattr(n, field).first_selected_option.text, value,
'New value')
getattr(n, field).options[0].click()
Networks().cancel_changes.click()
time.sleep(1)
with getattr(Networks(), network) as n:
self.assertEqual(
getattr(n, field).first_selected_option.text, value,
"cancel changes")
class TestNeutronNetworks(SimpleFlatNetworks):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
preconditions.Environment.simple_neutron_gre()
def test_id_start(self):
self._test_text_field('neutron', 'id_start', '1500')
def test_id_end(self):
self._test_text_field('neutron', 'id_end', '3500')
def test_base_mac(self):
self._test_text_field('neutron', 'base_mac', 'aa:bb:3e:14:b4:a3')
def test_floating_start(self):
self._test_text_field('neutron', 'floating_start', RANGES[3][0])
def test_floating_end(self):
self._test_text_field('neutron', 'floating_end', RANGES[3][1])
def test_cidr(self):
self._test_text_field('neutron', 'cidr', '192.168.111.0/16')
def test_gateway(self):
self._test_text_field('neutron', 'gateway', '192.168.111.2')
def test_nameserver0(self):
self._test_text_field('neutron', 'nameserver0', '5.5.5.5')
def test_nameserver1(self):
self._test_text_field('neutron', 'nameserver1', '5.5.5.5')
class TestSimpleVlanNetworks(SimpleFlatNetworks):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
preconditions.Environment.simple_flat()
Environments().create_cluster_boxes[0].click()
Tabs().networks.click()
with Networks() as n:
n.vlan_manager.click()
n.save_settings.click()
time.sleep(1)
def test_fixed_number_of_networks(self):
self._test_text_field('fixed', 'number_of_networks', '3')
def test_fixed_size_of_networks(self):
self._test_select_field('fixed', 'network_size', '128')
def test_fixed_vlan_range_start(self):
self._test_text_field('fixed', 'vlan_id', '120')
def test_fixed_vlan_range_end_calculation(self):
start_values = [105, 120]
with Networks().fixed as n:
number = int(n.number_of_networks.get_attribute('value'))
for v in start_values:
n.vlan_id.clear()
n.vlan_id.send_keys(v)
self.assertEqual(
n.vlan_end.get_attribute('value'),
str(v + number - 1), 'end value')
def test_fixed_vlan_range_end_calculation_2(self):
numbers = [5, 20]
with Networks().fixed as n:
start = int(n.vlan_id.get_attribute('value'))
for v in numbers:
n.number_of_networks.clear()
n.number_of_networks.send_keys(v)
self.assertEqual(
n.vlan_end.get_attribute('value'),
str(v + start - 1), 'end value')
class TestRangesControls(SimpleFlatNetworks):
def test_public_plus_icon(self):
self._test_ranges_plus_icon('public')
def test_public_minus_icon(self):
self._test_ranges_minus_icon('public')
def test_floating_plus_icon(self):
self._test_ranges_plus_icon('floating')
def test_floating_minus_icon(self):
self._test_ranges_minus_icon('floating')
class TestPublicNetwork(SimpleFlatNetworks):
def test_ranges(self):
self._test_ranges('public', RANGES[:2])
def test_use_vlan_tagging(self):
self._test_use_vlan_tagging('public', '111', False)
def test_net_mask(self):
self._test_text_field('public', 'netmask', '255.255.0.0')
def test_gateway(self):
self._test_text_field('public', 'gateway', '172.16.0.2')
class TestFloatingNetwork(SimpleFlatNetworks):
def test_ranges(self):
self._test_ranges('floating', RANGES[2:4])
def test_use_vlan_tagging(self):
value = '112'
with Networks().public as n:
n.vlan_tagging.click()
n.vlan_id.send_keys(value)
with Networks().floating as n:
self.assertTrue(
n.vlan_tagging.find_element_by_tag_name('input').is_selected())
self.assertEqual(n.vlan_id.get_attribute('value'), value)
Networks().save_settings.click()
time.sleep(1)
self.refresh()
with Networks().floating as n:
self.assertTrue(
n.vlan_tagging.find_element_by_tag_name('input').is_selected())
self.assertEqual(n.vlan_id.get_attribute('value'), value)
class TestManagementNetwork(SimpleFlatNetworks):
def test_cidr(self):
self._test_text_field('management', 'cidr', '192.169.0.0/16')
def test_use_vlan_tagging(self):
self._test_use_vlan_tagging('management', '111', True)
class TestStorageNetwork(SimpleFlatNetworks):
def test_cidr(self):
self._test_text_field('storage', 'cidr', '192.170.0.0/16')
def test_use_vlan_tagging(self):
self._test_use_vlan_tagging('storage', '111', True)
class TestFixedNetwork(SimpleFlatNetworks):
def test_cidr(self):
self._test_text_field('fixed', 'cidr', '10.1.0.0/24')
def test_use_vlan_tagging(self):
self._test_use_vlan_tagging('fixed', '111', True)
class TestDnsServers(SimpleFlatNetworks):
def test_name_servers(self):
v1 = '8.7.7.7'
v2 = '8.6.6.6'
with Networks() as n:
n.dns1.clear()
n.dns1.send_keys(v1)
n.dns2.clear()
n.dns2.send_keys(v2)
self._save_settings()
with Networks() as n:
self.assertEqual(n.dns1.get_attribute('value'), v1, 'dns1')
self.assertEqual(n.dns1.get_attribute('value'), v1, 'dns2')
n.dns1.clear()
n.dns1.send_keys(' ')
self.assertIn('Invalid nameserver',
n.dns1.find_element_by_xpath('../../..').text)
n.dns2.clear()
n.dns2.send_keys(' ')
self.assertIn('Invalid nameserver',
n.dns2.find_element_by_xpath('../../..').text)
self._assert_save_verify_disabled()
Networks().cancel_changes.click()
self.assertEqual(n.dns1.get_attribute('value'), v1,
'cancel changes dns1')
self.assertEqual(n.dns1.get_attribute('value'), v1,
'cancel changes dns2')
class TestFlatVerifyNetworks(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
def setUp(self):
BaseTestCase.clear_nailgun_database()
BaseTestCase.setUp(self)
preconditions.Environment.simple_flat()
Environments().create_cluster_boxes[0].click()
Tabs().networks.click()
time.sleep(1)
def test_no_nodes(self):
with Networks() as n:
n.verify_networks.click()
self.assertIn(
'At least two nodes are required',
n.verification_alert.text,
'Alert text contains "At least two nodes are required"')
def test_one_node(self):
Tabs().nodes.click()
Nodes().add_nodes.click()
time.sleep(1)
Nodes().nodes_discovered[0].checkbox.click()
RolesPanel().controller.click()
Nodes().apply_changes.click()
time.sleep(1)
Tabs().networks.click()
time.sleep(1)
with Networks() as n:
n.verify_networks.click()
self.assertIn(
'At least two nodes are required',
n.verification_alert.text,
'Alert text contains "At least two nodes are required"')
def test_two_nodes(self):
Tabs().nodes.click()
Nodes().add_nodes.click()
time.sleep(1)
Nodes().nodes_discovered[0].checkbox.click()
Nodes().nodes_discovered[1].checkbox.click()
RolesPanel().compute.click()
Nodes().apply_changes.click()
time.sleep(1)
Tabs().networks.click()
time.sleep(1)
with Networks() as n:
n.verify_networks.click()
self.assertIn(
'Verification succeeded. Your network is configured correctly',
n.verification_alert.text,
'Verification succeeded')

View File

@ -0,0 +1,74 @@
from pageobjects.base import PageObject
from pageobjects.environments import RedhatAccountPopup
from pageobjects.header import Header
from pageobjects.releases import Releases
from fuelweb_ui_test.settings import OPENSTACK_REDHAT
from fuelweb_ui_test.settings import REDHAT_USERNAME
from fuelweb_ui_test.settings import REDHAT_PASSWORD
from fuelweb_ui_test.settings import REDHAT_SATELLITE
from fuelweb_ui_test.settings import REDHAT_ACTIVATION_KEY
from fuelweb_ui_test.settings import OPENSTACK_CENTOS
from fuelweb_ui_test.settings import OPENSTACK_UBUNTU
from tests.base import BaseTestCase
class TestReleases(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
def setUp(self):
BaseTestCase.clear_nailgun_database()
BaseTestCase.setUp(self)
Header().releases.click()
def test_centos_is_active(self):
with Releases() as r:
self.assertEqual(
'Active', r.dict[OPENSTACK_CENTOS].status.text,
'CentOS status is active')
def test_ubuntu_is_active(self):
with Releases() as r:
self.assertEqual(
'Active', r.dict[OPENSTACK_UBUNTU].status.text,
'Ubuntu status is active')
def test_rhos_is_active(self):
with Releases() as r:
self.assertEqual(
'Not available', r.dict[OPENSTACK_REDHAT].status.text,
'RHOS status is Not available')
def test_rhsm(self):
Releases().rhel_setup.click()
with RedhatAccountPopup() as p:
p.license_rhsm.click()
p.redhat_username.send_keys(REDHAT_USERNAME)
p.redhat_password.send_keys(REDHAT_PASSWORD)
p.apply.click()
p.wait_until_exists()
with Releases() as r:
PageObject.wait_until_exists(
r.dict[OPENSTACK_REDHAT].download_progress, timeout=20)
self.assertEqual(
'Active', r.dict[OPENSTACK_REDHAT].status.text,
'RHOS status is active')
def test_rhn_satellite(self):
Releases().rhel_setup.click()
with RedhatAccountPopup() as p:
p.license_rhn.click()
p.redhat_username.send_keys(REDHAT_USERNAME)
p.redhat_password.send_keys(REDHAT_PASSWORD)
p.redhat_satellite.send_keys(REDHAT_SATELLITE)
p.redhat_activation_key.send_keys(REDHAT_ACTIVATION_KEY)
p.apply.click()
p.wait_until_exists()
with Releases() as r:
PageObject.wait_until_exists(
r.dict[OPENSTACK_REDHAT].download_progress, timeout=20)
self.assertEqual(
'Active', r.dict[OPENSTACK_REDHAT].status.text,
'RHOS status is active')

View File

@ -0,0 +1,168 @@
import time
from pageobjects.environments import Environments
from pageobjects.nodes import Nodes, RolesPanel
from tests import preconditions
from tests.base import BaseTestCase
ERROR_ROLE_CANNOT_COMBINE = 'This role cannot be combined ' \
'with the other roles already selected.'
ROLE_UNALLOCATED = 'UNALLOCATED'
ROLE_CONTROLLER = 'CONTROLLER'
ROLE_COMPUTE = 'COMPUTE'
ROLE_CINDER = 'CINDER'
ROLE_CEPH = 'CEPH-OSD'
class BaseClass(BaseTestCase):
def assertNodeInRoles(self, node, roles):
for role in roles:
self.assertIn(role, node.roles.text, "node's roles")
def setUp(self):
BaseTestCase.setUp(self)
Environments().create_cluster_boxes[0].click()
Nodes().add_nodes.click()
time.sleep(1)
class TestRolesSimpleFlat(BaseClass):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
preconditions.Environment.simple_flat()
def test_controller(self):
with Nodes()as n:
n.nodes_discovered[0].checkbox.click()
with RolesPanel() as r:
r.controller.click()
self.assertFalse(r.compute.is_enabled())
self.assertIn(
ERROR_ROLE_CANNOT_COMBINE,
r.compute.find_element_by_xpath('../..').text,
'error "{}" is visible'.format(ERROR_ROLE_CANNOT_COMBINE))
with Nodes()as n:
self.assertNodeInRoles(n.nodes_discovered[0], [ROLE_CONTROLLER])
self.assertTrue(n.apply_changes.is_enabled())
n.nodes_discovered[0].checkbox.click()
self.assertFalse(n.apply_changes.is_enabled())
self.assertNodeInRoles(n.nodes_discovered[0], [ROLE_UNALLOCATED])
def test_one_controller_allowed_nodes_disabled(self):
with Nodes()as n:
n.nodes_discovered[0].checkbox.click()
with RolesPanel() as r:
r.controller.click()
for n in Nodes().nodes_discovered[1:]:
self.assertFalse(
n.checkbox.find_element_by_tag_name('input').is_enabled(),
'Checkbox is disabled')
def test_one_controller_allowed_controller_role_disabled(self):
with Nodes()as n:
with RolesPanel() as r:
n.nodes_discovered[0].checkbox.click()
self.assertTrue(r.controller.is_enabled())
for node in n.nodes_discovered[1:]:
node.checkbox.click()
self.assertFalse(r.controller.is_enabled())
def test_compute(self):
with Nodes()as n:
n.nodes_discovered[0].checkbox.click()
with RolesPanel() as r:
r.compute.click()
self.assertFalse(r.controller.is_enabled())
self.assertIn(
ERROR_ROLE_CANNOT_COMBINE,
r.controller.find_element_by_xpath('../..').text,
'error "{}" is visible'.format(ERROR_ROLE_CANNOT_COMBINE))
with Nodes()as n:
self.assertNodeInRoles(n.nodes_discovered[0], [ROLE_COMPUTE])
self.assertTrue(n.apply_changes.is_enabled())
n.nodes_discovered[0].checkbox.click()
self.assertFalse(n.apply_changes.is_enabled())
self.assertNodeInRoles(n.nodes_discovered[0], [ROLE_UNALLOCATED])
def test_cinder(self):
with Nodes()as n:
n.nodes_discovered[0].checkbox.click()
with RolesPanel() as r:
r.cinder.click()
with Nodes()as n:
self.assertNodeInRoles(n.nodes_discovered[0], [ROLE_CINDER])
self.assertTrue(n.apply_changes.is_enabled())
n.nodes_discovered[0].checkbox.click()
self.assertFalse(n.apply_changes.is_enabled())
self.assertNodeInRoles(n.nodes_discovered[0], [ROLE_UNALLOCATED])
def test_ceph(self):
with Nodes()as n:
n.nodes_discovered[0].checkbox.click()
with RolesPanel() as r:
r.ceph_osd.click()
with Nodes()as n:
self.assertNodeInRoles(n.nodes_discovered[0], [ROLE_CEPH])
self.assertTrue(n.apply_changes.is_enabled())
n.nodes_discovered[0].checkbox.click()
self.assertFalse(n.apply_changes.is_enabled())
self.assertNodeInRoles(n.nodes_discovered[0], [ROLE_UNALLOCATED])
def test_multiroles(self):
with Nodes()as n:
n.nodes_discovered[0].checkbox.click()
with RolesPanel() as r:
r.controller.click()
r.cinder.click()
r.ceph_osd.click()
with Nodes()as n:
self.assertNodeInRoles(
n.nodes_discovered[0],
[ROLE_CONTROLLER, ROLE_CINDER, ROLE_CEPH])
def test_several_nodes(self):
with Nodes()as n:
n.nodes_discovered[0].checkbox.click()
n.nodes_discovered[1].checkbox.click()
n.nodes_discovered[2].checkbox.click()
with RolesPanel() as r:
r.compute.click()
r.cinder.click()
r.ceph_osd.click()
with Nodes()as n:
self.assertNodeInRoles(
n.nodes_discovered[0],
[ROLE_COMPUTE, ROLE_CINDER, ROLE_CEPH])
self.assertNodeInRoles(
n.nodes_discovered[1],
[ROLE_COMPUTE, ROLE_CINDER, ROLE_CEPH])
self.assertNodeInRoles(
n.nodes_discovered[2],
[ROLE_COMPUTE, ROLE_CINDER, ROLE_CEPH])
class TestRolesHAFlat(BaseClass):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
preconditions.Environment.ha_flat()
def test_controller_role_always_enabled(self):
with Nodes()as n:
for node in n.nodes_discovered:
node.checkbox.click()
self.assertTrue(RolesPanel().controller.is_enabled())
RolesPanel().controller.click()
for node in n.nodes_discovered:
self.assertNodeInRoles(node, [ROLE_CONTROLLER])
def test_all_nodes_could_be_controller(self):
RolesPanel().controller.click()
with Nodes()as n:
for node in n.nodes_discovered:
node.checkbox.click()
for node in n.nodes_discovered:
self.assertNodeInRoles(node, [ROLE_CONTROLLER])

View File

@ -0,0 +1,59 @@
import re
import time
import browser
from pageobjects.base import PageObject
from pageobjects.header import Header
from pageobjects.support import Support
from tests.base import BaseTestCase
class TestSupport(BaseTestCase):
@classmethod
def setUpClass(cls):
BaseTestCase.setUpClass()
def setUp(self):
BaseTestCase.clear_nailgun_database()
BaseTestCase.setUp(self)
time.sleep(1)
Header().support.click()
time.sleep(1)
def test_register_fuel(self):
with Support() as s:
key = re.search(
'key=(?P<key>.*)',
s.register_fuel.get_attribute('href')).group('key')
self.assertEqual(216, len(key), 'Key not empty')
s.register_fuel.click()
time.sleep(4)
browser.driver.switch_to_window(browser.driver.window_handles.pop())
self.assertTrue(
browser.driver.find_element_by_css_selector(
'[value="Register and Activate subscription"]').is_displayed(),
'"Register and Activate subscription" is displayed')
def test_contact_support(self):
Support().contact_support.click()
time.sleep(4)
browser.driver.switch_to_window(browser.driver.window_handles.pop())
self.assertIn('http://software.mirantis.com/',
browser.driver.current_url)
def test_diagnostic_snapshot(self):
Support().generate_snapshot.click()
with Support() as s:
PageObject.wait_element(s, 'download_snapshot')
self.assertTrue(
s.download_snapshot.is_enabled(),
'"Diagnostic Snapshot" is displayed')
def test_capacity_audit(self):
Support().view_capacity_audit.click()
self.assertEqual(
'Home/ Support/ Capacity',
Header().breadcrumb.text,
'Breadcrumb text'
)

View File

@ -3,5 +3,5 @@
set -e
set -x
flake8 --ignore=H302,H802 --exclude bin/,include/,lib/,local/,tmp/ --show-source fuelweb_test
flake8 --ignore=H302,H802 --exclude bin/,include/,lib/,local/,tmp/ --show-source fuelweb_test fuelweb_ui_test