From 9223f3b9a4e51e2cb5bdce70f3f7209f8688c1f1 Mon Sep 17 00:00:00 2001 From: Timur Nurlygayanov Date: Thu, 4 Apr 2013 18:11:31 +0400 Subject: [PATCH] Initialization of tox for conductor and portas. Add new webUI automated tests. --- conductor/tox.ini | 46 +++++ portas/tox.ini | 46 +++++ tests/selenium/conf.ini | 2 +- tests/selenium/datacenters_page.py | 30 ++-- tests/selenium/objects.xml | 73 ++++++++ tests/selenium/page.py | 113 ++++++++++--- tests/selenium/services_details_page.py | 16 ++ tests/selenium/services_page.py | 40 ++++- tests/selenium/test.py | 216 ++++++++++++++---------- tests/selenium/test_case.py | 26 +++ 10 files changed, 470 insertions(+), 138 deletions(-) create mode 100644 conductor/tox.ini create mode 100644 portas/tox.ini create mode 100644 tests/selenium/objects.xml create mode 100644 tests/selenium/services_details_page.py create mode 100644 tests/selenium/test_case.py diff --git a/conductor/tox.ini b/conductor/tox.ini new file mode 100644 index 0000000..97f0572 --- /dev/null +++ b/conductor/tox.ini @@ -0,0 +1,46 @@ +[tox] +envlist = py26,py27,pep8 + +[testenv] +setenv = VIRTUAL_ENV={envdir} + NOSE_WITH_OPENSTACK=1 + NOSE_OPENSTACK_COLOR=1 + NOSE_OPENSTACK_RED=0.05 + NOSE_OPENSTACK_YELLOW=0.025 + NOSE_OPENSTACK_SHOW_ELAPSED=1 +deps = -r{toxinidir}/tools/pip-requires + -r{toxinidir}/tools/test-requires +commands = nosetests + +[testenv:pep8] +deps = pep8==1.3.3 +commands = pep8 --repeat --show-source conductor setup.py + +[testenv:venv] +commands = {posargs} + +[testenv:cover] +commands = nosetests --cover-erase --cover-package=conductor --with-xcoverage + +[tox:jenkins] +downloadcache = ~/cache/pip + +[testenv:jenkins26] +basepython = python2.6 +setenv = NOSE_WITH_XUNIT=1 +deps = file://{toxinidir}/.cache.bundle + +[testenv:jenkins27] +basepython = python2.7 +setenv = NOSE_WITH_XUNIT=1 +deps = file://{toxinidir}/.cache.bundle + +[testenv:jenkinscover] +deps = file://{toxinidir}/.cache.bundle +setenv = NOSE_WITH_XUNIT=1 +commands = nosetests --cover-erase --cover-package=conductor --with-xcoverage + +[testenv:jenkinsvenv] +deps = file://{toxinidir}/.cache.bundle +setenv = NOSE_WITH_XUNIT=1 +commands = {posargs} diff --git a/portas/tox.ini b/portas/tox.ini new file mode 100644 index 0000000..646dad9 --- /dev/null +++ b/portas/tox.ini @@ -0,0 +1,46 @@ +[tox] +envlist = py26,py27,pep8 + +[testenv] +setenv = VIRTUAL_ENV={envdir} + NOSE_WITH_OPENSTACK=1 + NOSE_OPENSTACK_COLOR=1 + NOSE_OPENSTACK_RED=0.05 + NOSE_OPENSTACK_YELLOW=0.025 + NOSE_OPENSTACK_SHOW_ELAPSED=1 +deps = -r{toxinidir}/tools/pip-requires + -r{toxinidir}/tools/test-requires +commands = nosetests + +[testenv:pep8] +deps = pep8==1.3.3 +commands = pep8 --repeat --show-source portas setup.py + +[testenv:venv] +commands = {posargs} + +[testenv:cover] +commands = nosetests --cover-erase --cover-package=portas --with-xcoverage + +[tox:jenkins] +downloadcache = ~/cache/pip + +[testenv:jenkins26] +basepython = python2.6 +setenv = NOSE_WITH_XUNIT=1 +deps = file://{toxinidir}/.cache.bundle + +[testenv:jenkins27] +basepython = python2.7 +setenv = NOSE_WITH_XUNIT=1 +deps = file://{toxinidir}/.cache.bundle + +[testenv:jenkinscover] +deps = file://{toxinidir}/.cache.bundle +setenv = NOSE_WITH_XUNIT=1 +commands = nosetests --cover-erase --cover-package=portas --with-xcoverage + +[testenv:jenkinsvenv] +deps = file://{toxinidir}/.cache.bundle +setenv = NOSE_WITH_XUNIT=1 +commands = {posargs} diff --git a/tests/selenium/conf.ini b/tests/selenium/conf.ini index 437aeba..12af6f5 100644 --- a/tests/selenium/conf.ini +++ b/tests/selenium/conf.ini @@ -1,4 +1,4 @@ [server] -address=http://172.18.124.101 +address=http://172.18.124.101:8080 user=admin password=swordfish \ No newline at end of file diff --git a/tests/selenium/datacenters_page.py b/tests/selenium/datacenters_page.py index 03e4e26..0e0f79c 100644 --- a/tests/selenium/datacenters_page.py +++ b/tests/selenium/datacenters_page.py @@ -4,15 +4,13 @@ import page class DataCentersPage(page.Page): + name = 'DataCenters' def create_data_center(self, name): self.Refresh() - self.Button('Create Windows Data Center').Click() - self.EditBox('id_name').Set(name) - xpath = "//input[@value='Create']" - self.Button(xpath).Click() + self.Button('Create').Click() def delete_data_center(self, name): self.Refresh() @@ -20,13 +18,10 @@ class DataCentersPage(page.Page): link = self.Link(name).Address() datacenter_id = re.search('windc/(\S+)', link).group(0)[6:-1] - xpath = ".//*[@id='windc__row__%s']/td[4]/div/a[2]" % datacenter_id - self.Button(xpath).Click() - - button_id = "windc__row_%s__action_delete" % datacenter_id - self.Button(button_id).Click() - - self.Button("Delete Data Center").Click() + self.Button('More', datacenter_id).Click() + self.Button('Delete', datacenter_id).Click() + # confirm: + self.Button('Delete Data Center').Click() def select_data_center(self, name): self.Link(name).Click() @@ -39,16 +34,13 @@ class DataCentersPage(page.Page): link = self.Link(name).Address() datacenter_id = re.search('windc/(\S+)', link).group(0)[6:-1] - xpath = ".//*[@id='windc__row__%s']/td[4]/div/a[2]" % datacenter_id - self.Button(xpath).Click() - - button_id = "windc__row_%s__action_deploy" % datacenter_id - self.Button(button_id).Click() + self.Button('More', datacenter_id).Click() + self.Button('Deploy', datacenter_id).Click() def get_datacenter_status(self, name): - self.Navigate('Windows Data Centers') + self.Refresh() + link = self.Link(name).Address() datacenter_id = re.search('windc/(\S+)', link).group(0)[6:-1] - xpath = ".//*[@id='windc__row__%s']/td[3]" % datacenter_id - return self.TableCell(xpath).Text() + return self.TableCell('Status', datacenter_id).Text() diff --git a/tests/selenium/objects.xml b/tests/selenium/objects.xml new file mode 100644 index 0000000..8af0375 --- /dev/null +++ b/tests/selenium/objects.xml @@ -0,0 +1,73 @@ + + + Button + Create + //input[@value='Create'] + + + Button + Services + More + .//*[@id='services__row__%s']/td[5]/div/a[2] + + + Button + Services + Delete + services__row_%s__action_delete + + + Button + Services + CreateService + services__action_CreateService + + + Button + DataCenters + More + .//*[@id='windc__row__%s']/td[4]/div/a[2] + + + Button + DataCenters + Delete + windc__row_%s__action_delete + + + Button + DataCenters + Deploy + windc__row_%s__action_deploy + + + TableCell + DataCenters + Status + .//*[@id='windc__row__%s']/td[3] + + + TableCell + ServicesDetails + Name + .//*[@id='services_details___service']/div/dl/dd[1] + + + TableCell + ServicesDetails + Domain + .//*[@id='services_details___service']/div/dl/dd[3] + + + Link + ServicesDetails + Service + .//*[@id='services_details']/li[1]/a + + + TableCell + Services + Status + .//*[@id='services__row__%s']/td[4] + + \ No newline at end of file diff --git a/tests/selenium/page.py b/tests/selenium/page.py index 43ed7cc..27c5e53 100644 --- a/tests/selenium/page.py +++ b/tests/selenium/page.py @@ -1,7 +1,46 @@ import logging from selenium.webdriver.support.ui import Select +import xml.etree.ElementTree as ET + + logging.basicConfig() LOG = logging.getLogger(' Page object: ') +""" + Disable selenium logging: +""" +logger = logging.getLogger('selenium.webdriver.remote.remote_connection') +logger.setLevel('ERROR') + + +class ObjectsLibrary: + file = None + objects = [] + + def __init__(self, file_name='objects.xml'): + """ + Initialization of the Objects Library. + Read objects descriptions from XML file. + """ + self.file = file_name + tree = ET.parse(self.file) + objects = tree.getroot() + self.objects = [] + for element in objects: + object = {} + for parameter in element: + object.update({parameter.tag: parameter.text}) + self.objects.append(object) + + def get_object(self, name, pagename): + """ + Search objects in Objects Library. + """ + for object in self.objects: + obj_pagename = object.get('pagename', None) + if object['name'] == name and (obj_pagename == pagename + or obj_pagename is None): + return object['parameter'] + return None class TableCellClass: @@ -14,7 +53,8 @@ class TableCellClass: def Text(self): if self.table: - return self.table.text() + LOG.critical(self.table.text) + return self.table.text else: return '' @@ -75,8 +115,11 @@ class EditBoxClass: def Set(self, value): if self.edit: - self.edit.clear() - self.edit.send_keys(value) + try: + self.edit.clear() + self.edit.send_keys(value) + except: + LOG.error('Can not set value for text box.') def Text(self): if self.edit: @@ -100,7 +143,11 @@ class DropDownListClass: def Set(self, value): if self.select: - Select(self.select).select_by_visible_text(value) + try: + Select(self.select).select_by_visible_text(value) + except: + LOG.error('Can not select element %s from drop down list.' + .format(value)) def Text(self): if self.select: @@ -118,40 +165,57 @@ error_msg = """ class Page: driver = None - timeout = 30 + timeout = 10 + lib = None + name = None def __init__(self, driver): - driver.set_page_load_timeout(30) + driver.set_page_load_timeout(self.timeout) driver.implicitly_wait(0.01) self.driver = driver - def _find_element(self, parameter): + def _find_element(self, name, parameter=None): + """ + This method allows to find element, + based on descriptions in Object Library, + xpath, id, name or pertial link text. + If parameter != None will be used name % parameter + """ + lib = ObjectsLibrary() + if lib.get_object(name, self.name): + name = lib.get_object(name, self.name) + + if parameter: + name = name % parameter + obj = None k = 0 + while (obj is None and k < self.timeout): k += 1 + try: - obj = self.driver.find_element_by_name(parameter) + obj = self.driver.find_element_by_name(name) return obj except: pass try: - obj = self.driver.find_element_by_id(parameter) + obj = self.driver.find_element_by_id(name) return obj except: pass try: - obj = self.driver.find_element_by_xpath(parameter) + obj = self.driver.find_element_by_xpath(name) return obj except: pass try: - obj = self.driver.find_element_by_partial_link_text(parameter) + obj = self.driver.find_element_by_partial_link_text(name) return obj except: pass - LOG.error(error_msg % parameter) + LOG.error(error_msg % name) return None def Open(self, url): @@ -160,32 +224,37 @@ class Page: def Refresh(self): self.driver.refresh() - def TableCell(self, name): - obj = self._find_element(name) + def TableCell(self, name, parameter=None): + obj = self._find_element(name, parameter) table = TableCellClass(obj) return table - def Button(self, name): - obj = self._find_element(name) + def Button(self, name, parameter=None): + obj = self._find_element(name, parameter) button = ButtonClass(obj) return button - def Link(self, name): - obj = self._find_element(name) + def Link(self, name, parameter=None): + obj = self._find_element(name, parameter) link = LinkClass(obj) return link - def EditBox(self, name): - obj = self._find_element(name) + def EditBox(self, name, parameter=None): + obj = self._find_element(name, parameter) edit = EditBoxClass(obj) return edit - def DropDownList(self, name): - obj = self._find_element(name) + def DropDownList(self, name, parameter=None): + obj = self._find_element(name, parameter) select = DropDownListClass(obj) return select def Navigate(self, path): + """ + This method allows to navigate by + webUI menu button and links to + the specific page + """ steps = path.split(':') for step in steps: diff --git a/tests/selenium/services_details_page.py b/tests/selenium/services_details_page.py new file mode 100644 index 0000000..a7e8c6e --- /dev/null +++ b/tests/selenium/services_details_page.py @@ -0,0 +1,16 @@ +import page + + +class ServicesDetailsPage(page.Page): + + name = 'ServicesDetails' + + def get_service_name(self): + self.Refresh() + self.Link('Service').Click() + return self.TableCell('Name').Text() + + def get_service_domain(self): + self.Refresh() + self.Link('Service').Click() + return self.TableCell('Domain').Text() \ No newline at end of file diff --git a/tests/selenium/services_page.py b/tests/selenium/services_page.py index 772b9df..213fa8e 100644 --- a/tests/selenium/services_page.py +++ b/tests/selenium/services_page.py @@ -1,20 +1,32 @@ import page import re +from services_details_page import ServicesDetailsPage class ServicesPage(page.Page): + + name = 'Services' - def create_service(self, service_type, parameters): + def create_service(self, parameters): + service_type = parameters[0] + parameters = parameters[1] self.Refresh() - self.Button('services__action_CreateService').Click() + self.Button('CreateService').Click() self.DropDownList('0-service').Set(service_type) self.Button('wizard_goto_step').Click() for key in parameters: - self.EditBox(key).Set(parameters[key]) + try: + self.EditBox(key).Set(parameters[key]) + except: + pass + try: + self.DropDownList(key).Set(parameters[key]) + except: + pass - self.Button("//input[@value='Create']").Click() + self.Button('Create').Click() def delete_service(self, name): self.Refresh() @@ -23,10 +35,20 @@ class ServicesPage(page.Page): service_id = re.search('windc/(\S+)', link).group(0)[6:-1] - xpath = ".//*[@id='services__row__%s']/td[5]/div/a[2]" % service_id - self.Button(xpath).Click() + self.Button('More', service_id).Click() + self.Button('Delete', service_id).Click() + # confirm: + self.Button('Delete Service').Click() - button_id = "services__row_%s__action_delete" % service_id - self.Button(button_id).Click() + def select_service(self, name): + self.Link(name).Click() + page = ServicesDetailsPage(self.driver) + return page - self.Button("Delete Service").Click() + def get_service_status(self, name): + self.Refresh() + + link = self.Link(name).Address() + service_id = re.search('windc/(\S+)', link).group(0)[6:-8] + + return self.TableCell('Status', service_id).Text() diff --git a/tests/selenium/test.py b/tests/selenium/test.py index b1c2b60..ef81e36 100644 --- a/tests/selenium/test.py +++ b/tests/selenium/test.py @@ -1,15 +1,47 @@ # -*- coding: utf-8 -*- import unittest2 +import logging from login_page import LoginPage from datacenters_page import DataCentersPage +from test_case import TestCase from selenium import webdriver +logging.basicConfig() +LOG = logging.getLogger(' Tests: ') + + +def generate_ad(name="test", count=1): + """ + This function generates parameters for + Active Directory service + """ + ad_parameters = {'1-dc_name': name, + '1-dc_count': count, + '1-adm_password': "P@ssw0rd", + '1-recovery_password': "P@ssw0rd2"} + return ['Active Directory', ad_parameters] + +def generate_iis(name="test", domain="test"): + """ + This function generates parameters for + Internet Information Services service + """ + iis_parameters = {'1-iis_name': name, + '1-adm_password': "P@ssw0rd", + '1-iis_domain': domain} + return ['Internet Information Services', iis_parameters] + + class SanityTests(unittest2.TestCase): @classmethod def setUpClass(self): + """ + Open browser, navigate to the login page, + login and navigate to the Windows Data Centers page + """ driver = webdriver.Firefox() self.page = LoginPage(driver) self.page.login() @@ -18,23 +50,46 @@ class SanityTests(unittest2.TestCase): @classmethod def tearDownClass(self): + """ + Close browser + """ self.page.driver.close() - def test_01_create_data_center(self): + def test_001_create_data_center(self): self.page.create_data_center('dc1') assert self.page.Link('dc1').isPresented() - def test_02_delete_data_center(self): + def test_002_delete_data_center(self): self.page.delete_data_center('dc1') assert not self.page.Link('dc1').isPresented() - def test_03_create_data_centers(self): + def test_003_deploy_data_center(self): + ad_name = "AD.net" + iis_name = "iis_server" + self.page.Navigate('Windows Data Centers') + self.page.create_data_center('data_center_for_deploy') + self.page = self.page.select_data_center('data_center_for_deploy') + + self.page.create_service(generate_ad(ad_name, 2)) + assert self.page.Link(ad_name).isPresented() + + self.page.create_service(generate_iis(iis_name, ad_name)) + assert self.page.Link(iis_name).isPresented() + + self.page.Navigate('Windows Data Centers') + self.page = DataCentersPage(self.page.driver) + self.page.deploy_data_center('data_center_for_deploy') + + status = self.page.get_datacenter_status('data_center_for_deploy') + assert 'Deploy in progress' in status + + def test_004_create_data_centers(self): for i in range(1, 10): - name = 'datacenter' + str(i) + name = "datacenter" + str(i) self.page.create_data_center(name) assert self.page.Link(name).isPresented() - def test_04_delete_data_centers(self): + def test_005_delete_data_centers(self): self.page.delete_data_center('datacenter1') self.page.delete_data_center('datacenter9') assert not self.page.Link('datacenter1').isPresented() @@ -44,111 +99,98 @@ class SanityTests(unittest2.TestCase): name = 'datacenter' + str(i) assert self.page.Link(name).isPresented() - def test_05_create_service_ad(self): - name = 'dc001.local' + def test_006_create_service_ad(self): + name = "dc001.local" self.page.Navigate('Windows Data Centers') + self.page = DataCentersPage(self.page.driver) + self.page.create_data_center('test05') self.page = self.page.select_data_center('test05') - ad_parameters = {'1-dc_name': name, - '1-dc_count': 1, - '1-adm_password': 'AkvareL707!', - '1-recovery_password': 'AkvareL707!'} - self.page.create_service('Active Directory', ad_parameters) + self.page.create_service(generate_ad(name, 1)) - assert self.page.Link(name).isPresented() + test_case = TestCase(self.page.driver, test_name) + assert test_case.verify(self.page.Link(name).isPresented()) - def test_06_create_service_ad_two_instances(self): - name = 'dc002.local' + def test_007_create_service_ad_two_instances(self): + test_name = "Create AD service with two instances" + name = "dc002.local" self.page.Navigate('Windows Data Centers') + self.page = DataCentersPage(self.page.driver) + self.page.create_data_center('test06') self.page = self.page.select_data_center('test06') - ad_parameters = {'1-dc_name': name, - '1-dc_count': 2, - '1-adm_password': 'P@ssw0rd2', - '1-recovery_password': 'P@ssw0rd'} - self.page.create_service('Active Directory', ad_parameters) + self.page.create_service(generate_ad(name, 2)) - assert self.page.Link(name).isPresented() + test_case = TestCase(self.page.driver, test_name) + assert test_case.verify(self.page.Link(name).isPresented()) - def test_07_create_service_ad_with_iis(self): - ad_name = 'dc003.local' + def test_008_create_service_ad_with_iis(self): + test_name = "Create data center with a few services" + ad_name = "dc003.local" self.page.Navigate('Windows Data Centers') + self.page = DataCentersPage(self.page.driver) + self.page.create_data_center('test07') self.page = self.page.select_data_center('test07') - ad_parameters = {'1-dc_name': ad_name, - '1-dc_count': 3, - '1-adm_password': 'P@ssw0rd', - '1-recovery_password': 'P@ssw0rd2'} - self.page.create_service('Active Directory', ad_parameters) + self.page.create_service(generate_ad(ad_name, 3)) - assert self.page.Link(ad_name).isPresented() + test_case = TestCase(self.page.driver, test_name) + assert test_case.verify(self.page.Link(ad_name).isPresented()) - iis_name = 'iis_server1' - iis_parameters = {'1-iis_name': iis_name, - '1-adm_password': 'P@ssw0rd', - '1-iis_domain': 'dc003.local', - '1-domain_user_name': 'Administrator', - '1-domain_user_password': 'P@ssw0rd'} - self.page.create_service('Internet Information Services', - iis_parameters) + for i in range(5): + iis_name = 'iis_server' + str(i) + self.page.create_service(generate_iis(iis_name, ad_name)) + assert test_case.verify(self.page.Link(iis_name).isPresented()) - assert self.page.Link(iis_name).isPresented() - - iis_name = 'iis_server2' - iis_parameters = {'1-iis_name': iis_name, - '1-adm_password': 'P@ssw0rd', - '1-iis_domain': 'dc003.local', - '1-domain_user_name': 'Administrator', - '1-domain_user_password': 'P@ssw0rd'} - self.page.create_service('Internet Information Services', - iis_parameters) - - assert self.page.Link(iis_name).isPresented() - - iis_name = 'iis_server3' - iis_parameters = {'1-iis_name': iis_name, - '1-adm_password': 'P@ssw0rd', - '1-iis_domain': 'dc003.local', - '1-domain_user_name': 'Administrator', - '1-domain_user_password': 'P@ssw0rd'} - self.page.create_service('Internet Information Services', - iis_parameters) - - assert self.page.Link(iis_name).isPresented() - - def test_08_deploy_data_center(self): - ad_name = 'AD.net' - self.page.Navigate('Windows Data Centers') - self.page.create_data_center('test08') - self.page = self.page.select_data_center('test08') - - ad_parameters = {'1-dc_name': ad_name, - '1-dc_count': 2, - '1-adm_password': 'P@ssw0rd', - '1-recovery_password': 'P@ssw0rd2'} - self.page.create_service('Active Directory', ad_parameters) - - assert self.page.Link(ad_name).isPresented() - - iis_parameters = {'1-iis_name': 'iis_server', - '1-adm_password': 'P@ssw0rd', - '1-iis_domain': 'AD.net', - '1-domain_user_name': 'Administrator', - '1-domain_user_password': 'P@ssw0rd'} - self.page.create_service('Internet Information Services', - iis_parameters) - - assert self.page.Link('iis_server').isPresented() + def test_009_delete_data_center_with_services(self): + test_name = "Delete data center with a few services with status ready to deploy" + dc_name = "test07" self.page.Navigate('Windows Data Centers') self.page = DataCentersPage(self.page.driver) - self.page.deploy_data_center('test08') + self.page.delete_data_center(dc_name) - status = self.page.get_datacenter_status('test08') - assert 'Deploy in progress' in status + test_case = TestCase(self.page.driver, test_name) + assert test_case.verify(not self.page.Link(dc_name).isPresented()) + + def test_010_service_deploy_in_progress_status(self): + test_name = "Check status for services in deploing state" + + dc_name = "data_center_for_deploy" + ad_name = "AD.net" + iis_name = "iis_server" + + self.page.Navigate('Windows Data Centers') + self.page = DataCentersPage(self.page.driver) + self.page = self.page.select_data_center(dc_name) + + ad_status = self.page.get_service_status(ad_name) + iis_status = self.page.get_service_status(iis_name) + + test_case = TestCase(self.page.driver, test_name) + assert test_case.verify('Deploy in progress' in ad_status) + assert test_case.verify('Deploy in progress' in iis_status) + + def test_011_show_service_details_for_deploy(self): + test_name = "Check IIS service details page" + dc_name = "data_center_for_deploy" + ad_name = "AD.net" + iis_name = "iis_server" + + self.page.Navigate('Windows Data Centers') + self.page = DataCentersPage(self.page.driver) + self.page = self.page.select_data_center(dc_name) + self.page = self.page.select_service(iis_name) + + name = self.page.get_service_name() + domain = self.page.get_service_domain() + + test_case = TestCase(self.page.driver, test_name) + assert test_case.verify(name == iis_name) + assert test_case.verify(name == ad_name) if __name__ == '__main__': diff --git a/tests/selenium/test_case.py b/tests/selenium/test_case.py new file mode 100644 index 0000000..b8ebe46 --- /dev/null +++ b/tests/selenium/test_case.py @@ -0,0 +1,26 @@ +import logging + + +logging.basicConfig() +LOG = logging.getLogger(' Test Case: ') + + +class TestCase: + name = None + driver = None + + def __init__(self, driver, name): + self.name = name + self.driver = driver + + def verify(self, condition): + try: + self.driver.save_screenshot(self.name) + except: + LOG.critical("Can not create screenshot file.") + if condition: + LOG.info(self.name + " PASSED") + return True + else: + LOG.critical(self.name + " FAILED") + return False \ No newline at end of file