diff --git a/HA/README.md b/HA/README.md new file mode 100644 index 0000000..009e726 --- /dev/null +++ b/HA/README.md @@ -0,0 +1,26 @@ +HA Testing Scripts +============ + + The scripts for OpenStack Murano HA testing. + +How To Test +============ + To run HA tests need to perform the following steps: + +1. Copy agent.py on all controller nodes (with services, which we want to control) + +2. Copy controller.py and controller.conf on your personal host (to manage services on controller modes) + +3. Change controller.conf - need to fix IP addresses of controller nodes and parameters file1 and file2 + +4. Execute agent.py on all controller-nodes (with services, like Murano Conductor service): + + sudo python agent.py + +5. Execute controller.py on your personal host and start to testing. For example, you can start to deploy environment. In this case Murano Conductor service on the first node will start to deploy VMs and these testing scripts will detect node with Active Murano Controller service - and will stop it for several secconds. In case of properly HA the same service on the other nodes should start and continue to deploy environment. + + + + + + Mirantis Inc (C) 2013. diff --git a/HA/agent.py b/HA/agent.py new file mode 100644 index 0000000..e7ef8e6 --- /dev/null +++ b/HA/agent.py @@ -0,0 +1,51 @@ +# Copyright (c) 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. + +import shlex +import subprocess +import filecmp +import xmlrpclib +import time +from SimpleXMLRPCServer import SimpleXMLRPCServer + +""" + This is simple XML-RPC server which can: + 1. Execute any shell commands by the request + 2. Compare two files + + This server should be run on OpenStack controller nodes + to control services on these nodes. +""" + + +def run_bash_command(cmd, timeout=0): + args = shlex.split(cmd) + p = subprocess.Popen(args, shell=False, stdout=subprocess.PIPE) + for line in p.stdout: + print line + time.sleep(timeout) + return p.stdout + + +def check_diff_files(file1, file2): + return not filecmp.cmp(file1, file2) + + +server = SimpleXMLRPCServer(("0.0.0.0", 7007),allow_none=True) +print "Listening on port 7007..." +server.register_function(run_bash_command, "run_bash_command") +server.register_function(check_diff_files, "check_diff_files") + +server.serve_forever() diff --git a/HA/controller.conf b/HA/controller.conf new file mode 100644 index 0000000..fcd64aa --- /dev/null +++ b/HA/controller.conf @@ -0,0 +1,21 @@ +[HA_Testing] + +nodes = n1 n2 + +port = 7007 + +mode = compare_files +file1 = /var/log/murano-conductor.log +file2 = /var/log/murano-conductor.log.diff + +activate_cmd = service murano-conductor start +diactivate_cmd = service murano-conductor stop + +minimum_count_of_active_nodes = 1 + + +[n1] +host = 172.18.79.81 + +[n2] +host = 172.18.79.82 \ No newline at end of file diff --git a/HA/controller.py b/HA/controller.py new file mode 100644 index 0000000..15d6c40 --- /dev/null +++ b/HA/controller.py @@ -0,0 +1,126 @@ +# Copyright (c) 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. + +import xmlrpclib +import ConfigParser +import time + + +class ControllerNode(): + + def __init__(self, status='on', host='', port='7007', file1='', file2='', + activate_cmd='', diactivate_cmd='', agent=None): + self.status = status + self.host = host + self.port = port + self.file1 = file1 + self.file2 = file2 + self.activate_cmd = activate_cmd + self.diactivate_cmd = diactivate_cmd + self.agent = agent + self.checks_timeout = -1 + + def check_files(self, access): + self.checks_timeout -= 1 + if self.checks_timeout == 0: + self.activate() + return 1 + + if self.agent.check_diff_files(self.file1, self.file2) and access: + self.diactivate() + return -1 + + return 0 + + def activate(self, timeout=5): + print 'Start to activate node ' + self.host + init_cmd = 'cp %s %s' % (self.file1, self.file2) + self.agent.run_bash_command(self.activate_cmd) + time.sleep(timeout) + self.agent.run_bash_command(init_cmd) + + def diactivate(self, timeout=5): + print 'Start to diactivate node ' + self.host + time.sleep(timeout) + self.agent.run_bash_command(self.diactivate_cmd) + self.checks_timeout = 10 + + +class Controller(): + + nodes = [] + + def __init__(self, config_file='controller.conf'): + self.config = ConfigParser.ConfigParser() + self.config.read(config_file) + + self.agents_list = self.get_from_cfg('HA_Testing', 'nodes').split(' ') + self.port = self.get_from_cfg('HA_Testing', 'port', '7007') + + self.activate_cmd = self.get_from_cfg('HA_Testing', 'activate_cmd') + self.diactivate_cmd = self.get_from_cfg('HA_Testing', 'diactivate_cmd') + + self.mode = self.get_from_cfg('HA_Testing', 'mode', 'compare_files') + self.file1 = self.get_from_cfg('HA_Testing', 'file1') + self.file2 = self.get_from_cfg('HA_Testing', 'file2') + + parameter = 'minimum_count_of_active_nodes' + self.min_active_nodes = self.get_from_cfg('HA_Testing', + parameter, 1) + + for agent in self.agents_list: + host = self.get_from_cfg(agent, 'host') + port = self.get_from_cfg(agent, 'port', self.port) + file1 = self.get_from_cfg(agent, 'file1', self.file1) + file2 = self.get_from_cfg(agent, 'file2', self.file2) + activate_cmd = self.get_from_cfg(agent, 'activate_cmd', + self.activate_cmd) + diactivate_cmd = self.get_from_cfg(agent, 'diactivate_cmd', + self.diactivate_cmd) + + new_agent = xmlrpclib.ServerProxy("http://%s:%s" + % (host, port), allow_none=True) + + new_node = ControllerNode('on', host, port, file1, file2, + activate_cmd, diactivate_cmd, new_agent) + + new_node.activate() + " If all OK, add this node to the list " + self.nodes.append(new_node) + + self.active_nodes = len(self.nodes) + print 'Minimal count of active nodes: ' + str(self.min_active_nodes) + print 'Active nodes: ' + str(self.active_nodes) + + def get_from_cfg(self, p1, p2, default=''): + try: + result = self.config.get(p1, p2) + return result + except: + return default + + def execute(self): + if 'compare_files' in self.mode: + self.monitor_file_changes() + + def monitor_file_changes(self): + while self.active_nodes != self.min_active_nodes: + for node in self.nodes: + access = int(self.active_nodes) > int(self.min_active_nodes) + self.active_nodes += node.check_files(access) + + +ctrl = Controller() +ctrl.execute() diff --git a/boffin/README.rst b/boffin/README.rst new file mode 100644 index 0000000..6d2c594 --- /dev/null +++ b/boffin/README.rst @@ -0,0 +1,6 @@ +Robotframework-Boffin +========================== + +This library extends available keywords of Robotframework and robotframework-selenium2library. + +And provides keywords for REST requests testing. \ No newline at end of file diff --git a/boffin/build/lib/Boffin/_Settings.py b/boffin/build/lib/Boffin/_Settings.py new file mode 100644 index 0000000..3b9709b --- /dev/null +++ b/boffin/build/lib/Boffin/_Settings.py @@ -0,0 +1,54 @@ +# Copyright (c) 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. + +from ConfigParser import ConfigParser +from os import getcwd +from os.path import join + +from robot.libraries.BuiltIn import BuiltIn + + +_settingsFileName = 'settings.ini' + + +class _SettingsReader(object): + """ 'settings.ini' driver. """ + + @staticmethod + def read(): + """ + Loads default variables from the 'resources/settings.ini' file. + + Arguments: + - None. + + Return: + - None. + """ + try: + p = BuiltIn().get_variable_value('${resources_path}') + if p is not None: + _settingsFullFileName = join(p, _settingsFileName) + else: + _settingsFullFileName = join(getcwd(), 'resources', + _settingsFileName) + + conf = ConfigParser() + conf.read(_settingsFullFileName) + + for setting in conf.options('default'): + BuiltIn().set_global_variable('${%s}' % setting, + conf.get('default', setting)) + except: + pass diff --git a/boffin/build/lib/Boffin/__init__.py b/boffin/build/lib/Boffin/__init__.py new file mode 100644 index 0000000..292f903 --- /dev/null +++ b/boffin/build/lib/Boffin/__init__.py @@ -0,0 +1,54 @@ +# Copyright (c) 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. + + +from os.path import join, dirname + +from Selenium2Library import Selenium2Library + +from _Settings import _SettingsReader +from keywords import * + +execfile(join(dirname(__file__), 'version.py')) + +__version__ = VERSION + +_SettingsReader.read() + + +class WebUIlib(Selenium2Library, _WebUIlib): + """ + This class supports WebUi related testing using the Robot Framework. + """ + + ROBOT_LIBRARY_SCOPE = 'GLOBAL' + ROBOT_LIBRARY_VERSION = VERSION + + +class Rest(_Rest): + """ + This class supports Rest related testing using the Robot Framework. + """ + + ROBOT_LIBRARY_SCOPE = 'GLOBAL' + ROBOT_LIBRARY_VERSION = VERSION + + +class DB(Pydblibrary): + """ + This library supports database-related testing using the Robot Framework. + """ + + ROBOT_LIBRARY_SCOPE = 'GLOBAL' + ROBOT_LIBRARY_VERSION = VERSION diff --git a/boffin/build/lib/Boffin/keywords/_Rest.py b/boffin/build/lib/Boffin/keywords/_Rest.py new file mode 100644 index 0000000..15b9629 --- /dev/null +++ b/boffin/build/lib/Boffin/keywords/_Rest.py @@ -0,0 +1,238 @@ +# Copyright (c) 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. + +import json +import requests +from robot.api import logger + + +class _Rest(object): + + ROBOT_LIBRARY_SCOPE = 'GLOBAL' + + headers = None + body = None + url = None + + def clear_headers(self): + """ + Clears headers for REST API requests. + + *Arguments:* + - None. + + *Return:* + - None. + + *Examples*: + | Clear Headers | + """ + self.headers = [] + + def set_headers(self, headers_dict): + """ + Configures headers for REST API requests. + + *Arguments:* + - headers_dict: string with json dict. + + *Return:* + - None. + + *Examples*: + | Set Headers | {'Content-Type': 'application/json' | + """ + try: + self.headers = json.loads(headers_dict) + except: + raise AssertionError('Incorrect headers: %s' % headers_dict) + + def update_headers(self, name, value): + """ + Modifies headers for REST API requests. + + *Arguments:* + - name: header name. + - value: header value. + + *Return:* + - None. + + *Examples*: + | Update Headers | X-Auth-Token | 8808880808080808 | + """ + self.headers[name] = value + + def set_body(self, body_dict): + """ + This function allows to configure body for REST API requests. + + *Arguments:* + - body_dict: string with json dict. + + *Return:* + - None. + + *Examples*: + | Set Headers | {'Content-Type': 'application/json' | + """ + self.body = body_dict + + def get_headers(self): + """ + Gets headers for REST API requests. + + *Arguments:* + - None. + + *Return:* + - Headers dict. + + *Examples*: + | ${headers} | Get Headers | + """ + return self.headers + + def GET_request(self, url): + """ + Sends GET request. + + *Arguments:* + - url: destination url. + + *Return:* + - None. + + Examples: + | GET request | http://10.10.10.1:8082/environments | + """ + self.response = requests.request('GET', url=url, headers=self.headers) + + def POST_request(self, url): + """ + Sends POST request. + + *Arguments:* + - url: destination url. + + *Return:* + - None. + + *Examples*: + | POST request | http://10.10.10.1:8082/environments | + """ + debug_data = 'POST Request to URL: %s \n' \ + 'with Headers: %s \n' \ + 'and Body: %s' % (url, self.headers, self.body) + logger.debug(debug_data) + + self.response = requests.request('POST', url, + headers=self.headers, + data=self.body) + + logger.debug('Response: %s' % self.response.text) + + def POST_request_without_body(self, url): + """ + Sends POST request without body. + + *Arguments:* + - url: destination url. + + *Return:* + - None. + + *Examples*: + | POST request | http://10.10.10.1:8082/environments | + """ + debug_data = 'POST Request to URL: %s \n' \ + 'with Headers: %s \n' % (url, self.headers) + logger.debug(debug_data) + + self.response = requests.request('POST', url, + headers=self.headers) + logger.debug('Response: %s' % self.response.text) + + def DELETE_request(self, url): + """ + Sends DELETE request. + + *Arguments:* + - url: destination url. + + *Return:* + - None. + + *Examples*: + | DELETE request | http://10.10.10.1:8082/environments | + """ + self.response = requests.request('DELETE', url=url, + headers=self.headers) + + def PUT_request(self, url): + """ + Sends PUT request. + + *Arguments:* + - url: destination url. + + *Return:* + - None. + + *Examples*: + | PUT request | http://10.10.10.1:8082/env | + """ + debug_data = 'POST Request to URL: %s \n' \ + 'with Headers: %s \n' \ + 'and Body: %s' % (url, self.headers, self.body) + logger.debug(debug_data) + + self.response = requests.request('PUT', url, + headers=self.headers, + data=self.body) + logger.debug('Response: %s' % self.response.text) + + def get_response_code(self): + """ + Gets response code. + + *Arguments:* + - None. + + *Return:* + - response code. + + *Examples*: + | ${code} | Get Response Code | + """ + return self.response.status_code + + def get_response_body(self): + """ + Gets response body. + + *Arguments:* + - None. + + *Return:* + - response body. + + *Examples*: + | ${body} | Get Response Body | + """ + logger.debug('Response: %s' % self.response.text) + if self.response.text is None: + self.response.text = {} + + return json.loads(self.response.text) diff --git a/boffin/build/lib/Boffin/keywords/_Utils.py b/boffin/build/lib/Boffin/keywords/_Utils.py new file mode 100644 index 0000000..ad4093a --- /dev/null +++ b/boffin/build/lib/Boffin/keywords/_Utils.py @@ -0,0 +1,328 @@ +# Copyright (c) 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. + +from ConfigParser import ConfigParser +from os import getcwd +from os.path import join +from bs4 import BeautifulSoup +from robot.libraries.BuiltIn import BuiltIn + + +class _ArtificialIntelligence: + """ + This class allows to find input and select controls \ + without manual input of identificators. + We can find input fields by labels near those fields. \ + Boffin heart. + """ + + ROBOT_LIBRARY_SCOPE = 'GLOBAL' + + def __init__(self, page_source): + """ + Class constructor. + + *Arguments:* + - page_source: web page source code. + + *Return:* + - None. + """ + self.page_source = page_source + + def _get_xpath_of_element(self, element): + """ + This function allows to get xpath of soup elements. + + *Arguments:* + - element: selector name. + + *Return:* + - element xpath. + """ + + number = 1 + try: + number += len(element.find_previous_siblings(element.name)) + except: + pass + + xpath = element.name + if number > 1: + xpath += '[' + str(number) + ']' + + for parent in element.findParents(): + if parent.name != '[document]': + k = 0 + for tag in parent.find_previous_siblings(): + if tag.name == parent.name: + k += 1 + if k == 0: + xpath = parent.name + '/' + xpath + else: + xpath = parent.name + '[' + str(k + 1) + ']/' + xpath + + return xpath + + def extra_search(self, soup, value, tag=None): + """ + This function allows to get element by its parameters. + + *Arguments:* + - soup: soup structure. + - value: element name. + + *Return:* + - label_element. + """ + + label_element = None + + if label_element is None: + label_element = soup.find(tag, text=str(value)) + if label_element is None: + label_element = soup.find(tag, attrs={'value': value}) + if label_element is None: + label_element = soup.find(tag, attrs={'title': value}) + + if label_element is None: + try: + for element in soup.find_all(tag): + if str(value) in element.text: + label_element = element + except: + pass + + return label_element + + def find_element(self, label, element_type='input', method='next', + result='xpath'): + """ + Looks for specified element on the page. + + *Arguments:* + - label: selector name. + - element_type: element tag name. It could be any tag or \ + several tags (then they are listed as 'select/input/a'). + - method: element search method. If 'next' is set, then \ + function is looking for the next input field after the \ + specified element. + Otherwise it returns the specified element itself. + + *Return:* + - element xpath. + + *Examples:* + | ${xpath} | Find element | E-mail | input | next | + | ${xpath} | Find element | Cancel | a/div | this | + """ + html = str(self.page_source.encode("utf-8", "replace")) + + " load html to soup structure for parsing " + soup = BeautifulSoup(html) + + " search element after the label" + try: + element_types = element_type.split('/') + element = None + + label_element = self.extra_search(soup, label) + for element_type in element_types: + if method == 'next': + element = label_element.parent.find_next(element_type) + + elif method == 'previous': + element = label_element.parent.find_previous(element_type) + + elif method == 'associated': + for t in ['a', 'button', 'input', 'select']: + elements = label_element.parent.find_all_next(t) + for e in elements: + if element_type in e.text: + element = e + if element: + break + elements = label_element.parent.find_all_previous(t) + for e in elements: + if element_type in e.text: + element = e + if element: + break + else: + element = self.extra_search(soup, label, element_type) + + if element: + break + + " return xpath of element " + if result == 'xpath': + return self._get_xpath_of_element(element) + else: + return element + except: + return None + + +class _Utils(object): + ROBOT_LIBRARY_SCOPE = 'GLOBAL' + + def get_element_from_repo(self, element_name): + """ + Returns element type, identificator and frame from \ + the 'resources/objrepo/%screen_name%.ini' file by element name. + + *Arguments:* + - elementName: screen name and selector name divided by dot. + + *Return:* + - [elType, elIdentificator, elFrame]. + + *Example:* + | @{element} | Get Element From Repo | Home . Banner Page 2 Button | + """ + try: + p = BuiltIn().get_variable_value('${resources_path}') + if p is not None: + _objRepoPath = join(p, 'objrepo') + else: + _objRepoPath = join(getcwd(), 'resources', 'objrepo') + + element_name = element_name.lower().replace(' ', '') + print "Element Name: " + element_name + inputElement = element_name.split('.') + + if len(inputElement) == 1: + fileName = 'common.ini' + name = element_name + + else: + fileName = '%s.ini' % inputElement[0] + name = inputElement[1] + + fullFileName = join(_objRepoPath, fileName) + print "fullFileName " + fullFileName + conf = ConfigParser() + conf.read(fullFileName) + + print "A: " + conf.get(str(name), 'type') + print "A: " + conf.get(name, 'type') + + if not conf.has_section(name): + print name + return ['', None, ''] + element_type = conf.get(name, 'type') + + element_identificator = '' + element_parent_name = conf.get(name, 'parent') + if element_parent_name: + element_identificator = \ + self.get_element_from_repo(element_parent_name)[1] + \ + element_identificator + + element_identificator += conf.get(name, 'identificator') + + element_frame = conf.get(name, 'frame') + return [element_type, element_identificator, element_frame] + except: + return ['', None, ''] + + def get_web_element_frame(self, elementName): + """ + Returns element frame by its name in the + 'resources/objrepo/%screen_name%.ini' file. + + *Arguments:* + - elementName: screen name and selector name divided by dot. + + *Return:* + - elFrame. + + *Example:* + | ${elFrame} | GetElementFrame | Blog . Post Text field | + """ + type, id, frame = self.get_element_from_repo(elementName) + return frame + + def get_web_element_selector(self, name, page_source=None, + element_type='input', method='next', + result='xpath'): + """ + Returns element selector by its name in the \ + 'resources/ObjRepo.ini' file. + + *Arguments:* + - name: selector name. + - page_source: web page source code. + - element_type: element tag name. It could be any tag or several \ + tags (then they are listed as 'select/input/a'). + - method: element search method. If 'next' is set, then function + is looking for the next input field after the specified element. + Otherwise it returns the specified element itself. + + *Return:* + - elIdentificator. + + *Examples:* + | ${selector} | Get element selector | User Name | ${source_code} \ + | input | next | + | ${selector} | Get element selector | Submit Button | ${source_code} \ + | a | this | + """ + type, id, frame = self.get_element_from_repo(name) + + if not id and page_source: + boffin = _ArtificialIntelligence(page_source) + id = boffin.find_element(name, element_type, method, result) + if result != 'xpath': + return id + if id: + type = 'xpath' + + identificator = None + if id: + identificator = '%s%s' % \ + ('' if not type else '%s=' % str(type), str(id)) + + return identificator + + def get_table_row_xpath(self, page_source, name): + """ + This method allows to parse tables on web pages \ + and determine the table row by element from table. + + *Arguments:* + - page_source: web page source code. + - name: identificator of row element. + + *Return:* + - xpath of table row. + + *Example:* + | ${elXpath} | Get Table Row Xpath | Entity 123 | + """ + _type = 'td/a/label/input/select' + element = self.get_web_element_selector(name, page_source, + _type, method='this', + result='element') + tag = element.name + while tag != 'tr' and tag: + try: + tag = element.parent.name + element = element.parent + except: + tag = None + pass + + e = _ArtificialIntelligence(page_source) + return e._get_xpath_of_element(element) diff --git a/boffin/build/lib/Boffin/keywords/_WebUIlib.py b/boffin/build/lib/Boffin/keywords/_WebUIlib.py new file mode 100644 index 0000000..40f3c08 --- /dev/null +++ b/boffin/build/lib/Boffin/keywords/_WebUIlib.py @@ -0,0 +1,668 @@ +# Copyright (c) 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 + +from time import sleep + +from robot.libraries.BuiltIn import BuiltIn + +from _Utils import _Utils + + +# Decorator for framed elements. +def _framed(framed_element_name): + def real_framed(function): + def wrapper(self, *args): + co_varnames = function.func_code.co_varnames + upper_varnames = [varnames.upper() for varnames in co_varnames] + index = upper_varnames.index(framed_element_name.upper()) + + element_frame = \ + self.get_web_element_frame(args[index - 1]) + if element_frame: + self.set_current_frame(element_frame) + + res = function(self, *args) + + if element_frame: + self.unselect_frame() + + return res + + return wrapper + + return real_framed + + +class _WebUIlib(_Utils): + + def navigate_to(self, path, dont_wait=None): + """ + Navigates to the page by given links sequence. + + *Arguments:* + - path: sequence of links separated by '>'. + - dont_wait: optional parameter. Should be set to skip waiting \ + for page loaded. + + *Return:* + - None. + + *Examples:* + | Navigate to | Careers>Account Executive | + """ + links = path.split('>') + + for link in links: + self.click_link(link) + self.wait_for_page_loaded(dont_wait) + + @_framed('over_element_name') + def click_on_submenu(self, over_element_name, name, dont_wait=None): + """ + Puts mouse over menu element and then clicks on submenu element by \ + given selector names and waits for page loaded if needed. + + *Arguments:* + - over_element_name: menu selector title taken from object \ + repository. + - name: submenu selector title taken from object repository. + - dont_wait: optional parameter. Should be set to skip waiting \ + for page loaded. + + *Return:* + - None. + + *Examples:* + | Click on submenu | Settings | Profile | + """ + self.put_mouse_over(over_element_name) + sleep(1) + self.click_on(name) + self.wait_for_page_loaded(dont_wait) + + def click_on_link(self, link, dont_wait=None): + """ + Clicks the link by given localor and waits for page loaded if needed. + + *Arguments:* + - link: this attribute can contain one of following: id, name, \ + href or link text. + - dont_wait: optional parameter. Should be set to skip waiting \ + for page loaded. + + *Return:* + - None. + + *Examples:* + | Click on link | Move to Trash | + | Click on link | Delete | don't wait | + """ + self.wait_for_element_found(link, 'a', 'this') + self.click_link(link) + self.wait_for_page_loaded(dont_wait) + + def wait_for_page_loaded(self, dont_wait=None, page_load_timeout=60): + """ + Waits for 'complete' page state during predefined page load timeout. + + Does not wait for page loading if wait argument is set to any value \ + except the ${empty}. + + *Arguments:* + - dont_wait: optional parameter. Should be set to skip waiting \ + for page loaded. + - page_load_timeout: optional parameter. Timeout for page loading. + + *Return:* + - None. + + *Examples:* + | Wait for page loaded | + | Wait for page loaded | don't wait | + """ + ajax_wait_timeout = \ + BuiltIn().get_variable_value('${ajax_wait_timeout}') + + if ajax_wait_timeout: + self.wait_for_condition('return window.jQuery.active == 0', + ajax_wait_timeout, + 'Ajax request was not loaded in ' + '%s second(s)' % ajax_wait_timeout) + + if not dont_wait: + self.wait_for_condition('return document.readyState == "complete"', + page_load_timeout, + 'Page was not loaded in ' + '%s second(s)' % page_load_timeout) + + def title_should_contain(self, text): + """ + Verifies that current page title contains given text. + + *Arguments:* + - text: text which should be in the title set in test case. + + *Return:* + - None. + + *Examples:* + | Title should contain | Account Executive | + """ + title = self.get_title() + BuiltIn().should_contain(title, text) + + @_framed('name') + def click_on(self, name, dont_wait=None): + """ + Clicks the element by given selector name and waits for page loaded \ + if needed. + + *Arguments:* + - name: selector title taken from object repository. + - dont_wait: optional parameter. Should be set to skip waiting \ + for page loaded. + + *Return:* + - None. + + *Examples:* + | Click on | Dashboard . Users button | + """ + selector = self.wait_for_element_found(name, 'button/input/a', 'this') + self.click_element(selector) + self.wait_for_page_loaded(dont_wait) + + def set_current_frame(self, name): + """ + Sets frame identified by given selector name as current frame. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Set current frame | Post Editor Frame | + """ + selector = self.get_web_element_selector(name) + self.select_frame(selector) + + def element_text_should_contain(self, name, text): + """ + Verifies that element with given selector type contains the given text. + + *Arguments:* + - name: selector title taken from object repository. + - text: text to be found set in test. + + *Return:* + - None. + + *Examples:* + | Element Text Should Contain | Dashboard . Message text | \ + Post Updated | + """ + selector = self.get_web_element_selector(name) + self.element_should_contain(selector, text) + + def element_text_should_be_equal_to(self, name, text): + """ + Verifies that element with given selector type equals to the \ + given text. + + *Arguments:* + - name: selector title taken from object repository. + - text: text to be found set in test. + + *Return:* + - None. + + *Examples:* + | Element Text Should Be Equal To | Dashboard . Message text | \ + User deleted | + """ + selector = self.get_web_element_selector(name) + self.element_text_should_be(selector, text) + + def element_text_should_not_contain(self, name, text): + """ + Verifies that element with given selector type not contain the \ + given text. + + *Arguments:* + - name: selector title taken from object repository. + - text: text to be found set in test. + + *Return:* + - None. + + *Examples:* + | Element Text Should Not Contain | Dashboard . Message text \ + | Post Updated. | + """ + selector = self.get_web_element_selector(name) + self.element_should_not_contain(selector, text) + + def element_text_should_not_be_equal_to(self, name, text): + """ + Verifies that element text with given selector type not qual to the \ + given text. + + *Arguments:* + - name: selector title taken from object repository. + - text: text to be found set in test. + + *Return:* + - None. + + *Examples:* + | Element Text Should Not Be Equal To | Dashboard . Message text \ + | Post Updated. | + """ + selector = self.get_web_element_selector(name) + self.element_text_should_not_be(selector, text) + + def element_should_not_contain(self, selector, text): + """ + Verifies element identified by given selector does not contain \ + given text. + + *Arguments:* + - selector: element identificator in the object repository. + - text: text to be checked. + + *Return:* + - None. + + *Examples:* + | Element Should Not Contain | xpath=//div[@id='moderated']/p \ + | rude message | + """ + obj_text = self.get_text(selector) + BuiltIn().should_not_contain(obj_text, text) + + def element_text_should_not_be(self, selector, text): + """ + Verifies element identified by given selector does not equal to the \ + given text. + + *Arguments:* + - selector: element identificator in the object repository. + - text: text to be checked. + + *Return:* + - None. + + *Examples:* + | Element Should Not Be | xpath=//div[@id='moderated']/p \ + | rude message | + """ + obj_text = self.get_text(selector) + BuiltIn._should_not_be_equal(obj_text, text) + + def page_should_have_number_of_elements(self, count, name): + """ + Verifies that current page contains given number of elements with \ + given selector type. + + *Arguments:* + - count: number of element to be found. + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Page should have number of elements | 4 | Banner Buttons | + """ + element = self.get_element_from_repo(name) + self.xpath_should_match_x_times(element[1], count) + + def page_should_have_element(self, name): + """ + Verifies that current page contains given element. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Page should have element | Contact Us button | + """ + selector = self.get_web_element_selector(name) + self.page_should_contain_element(selector) + + def page_should_not_have_element(self, name): + """ + Verifies that current page does not contain given element. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Page should not have element | Contact Us button | + """ + selector = self.get_web_element_selector(name) + self.page_should_not_contain_element(selector) + + def put_mouse_over(self, name): + """ + Simulates hovering mouse over the element specified by selector name. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Put mouse over | Dashboard . Posts button | + """ + selector = self.get_web_element_selector(name) + self.mouse_over(selector) + + @_framed('field_name') + def fill_field(self, field_name, text): + """ + Gets element by its field name and fills it with given text. + Note: If field name will be 'password' then \ + ${text} won't be logged. + + *Arguments:* + - field_name: selector title taken from object repository. + - text: text to be entered into field. + + *Return:* + - None. + + *Examples:* + | Fill field | Dashboard . New Post Title field | Test blog-post | + """ + selector = self.wait_for_element_found(field_name, 'input/textarea', + 'next') + + if 'PASSWORD' in field_name.upper(): + self.input_password(selector, text) + else: + self.input_text(selector, '') + self.input_text(selector, text) + + def wait_for_element_found(self, element_name, element_type, method): + """ + Makes 10 retries to get element by its name with defined retry \ + interval (1 second). + + *Arguments:* + - element_name: selector title taken from object repository; + - element_type: element tag, could take several tags at once \ + (e.g. select/input/a); + - method: a method of how to search for the element. + + *Return:* + - selector: element identificator from object repository. + + *Examples:* + | ${selector} | Wait for element found | Dashboard Menu Title field \ + | input | next | + """ + for attempt in range(10): + try: + page_source_code = self.get_source() + selector = self.get_web_element_selector(element_name, + page_source_code, + element_type, + method) + except: + pass + if selector: + break + + sleep(1) + + if not selector: + BuiltIn().run_keyword('Capture Page Screenshot') + raise AssertionError('Web element "%s" was not found in object ' + 'repository and on page.' % element_name) + + return selector + + @_framed('name') + def select_item_from_list(self, name, item_name): + """ + Selects specified item from given list. + + *Arguments:* + - name: selector title taken from object repository. + - item_name: list box item. + + *Return:* + - None. + + *Examples:* + | Select item from list | Dashboard . User Action dropdown | Delete | + """ + selector = self.wait_for_element_found(name, 'select', 'next') + self.select_from_list(selector, item_name) + + @_framed('name') + def set_checkbox_on(self, name): + """ + Set checkbox with given title on. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Set checkbox on | Dashboard . Delete Posts Role checkbox | + """ + selector = self.wait_for_element_found(name, 'select', 'previous') + self.select_checkbox(selector) + + @_framed('name') + def set_checkbox_off(self, name): + """ + Set checkbox with given title off. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Set checkbox off | Dashboard . Delete Posts Role checkbox | + """ + selector = self.wait_for_element_found(name, 'select', 'previous') + self.unselect_checkbox(selector) + + @_framed('from_name') + def drag_and_drop_to(self, from_name, to_name): + """ + Drags and drops from one given element to other. + + *Arguments:* + - from_name: selector title taken from object repository to get \ + content from; + - to_name: selector title taken from object repository to put \ + content to. + + *Return:* + - None. + + *Examples:* + | Drag And Drop To | Photo gallery | User avatar | + """ + from_selector = self.wait_for_element_found(from_name, + 'button/input/a/img/div', + 'this') + to_selector = self.wait_for_element_found(to_name, + 'button/input/a/img/div', + 'this') + self.drag_and_drop_to(from_selector, to_selector) + + def find_associated_element(self, first_element, desired_element): + """ + This method allows to find element, which located near other element \ + and returns xpath of this element. + Sometimes we have many identical elements on page and we can find \ + correct element based on nearest unique elements. + + *Arguments:* + - First_Element: base element, near this element we want to find \ + other element. + - Desired_Element: this is element which we want to find. + + *Return:* + - xpath of Desired_Element or None + + *Examples:* + | {element_xpath} | Find Associated Element | MyUniqueElement \ + | DesiredElement | + """ + element = self.wait_for_element_found(first_element, desired_element, + 'associated') + + return element + + @_framed('name') + def select_radio_by_selector(self, name, value): + """ + Sets selection of radio button group identified by selector name \ + to value. + + *Arguments:* + - name: selector title taken from object repository. + - value: value to be selected, is used for the value attribute or \ + for the id attribute. + + *Return:* + - None. + + *Examples:* + | Select Radio By Selector | Dashboard . Questionnaire | Yes | + """ + selector = self.wait_for_element_found(name, 'input', 'previous') + self.select_radio_button(selector, value) + + def get_table_row_with(self, element): + """ + This method allows to find table row with specific element. \ + After this xpath of table row can be used like base for xpath of \ + different elements in this table. + + *Arguments:* + - element: the unique element from table. + + *Return:* + - xpath of table row for this element + + *Examples:* + | {table_xpath} | Get Table Row With | MyUniqueElement | + | Click Element \ \ | xpath={table_xpath}/td[4]/button | + """ + source_code = self.get_source() + result = self.get_table_row_xpath(source_code, element) + + return result + + @_framed('name') + def element_should_be_invisible(self, name): + """ + Verifies that element is invisible on the page. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Element Should Be Invisible | Dashboard . Post Publish button | + """ + selector = self.wait_for_element_found(name, + 'button/input/a/img', + 'this') + self.element_should_not_be_visible(selector) + + @_framed('name') + def element_should_not_be_invisible(self, name): + """ + Verifies that element is visible on the page. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Element Should Not Be Invisible | Dashboard . Post Publish button | + """ + selector = self.wait_for_element_found(name, + 'button/input/a/img', + 'this') + self.element_should_be_visible(selector) + + @_framed('name') + def get_element_text(self, name): + """ + Gets text of given element. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - text of element. + + *Examples:* + | ${text} | Get Element Text | Main header | + """ + selector = self.wait_for_element_found(name, + 'button/input/a/img', + 'this') + text = self.get_text(selector) + + return text + + @_framed('name') + def get_attribute_of_element(self, name, attribute): + """ + Gets attribute of given element. + + *Arguments:* + - name: selector title taken from object repository. + - attribute: attribute that would be taken. + + *Return:* + - text of element attribute. + + *Examples:* + | ${id_text} | Get Attribute Of Element | Main header | id | + """ + selector = self.wait_for_element_found(name, + 'button/input/a/img', + 'this') + attr_selector = '%s@%s' % (selector, attribute) + attr_text = self.get_element_attribute(attr_selector) + + return attr_text diff --git a/boffin/build/lib/Boffin/keywords/__init__.py b/boffin/build/lib/Boffin/keywords/__init__.py new file mode 100644 index 0000000..b781ab7 --- /dev/null +++ b/boffin/build/lib/Boffin/keywords/__init__.py @@ -0,0 +1,23 @@ +# Copyright (c) 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. + +from _WebUIlib import _WebUIlib +from _Rest import _Rest +from Pydblibrary import Pydblibrary + +__all__ = [ + '_WebUIlib', + '_Rest', + 'Pydblibrary' +] diff --git a/boffin/build/lib/Boffin/version.py b/boffin/build/lib/Boffin/version.py new file mode 100644 index 0000000..72a783a --- /dev/null +++ b/boffin/build/lib/Boffin/version.py @@ -0,0 +1 @@ +VERSION = '1.0rc3' diff --git a/boffin/dist/robotframework_boffin-1.0rc3-py2.7.egg b/boffin/dist/robotframework_boffin-1.0rc3-py2.7.egg new file mode 100644 index 0000000..3bee454 Binary files /dev/null and b/boffin/dist/robotframework_boffin-1.0rc3-py2.7.egg differ diff --git a/boffin/make_virtual_displays.pp b/boffin/make_virtual_displays.pp new file mode 100644 index 0000000..e46a855 --- /dev/null +++ b/boffin/make_virtual_displays.pp @@ -0,0 +1,51 @@ +package { ['xvfb', + 'x11-xkb-utils', + 'xfonts-100dpi', + 'xfonts-75dpi', + 'xfonts-scalable', + 'xfonts-cyrillic', + 'xserver-xorg-core']: + ensure => latest, +} +exec {'Create new virtual desktop1': + require => [ Package['xvfb'], + Package['x11-xkb-utils'], + Package['xfonts-100dpi'], + Package['xfonts-75dpi'], + Package['xfonts-scalable'], + Package['xfonts-cyrillic'], + Package['xserver-xorg-core'] ], + command => 'Xvfb -fp /usr/share/fonts/X11/misc/ :20 + -screen 0 1024x768x16 2>&1; echo "ok"', + user => 'root', + provider => shell, + path => '/usr/bin', +} +exec {'Create new virtual desktop2': + require => [ Package['xvfb'], + Package['x11-xkb-utils'], + Package['xfonts-100dpi'], + Package['xfonts-75dpi'], + Package['xfonts-scalable'], + Package['xfonts-cyrillic'], + Package['xserver-xorg-core'] ], + command => 'Xvfb -fp /usr/share/fonts/X11/misc/ :21 + -screen 1 1024x768x16 2>&1; echo "ok"', + user => 'root', + provider => shell, + path => '/usr/bin', +} +exec {'Create new virtual desktop3': + require => [ Package['xvfb'], + Package['x11-xkb-utils'], + Package['xfonts-100dpi'], + Package['xfonts-75dpi'], + Package['xfonts-scalable'], + Package['xfonts-cyrillic'], + Package['xserver-xorg-core'] ], + command => 'Xvfb -fp /usr/share/fonts/X11/misc/ :22 + -screen 2 1024x768x16 2>&1; echo "ok"', + user => 'root', + provider => shell, + path => '/usr/bin', +} diff --git a/boffin/run_concurrently.py b/boffin/run_concurrently.py new file mode 100644 index 0000000..9b30a75 --- /dev/null +++ b/boffin/run_concurrently.py @@ -0,0 +1,171 @@ +# Copyright (c) 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. + +# Please, install python and puppet before run this script. +# Also, please, do not forget to install the following packages for tests: +# robotframework, robotframework-selenium2library, BeautifulSoup4 + +from subprocess import Popen +from argparse import ArgumentParser +from time import sleep +from os import listdir +from os.path import join, split + + +def wait_for_finished(threads): + """ + Wait until threads finish. + """ + for ind, t in enumerate(threads): + if t.poll() is not None: + threads.pop(ind) + sleep(1) + + +s = "This script allows to run Robot Framework tests concurrently." +parser = ArgumentParser(description=s) + +parser.add_argument("-n", action="store", dest="processes_count", + default=1, type=int, + help="The number of parallel threads (1 by default).") + +req_group = parser.add_mutually_exclusive_group(required=True) + +req_group.add_argument('-s', action='store', dest='script_name', + default=None, type=str, + help='The name of file with tests or name pattern.') + +req_group.add_argument('-l', action='store', dest='scripts_list', + default=None, nargs='*', + help='Names of test files separated by spaces.') + +req_group.add_argument('-d', action='store', dest='tests_dir', + default=None, type=str, + help='The name of directory with tests to be executed.') + +parser.add_argument("-t", action="store", dest="tags_list", + default=None, nargs='*', + help="Test tags separated by spaces. Should be specified " + "with SCRIPT_NAME argument.") + +parser.add_argument('-R', action='store', dest='resources_dir', + default=None, type=str, + help='The resources directory path (e.g. ' + 'samples/mirantis.com/resources/).') + +parser.add_argument('-r', action='store', dest='reports_dir', + default="reports", type=str, + help='The directory name with reports ' + '("reports" directory by default).') + +args = parser.parse_args() + + +# Generate puppet manifest: +content = """package { ['xvfb', + 'x11-xkb-utils', + 'xfonts-100dpi', + 'xfonts-75dpi', + 'xfonts-scalable', + 'xfonts-cyrillic', + 'xserver-xorg-core']: + ensure => latest, +}\n""" +for i in xrange(args.processes_count): + content += """exec {'Create new virtual desktop%s': + require => [ Package['xvfb'], + Package['x11-xkb-utils'], + Package['xfonts-100dpi'], + Package['xfonts-75dpi'], + Package['xfonts-scalable'], + Package['xfonts-cyrillic'], + Package['xserver-xorg-core'] ], + command => 'Xvfb -fp /usr/share/fonts/X11/misc/ :2%s + -screen %s 1024x768x16 2>&1; echo "ok"', + user => 'root', + provider => shell, + path => '/usr/bin', +}\n""" % (i + 1, i, i) + +f = open('make_virtual_displays.pp', 'w') +f.write(content) +f.close() + +# Deploy puppet manifest to create a few virtual displays: +cmd = 'sudo puppet apply make_virtual_displays.pp' +make_displays = Popen(cmd, shell=True) + +print "Start to make a new virtual displays" +while make_displays.poll() is None: + sleep(1) + +if make_displays.poll() == 0: + print "Virtual Displays are ready." +else: + print "Can not create virtual displays: error code: " +\ + str(make_displays.poll()) + exit(1) + + +# Generate the command for executing tests. +cmd = "export DISPLAY=:%s; pybot -C off -K off -r %s.report.html " \ + "-l %s.log.html -o %s.output.xml -d " + args.reports_dir + " " +if args.resources_dir: + cmd += " -v resources_path:" + args.resources_dir + " " + + +# Start all threads with tests. +if args.tags_list and args.script_name: + cmd += " -i %s " + args.script_name + " 2>/dev/null" + # Start all threads with tests and ignore empty threads. + threads = [] + for i, tag in enumerate(args.tags_list): + f_name = args.script_name.split('.')[0] + values = ("2%s" % i, f_name, f_name, f_name, tag) + print "Execute command:\n", cmd % values + threads.append(Popen(cmd % values, shell=True)) + while len(threads) == args.processes_count: + wait_for_finished(threads) + sleep(1) + +else: + if args.tests_dir: + files = listdir(args.tests_dir) + files = filter(lambda x: x.endswith('.txt'), files) + txt_scripts = [join(args.tests_dir, s) for s in files] + elif args.scripts_list: + txt_scripts = args.scripts_list + elif args.script_name: + txt_scripts = [args.script_name] + + cmd += "%s" # script name + threads = [] + for i, s in enumerate(txt_scripts): + # values for string formatting: + _, f = split(s) + f_name = f.split('.')[0] + values = ("2%s" % i, f_name, f_name, f_name, s) + # add thread + print "Execute command:\n", cmd % values + threads.append(Popen(cmd % values, shell=True)) + while len(threads) == args.processes_count: + wait_for_finished(threads) + sleep(1) + + +# Wait for all threads finish. +while len(threads) > 0: + wait_for_finished(threads) +print "\nFinished." +exit(0) diff --git a/boffin/samples/Murano/Resources/objrepo/common.ini b/boffin/samples/Murano/Resources/objrepo/common.ini new file mode 100644 index 0000000..f48f3c4 --- /dev/null +++ b/boffin/samples/Murano/Resources/objrepo/common.ini @@ -0,0 +1,8 @@ +[DEFAULT] +type=identifier +frame= +parent= + +[newenvironmentname] +type=id +identificator=id_name \ No newline at end of file diff --git a/boffin/samples/Murano/sanity_checks.txt b/boffin/samples/Murano/sanity_checks.txt new file mode 100644 index 0000000..bd4b73e --- /dev/null +++ b/boffin/samples/Murano/sanity_checks.txt @@ -0,0 +1,653 @@ +*** Settings *** +Suite Setup Open Browser http://172.18.79.83/horizon +Suite Teardown Close All Browsers +Library String +Library Boffin.WebUIlib 20 10 + +*** Variables *** +${resources_path} /home/user/murano-tests/WebUI/Resources/ + +*** Test Cases *** +Check Environments Tab + [Tags] thread1 work + Log in WebUI by admin/swordfish + Page should contain element "Environments" + Log out + +Create environment + [Tags] thread1 work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env" for field Environment Name + User click on Create + Page should contain element "env" + Log out + +Edit environment + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env1" for field Environment Name + User click on Create + User click on "More" for element "env1" + User click on "Edit Environment" for element "env1" + User set value "edited_env" for field New Environment Name + User click on Save + Page should contain element "edited_env" + Log out + +Delete Environment + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env2" for field Environment Name + User click on Create + User click on "More" for element "env2" + User click on "Delete Environment" for element "env2" + User confirms deletion + Page should not contain element "env2" + Log out + +Create AD Service + [Tags] work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_one_ad" for field Environment Name + User click on Create + User click on env_with_one_ad + User click on Create Service + User select "Active Directory" from dropdown list "Service Type" + User click on Next + User set value "ad.nastya" for field Domain Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field Recovery password + User set value "P@ssw0rd" for field Confirm password AD + User set value "ad" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "ad.nastya" + Log out + +Create IIS service + [Tags] thread1 work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_one_iis" for field Environment Name + User click on Create + User click on env_with_one_iis + User click on Create Service + User select "Internet Information Service" from dropdown list "Service Type" + User click on Next + User set value "iis-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iis" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "iis-service" + Log out + +Create ASP.Net App + [Tags] work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_one_asp" for field Environment Name + User click on Create + User click on env_with_one_asp + User click on Create Service + User select "ASP.NET Application" from dropdown list "Service Type" + User click on Next + User set value "asp-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "git://github.com/Mirantis/murano-mvc-demo.git" for field Git repository + User set value "asp" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "asp-service" + Log out + +Create IIS Farm + [Tags] work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_iis_farm" for field Environment Name + User click on Create + User click on env_with_iis_farm + User click on Create Service + User select "Internet Information Service Web Farm" from dropdown list "Service Type" + User click on Next + User set value "iis_farm" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iisfarm#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "iis_farm" + Log out + +Create ASP.NET Farm + [Tags] work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_asp_farm" for field Environment Name + User click on Create + User click on env_with_asp_farm + User click on Create Service + User select "ASP.NET Application Web Farm" from dropdown list "Service Type" + User click on Next + User set value "asp-farm" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "git://github.com/Mirantis/murano-mvc-demo.git" for field Git repository + User set value "aspfarm#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "asp-farm" + Log out + +Create MS SQL Server + [Tags] work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_one_mssql" for field Environment Name + User click on Create + User click on env_with_one_mssql + User click on Create Service + User select "MS SQL Server" from dropdown list "Service Type" + User click on Next + User set value "ms_sql" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field SA password + User set value "P@ssw0rd" for field Confirm password SQL + User set value "sql" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "ms_sql" + Log out + +Create MS SQL Cluster + [Tags] work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_sqlcluster" for field Environment Name + User click on Create + User click on env_with_sqlcluster + User click on Create Service + User create Active Directory ad.mssql + Page should contain element "ad.mssql" + User click on Create Service + User select "MS SQL Cluster Server" from dropdown list "Service Type" + User click on Next + User set value "sql_cluster" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User select "ad.mssql" from dropdown list "Active Directory Domain" + User set value "P@ssw0rd" for field SA password + User set value "P@ssw0rd" for field Confirm password cluster + User set value "sqlcluster#" for field Hostname template + User click on Next + User set value "10.200.0.88" for field Cluster Static IP + User set value "cluster" for field Cluster Name + User set value "AG_name" for field Availability Group Name + User set value "AG_listener_name" for field Availability Group Listener Name + User set value "10.200.0.89" for field Availability Group Listener IP + User set value "user" for field SQL User Name + User set value "P@ssw0rd" for field SQL User Password + User set value "P@ssw0rd" for field Confirm Password + User click on Next + User set value "testbase" for field Database list + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Sleep 3s + Page should contain element "sql_cluster" + Log out + +Delete AD service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "delete_ad" for field Environment Name + User click on Create + User click on delete_ad + User click on Create Service + User select "Active Directory" from dropdown list "Service Type" + User click on Next + User set value "ad.nastya" for field Domain Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field Recovery password + User set value "P@ssw0rd" for field Confirm password AD + User set value "ad" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + User click on Delete Service + User confirms deletion + Page should not contain element "ad.nastya" + Log out + +Delete IIS service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "delete_iis" for field Environment Name + User click on Create + User click on delete_iis + User click on Create Service + User select "Internet Information Service" from dropdown list "Service Type" + User click on Next + User set value "iis_service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iis" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + User click on Delete Service + User confirms deletion + Page should not contain element "iis_service" + Log out + +Delete ASP.NET service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "delete_asp" for field Environment Name + User click on Create + User click on delete_asp + User click on Create Service + User select "ASP.NET Application" from dropdown list "Service Type" + User click on Next + User set value "asp-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "git://github.com/Mirantis/murano-mvc-demo.git" for field Git repository + User set value "asp" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + User click on Delete Service + User confirms deletion + Page should not contain element "asp-service" + Log out + +Delete IIS Farm service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "delete_iis_farm" for field Environment Name + User click on Create + User click on delete_iis_farm + User click on Create Service + User select "Internet Information Service Web Farm" from dropdown list "Service Type" + User click on Next + User set value "iis_farm" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iisfarm#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + User click on iis_farm + User confirms deletion + Page should not contain element "iis_farm" + Log out + +Delete ASP.NET Farm service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "delete_asp_farm" for field Environment Name + User click on Create + User click on delete_asp_farm + User click on Create Service + User select "ASP.NET Application Web Farm" from dropdown list "Service Type" + User click on Next + User set value "asp-farm" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "git://github.com/Mirantis/murano-mvc-demo.git" for field Git repository + User set value "aspfarm#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + User click on Delete Service + User confirms deletion + Page should not contain element "asp-farm" + Log out + +Delete MS SQL server + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "delete_mssql" for field Environment Name + User click on Create + User click on delete_mssql + User click on Create Service + User select "MS SQL Server" from dropdown list "Service Type" + User click on Next + User set value "ms_sql" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field SA password + User set value "P@ssw0rd" for field Confirm password SQL + User set value "sql" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + User click on Delete Service + User confirms deletion + Page should not contain element "ms_sql" + Log out + +Check opportunity to choose availability zone + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_av_zone" for field Environment Name + User click on Create + User click on env_av_zone + User click on Create Service + User select "Internet Information Service" from dropdown list "Service Type" + User click on Next + User set value "iis-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iis" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User select "nova" from dropdown list "Availability zone" + Log out + +Check opportunity to choose Instance Flavor + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_inst_flavor" for field Environment Name + User click on Create + User click on env_inst_flavor + User click on Create Service + User select "Internet Information Service" from dropdown list "Service Type" + User click on Next + User set value "iis-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iis" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User select "m1.small" from dropdown list "Instance flavor" + User select "m1.large" from dropdown list "Instance flavor" + User select "m1.medium" from dropdown list "Instance flavor" + Log out + +Check opportunity to choose Instance Image + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_inst_image" for field Environment Name + User click on Create + User click on env_inst_image + User click on Create Service + User select "Internet Information Service" from dropdown list "Service Type" + User click on Next + User set value "iis-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iis" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User select "Windows Server 2012 x64 core Standard edition" from dropdown list "Instance image" + User select "Windows Server 2008 R2 x64 Standard edition" from dropdown list "Instance image" + Log out + +Deploy environment with AD Service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_one_ad" for field Environment Name + User click on Create + User click on deploy_one_ad + User click on Create Service + User select "Active Directory" from dropdown list "Service Type" + User click on Next + User set value "ad.nastya" for field Domain Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field Recovery password + User set value "P@ssw0rd" for field Confirm password AD + User set value "ad" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "ad.nastya" + User click on Deploy This Environment + Check the status of environment "deploy_one_ad" (should be "Ready") + Log out + +Deploy environment with IIS Service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_iis" for field Environment Name + User click on Create + User click on deploy_iis + User click on Create Service + User select "Internet Information Service" from dropdown list "Service Type" + User click on Next + User set value "iis-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iis" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "iis-service" + User click on Deploy This Environment + Check the status of environment "deploy_iis" (should be "Ready") + Log out + +Deploy environment with ASP.NET Service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_asp" for field Environment Name + User click on Create + User click on deploy_asp + User click on Create Service + User select "ASP.NET Application" from dropdown list "Service Type" + User click on Next + User set value "asp-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "git://github.com/Mirantis/murano-mvc-demo.git" for field Git repository + User set value "asp" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "asp-service" + User click on Deploy This Environment + Check the status of environment "deploy_asp" (should be "Ready") + Log out + +Deploy environment with IIS Farm + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_iis_farm" for field Environment Name + User click on Create + User click on deploy_iis_farm + User click on Create Service + User select "Internet Information Service Web Farm" from dropdown list "Service Type" + User click on Next + User set value "iis_farm" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iisfarm#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "iis_farm" + User click on Deploy This Environment + Check the status of environment "deploy_iis_farm" (should be "Ready") + Log out + +Deploy environment with ASP.NET Farm + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_asp_farm" for field Environment Name + User click on Create + User click on deploy_asp_farm + User click on Create Service + User select "ASP.NET Application Web Farm" from dropdown list "Service Type" + User click on Next + User set value "asp-farm" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "git://github.com/Mirantis/murano-mvc-demo.git" for field Git repository + User set value "aspfarm#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "asp-farm" + User click on Deploy This Environment + Check the status of environment "deploy_asp_farm" (should be "Ready") + Log out + +Deploy environment with MS SQL server + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_mssql" for field Environment Name + User click on Create + User click on deploy_mssql + User click on Create Service + User select "MS SQL Server" from dropdown list "Service Type" + User click on Next + User set value "ms_sql" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field SA password + User set value "P@ssw0rd" for field Confirm password SQL + User set value "sql" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "ms_sql" + User click on Deploy This Environment + Check the status of environment "deploy_mssql" (should be "Ready") + Log out + +test + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "test" for field Environment Name + User click on Create + Page should contain element "test" + Check status test + +Deploy AD with 2 instances + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_ad_2_inst" for field Environment Name + User click on Create + User click on deploy_ad_2_inst + User click on Create Service + User select "Active Directory" from dropdown list "Service Type" + User click on Next + User set value "ad.nastya.two" for field Domain Name + User set value "2" for field Instance Count + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field Recovery password + User set value "P@ssw0rd" for field Confirm password AD + User set value "adtwo#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "ad.nastya.two" + User click on Deploy This Environment + Check the status of environment "deploy_ad_2_inst" (should be "Ready") + Log out + +Deploy MSSQL with 2 instances + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_mssql" for field Environment Name + User click on Create + User click on deploy_mssql + User click on Create Service + User select "MS SQL Server" from dropdown list "Service Type" + User click on Next + User set value "ms_sql" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field SA password + User set value "P@ssw0rd" for field Confirm password SQL + User set value "sql" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "ms_sql" + User click on Deploy This Environment + Check the status of environment "deploy_mssql" (should be "Ready") + Log out + +*** Keywords *** +Log in WebUI by ${user}/${password} + Fill Field User Name ${user} + Fill Field Password ${password} + Click on Sign In + Navigate to Project>Environments + +User set value "${value}" for field ${field} + Fill Field ${field} ${value} + +Select type of the service + [Arguments] ${type} + Select Item From List Service Type ${type} + Click Button Next + +Log out + Click on Sign Out + Page Should Contain Button Sign In + +Check the status of environment "${env_name}" (should be "Ready") + Wait Until Keyword Succeeds 20 minute 5s Check status ${env_name} + +Check status + [Arguments] ${env_name} + Navigate to Project>Environments + ${row} Find Associated Element ${env_name} Ready to configure + +User click on + [Arguments] ${arg} + Sleep 2s + Click on ${arg} + Sleep 2s + +Page should contain element "${element}" + Sleep 3s + Page Should Contain ${element} + +Page should not contain element "${element}" + Page Should Not Contain ${element} + +User click on "${button}" for element "${env}" + ${element} Find Associated Element ${env} ${button} + Click Element ${element} + +User select "${item}" from dropdown list "${menu}" + Select Item From List ${menu} ${item} + +User confirms deletion + ${element}= Find Associated Element Cancel Delete Environment + Click Link Delete Environment + Sleep 3s + +User create Active Directory + [Arguments] ${name} + User select "Active Directory" from dropdown list "Service Type" + User click on Next + User set value "${name}" for field Domain Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field Recovery password + User set value "P@ssw0rd" for field Confirm password AD + User set value "adforsql" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create diff --git a/boffin/samples/Murano_REST_API/REST_Tests.txt b/boffin/samples/Murano_REST_API/REST_Tests.txt new file mode 100644 index 0000000..da03252 --- /dev/null +++ b/boffin/samples/Murano_REST_API/REST_Tests.txt @@ -0,0 +1,491 @@ +*** Settings *** +Library Collections +Resource libs/MuranoRest.txt + +*** Variables *** +${ip} 172.18.124.201 +${ip_keystone} 172.18.124.201 +${user} muranorestapi +${password} swordfish + +*** Test Cases *** +Begin of testing + [Tags] thread1 + Get X-Auth-Token ${ip_keystone} + Get Headers + +Clearing + [Tags] thread1 + #Delete All Environments # закоментировано так, на всякий случай..... + ${result} Get List Of Environments + #Should Be Empty ${result['environments']} + +Get list of environments + [Tags] thread1 + ${result} Get List Of Environments + ${list} Format List ${result['environments']} + Log List ${list} + +Create environment + [Tags] thread1 + Create Environment test-rest-api-env2 + +Create/edit/delete environment + [Tags] thread1 + ${result} Get List Of Environments + ${len} Get Length ${result['environments']} + ${list} Format List ${result['environments']} + Log List ${list} + Create Environment env_2_del + ${result} Get List Of Environments + ${len1} Get Length ${result['environments']} + ${len1} = Evaluate ${len1} - 1 + Should Be Equal As Integers ${len} ${len1} + ${list} Format List ${result['environments']} + Log List ${list} + ${env_id} Get Environment ID env_2_modify + Should Be Equal ${env_id} None + Update Environment env_2_del env_2_modify + ${result} Get List Of Environments + ${list} Format List ${result['environments']} + Log List ${list} + ${env_id} Get Environment ID env_2_modify + Should Not Be Equal ${env_id} None + Delete Environment env_2_modify + ${result} Get List Of Environments + ${len2} Get Length ${result['environments']} + #Should Be Equal As Integers ${len} ${len2} + ${list} Format List ${result['environments']} + Log List ${list} + +Get Environment_ID of previosly created environment + [Tags] thread1 + ${result} Get Environment ID test-rest-api-env2 + Should Not Be Empty ${result} + +Create session to previosly created environment + [Tags] thread1 + ${result} Create session test-rest-api-env2 + Set Global Variable ${session_id} ${result['id']} + #${session_id} Set Variable ${result['id']} + Should Not Be Empty ${result['id']} + +Get session information_1 + [Tags] thread1 + Log ${session_id} + ${result} Get session information test-rest-api-env2 ${session_id} + +Delete session + [Tags] thread1 + ${result} Delete session test-rest-api-env2 ${session_id} + +Get session information_2 and almost empty report + [Tags] thread1 + ${result} Create session test-rest-api-env2 + Set Global Variable ${session_id} ${result['id']} + ${result} Get session information test-rest-api-env2 ${session_id} + ${result} Get session reports test-rest-api-env2 ${session_id} + +Create AD service + [Tags] thread1 + Create AD test-rest-api-env2 ad001 + +List AD services + [Tags] thread1 + ${result} Get List of AD test-rest-api-env2 + ${list} Format List ${result['activeDirectories']} + Log List ${list} + ${len} Get Length ${result['activeDirectories']} + Should Be Equal as Integers 1 ${len} + +Delete AD service + [Tags] thread1 + Delete AD test-rest-api-env2 ad001 + ${result} Get List of AD test-rest-api-env2 + ${len} Get Length ${result['activeDirectories']} + Should Be Equal as Integers ${len} 0 + +Create IIS service + [Tags] thread1 + Create IIS test-rest-api-env2 iis001 + +List IIS services + [Tags] thread1 + ${result} Get List of IIS test-rest-api-env2 + ${list} Format List ${result['webServers']} + Log List ${list} + ${len} Get Length ${result['webServers']} + Should Be Equal as Integers 1 ${len} + +Delete IIS service + [Tags] thread1 + Delete IIS test-rest-api-env2 iis001 + ${result} Get List of IIS test-rest-api-env2 + ${len} Get Length ${result['webServers']} + Should Be Equal as Integers ${len} 0 + +Create ASP NET service + [Tags] thread1 + Create ASP NET test-rest-api-env2 asp001 + +List ASP NET services + [Tags] thread1 + ${result} Get List of ASP NET test-rest-api-env2 + ${list} Format List ${result['aspNetApps']} + Log List ${list} + ${len} Get Length ${result['aspNetApps']} + Should Be Equal as Integers 1 ${len} + +Delete ASP NET service + [Tags] thread1 + Delete ASP NET test-rest-api-env2 asp001 + ${result} Get List of ASP NET test-rest-api-env2 + ${len} Get Length ${result['aspNetApps']} + Should Be Equal as Integers ${len} 0 + +Create ASP NET Farm service + [Tags] thread1 + Create ASP NET Farm test-rest-api-env2 aspFarm001 + +List ASP NET Farm services + [Tags] thread1 + ${result} Get List of ASP NET Farm test-rest-api-env2 + ${list} Format List ${result['aspNetAppFarms']} + Log List ${list} + ${len} Get Length ${result['aspNetAppFarms']} + Should Be Equal as Integers 1 ${len} + +Delete ASP NET Farm service + [Tags] thread1 + Delete ASP NET Farm test-rest-api-env2 aspFarm001 + ${result} Get List of ASP NET Farm test-rest-api-env2 + ${len} Get Length ${result['aspNetAppFarms']} + Should Be Equal as Integers ${len} 0 + +Create IIS Farm service + [Tags] thread1 + Create IIS Farm test-rest-api-env2 iisFarm001 + +List IIS Farm services + [Tags] thread1 + ${result} Get List of IIS Farm test-rest-api-env2 + ${list} Format List ${result['webServerFarms']} + Log List ${list} + ${len} Get Length ${result['webServerFarms']} + Should Be Equal as Integers 1 ${len} + +Delete IIS Farm service + [Tags] thread1 + Delete IIS Farm test-rest-api-env2 iisFarm001 + ${result} Get List of IIS Farm test-rest-api-env2 + ${len} Get Length ${result['webServerFarms']} + Should Be Equal as Integers ${len} 0 + +Create some services + [Tags] thread1 + Create AD test-rest-api-env2 ad001 + Create AD test-rest-api-env2 ad002 + Create AD test-rest-api-env2 ad005 + Create ASP NET test-rest-api-env2 asp005 + Create ASP NET test-rest-api-env2 asp005 + Create IIS Farm test-rest-api-env2 iisFarm002 + Create ASP NET test-rest-api-env2 asp006 + Create ASP NET Farm test-rest-api-env2 aspFarm005 + Create ASP NET Farm test-rest-api-env2 aspfarm005 + Create IIS test-rest-api-env2 iis003 + Create IIS Farm test-rest-api-env2 iisFarm003 + Create IIS test-rest-api-env2 iis001 + Create IIS test-rest-api-env2 iis_001 + Create IIS test-rest-api-env2 iis001 + Create IIS test-rest-api-env2 iis002 + Create AD test-rest-api-env2 ad001 + Create IIS Farm test-rest-api-env2 iisFarm002 + Create IIS Farm test-rest-api-env2 iisFarm004 + Create IIS Farm test-rest-api-env2 iisFarm005 + Create IIS Farm test-rest-api-env2 iisFarm006 + # View all services + ${list} Get List of All Services test-rest-api-env2 + Log List ${list} + # Check number of ADs + ${result} Get List of AD test-rest-api-env2 + ${list} Format List ${result['activeDirectories']} + Log List ${list} + ${len} Get Length ${result['activeDirectories']} + Should Be Equal as Integers 4 ${len} + # Check number of IISs + ${result} Get List of IIS test-rest-api-env2 + ${list} Format List ${result['webServers']} + Log List ${list} + ${len} Get Length ${result['webServers']} + Should Be Equal as Integers 5 ${len} + # Check number of ASP NETs + ${result} Get List of ASP NET test-rest-api-env2 + ${list} Format List ${result['aspNetApps']} + Log List ${list} + ${len} Get Length ${result['aspNetApps']} + Should Be Equal as Integers 3 ${len} + # Check number of IIS Farms + ${result} Get List of IIS Farm test-rest-api-env2 + ${list} Format List ${result['webServerFarms']} + Log List ${list} + ${len} Get Length ${result['webServerFarms']} + Should Be Equal as Integers 6 ${len} + # Check number of ASP NET Farms + ${result} Get List of ASP NET Farm test-rest-api-env2 + ${list} Format List ${result['aspNetAppFarms']} + Log List ${list} + ${len} Get Length ${result['aspNetAppFarms']} + Should Be Equal as Integers 2 ${len} + +Test of multisession + [Tags] thread1 + # Store session + ${session1_1} Set Variable ${session_id} + # Create additional sessions + ${result} Create session test-rest-api-env2 + ${session1_2} Set Variable ${result['id']} + ${result} Create session test-rest-api-env2 + ${session1_3} Set Variable ${result['id']} + # Stage 1: Begin of create some services =================== + Update Headers X-Configuration-Session ${session1_1} + Create AD test-rest-api-env2 ad001 + Create AD test-rest-api-env2 ad002 + Create ASP NET test-rest-api-env2 asp005 + Create ASP NET test-rest-api-env2 asp005 + Create IIS Farm test-rest-api-env2 iisFarm002 + Create ASP NET test-rest-api-env2 asp006 + Create ASP NET Farm test-rest-api-env2 aspFarm005 + Create ASP NET Farm test-rest-api-env2 aspfarm005 + Create IIS test-rest-api-env2 iis003 + # View all services + ${list} Get List of All Services test-rest-api-env2 + Log List ${list} + Update Headers X-Configuration-Session ${session1_2} + Create AD test-rest-api-env2 ad001 + Create ASP NET test-rest-api-env2 asp005 + Create ASP NET test-rest-api-env2 asp005 + Create IIS Farm test-rest-api-env2 iisFarm002 + Create ASP NET test-rest-api-env2 asp006 + # View all services + ${list} Get List of All Services test-rest-api-env2 + Log List ${list} + Update Headers X-Configuration-Session ${session1_3} + Create ASP NET test-rest-api-env2 asp005_3 + Create ASP NET test-rest-api-env2 asp005_3 + Create IIS Farm test-rest-api-env2 iisFarm002_3 + Create ASP NET test-rest-api-env2 asp006_3 + Create ASP NET Farm test-rest-api-env2 aspFarm005_3 + Create ASP NET Farm test-rest-api-env2 aspfarm005_3 + Create IIS test-rest-api-env2 iis003_3 + Create IIS Farm test-rest-api-env2 iisFarm003_3 + Create IIS test-rest-api-env2 iis001_3 + Create IIS test-rest-api-env2 iis_001_3 + Create IIS test-rest-api-env2 iis001_3 + Create IIS test-rest-api-env2 iis002_3 + Create IIS Farm test-rest-api-env2 iisFarm002_3 + Create IIS Farm test-rest-api-env2 iisFarm004_3 + # View all services + ${list} Get List of All Services test-rest-api-env2 + Log List ${list} + # Stage 2: End of create some services =================== + Update Headers X-Configuration-Session ${session1_1} + Create IIS Farm test-rest-api-env2 iisFarm003 + Create IIS test-rest-api-env2 iis001 + Create IIS test-rest-api-env2 iis002 + Create AD test-rest-api-env2 ad001 + Create IIS Farm test-rest-api-env2 iisFarm002 + Create IIS Farm test-rest-api-env2 iisFarm004 + Create IIS Farm test-rest-api-env2 iisFarm005 + Create IIS Farm test-rest-api-env2 iisFarm006 + # View all services + ${list} Get List of All Services test-rest-api-env2 + Log List ${list} + Update Headers X-Configuration-Session ${session1_2} + Create ASP NET Farm test-rest-api-env2 aspFarm005 + Create ASP NET Farm test-rest-api-env2 aspfarm005 + Create IIS test-rest-api-env2 iis003 + Create IIS Farm test-rest-api-env2 iisFarm003 + Create IIS test-rest-api-env2 iis001 + Create IIS test-rest-api-env2 iis_001 + Create IIS test-rest-api-env2 iis002 + Create AD test-rest-api-env2 ad001 + Create IIS Farm test-rest-api-env2 iisFarm002 + Create IIS Farm test-rest-api-env2 iisFarm005 + Create IIS Farm test-rest-api-env2 iisFarm006 + # View all services + ${list} Get List of All Services test-rest-api-env2 + Log List ${list} + Update Headers X-Configuration-Session ${session1_3} + Create AD test-rest-api-env2 ad001_3 + Create IIS Farm test-rest-api-env2 iisFarm005_3 + Create IIS Farm test-rest-api-env2 iisFarm006_3 + # === View services in all sessions === + Update Headers X-Configuration-Session ${session1_1} + # View all services + ${list} Get List of All Services test-rest-api-env2 + Log List ${list} + Update Headers X-Configuration-Session ${session1_2} + # View all services + ${list} Get List of All Services test-rest-api-env2 + Log List ${list} + Update Headers X-Configuration-Session ${session1_3} + # View all services + ${list} Get List of All Services test-rest-api-env2 + Log List ${list} + # Need control of number created services + # Stage 3: delete some services =================== + Delete IIS test-rest-api-env2 iis_001_3 + Delete IIS test-rest-api-env2 iis002_3 + Delete IIS Farm test-rest-api-env2 iisFarm006_3 + Delete ASP NET Farm test-rest-api-env2 aspfarm005_3 + Delete AD test-rest-api-env2 ad001_3 + # View all services + ${list} Get List of All Services test-rest-api-env2 + Log List ${list} + Update Headers X-Configuration-Session ${session1_2} + Delete IIS test-rest-api-env2 iis_001 + Delete IIS test-rest-api-env2 iis002 + Delete AD test-rest-api-env2 ad001 + Delete IIS Farm test-rest-api-env2 iisFarm006 + # View all services + ${list} Get List of All Services test-rest-api-env2 + Log List ${list} + Update Headers X-Configuration-Session ${session1_1} + Delete AD test-rest-api-env2 ad001 + Delete AD test-rest-api-env2 ad002 + #Delete ASP NET test-rest-api-env2 asp005 + #Delete ASP NET test-rest-api-env2 asp005 + #Delete IIS Farm test-rest-api-env2 iisFarm002 + Delete ASP NET test-rest-api-env2 asp006 + #Delete ASP NET Farm test-rest-api-env2 aspFarm005 + Delete ASP NET Farm test-rest-api-env2 aspfarm005 + Delete IIS test-rest-api-env2 iis003 + #Delete IIS Farm test-rest-api-env2 iisFarm003 + Delete IIS test-rest-api-env2 iis001 + Delete IIS test-rest-api-env2 iis002 + Delete AD test-rest-api-env2 ad001 + #Delete IIS Farm test-rest-api-env2 iisFarm002 + #Delete IIS Farm test-rest-api-env2 iisFarm004 + #Delete IIS Farm test-rest-api-env2 iisFarm005 + # Create IIS Farm test-rest-api-env2 iisFarm006 - must be only this + # View all services + ${list} Get List of All Services test-rest-api-env2 + Log List ${list} + # View all services + ${list} Get List of All Services test-rest-api-env2 + Log List ${list} + Update Headers X-Configuration-Session ${session1_1} + +Deploy one AD + Create environment 4kate-ad + ${result} Create session 4kate-ad + Set Global Variable ${session_id} ${result['id']} + Create AD 4kate-ad AD_2_deploy + Deploy session 4kate-ad ${session_id} + ${rep} Get session reports 4kate-ad ${session_id} + Wait Until Keyword Succeeds 20m 5s Check Environment 4kate-ad ready + Get Environment ID 4kate-ad + ${rep2} Get session reports 4kate-ad ${session_id} + ${rep3} Format session report ${rep2} + Log List ${rep3} + # Delete environment bigden-ad + +Deploy one IIS + Create environment bigden-iis + ${result} Create session bigden-iis + Set Global Variable ${session_id} ${result['id']} + Create IIS bigden-iis IIS_2_deploy + Deploy session bigden-iis ${session_id} + ${rep} Get session reports bigden-iis ${session_id} + Wait Until Keyword Succeeds 20m 5s Check Environment bigden-iis ready + Get Environment ID bigden-iis + ${rep2} Get session reports bigden-iis ${session_id} + ${rep3} Format session report ${rep2} + Log List ${rep3} + Delete environment bigden-iis + +Deploy one ASP.NET + Create environment bigden-asp + ${result} Create session bigden-asp + Set Global Variable ${session_id} ${result['id']} + Create ASP NET bigden-asp ASP_2_deploy + Deploy session bigden-asp ${session_id} + ${rep} Get session reports bigden-asp ${session_id} + Wait Until Keyword Succeeds 20m 5s Check Environment bigden-asp ready + Get Environment ID bigden-asp + ${rep2} Get session reports bigden-asp ${session_id} + ${rep3} Format session report ${rep2} + Log List ${rep3} + Delete environment bigden-asp + +Deploy one ASP.NET Farm + Create environment bigden-asp-farm + ${result} Create session bigden-asp-farm + Set Global Variable ${session_id} ${result['id']} + Create ASP NET Farm + ASP-Farm_2_deploy + Deploy session bigden-asp-farm ${session_id} + ${rep} Get session reports bigden-asp-farm ${session_id} + Wait Until Keyword Succeeds 20m 5s Check Environment bigden-asp-farm ready + Get Environment ID bigden-asp-farm + ${rep2} Get session reports bigden-asp-farm ${session_id} + ${rep3} Format session report ${rep2} + Log List ${rep3} + Delete environment bigden-asp-farm + +Deploy one IIS Farm + Create environment bigden-iis-farm + ${result} Create session bigden-iis-farm + Set Global Variable ${session_id} ${result['id']} + Create IIS Farm bigden-iis-farm IIS-Farm_2_deploy + Deploy session bigden-iis-farm ${session_id} + ${rep} Get session reports bigden-iis-farm ${session_id} + Wait Until Keyword Succeeds 20m 5s Check Environment bigden-iis-farm ready + Get Environment ID bigden-iis-farm + ${rep2} Get session reports bigden-iis-farm ${session_id} + ${rep3} Format session report ${rep2} + Log List ${rep3} + Delete environment bigden-iis-farm + +Sequence deploy + Create environment bigden-all_service + ${result} Create session bigden-all_service + Set Global Variable ${session_id} ${result['id']} + Create AD bigden-all_service AD_2_deploy + Create IIS bigden-all_service IIS_2_deploy + Create ASP NET bigden-all_service ASP.NET_2_deploy + Create ASP NET Farm bigden-all_service ASP.NET_Farm_2_deploy + Create IIS Farm bigden-all_service IIS_Farm_2_deploy + Deploy session bigden-all_service ${session_id} + ${rep} Get session reports bigden-all_service ${session_id} + Wait Until Keyword Succeeds 60m 10s Check Environment bigden-all_service ready + Get Environment ID bigden-all_service + ${rep2} Get session reports bigden-all_service ${session_id} + ${rep3} Format session report ${rep2} + Log List ${rep3} + Delete environment bigden-all_service + +Delete created environments + [Tags] thread1 + Delete Environment test-rest-api-env2 + +Delete session after deploy + Create environment bigden-ad + ${result} Create session bigden-ad + Set Global Variable ${session_id} ${result['id']} + Create IIS bigden-ad IIS_2_deploy + Deploy session bigden-ad ${session_id} + ${rep} Get session reports bigden-ad ${session_id} + Wait Until Keyword Succeeds 60m 20s Check Environment bigden-ad ready + Get Environment ID bigden-ad + ${rep2} Get session reports bigden-ad ${session_id} + ${rep3} Format session report ${rep2} + Log List ${rep3} + Try to delete session bigden-ad ${session_id} + Delete environment bigden-ad + Try to delete session bigden-ad ${session_id} + +*** Keywords *** +Compare reports + [Arguments] ${rep_2_compare} ${ASP_Farm_name} + ${rep2} Get session reports test-rest-api-env2 ${session_id} + Should Not Be Equal ${rep} ${rep2} diff --git a/boffin/samples/Murano_REST_API/libs/MuranoRest.txt b/boffin/samples/Murano_REST_API/libs/MuranoRest.txt new file mode 100644 index 0000000..ff6da62 --- /dev/null +++ b/boffin/samples/Murano_REST_API/libs/MuranoRest.txt @@ -0,0 +1,707 @@ +*** Settings *** +Library Boffin.Rest +Library Collections + +*** Keywords *** +Get List Of Environments + [Documentation] Gets list of all environments. + ... + ... *Arguments:* + ... - None. + ... + ... *Return:* + ... - response body with environments. + ... + ... *Examples:* + ... | ${result} | Get List Of Environments | + ... | *LOG* | ${result['environments']} | + GET request http://${ip}:8082/environments + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${result} get response body + [Return] ${result} + +Create Environment + [Arguments] ${environment_name} + [Documentation] Sends POST request to create new environment. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Create Environment | env001 | + Set body {"name":"${environment_name}"} + POST request http://${ip}:8082/environments + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${result} get response body + [Return] ${result} + +Get Environment ID + [Arguments] ${environment_name} + [Documentation] Gets environment id. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... + ... *Return:* + ... - environment id. + ... + ... *Examples:* + ... | ${id} | Get Environment ID | test | + ${environment_id} Set Variable None + ${data} Get List Of Environments + @{environments_list} Convert To List ${data['environments']} + : FOR ${x} IN @{environments_list} + \ ${environment_id} = Set Variable If "${x['name']}" == "${environment_name}" ${x['id']} ${environment_id} + [Return] ${environment_id} + +Update Environment + [Arguments] ${environment_name} ${new_environment_name} + [Documentation] Sends PUT request to update environment. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - new_environment_name: new environment name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Update Environment | env001 | env001_modify | + Set body {"name":"${new_environment_name}"} + ${env_id} Get Environment ID ${environment_name} + PUT request http://${ip}:8082/environments/${env_id} + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${result} get response body + [Return] ${result} + +Delete Environment + [Arguments] ${environment_name} + [Documentation] Sends DELETE request to delete one environment. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... + ... *Return:* + ... - None. + ... + ... *Examples:* + ... | Delete Environment | test | + ${env_id} Get Environment ID ${environment_name} + DELETE request http://${ip}:8082/environments/${env_id} + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + +Delete All Environments + [Documentation] Sends DELETE request to delete all environments. + ... + ... *Arguments:* + ... - None. + ... + ... *Return:* + ... - None. + ... + ... *Examples:* + ... | Delete All Environment | + Get X-Auth-Token ${ip} + ${result} Get List Of Environments + @{list} Convert To List ${result['environments']} + : FOR ${environment} IN @{list} + \ Delete Environment ${environment['name']} + +Get X-Auth-Token + [Arguments] ${ip} ${user}="admin" ${password}="swordfish" + [Documentation] Gets X-Auth-Token for requests headers. + ... + ... *Arguments:* + ... - ip: ip. + ... - user: user name. + ... - password: user password. + ... + ... *Return:* + ... - None. + ... + ... *Examples:* + ... | Get X-Auth-Token | 10.10.10.1 | + Set Headers {"Content-Type":"application/json"} + ${auth} Set Variable {"auth": {"tenantName": ${user}, "passwordCredentials": {"username": ${user}, "password": ${password}}}} + Set Body ${auth} + POST Request http://${ip}:5000/v2.0/tokens + ${body} Get Response Body + Update Headers X-Auth-Token ${body['access']['token']['id']} + +Format List + [Arguments] ${list_2_format} + [Documentation] Formats list in pretty view with name and id. + ... + ... *Arguments:* + ... - list_2_format: list that will be formatted. + ... + ... *Return:* + ... - None. + ... + ... *Examples:* + ... | Format List | ${id['environments']} | + ${nice_list} = Create List + @{list} Convert To List ${list_2_format} + : FOR ${x} IN @{list} + \ Append To List ${nice_list} ${x['name']}, id: ${x['id']} + Log List ${nice_list} + [Return] ${nice_list} + +Get List of All Services + [Arguments] ${environment_name} + [Documentation] Sends GET requests to list all services + ... in environment_name. Header must be filled correctly. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... + ... *Return:* + ... - formatted list of services. + ... + ... *Examples:* + ... | Get List of All Services | env001 | + ${env_id} Get Environment ID ${environment_name} + GET request http://${ip}:8082/environments/${env_id}/activeDirectories + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + ${nice_list} = Create List + @{list} Convert To List ${resp['activeDirectories']} + : FOR ${x} IN @{list} + \ Append To List ${nice_list} AD: ${x['name']}, id: ${x['id']} + GET request http://${ip}:8082/environments/${env_id}/webServers + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + @{list} Convert To List ${resp['webServers']} + : FOR ${x} IN @{list} + \ Append To List ${nice_list} IIS: ${x['name']}, id: ${x['id']} + GET request http://${ip}:8082/environments/${env_id}/aspNetApps + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + @{list} Convert To List ${resp['aspNetApps']} + : FOR ${x} IN @{list} + \ Append To List ${nice_list} ASP NET: ${x['name']}, id: ${x['id']} + GET request http://${ip}:8082/environments/${env_id}/aspNetAppFarms + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + @{list} Convert To List ${resp['aspNetAppFarms']} + : FOR ${x} IN @{list} + \ Append To List ${nice_list} ASP NET Farm: ${x['name']}, id: ${x['id']} + GET request http://${ip}:8082/environments/${env_id}/webServerFarms + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + @{list} Convert To List ${resp['webServerFarms']} + : FOR ${x} IN @{list} + \ Append To List ${nice_list} IIS Farm: ${x['name']}, id: ${x['id']} + [Return] ${nice_list} + +Check Environment + [Arguments] ${environment_name} ${status} + [Documentation] Checks environment for given status. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - status: environment status. + ... + ... *Return:* + ... - None. + ... + ... *Examples:* + ... | Check Environment | test01 | ready | + ${r2} Get session reports ${environment_name} ${session_id} + ${r3} Format session report ${r2} + Log List ${r3} + ${env_id} Get Environment ID ${environment_name} + ${environment_status} Set Variable None + ${data} Get List Of Environments + @{environments_list} Convert To List ${data['environments']} + : FOR ${x} IN @{environments_list} + \ ${environment_status} = Set Variable If "${x['name']}" == "${environment_name}" ${x['status']} ${environment_status} + Log ${environment_status} + Should Be Equal ${status} ${environment_status} + +Create Session + [Arguments] ${environment_name} + [Documentation] Sends POST request to create new session + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - status: environment status. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | ${result} | Create Session | env001 | + ${env_id} Get Environment ID ${environment_name} + POST request without body http://${ip}:8082/environments/${env_id}/configure + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + ${session_id} Set Variable ${resp['id']} + Log ${session_id} + Update Headers X-Configuration-Session ${session_id} + [Return] ${resp} + +Delete session + [Arguments] ${environment_name} ${session_id} + [Documentation] Sends DELETE request to delete session + ... with session_id in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - session_id: session id. + ... + ... *Return:* + ... - None. + ... + ... *Examples:* + ... | Delete Session | ${result['id']} | + ${env_id} Get Environment ID ${environment_name} + DELETE request http://${ip}:8082/environments/${env_id}/sessions/${session_id} + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + +Get session information + [Arguments] ${environment_name} ${session_id} + [Documentation] Sends GET request to get session information + ... with session_id in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - session_id: session id. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Get Session Information | ${result['id']} | + ${env_id} Get Environment ID ${environment_name} + GET request http://${ip}:8082/environments/${env_id}/sessions/${session_id} + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + [Return] ${resp} + +Get session reports + [Arguments] ${environment_name} ${session_id} + [Documentation] Sends GET request to get session reports + ... with session_id in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - session_id: session id. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Get Session Reports | ${result['id']} | + ${env_id} Get Environment ID ${environment_name} + GET request http://${ip}:8082/environments/${env_id}/sessions/${session_id}/reports + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + [Return] ${resp} + +Format session report + [Arguments] ${session_report} + [Documentation] Formats report to user-friendly view. + ... + ... *Arguments:* + ... - session_report: session report. + ... + ... *Return:* + ... - formatted session report. + ... + ... *Examples:* + ... | ${rep} | Format session report | ${report} | + ${nice_list} = Create List + @{list} Convert To List ${session_report['reports']} + : FOR ${x} IN @{list} + \ Append To List ${nice_list} time: ${x['created']}, text: ${x['text']} + Log List ${nice_list} + [Return] ${nice_list} + +Deploy session + [Arguments] ${environment_name} ${session_id} + [Documentation] Sends POST request to deploy session + ... with session_id in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - session_id: session id. + ... + ... *Return:* + ... - None. + ... + ... *Examples:* + ... | Deploy Session | ${result['id']} | + ${env_id} Get Environment ID ${environment_name} + POST request without body http://${ip}:8082/environments/${env_id}/sessions/${session_id}/deploy + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + +Try to delete session + [Arguments] ${environment_name} ${session_id} + [Documentation] Sends DELETE request to delete session + ... with session_id in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - session_id: session id. + ... + ... *Return:* + ... - None. + ... + ... *Examples:* + ... | Delete Session | ${result['id']} | + ${env_id} Get Environment ID ${environment_name} + DELETE request http://${ip}:8082/environments/${env_id}/sessions/${session_id} + +Create AD + [Arguments] ${environment_name} ${AD_name} + [Documentation] Sends POST request to create new AD + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - AD_name: AD name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Create AD | env001 | ad001 | + ${env_id} Get Environment ID ${environment_name} + ${auth} Set Variable {"name": "${AD_name}", "adminPassword": "swordfish", "domain": "acme.dc", "units": [{"isMaster": true, "recoveryPassword": "swordfish", "location": "west-dc"}, {"isMaster": false, "recoveryPassword": "swordfish", "location": "west-dc"}]} + Set Body ${auth} + POST request http://${ip}:8082/environments/${env_id}/activeDirectories + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + [Return] ${resp} + +Get List of AD + [Arguments] ${environment_name} + [Documentation] Sends GET request to list all AD's + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Get List of AD | env001 | + ${env_id} Get Environment ID ${environment_name} + GET request http://${ip}:8082/environments/${env_id}/activeDirectories + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + [Return] ${resp} + +Delete AD + [Arguments] ${environment_name} ${AD_name} + [Documentation] Sends DELETE request to delete AD + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - AD_name: AD name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Delete AD | env001 | ad001 | + ${env_id} Get Environment ID ${environment_name} + ${ad_id} Set Variable None + ${data} Get List of AD ${environment_name} + @{ad_list} Convert To List ${data['activeDirectories']} + : FOR ${x} IN @{ad_list} + \ ${ad_id} = Set Variable If "${x['name']}" == "${AD_name}" ${x['id']} ${ad_id} + DELETE request http://${ip}:8082/environments/${env_id}/activeDirectories/${ad_id} + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + +Create IIS + [Arguments] ${environment_name} ${IIS_name} + [Documentation] Sends POST request to create new AD + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - IIS_name: IIS name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Create IIS | env001 | iis001 | + ${env_id} Get Environment ID ${environment_name} + ${auth} Set Variable {"name": "${IIS_name}", "adminPassword": "swordfish", "domain": "acme.dc", "units": [{}]} + Set Body ${auth} + POST request http://${ip}:8082/environments/${env_id}/webServers + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + [Return] ${resp} + +Get List of IIS + [Arguments] ${environment_name} + [Documentation] Sends GET request to list all IIS's + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Get List of IIS | env001 | + ${env_id} Get Environment ID ${environment_name} + GET request http://${ip}:8082/environments/${env_id}/webServers + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + [Return] ${resp} + +Delete IIS + [Arguments] ${environment_name} ${IIS_name} + [Documentation] Sends DELETE request to delete IIS + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - IIS_name: IIS name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Delete IIS | env001 | iis001 | + ${env_id} Get Environment ID ${environment_name} + ${iis_id} Set Variable None + ${data} Get List of IIS ${environment_name} + @{iis_list} Convert To List ${data['webServers']} + : FOR ${x} IN @{iis_list} + \ ${iis_id} = Set Variable If "${x['name']}" == "${IIS_name}" ${x['id']} ${iis_id} + DELETE request http://${ip}:8082/environments/${env_id}/webServers/${iis_id} + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + +Create ASP NET + [Arguments] ${environment_name} ${ASP_name} + [Documentation] Sends POST request to create new AD + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - ASP_name: ASP name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Create ASP NET | asp001 | + ${env_id} Get Environment ID ${environment_name} + ${auth} Set Variable {"name": "${ASP_name}", "credentials": {"username": "Administrator","password": "swordfish"}, "domain": "acme.dc", "adminPassword": "swordfish", "units":[{}], "repository": "git://github.com/Mirantis/murano-mvc-demo.git"} + Set Body ${auth} + POST request http://${ip}:8082/environments/${env_id}/aspNetApps + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response Body + [Return] ${resp} + +Get List of ASP NET + [Arguments] ${environment_name} + [Documentation] Sends GET request to list all IIS's + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | List ASP NET | + ${env_id} Get Environment ID ${environment_name} + GET request http://${ip}:8082/environments/${env_id}/aspNetApps + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response Body + [Return] ${resp} + +Delete ASP NET + [Arguments] ${environment_name} ${ASP_name} + [Documentation] Sends DELETE request to delete IIS + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - ASP_name: ASP name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Delete ASP NET | asp001 | + ${env_id} Get Environment ID ${environment_name} + ${asp_id} Set Variable None + ${data} Get List of ASP NET ${environment_name} + @{asp_list} Convert To List ${data['aspNetApps']} + : FOR ${x} IN @{asp_list} + \ ${asp_id} = Set Variable If "${x['name']}" == "${ASP_name}" ${x['id']} ${asp_id} + DELETE request http://${ip}:8082/environments/${env_id}/aspNetApps/${asp_id} + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + +Create IIS Farm + [Arguments] ${environment_name} ${IIS_Farm_name} + [Documentation] Sends POST request to create new AD + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - IIS_Farm_name: IIS farm name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Create IIS Farm | env001 | iisFarm001 | + ${env_id} Get Environment ID ${environment_name} + ${auth} Set Variable {"name": "${IIS_Farm_name}", "adminPassword": "swordfish", "domain": "acme.dc", "units": [{}], "loadBalancerPort": "80"} + Set Body ${auth} + POST request http://${ip}:8082/environments/${env_id}/webServerFarms + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + [Return] ${resp} + +Get List of IIS Farm + [Arguments] ${environment_name} + [Documentation] Sends GET request to list all IIS's + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Get List of IIS Farm | env001 | + ${env_id} Get Environment ID ${environment_name} + GET request http://${ip}:8082/environments/${env_id}/webServerFarms + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response body + [Return] ${resp} + +Delete IIS Farm + [Arguments] ${environment_name} ${IIS_Farm_name} + [Documentation] Sends DELETE request to delete IIS + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - IIS_Farm_name: IIS farm name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Delete IIS Farm | env001 | iis001 | + ${env_id} Get Environment ID ${environment_name} + ${iis_Farm_id} Set Variable None + ${data} Get List of IIS Farm ${environment_name} + @{iis_Farm_list} Convert To List ${data['webServerFarms']} + : FOR ${x} IN @{iis_Farm_list} + \ ${iis_Farm_id} = Set Variable If "${x['name']}" == "${IIS_Farm_name}" ${x['id']} ${iis_Farm_id} + DELETE request http://${ip}:8082/environments/${env_id}/webServerFarms/${iis_Farm_id} + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + +Create ASP NET Farm + [Arguments] ${environment_name} ${ASP_Farm_name} + [Documentation] Sends POST request to create new AD + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - ASP_Farm_name: ASP farm name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Create ASP NET Farm | asp001 | + ${env_id} Get Environment ID ${environment_name} + ${auth} Set Variable {"name": "${ASP_Farm_name}", "credentials": {"username": "Administrator","password": "swordfish"}, "domain": "acme.dc", "adminPassword": "swordfish", "units":[{}], "repository": "git://github.com/Mirantis/murano-mvc-demo.git", "loadBalancerPort": "80"} + Set Body ${auth} + POST request http://${ip}:8082/environments/${env_id}/aspNetAppFarms + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response Body + [Return] ${resp} + +Get List of ASP NET Farm + [Arguments] ${environment_name} + [Documentation] Sends GET request to list all IIS's + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | List ASP NET Farm | + ${env_id} Get Environment ID ${environment_name} + GET request http://${ip}:8082/environments/${env_id}/aspNetAppFarms + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} + ${resp} Get Response Body + [Return] ${resp} + +Delete ASP NET Farm + [Arguments] ${environment_name} ${ASP_Farm_name} + [Documentation] Sends DELETE request to delete IIS + ... in environment_name. + ... + ... *Arguments:* + ... - environment_name: environment name. + ... - ASP_Farm_name: ASP farm name. + ... + ... *Return:* + ... - response body. + ... + ... *Examples:* + ... | Delete ASP NET Farm | asp001 | + ${env_id} Get Environment ID ${environment_name} + ${asp_Farm_id} Set Variable None + ${data} Get List of ASP NET Farm ${environment_name} + @{asp_Farm_list} Convert To List ${data['aspNetAppFarms']} + : FOR ${x} IN @{asp_Farm_list} + \ ${asp_Farm_id} = Set Variable If "${x['name']}" == "${ASP_Farm_name}" ${x['id']} ${asp_Farm_id} + DELETE request http://${ip}:8082/environments/${env_id}/aspNetAppFarms/${asp_Farm_id} + ${resp_code} Get Response Code + Should Be Equal As Integers 200 ${resp_code} diff --git a/boffin/setup.py b/boffin/setup.py new file mode 100644 index 0000000..3071d15 --- /dev/null +++ b/boffin/setup.py @@ -0,0 +1,37 @@ +# Copyright (c) 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. + +from os.path import join, dirname +from setuptools import setup + +execfile(join(dirname(__file__), 'src', 'Boffin', 'version.py')) + +setup( + name='robotframework-boffin', + version=VERSION, + author='Mirantis, Inc.', + license='Apache License 2.0', + description='Extension for Robot Framework', + long_description=open('README.rst').read(), + package_dir={'': 'src'}, + packages=['Boffin', 'Boffin.keywords'], + install_requires=['robotframework>=2.8.1', + 'selenium>=2.33.0', + 'robotframework-selenium2library>=1.2.0', + 'robotframework-pydblibrary>=1.1', + 'beautifulsoup4>=4.2.1', + 'requests>=1.2.0'], + platforms='any', + zip_safe=False +) diff --git a/boffin/src/Boffin/_Settings.py b/boffin/src/Boffin/_Settings.py new file mode 100644 index 0000000..3b9709b --- /dev/null +++ b/boffin/src/Boffin/_Settings.py @@ -0,0 +1,54 @@ +# Copyright (c) 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. + +from ConfigParser import ConfigParser +from os import getcwd +from os.path import join + +from robot.libraries.BuiltIn import BuiltIn + + +_settingsFileName = 'settings.ini' + + +class _SettingsReader(object): + """ 'settings.ini' driver. """ + + @staticmethod + def read(): + """ + Loads default variables from the 'resources/settings.ini' file. + + Arguments: + - None. + + Return: + - None. + """ + try: + p = BuiltIn().get_variable_value('${resources_path}') + if p is not None: + _settingsFullFileName = join(p, _settingsFileName) + else: + _settingsFullFileName = join(getcwd(), 'resources', + _settingsFileName) + + conf = ConfigParser() + conf.read(_settingsFullFileName) + + for setting in conf.options('default'): + BuiltIn().set_global_variable('${%s}' % setting, + conf.get('default', setting)) + except: + pass diff --git a/boffin/src/Boffin/__init__.py b/boffin/src/Boffin/__init__.py new file mode 100644 index 0000000..292f903 --- /dev/null +++ b/boffin/src/Boffin/__init__.py @@ -0,0 +1,54 @@ +# Copyright (c) 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. + + +from os.path import join, dirname + +from Selenium2Library import Selenium2Library + +from _Settings import _SettingsReader +from keywords import * + +execfile(join(dirname(__file__), 'version.py')) + +__version__ = VERSION + +_SettingsReader.read() + + +class WebUIlib(Selenium2Library, _WebUIlib): + """ + This class supports WebUi related testing using the Robot Framework. + """ + + ROBOT_LIBRARY_SCOPE = 'GLOBAL' + ROBOT_LIBRARY_VERSION = VERSION + + +class Rest(_Rest): + """ + This class supports Rest related testing using the Robot Framework. + """ + + ROBOT_LIBRARY_SCOPE = 'GLOBAL' + ROBOT_LIBRARY_VERSION = VERSION + + +class DB(Pydblibrary): + """ + This library supports database-related testing using the Robot Framework. + """ + + ROBOT_LIBRARY_SCOPE = 'GLOBAL' + ROBOT_LIBRARY_VERSION = VERSION diff --git a/boffin/src/Boffin/keywords/_Rest.py b/boffin/src/Boffin/keywords/_Rest.py new file mode 100644 index 0000000..15b9629 --- /dev/null +++ b/boffin/src/Boffin/keywords/_Rest.py @@ -0,0 +1,238 @@ +# Copyright (c) 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. + +import json +import requests +from robot.api import logger + + +class _Rest(object): + + ROBOT_LIBRARY_SCOPE = 'GLOBAL' + + headers = None + body = None + url = None + + def clear_headers(self): + """ + Clears headers for REST API requests. + + *Arguments:* + - None. + + *Return:* + - None. + + *Examples*: + | Clear Headers | + """ + self.headers = [] + + def set_headers(self, headers_dict): + """ + Configures headers for REST API requests. + + *Arguments:* + - headers_dict: string with json dict. + + *Return:* + - None. + + *Examples*: + | Set Headers | {'Content-Type': 'application/json' | + """ + try: + self.headers = json.loads(headers_dict) + except: + raise AssertionError('Incorrect headers: %s' % headers_dict) + + def update_headers(self, name, value): + """ + Modifies headers for REST API requests. + + *Arguments:* + - name: header name. + - value: header value. + + *Return:* + - None. + + *Examples*: + | Update Headers | X-Auth-Token | 8808880808080808 | + """ + self.headers[name] = value + + def set_body(self, body_dict): + """ + This function allows to configure body for REST API requests. + + *Arguments:* + - body_dict: string with json dict. + + *Return:* + - None. + + *Examples*: + | Set Headers | {'Content-Type': 'application/json' | + """ + self.body = body_dict + + def get_headers(self): + """ + Gets headers for REST API requests. + + *Arguments:* + - None. + + *Return:* + - Headers dict. + + *Examples*: + | ${headers} | Get Headers | + """ + return self.headers + + def GET_request(self, url): + """ + Sends GET request. + + *Arguments:* + - url: destination url. + + *Return:* + - None. + + Examples: + | GET request | http://10.10.10.1:8082/environments | + """ + self.response = requests.request('GET', url=url, headers=self.headers) + + def POST_request(self, url): + """ + Sends POST request. + + *Arguments:* + - url: destination url. + + *Return:* + - None. + + *Examples*: + | POST request | http://10.10.10.1:8082/environments | + """ + debug_data = 'POST Request to URL: %s \n' \ + 'with Headers: %s \n' \ + 'and Body: %s' % (url, self.headers, self.body) + logger.debug(debug_data) + + self.response = requests.request('POST', url, + headers=self.headers, + data=self.body) + + logger.debug('Response: %s' % self.response.text) + + def POST_request_without_body(self, url): + """ + Sends POST request without body. + + *Arguments:* + - url: destination url. + + *Return:* + - None. + + *Examples*: + | POST request | http://10.10.10.1:8082/environments | + """ + debug_data = 'POST Request to URL: %s \n' \ + 'with Headers: %s \n' % (url, self.headers) + logger.debug(debug_data) + + self.response = requests.request('POST', url, + headers=self.headers) + logger.debug('Response: %s' % self.response.text) + + def DELETE_request(self, url): + """ + Sends DELETE request. + + *Arguments:* + - url: destination url. + + *Return:* + - None. + + *Examples*: + | DELETE request | http://10.10.10.1:8082/environments | + """ + self.response = requests.request('DELETE', url=url, + headers=self.headers) + + def PUT_request(self, url): + """ + Sends PUT request. + + *Arguments:* + - url: destination url. + + *Return:* + - None. + + *Examples*: + | PUT request | http://10.10.10.1:8082/env | + """ + debug_data = 'POST Request to URL: %s \n' \ + 'with Headers: %s \n' \ + 'and Body: %s' % (url, self.headers, self.body) + logger.debug(debug_data) + + self.response = requests.request('PUT', url, + headers=self.headers, + data=self.body) + logger.debug('Response: %s' % self.response.text) + + def get_response_code(self): + """ + Gets response code. + + *Arguments:* + - None. + + *Return:* + - response code. + + *Examples*: + | ${code} | Get Response Code | + """ + return self.response.status_code + + def get_response_body(self): + """ + Gets response body. + + *Arguments:* + - None. + + *Return:* + - response body. + + *Examples*: + | ${body} | Get Response Body | + """ + logger.debug('Response: %s' % self.response.text) + if self.response.text is None: + self.response.text = {} + + return json.loads(self.response.text) diff --git a/boffin/src/Boffin/keywords/_Utils.py b/boffin/src/Boffin/keywords/_Utils.py new file mode 100644 index 0000000..ad4093a --- /dev/null +++ b/boffin/src/Boffin/keywords/_Utils.py @@ -0,0 +1,328 @@ +# Copyright (c) 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. + +from ConfigParser import ConfigParser +from os import getcwd +from os.path import join +from bs4 import BeautifulSoup +from robot.libraries.BuiltIn import BuiltIn + + +class _ArtificialIntelligence: + """ + This class allows to find input and select controls \ + without manual input of identificators. + We can find input fields by labels near those fields. \ + Boffin heart. + """ + + ROBOT_LIBRARY_SCOPE = 'GLOBAL' + + def __init__(self, page_source): + """ + Class constructor. + + *Arguments:* + - page_source: web page source code. + + *Return:* + - None. + """ + self.page_source = page_source + + def _get_xpath_of_element(self, element): + """ + This function allows to get xpath of soup elements. + + *Arguments:* + - element: selector name. + + *Return:* + - element xpath. + """ + + number = 1 + try: + number += len(element.find_previous_siblings(element.name)) + except: + pass + + xpath = element.name + if number > 1: + xpath += '[' + str(number) + ']' + + for parent in element.findParents(): + if parent.name != '[document]': + k = 0 + for tag in parent.find_previous_siblings(): + if tag.name == parent.name: + k += 1 + if k == 0: + xpath = parent.name + '/' + xpath + else: + xpath = parent.name + '[' + str(k + 1) + ']/' + xpath + + return xpath + + def extra_search(self, soup, value, tag=None): + """ + This function allows to get element by its parameters. + + *Arguments:* + - soup: soup structure. + - value: element name. + + *Return:* + - label_element. + """ + + label_element = None + + if label_element is None: + label_element = soup.find(tag, text=str(value)) + if label_element is None: + label_element = soup.find(tag, attrs={'value': value}) + if label_element is None: + label_element = soup.find(tag, attrs={'title': value}) + + if label_element is None: + try: + for element in soup.find_all(tag): + if str(value) in element.text: + label_element = element + except: + pass + + return label_element + + def find_element(self, label, element_type='input', method='next', + result='xpath'): + """ + Looks for specified element on the page. + + *Arguments:* + - label: selector name. + - element_type: element tag name. It could be any tag or \ + several tags (then they are listed as 'select/input/a'). + - method: element search method. If 'next' is set, then \ + function is looking for the next input field after the \ + specified element. + Otherwise it returns the specified element itself. + + *Return:* + - element xpath. + + *Examples:* + | ${xpath} | Find element | E-mail | input | next | + | ${xpath} | Find element | Cancel | a/div | this | + """ + html = str(self.page_source.encode("utf-8", "replace")) + + " load html to soup structure for parsing " + soup = BeautifulSoup(html) + + " search element after the label" + try: + element_types = element_type.split('/') + element = None + + label_element = self.extra_search(soup, label) + for element_type in element_types: + if method == 'next': + element = label_element.parent.find_next(element_type) + + elif method == 'previous': + element = label_element.parent.find_previous(element_type) + + elif method == 'associated': + for t in ['a', 'button', 'input', 'select']: + elements = label_element.parent.find_all_next(t) + for e in elements: + if element_type in e.text: + element = e + if element: + break + elements = label_element.parent.find_all_previous(t) + for e in elements: + if element_type in e.text: + element = e + if element: + break + else: + element = self.extra_search(soup, label, element_type) + + if element: + break + + " return xpath of element " + if result == 'xpath': + return self._get_xpath_of_element(element) + else: + return element + except: + return None + + +class _Utils(object): + ROBOT_LIBRARY_SCOPE = 'GLOBAL' + + def get_element_from_repo(self, element_name): + """ + Returns element type, identificator and frame from \ + the 'resources/objrepo/%screen_name%.ini' file by element name. + + *Arguments:* + - elementName: screen name and selector name divided by dot. + + *Return:* + - [elType, elIdentificator, elFrame]. + + *Example:* + | @{element} | Get Element From Repo | Home . Banner Page 2 Button | + """ + try: + p = BuiltIn().get_variable_value('${resources_path}') + if p is not None: + _objRepoPath = join(p, 'objrepo') + else: + _objRepoPath = join(getcwd(), 'resources', 'objrepo') + + element_name = element_name.lower().replace(' ', '') + print "Element Name: " + element_name + inputElement = element_name.split('.') + + if len(inputElement) == 1: + fileName = 'common.ini' + name = element_name + + else: + fileName = '%s.ini' % inputElement[0] + name = inputElement[1] + + fullFileName = join(_objRepoPath, fileName) + print "fullFileName " + fullFileName + conf = ConfigParser() + conf.read(fullFileName) + + print "A: " + conf.get(str(name), 'type') + print "A: " + conf.get(name, 'type') + + if not conf.has_section(name): + print name + return ['', None, ''] + element_type = conf.get(name, 'type') + + element_identificator = '' + element_parent_name = conf.get(name, 'parent') + if element_parent_name: + element_identificator = \ + self.get_element_from_repo(element_parent_name)[1] + \ + element_identificator + + element_identificator += conf.get(name, 'identificator') + + element_frame = conf.get(name, 'frame') + return [element_type, element_identificator, element_frame] + except: + return ['', None, ''] + + def get_web_element_frame(self, elementName): + """ + Returns element frame by its name in the + 'resources/objrepo/%screen_name%.ini' file. + + *Arguments:* + - elementName: screen name and selector name divided by dot. + + *Return:* + - elFrame. + + *Example:* + | ${elFrame} | GetElementFrame | Blog . Post Text field | + """ + type, id, frame = self.get_element_from_repo(elementName) + return frame + + def get_web_element_selector(self, name, page_source=None, + element_type='input', method='next', + result='xpath'): + """ + Returns element selector by its name in the \ + 'resources/ObjRepo.ini' file. + + *Arguments:* + - name: selector name. + - page_source: web page source code. + - element_type: element tag name. It could be any tag or several \ + tags (then they are listed as 'select/input/a'). + - method: element search method. If 'next' is set, then function + is looking for the next input field after the specified element. + Otherwise it returns the specified element itself. + + *Return:* + - elIdentificator. + + *Examples:* + | ${selector} | Get element selector | User Name | ${source_code} \ + | input | next | + | ${selector} | Get element selector | Submit Button | ${source_code} \ + | a | this | + """ + type, id, frame = self.get_element_from_repo(name) + + if not id and page_source: + boffin = _ArtificialIntelligence(page_source) + id = boffin.find_element(name, element_type, method, result) + if result != 'xpath': + return id + if id: + type = 'xpath' + + identificator = None + if id: + identificator = '%s%s' % \ + ('' if not type else '%s=' % str(type), str(id)) + + return identificator + + def get_table_row_xpath(self, page_source, name): + """ + This method allows to parse tables on web pages \ + and determine the table row by element from table. + + *Arguments:* + - page_source: web page source code. + - name: identificator of row element. + + *Return:* + - xpath of table row. + + *Example:* + | ${elXpath} | Get Table Row Xpath | Entity 123 | + """ + _type = 'td/a/label/input/select' + element = self.get_web_element_selector(name, page_source, + _type, method='this', + result='element') + tag = element.name + while tag != 'tr' and tag: + try: + tag = element.parent.name + element = element.parent + except: + tag = None + pass + + e = _ArtificialIntelligence(page_source) + return e._get_xpath_of_element(element) diff --git a/boffin/src/Boffin/keywords/_Utils.pyc b/boffin/src/Boffin/keywords/_Utils.pyc new file mode 100644 index 0000000..42428bf Binary files /dev/null and b/boffin/src/Boffin/keywords/_Utils.pyc differ diff --git a/boffin/src/Boffin/keywords/_WebUIlib.py b/boffin/src/Boffin/keywords/_WebUIlib.py new file mode 100644 index 0000000..ffe8cf3 --- /dev/null +++ b/boffin/src/Boffin/keywords/_WebUIlib.py @@ -0,0 +1,667 @@ +# Copyright (c) 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 + +from time import sleep + +from robot.libraries.BuiltIn import BuiltIn + +from _Utils import _Utils + + +# Decorator for framed elements. +def _framed(framed_element_name): + def real_framed(function): + def wrapper(self, *args): + co_varnames = function.func_code.co_varnames + upper_varnames = [varnames.upper() for varnames in co_varnames] + index = upper_varnames.index(framed_element_name.upper()) + + element_frame = \ + self.get_web_element_frame(args[index - 1]) + if element_frame: + self.set_current_frame(element_frame) + + res = function(self, *args) + + if element_frame: + self.unselect_frame() + + return res + + return wrapper + + return real_framed + + +class _WebUIlib(_Utils): + + def navigate_to(self, path, dont_wait=None): + """ + Navigates to the page by given links sequence. + + *Arguments:* + - path: sequence of links separated by '>'. + - dont_wait: optional parameter. Should be set to skip waiting \ + for page loaded. + + *Return:* + - None. + + *Examples:* + | Navigate to | Careers>Account Executive | + """ + links = path.split('>') + + for link in links: + self.click_link(link) + self.wait_for_page_loaded(dont_wait) + + @_framed('over_element_name') + def click_on_submenu(self, over_element_name, name, dont_wait=None): + """ + Puts mouse over menu element and then clicks on submenu element by \ + given selector names and waits for page loaded if needed. + + *Arguments:* + - over_element_name: menu selector title taken from object \ + repository. + - name: submenu selector title taken from object repository. + - dont_wait: optional parameter. Should be set to skip waiting \ + for page loaded. + + *Return:* + - None. + + *Examples:* + | Click on submenu | Settings | Profile | + """ + self.put_mouse_over(over_element_name) + sleep(1) + self.click_on(name) + self.wait_for_page_loaded(dont_wait) + + def click_on_link(self, link, dont_wait=None): + """ + Clicks the link by given localor and waits for page loaded if needed. + + *Arguments:* + - link: this attribute can contain one of following: id, name, \ + href or link text. + - dont_wait: optional parameter. Should be set to skip waiting \ + for page loaded. + + *Return:* + - None. + + *Examples:* + | Click on link | Move to Trash | + | Click on link | Delete | don't wait | + """ + self.wait_for_element_found(link, 'a', 'this') + self.click_link(link) + self.wait_for_page_loaded(dont_wait) + + def wait_for_page_loaded(self, dont_wait=None, page_load_timeout=60): + """ + Waits for 'complete' page state during predefined page load timeout. + + Does not wait for page loading if wait argument is set to any value \ + except the ${empty}. + + *Arguments:* + - dont_wait: optional parameter. Should be set to skip waiting \ + for page loaded. + - page_load_timeout: optional parameter. Timeout for page loading. + + *Return:* + - None. + + *Examples:* + | Wait for page loaded | + | Wait for page loaded | don't wait | + """ + ajax_wait_timeout = \ + BuiltIn().get_variable_value('${ajax_wait_timeout}') + + if ajax_wait_timeout: + self.wait_for_condition('return window.jQuery.active == 0', + ajax_wait_timeout, + 'Ajax request was not loaded in ' + '%s second(s)' % ajax_wait_timeout) + + if not dont_wait: + self.wait_for_condition('return document.readyState == "complete"', + page_load_timeout, + 'Page was not loaded in ' + '%s second(s)' % page_load_timeout) + + def title_should_contain(self, text): + """ + Verifies that current page title contains given text. + + *Arguments:* + - text: text which should be in the title set in test case. + + *Return:* + - None. + + *Examples:* + | Title should contain | Account Executive | + """ + title = self.get_title() + BuiltIn().should_contain(title, text) + + @_framed('name') + def click_on(self, name, dont_wait=None): + """ + Clicks the element by given selector name and waits for page loaded \ + if needed. + + *Arguments:* + - name: selector title taken from object repository. + - dont_wait: optional parameter. Should be set to skip waiting \ + for page loaded. + + *Return:* + - None. + + *Examples:* + | Click on | Dashboard . Users button | + """ + selector = self.wait_for_element_found(name, 'button/input/a', 'this') + self.click_element(selector) + self.wait_for_page_loaded(dont_wait) + + def set_current_frame(self, name): + """ + Sets frame identified by given selector name as current frame. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Set current frame | Post Editor Frame | + """ + selector = self.get_web_element_selector(name) + self.select_frame(selector) + + def element_text_should_contain(self, name, text): + """ + Verifies that element with given selector type contains the given text. + + *Arguments:* + - name: selector title taken from object repository. + - text: text to be found set in test. + + *Return:* + - None. + + *Examples:* + | Element Text Should Contain | Dashboard . Message text | \ + Post Updated | + """ + selector = self.get_web_element_selector(name) + self.element_should_contain(selector, text) + + def element_text_should_be_equal_to(self, name, text): + """ + Verifies that element with given selector type equals to the \ + given text. + + *Arguments:* + - name: selector title taken from object repository. + - text: text to be found set in test. + + *Return:* + - None. + + *Examples:* + | Element Text Should Be Equal To | Dashboard . Message text | \ + User deleted | + """ + selector = self.get_web_element_selector(name) + self.element_text_should_be(selector, text) + + def element_text_should_not_contain(self, name, text): + """ + Verifies that element with given selector type not contain the \ + given text. + + *Arguments:* + - name: selector title taken from object repository. + - text: text to be found set in test. + + *Return:* + - None. + + *Examples:* + | Element Text Should Not Contain | Dashboard . Message text \ + | Post Updated. | + """ + selector = self.get_web_element_selector(name) + self.element_should_not_contain(selector, text) + + def element_text_should_not_be_equal_to(self, name, text): + """ + Verifies that element text with given selector type not qual to the \ + given text. + + *Arguments:* + - name: selector title taken from object repository. + - text: text to be found set in test. + + *Return:* + - None. + + *Examples:* + | Element Text Should Not Be Equal To | Dashboard . Message text \ + | Post Updated. | + """ + selector = self.get_web_element_selector(name) + self.element_text_should_not_be(selector, text) + + def element_should_not_contain(self, selector, text): + """ + Verifies element identified by given selector does not contain \ + given text. + + *Arguments:* + - selector: element identificator in the object repository. + - text: text to be checked. + + *Return:* + - None. + + *Examples:* + | Element Should Not Contain | xpath=//div[@id='moderated']/p \ + | rude message | + """ + obj_text = self.get_text(selector) + BuiltIn().should_not_contain(obj_text, text) + + def element_text_should_not_be(self, selector, text): + """ + Verifies element identified by given selector does not equal to the \ + given text. + + *Arguments:* + - selector: element identificator in the object repository. + - text: text to be checked. + + *Return:* + - None. + + *Examples:* + | Element Should Not Be | xpath=//div[@id='moderated']/p \ + | rude message | + """ + obj_text = self.get_text(selector) + BuiltIn._should_not_be_equal(obj_text, text) + + def page_should_have_number_of_elements(self, count, name): + """ + Verifies that current page contains given number of elements with \ + given selector type. + + *Arguments:* + - count: number of element to be found. + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Page should have number of elements | 4 | Banner Buttons | + """ + element = self.get_element_from_repo(name) + self.xpath_should_match_x_times(element[1], count) + + def page_should_have_element(self, name): + """ + Verifies that current page contains given element. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Page should have element | Contact Us button | + """ + selector = self.get_web_element_selector(name) + self.page_should_contain_element(selector) + + def page_should_not_have_element(self, name): + """ + Verifies that current page does not contain given element. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Page should not have element | Contact Us button | + """ + selector = self.get_web_element_selector(name) + self.page_should_not_contain_element(selector) + + def put_mouse_over(self, name): + """ + Simulates hovering mouse over the element specified by selector name. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Put mouse over | Dashboard . Posts button | + """ + selector = self.get_web_element_selector(name) + self.mouse_over(selector) + + @_framed('field_name') + def fill_field(self, field_name, text): + """ + Gets element by its field name and fills it with given text. + Note: If field name will be 'password' then \ + ${text} won't be logged. + + *Arguments:* + - field_name: selector title taken from object repository. + - text: text to be entered into field. + + *Return:* + - None. + + *Examples:* + | Fill field | Dashboard . New Post Title field | Test blog-post | + """ + selector = self.wait_for_element_found(field_name, 'input/textarea', + 'next') + + if 'PASSWORD' in field_name.upper(): + self.input_password(selector, text) + else: + self.input_text(selector, text) + + def wait_for_element_found(self, element_name, element_type, method): + """ + Makes 10 retries to get element by its name with defined retry \ + interval (1 second). + + *Arguments:* + - element_name: selector title taken from object repository; + - element_type: element tag, could take several tags at once \ + (e.g. select/input/a); + - method: a method of how to search for the element. + + *Return:* + - selector: element identificator from object repository. + + *Examples:* + | ${selector} | Wait for element found | Dashboard Menu Title field \ + | input | next | + """ + for attempt in range(10): + try: + page_source_code = self.get_source() + selector = self.get_web_element_selector(element_name, + page_source_code, + element_type, + method) + except: + pass + if selector: + break + + sleep(1) + + if not selector: + BuiltIn().run_keyword('Capture Page Screenshot') + raise AssertionError('Web element "%s" was not found in object ' + 'repository and on page.' % element_name) + + return selector + + @_framed('name') + def select_item_from_list(self, name, item_name): + """ + Selects specified item from given list. + + *Arguments:* + - name: selector title taken from object repository. + - item_name: list box item. + + *Return:* + - None. + + *Examples:* + | Select item from list | Dashboard . User Action dropdown | Delete | + """ + selector = self.wait_for_element_found(name, 'select', 'next') + self.select_from_list(selector, item_name) + + @_framed('name') + def set_checkbox_on(self, name): + """ + Set checkbox with given title on. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Set checkbox on | Dashboard . Delete Posts Role checkbox | + """ + selector = self.wait_for_element_found(name, 'select', 'previous') + self.select_checkbox(selector) + + @_framed('name') + def set_checkbox_off(self, name): + """ + Set checkbox with given title off. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Set checkbox off | Dashboard . Delete Posts Role checkbox | + """ + selector = self.wait_for_element_found(name, 'select', 'previous') + self.unselect_checkbox(selector) + + @_framed('from_name') + def drag_and_drop_to(self, from_name, to_name): + """ + Drags and drops from one given element to other. + + *Arguments:* + - from_name: selector title taken from object repository to get \ + content from; + - to_name: selector title taken from object repository to put \ + content to. + + *Return:* + - None. + + *Examples:* + | Drag And Drop To | Photo gallery | User avatar | + """ + from_selector = self.wait_for_element_found(from_name, + 'button/input/a/img/div', + 'this') + to_selector = self.wait_for_element_found(to_name, + 'button/input/a/img/div', + 'this') + self.drag_and_drop_to(from_selector, to_selector) + + def find_associated_element(self, first_element, desired_element): + """ + This method allows to find element, which located near other element \ + and returns xpath of this element. + Sometimes we have many identical elements on page and we can find \ + correct element based on nearest unique elements. + + *Arguments:* + - First_Element: base element, near this element we want to find \ + other element. + - Desired_Element: this is element which we want to find. + + *Return:* + - xpath of Desired_Element or None + + *Examples:* + | {element_xpath} | Find Associated Element | MyUniqueElement \ + | DesiredElement | + """ + element = self.wait_for_element_found(first_element, desired_element, + 'associated') + + return element + + @_framed('name') + def select_radio_by_selector(self, name, value): + """ + Sets selection of radio button group identified by selector name \ + to value. + + *Arguments:* + - name: selector title taken from object repository. + - value: value to be selected, is used for the value attribute or \ + for the id attribute. + + *Return:* + - None. + + *Examples:* + | Select Radio By Selector | Dashboard . Questionnaire | Yes | + """ + selector = self.wait_for_element_found(name, 'input', 'previous') + self.select_radio_button(selector, value) + + def get_table_row_with(self, element): + """ + This method allows to find table row with specific element. \ + After this xpath of table row can be used like base for xpath of \ + different elements in this table. + + *Arguments:* + - element: the unique element from table. + + *Return:* + - xpath of table row for this element + + *Examples:* + | {table_xpath} | Get Table Row With | MyUniqueElement | + | Click Element \ \ | xpath={table_xpath}/td[4]/button | + """ + source_code = self.get_source() + result = self.get_table_row_xpath(source_code, element) + + return result + + @_framed('name') + def element_should_be_invisible(self, name): + """ + Verifies that element is invisible on the page. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Element Should Be Invisible | Dashboard . Post Publish button | + """ + selector = self.wait_for_element_found(name, + 'button/input/a/img', + 'this') + self.element_should_not_be_visible(selector) + + @_framed('name') + def element_should_not_be_invisible(self, name): + """ + Verifies that element is visible on the page. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - None. + + *Examples:* + | Element Should Not Be Invisible | Dashboard . Post Publish button | + """ + selector = self.wait_for_element_found(name, + 'button/input/a/img', + 'this') + self.element_should_be_visible(selector) + + @_framed('name') + def get_element_text(self, name): + """ + Gets text of given element. + + *Arguments:* + - name: selector title taken from object repository. + + *Return:* + - text of element. + + *Examples:* + | ${text} | Get Element Text | Main header | + """ + selector = self.wait_for_element_found(name, + 'button/input/a/img', + 'this') + text = self.get_text(selector) + + return text + + @_framed('name') + def get_attribute_of_element(self, name, attribute): + """ + Gets attribute of given element. + + *Arguments:* + - name: selector title taken from object repository. + - attribute: attribute that would be taken. + + *Return:* + - text of element attribute. + + *Examples:* + | ${id_text} | Get Attribute Of Element | Main header | id | + """ + selector = self.wait_for_element_found(name, + 'button/input/a/img', + 'this') + attr_selector = '%s@%s' % (selector, attribute) + attr_text = self.get_element_attribute(attr_selector) + + return attr_text diff --git a/boffin/src/Boffin/keywords/__init__.py b/boffin/src/Boffin/keywords/__init__.py new file mode 100644 index 0000000..b781ab7 --- /dev/null +++ b/boffin/src/Boffin/keywords/__init__.py @@ -0,0 +1,23 @@ +# Copyright (c) 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. + +from _WebUIlib import _WebUIlib +from _Rest import _Rest +from Pydblibrary import Pydblibrary + +__all__ = [ + '_WebUIlib', + '_Rest', + 'Pydblibrary' +] diff --git a/boffin/src/Boffin/version.py b/boffin/src/Boffin/version.py new file mode 100644 index 0000000..72a783a --- /dev/null +++ b/boffin/src/Boffin/version.py @@ -0,0 +1 @@ +VERSION = '1.0rc3' diff --git a/boffin/src/robotframework_boffin.egg-info/PKG-INFO b/boffin/src/robotframework_boffin.egg-info/PKG-INFO new file mode 100644 index 0000000..6db010a --- /dev/null +++ b/boffin/src/robotframework_boffin.egg-info/PKG-INFO @@ -0,0 +1,15 @@ +Metadata-Version: 1.0 +Name: robotframework-boffin +Version: 1.0rc3 +Summary: Extension for Robot Framework +Home-page: UNKNOWN +Author: Mirantis, Inc. +Author-email: UNKNOWN +License: Apache License 2.0 +Description: Robotframework-Boffin + ========================== + + This library extends available keywords of Robotframework and robotframework-selenium2library. + + And provides keywords for REST requests testing. +Platform: any diff --git a/boffin/src/robotframework_boffin.egg-info/SOURCES.txt b/boffin/src/robotframework_boffin.egg-info/SOURCES.txt new file mode 100644 index 0000000..3a92f0e --- /dev/null +++ b/boffin/src/robotframework_boffin.egg-info/SOURCES.txt @@ -0,0 +1,15 @@ +README.rst +setup.py +src/Boffin/_Settings.py +src/Boffin/__init__.py +src/Boffin/version.py +src/Boffin/keywords/_Rest.py +src/Boffin/keywords/_Utils.py +src/Boffin/keywords/_WebUIlib.py +src/Boffin/keywords/__init__.py +src/robotframework_boffin.egg-info/PKG-INFO +src/robotframework_boffin.egg-info/SOURCES.txt +src/robotframework_boffin.egg-info/dependency_links.txt +src/robotframework_boffin.egg-info/not-zip-safe +src/robotframework_boffin.egg-info/requires.txt +src/robotframework_boffin.egg-info/top_level.txt \ No newline at end of file diff --git a/boffin/src/robotframework_boffin.egg-info/dependency_links.txt b/boffin/src/robotframework_boffin.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/boffin/src/robotframework_boffin.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/boffin/src/robotframework_boffin.egg-info/not-zip-safe b/boffin/src/robotframework_boffin.egg-info/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/boffin/src/robotframework_boffin.egg-info/not-zip-safe @@ -0,0 +1 @@ + diff --git a/boffin/src/robotframework_boffin.egg-info/requires.txt b/boffin/src/robotframework_boffin.egg-info/requires.txt new file mode 100644 index 0000000..439aba8 --- /dev/null +++ b/boffin/src/robotframework_boffin.egg-info/requires.txt @@ -0,0 +1,6 @@ +robotframework>=2.8.1 +selenium>=2.33.0 +robotframework-selenium2library>=1.2.0 +robotframework-pydblibrary>=1.1 +beautifulsoup4>=4.2.1 +requests>=1.2.0 \ No newline at end of file diff --git a/boffin/src/robotframework_boffin.egg-info/top_level.txt b/boffin/src/robotframework_boffin.egg-info/top_level.txt new file mode 100644 index 0000000..cbd7eb9 --- /dev/null +++ b/boffin/src/robotframework_boffin.egg-info/top_level.txt @@ -0,0 +1 @@ +Boffin diff --git a/rest_api_tests/functional/keywords.txt b/rest_api_tests/functional/keywords.txt index d39bc52..ac54778 100644 --- a/rest_api_tests/functional/keywords.txt +++ b/rest_api_tests/functional/keywords.txt @@ -3,7 +3,7 @@ Library simple_REST.py Library Collections *** Variables *** -${ip} 172.18.79.80 +${ip} 172.18.79.83 ${ip_keystone} 172.18.124.201 ${user} admin ${project} admin diff --git a/webUI/Resources/objrepo/common.ini b/webUI/Resources/objrepo/common.ini new file mode 100644 index 0000000..f48f3c4 --- /dev/null +++ b/webUI/Resources/objrepo/common.ini @@ -0,0 +1,8 @@ +[DEFAULT] +type=identifier +frame= +parent= + +[newenvironmentname] +type=id +identificator=id_name \ No newline at end of file diff --git a/webUI/sanity_checks.txt b/webUI/sanity_checks.txt new file mode 100644 index 0000000..bd4b73e --- /dev/null +++ b/webUI/sanity_checks.txt @@ -0,0 +1,653 @@ +*** Settings *** +Suite Setup Open Browser http://172.18.79.83/horizon +Suite Teardown Close All Browsers +Library String +Library Boffin.WebUIlib 20 10 + +*** Variables *** +${resources_path} /home/user/murano-tests/WebUI/Resources/ + +*** Test Cases *** +Check Environments Tab + [Tags] thread1 work + Log in WebUI by admin/swordfish + Page should contain element "Environments" + Log out + +Create environment + [Tags] thread1 work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env" for field Environment Name + User click on Create + Page should contain element "env" + Log out + +Edit environment + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env1" for field Environment Name + User click on Create + User click on "More" for element "env1" + User click on "Edit Environment" for element "env1" + User set value "edited_env" for field New Environment Name + User click on Save + Page should contain element "edited_env" + Log out + +Delete Environment + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env2" for field Environment Name + User click on Create + User click on "More" for element "env2" + User click on "Delete Environment" for element "env2" + User confirms deletion + Page should not contain element "env2" + Log out + +Create AD Service + [Tags] work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_one_ad" for field Environment Name + User click on Create + User click on env_with_one_ad + User click on Create Service + User select "Active Directory" from dropdown list "Service Type" + User click on Next + User set value "ad.nastya" for field Domain Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field Recovery password + User set value "P@ssw0rd" for field Confirm password AD + User set value "ad" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "ad.nastya" + Log out + +Create IIS service + [Tags] thread1 work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_one_iis" for field Environment Name + User click on Create + User click on env_with_one_iis + User click on Create Service + User select "Internet Information Service" from dropdown list "Service Type" + User click on Next + User set value "iis-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iis" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "iis-service" + Log out + +Create ASP.Net App + [Tags] work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_one_asp" for field Environment Name + User click on Create + User click on env_with_one_asp + User click on Create Service + User select "ASP.NET Application" from dropdown list "Service Type" + User click on Next + User set value "asp-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "git://github.com/Mirantis/murano-mvc-demo.git" for field Git repository + User set value "asp" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "asp-service" + Log out + +Create IIS Farm + [Tags] work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_iis_farm" for field Environment Name + User click on Create + User click on env_with_iis_farm + User click on Create Service + User select "Internet Information Service Web Farm" from dropdown list "Service Type" + User click on Next + User set value "iis_farm" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iisfarm#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "iis_farm" + Log out + +Create ASP.NET Farm + [Tags] work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_asp_farm" for field Environment Name + User click on Create + User click on env_with_asp_farm + User click on Create Service + User select "ASP.NET Application Web Farm" from dropdown list "Service Type" + User click on Next + User set value "asp-farm" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "git://github.com/Mirantis/murano-mvc-demo.git" for field Git repository + User set value "aspfarm#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "asp-farm" + Log out + +Create MS SQL Server + [Tags] work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_one_mssql" for field Environment Name + User click on Create + User click on env_with_one_mssql + User click on Create Service + User select "MS SQL Server" from dropdown list "Service Type" + User click on Next + User set value "ms_sql" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field SA password + User set value "P@ssw0rd" for field Confirm password SQL + User set value "sql" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "ms_sql" + Log out + +Create MS SQL Cluster + [Tags] work + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_with_sqlcluster" for field Environment Name + User click on Create + User click on env_with_sqlcluster + User click on Create Service + User create Active Directory ad.mssql + Page should contain element "ad.mssql" + User click on Create Service + User select "MS SQL Cluster Server" from dropdown list "Service Type" + User click on Next + User set value "sql_cluster" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User select "ad.mssql" from dropdown list "Active Directory Domain" + User set value "P@ssw0rd" for field SA password + User set value "P@ssw0rd" for field Confirm password cluster + User set value "sqlcluster#" for field Hostname template + User click on Next + User set value "10.200.0.88" for field Cluster Static IP + User set value "cluster" for field Cluster Name + User set value "AG_name" for field Availability Group Name + User set value "AG_listener_name" for field Availability Group Listener Name + User set value "10.200.0.89" for field Availability Group Listener IP + User set value "user" for field SQL User Name + User set value "P@ssw0rd" for field SQL User Password + User set value "P@ssw0rd" for field Confirm Password + User click on Next + User set value "testbase" for field Database list + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Sleep 3s + Page should contain element "sql_cluster" + Log out + +Delete AD service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "delete_ad" for field Environment Name + User click on Create + User click on delete_ad + User click on Create Service + User select "Active Directory" from dropdown list "Service Type" + User click on Next + User set value "ad.nastya" for field Domain Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field Recovery password + User set value "P@ssw0rd" for field Confirm password AD + User set value "ad" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + User click on Delete Service + User confirms deletion + Page should not contain element "ad.nastya" + Log out + +Delete IIS service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "delete_iis" for field Environment Name + User click on Create + User click on delete_iis + User click on Create Service + User select "Internet Information Service" from dropdown list "Service Type" + User click on Next + User set value "iis_service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iis" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + User click on Delete Service + User confirms deletion + Page should not contain element "iis_service" + Log out + +Delete ASP.NET service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "delete_asp" for field Environment Name + User click on Create + User click on delete_asp + User click on Create Service + User select "ASP.NET Application" from dropdown list "Service Type" + User click on Next + User set value "asp-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "git://github.com/Mirantis/murano-mvc-demo.git" for field Git repository + User set value "asp" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + User click on Delete Service + User confirms deletion + Page should not contain element "asp-service" + Log out + +Delete IIS Farm service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "delete_iis_farm" for field Environment Name + User click on Create + User click on delete_iis_farm + User click on Create Service + User select "Internet Information Service Web Farm" from dropdown list "Service Type" + User click on Next + User set value "iis_farm" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iisfarm#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + User click on iis_farm + User confirms deletion + Page should not contain element "iis_farm" + Log out + +Delete ASP.NET Farm service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "delete_asp_farm" for field Environment Name + User click on Create + User click on delete_asp_farm + User click on Create Service + User select "ASP.NET Application Web Farm" from dropdown list "Service Type" + User click on Next + User set value "asp-farm" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "git://github.com/Mirantis/murano-mvc-demo.git" for field Git repository + User set value "aspfarm#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + User click on Delete Service + User confirms deletion + Page should not contain element "asp-farm" + Log out + +Delete MS SQL server + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "delete_mssql" for field Environment Name + User click on Create + User click on delete_mssql + User click on Create Service + User select "MS SQL Server" from dropdown list "Service Type" + User click on Next + User set value "ms_sql" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field SA password + User set value "P@ssw0rd" for field Confirm password SQL + User set value "sql" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + User click on Delete Service + User confirms deletion + Page should not contain element "ms_sql" + Log out + +Check opportunity to choose availability zone + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_av_zone" for field Environment Name + User click on Create + User click on env_av_zone + User click on Create Service + User select "Internet Information Service" from dropdown list "Service Type" + User click on Next + User set value "iis-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iis" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User select "nova" from dropdown list "Availability zone" + Log out + +Check opportunity to choose Instance Flavor + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_inst_flavor" for field Environment Name + User click on Create + User click on env_inst_flavor + User click on Create Service + User select "Internet Information Service" from dropdown list "Service Type" + User click on Next + User set value "iis-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iis" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User select "m1.small" from dropdown list "Instance flavor" + User select "m1.large" from dropdown list "Instance flavor" + User select "m1.medium" from dropdown list "Instance flavor" + Log out + +Check opportunity to choose Instance Image + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "env_inst_image" for field Environment Name + User click on Create + User click on env_inst_image + User click on Create Service + User select "Internet Information Service" from dropdown list "Service Type" + User click on Next + User set value "iis-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iis" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User select "Windows Server 2012 x64 core Standard edition" from dropdown list "Instance image" + User select "Windows Server 2008 R2 x64 Standard edition" from dropdown list "Instance image" + Log out + +Deploy environment with AD Service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_one_ad" for field Environment Name + User click on Create + User click on deploy_one_ad + User click on Create Service + User select "Active Directory" from dropdown list "Service Type" + User click on Next + User set value "ad.nastya" for field Domain Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field Recovery password + User set value "P@ssw0rd" for field Confirm password AD + User set value "ad" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "ad.nastya" + User click on Deploy This Environment + Check the status of environment "deploy_one_ad" (should be "Ready") + Log out + +Deploy environment with IIS Service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_iis" for field Environment Name + User click on Create + User click on deploy_iis + User click on Create Service + User select "Internet Information Service" from dropdown list "Service Type" + User click on Next + User set value "iis-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iis" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "iis-service" + User click on Deploy This Environment + Check the status of environment "deploy_iis" (should be "Ready") + Log out + +Deploy environment with ASP.NET Service + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_asp" for field Environment Name + User click on Create + User click on deploy_asp + User click on Create Service + User select "ASP.NET Application" from dropdown list "Service Type" + User click on Next + User set value "asp-service" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "git://github.com/Mirantis/murano-mvc-demo.git" for field Git repository + User set value "asp" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "asp-service" + User click on Deploy This Environment + Check the status of environment "deploy_asp" (should be "Ready") + Log out + +Deploy environment with IIS Farm + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_iis_farm" for field Environment Name + User click on Create + User click on deploy_iis_farm + User click on Create Service + User select "Internet Information Service Web Farm" from dropdown list "Service Type" + User click on Next + User set value "iis_farm" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "iisfarm#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "iis_farm" + User click on Deploy This Environment + Check the status of environment "deploy_iis_farm" (should be "Ready") + Log out + +Deploy environment with ASP.NET Farm + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_asp_farm" for field Environment Name + User click on Create + User click on deploy_asp_farm + User click on Create Service + User select "ASP.NET Application Web Farm" from dropdown list "Service Type" + User click on Next + User set value "asp-farm" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "git://github.com/Mirantis/murano-mvc-demo.git" for field Git repository + User set value "aspfarm#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "asp-farm" + User click on Deploy This Environment + Check the status of environment "deploy_asp_farm" (should be "Ready") + Log out + +Deploy environment with MS SQL server + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_mssql" for field Environment Name + User click on Create + User click on deploy_mssql + User click on Create Service + User select "MS SQL Server" from dropdown list "Service Type" + User click on Next + User set value "ms_sql" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field SA password + User set value "P@ssw0rd" for field Confirm password SQL + User set value "sql" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "ms_sql" + User click on Deploy This Environment + Check the status of environment "deploy_mssql" (should be "Ready") + Log out + +test + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "test" for field Environment Name + User click on Create + Page should contain element "test" + Check status test + +Deploy AD with 2 instances + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_ad_2_inst" for field Environment Name + User click on Create + User click on deploy_ad_2_inst + User click on Create Service + User select "Active Directory" from dropdown list "Service Type" + User click on Next + User set value "ad.nastya.two" for field Domain Name + User set value "2" for field Instance Count + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field Recovery password + User set value "P@ssw0rd" for field Confirm password AD + User set value "adtwo#" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "ad.nastya.two" + User click on Deploy This Environment + Check the status of environment "deploy_ad_2_inst" (should be "Ready") + Log out + +Deploy MSSQL with 2 instances + Log in WebUI by admin/swordfish + User click on Create Environment + User set value "deploy_mssql" for field Environment Name + User click on Create + User click on deploy_mssql + User click on Create Service + User select "MS SQL Server" from dropdown list "Service Type" + User click on Next + User set value "ms_sql" for field Service Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field SA password + User set value "P@ssw0rd" for field Confirm password SQL + User set value "sql" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create + Page should contain element "ms_sql" + User click on Deploy This Environment + Check the status of environment "deploy_mssql" (should be "Ready") + Log out + +*** Keywords *** +Log in WebUI by ${user}/${password} + Fill Field User Name ${user} + Fill Field Password ${password} + Click on Sign In + Navigate to Project>Environments + +User set value "${value}" for field ${field} + Fill Field ${field} ${value} + +Select type of the service + [Arguments] ${type} + Select Item From List Service Type ${type} + Click Button Next + +Log out + Click on Sign Out + Page Should Contain Button Sign In + +Check the status of environment "${env_name}" (should be "Ready") + Wait Until Keyword Succeeds 20 minute 5s Check status ${env_name} + +Check status + [Arguments] ${env_name} + Navigate to Project>Environments + ${row} Find Associated Element ${env_name} Ready to configure + +User click on + [Arguments] ${arg} + Sleep 2s + Click on ${arg} + Sleep 2s + +Page should contain element "${element}" + Sleep 3s + Page Should Contain ${element} + +Page should not contain element "${element}" + Page Should Not Contain ${element} + +User click on "${button}" for element "${env}" + ${element} Find Associated Element ${env} ${button} + Click Element ${element} + +User select "${item}" from dropdown list "${menu}" + Select Item From List ${menu} ${item} + +User confirms deletion + ${element}= Find Associated Element Cancel Delete Environment + Click Link Delete Environment + Sleep 3s + +User create Active Directory + [Arguments] ${name} + User select "Active Directory" from dropdown list "Service Type" + User click on Next + User set value "${name}" for field Domain Name + User set value "P@ssw0rd" for field Administrator password + User set value "P@ssw0rd" for field Confirm password + User set value "P@ssw0rd" for field Recovery password + User set value "P@ssw0rd" for field Confirm password AD + User set value "adforsql" for field Hostname template + User click on Next + User select "Windows Server 2012 x64 Standard edition" from dropdown list "Instance image" + User click on Create