def compose_send_email(exec_type, abs_filepath, logs_dir, results_dir, result,
                       mail_on="per_execution"):
    """ compose and sends email from smtp server using input arguments as:
    :Arguments:
        1. exec_type - type of test(case/suite/project)
        2. abs_filepath - full path of case/suite/project
        3. logs_dir - full path of logs directory
        4. results_dir - full path of results directory
        5. result - execution result
        6. mail_on(optional) - it is to specify when to send an email
           Supported options below:
                (1) per_execution(default)
                (2) first_failure
                (3) every_failure
    """
    resultconverted = {"True": "Pass", "False": "Fail", "ERROR": "Error",
                       "EXCEPTION": "Exception", "RAN": "Ran"}.get(str(result))
    subject = str(resultconverted)+": "+file_Utils.getFileName(abs_filepath)
    body = construct_mail_body(exec_type, abs_filepath, logs_dir, results_dir)
    report_attachment = results_dir + os.sep + \
        file_Utils.getNameOnly(file_Utils.getFileName(abs_filepath)) + ".html"
    log_attachment = logs_dir + os.sep + \
        file_Utils.getNameOnly\
        (file_Utils.getFileName(abs_filepath)) + "_consoleLogs.log"

    if mail_on in ["per_execution"] and file_Utils.fileExists(report_attachment):
        files = [report_attachment]
    elif mail_on in ["first_failure", "every_failure"] and file_Utils.fileExists(log_attachment):
        files = [log_attachment]
    set_params_send_email(subject, body, files, mail_on)
Example #2
0
    def print_execution_summary_details(self, suite_tc_exec):
        """To print the consolidated test cases result in console at the end of
           Test Case/Test Suite/Project Execution"""
        for suite_tc in suite_tc_exec:
            path = suite_tc[3]
            name = suite_tc[1]
            if suite_tc_exec[0][0] == 'Suites' and file_Utils.fileExists(path):
                if suite_tc[0] == 'Testcase':
                    if str(suite_tc[4]).strip().upper() != 'NO_DATA' and \
                            suite_tc[4] is not False and \
                            file_Utils.fileExists(suite_tc[4]):
                        name = name + ' [' + os.path.basename(
                            suite_tc[4]) + ']'

            print_info(
                ("{0:10}{1:50}{2:10}{3:30}".format(suite_tc[0], name,
                                                   suite_tc[2], suite_tc[3])))
Example #3
0
def warrior_framework_details():
    """This gets framework details such the executing framework path, release
        & version details.
    """
    #The logic uses relative file path to locate Warrior framework and its\
    # release notes.Assumes the relative structure remains constant.
    release = False
    version = False
    version_file_path = os.path.normpath(os.path.join(__file__, "..{0}..{0}..".format(os.sep)))
    version_file = os.path.join(version_file_path, "version.txt")
    version_file_exists = file_Utils.fileExists(version_file)
    if version_file_exists:
        release_notes = open(version_file, "r")
        for line in release_notes:
            line = line.strip()
            #pattern matching Release:<>
            if re.match('(Release.*):(.*)', line):
                match = re.match(r'(Release.*):(.*)', line)
                release = match.group(2)
            #pattern matching Version:<>
            if re.match('(Version.*):(.*)', line):
                match = re.match(r'(Version.*):(.*)', line)
                version = match.group(2)

    user = getpass.getuser()
    if os.getenv("pipmode",None) == "False":
        #get warriorframework_py3 repo branch
        proc1 = subprocess.Popen(['git', 'branch'], stdout=subprocess.PIPE)
        proc2 = subprocess.Popen(['grep', '*'], stdin=proc1.stdout,
                                 stdout=subprocess.PIPE, stderr=None)
        proc1.stdout.close() # Allow proc1 to receive a SIGPIPE if proc2 exits.
        branch = proc2.communicate()[0]
        branch = branch.decode('utf-8')
        branch = branch.strip()[1:]
    hostname = platform.node()

    if release and version and version_file_path:
        pNote("========================== WARRIOR FRAMEWORK DETAILS ==========================",
              'notype')
        print_info('The Warrior framework used is {0}'.format(version_file_path))
        print_info('The Warrior framework user is {0}'.format(user))
        print_info('The Warrior framework Release is{0}'.format(release))
        print_info('The Warrior framework version is{0}'.format(version))
        if os.getenv("pipmode",None) == "False":
            print_info('The Warrior framework branch is{0}'.format(branch))
        print_info('The Warrior framework running on python version: {0} with OS: {1}'.
                   format(platform.python_version(), platform.platform()))
        print_info('Warrior script executed in host [{0}] on [{1}]'.format(hostname, date.today()))
        pNote("========================== WARRIOR FRAMEWORK DETAILS ==========================",
              'notype')

    #Sleep for the user to view the console for a second on the framework detail
    time.sleep(2)
    return None
def get_execution_files(filepath, execution_dir, extn):
    """Get the execution files like resultfile, logfile etc"""

    filename = file_Utils.getFileName(filepath)
    nameonly = file_Utils.getNameOnly(filename)
    if extn.lower() == "res":
        fullpath = execution_dir + os.sep + nameonly + "_results" + "." + extn
    else:
        fullpath = execution_dir + os.sep + nameonly + '.' + extn
    if file_Utils.fileExists(fullpath):
        fullpath = file_Utils.addTimeDate(fullpath)
    return fullpath
Example #5
0
 def check_tmp_file_exists(self, system_name="", filename=""):
     """ check if temp folder exist in the parallel execution result tmp dir """
     if system_name != "" and filename == "":
         filename = data_Utils.getSystemData(self.datafile, system_name,
                                             "filename")
     elif system_name == "" and filename == "":
         pNote("No system or filename found, needs to provide at least one",
               "error")
     path = data_Utils.get_object_from_datarepository(
         "parallel_exec_tmp_dir")
     path = os.path.join(path, filename)
     return file_Utils.fileExists(path)
 def check_defect_file(path):
     """Gets the list of defect json files for the testcase execution """
     abs_cur_dir = os.path.abspath(os.curdir)
     value = None
     if path.endswith(".json"):
         defect_file = file_Utils.getAbsPath(path, abs_cur_dir)
         if file_Utils.fileExists(defect_file):
             print_info("Defect file location is :{0}".format(defect_file))
             value = defect_file
         else:
             print_error("File Does not exist in provided location: "\
                         "{0} relative to cwd".format(path))
     return value
    def check_get_datafile(self):
        """Check InputDatFile tag in the xml file and
        based on the values return the datafile to be used for the testcase/testsuite
            - If user provided a datafile, will use it.
            - If user specified 'Default' will use the default datafile
            - If user did not provide any value will use default datafile
            - If user specified 'NODATA' will print a msg saying so.
        """

        datafile = xml_Utils.getChildTextbyParentTag(self.filepath, 'Details',
                                                     'InputDataFile')
        if datafile is None or datafile is False or \
                str(datafile).strip() == "":
            if self.filetype == "tc":
                # print "get default datatype for testcase"
                datafile = get_default_xml_datafile(self.filepath)
            if self.filetype == "ts":
                # Check if test suite datatype starts with iterative.
                # If yes then get default datafile else set it as false
                # this is because at testsuite level input datafile is
                # supported only if the suite datatype is iterative seq/parallel
                datatype = self.check_get_datatype(False)
                if str(datatype).lower().startswith("iterative"):
                    datafile = get_default_xml_datafile(self.filepath)
                else:
                    datafile = False
            elif self.filetype == "proj":
                datafile = False
        elif str(datafile).strip().upper() == "DEFAULT":
            print_debug(
                "This testcase will be executed using the default InputDataFile"
            )
            datafile = get_default_xml_datafile(self.filepath)
        elif str(datafile).strip().upper() == 'NO_DATA':
            print_debug('This test case will be run without any InputDataFile')
            datafile = "NO_DATA"

        elif datafile is not None and datafile is not False:
            datafile_rel = str(datafile).strip()
            datafile = file_Utils.getAbsPath(datafile_rel,
                                             os.path.dirname(self.filepath))

        if str(datafile).strip().upper(
        ) != 'NO_DATA' and datafile is not False:
            if not file_Utils.fileExists(datafile):
                print_debug('\n')
                print_error("!!! *** InputDataFile does not exist in provided path:" \
                            "{0} *** !!!".format(datafile))
        return datafile
def construct_mail_body(exec_type, abs_filepath, logs_dir, results_dir):
    """ construct e-mail body with Project, Logs/Results directory & Execution summary
    :Arguments:
        1. exec_type - type of test(case/suite/project)
        2. abs_filepath - full path of case/suite/project
        3. logs_dir - full path of logs directory
        4. results_dir - full path of results directory
    :Returns:
        1. body - return mail body
    """
    junit_result_file = os.path.join(
        results_dir, file_Utils.getNameOnly(file_Utils.getFileName(abs_filepath))) + "_junit.xml"
    suite_tc, body = "", ""
    body_arg = ('<html><body><p><b>{0}</b>{1}</p>'
                '<p><b>Logs directory:</b>{2}</p>'
                '<p><b>Results directory:</b>{3}</p>').format(exec_type, abs_filepath,\
                                                    logs_dir, results_dir)
    body_arg1 = ('<p><b>Execution Summary:</b></p>'
                '<table cellspacing="10" cellpadding="0"><tr><td><b>Type</b>'
                '</td><td><b>Name</b></td><td><b>Status</b></td>'
                '<td><b>Path</b></td></tr>')
    if file_Utils.fileExists(junit_result_file):
        body_arg = body_arg + body_arg1
        junit_object = ExecutionSummary(junit_result_file)
        project_sum = junit_object.project_summary(junit_result_file)
        suite_tc_sum = junit_object.suite_summary(junit_result_file)
        # complete html body that will be sent through mail
        if exec_type == 'Project: ':
            project = ""
            for proj in project_sum:
                project = project + ('<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td></tr>\n'\
                                 .format(proj[0], proj[1], proj[2], proj[3]))
            for value in suite_tc_sum:
                suite_tc = suite_tc + ('<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td></tr>\n'\
                                   .format(value[0], value[1], value[2], value[3]))
            body = body_arg + project + suite_tc + "</table></body></html>"
        elif exec_type == 'Test Suite: ' or exec_type == 'Test Case: ':
            for value in suite_tc_sum:
                suite_tc = suite_tc + ('<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td></tr>\n'\
                                   .format(value[0], value[1], value[2], value[3]))
            body = body_arg + suite_tc + "</table></body></html>"
    else:
        body = body_arg + "</table></body></html>"
    return body
Example #9
0
 def print_result_in_console(self, junit_file):
     """To print the consolidated test cases result in console at the end of Test Case/Test
        Suite/Project Execution"""
     file_type = self.get_file_type(junit_file)
     # Formatting execution summary as project_summary and suite_summary returns the list values
     print_info(
         "+++++++++++++++++++++++++++++++++++++++++++++++++ Execution Summary +++++++++++++++++++++++++++++++++++++++++++++++++"
     )
     print_info("{0:10}{1:50}{2:10}{3:50}".format('Type', 'Name [DataFile]',
                                                  'Status', 'Path'))
     if file_type == "Project":
         project_exec = self.project_summary(junit_file)
         invalid_suite_path = []
         for proj in project_exec:
             print_info(
                 ("{0:10}{1:50}{2:10}{3:30}".format(proj[0], proj[1],
                                                    proj[2], proj[3])))
             testsuite_list = common_execution_utils.get_steps_lists(
                 proj[3], "Testsuites", "Testsuite")
             project_dir = os.path.dirname(proj[3])
             for testsuite in testsuite_list:
                 testsuite_rel_path = testsuite_utils.get_path_from_xmlfile(
                     testsuite)
                 if testsuite_rel_path is not None:
                     testsuite_path = Utils.file_Utils.getAbsPath(
                         testsuite_rel_path, project_dir)
                 else:
                     testsuite_path = str(testsuite_rel_path)
                 if not file_Utils.fileExists(testsuite_path):
                     invalid_suite_path.append([
                         "Suites",
                         os.path.basename(testsuite_path), "ERROR",
                         testsuite_path
                     ])
         suite_tc_list = self.suite_summary(junit_file)
         suite_tc_exec = invalid_suite_path + suite_tc_list
         self.print_execution_summary_details(suite_tc_exec)
     elif file_type == "Suites":
         suite_tc_exec = self.suite_summary(junit_file)
         self.print_execution_summary_details(suite_tc_exec)
     print_info(
         "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
     )
Example #10
0
    def _make_ff(self, webdriver_remote_url, desired_capabilites, profile_dir,
                 **kwargs):
        """Create an instance of firefox browser"""
        binary = kwargs.get("binary", None)
        gecko_path = kwargs.get("gecko_path", None)
        # gecko_log is the absolute path to save geckodriver log
        gecko_log = kwargs.get("gecko_log", None)
        proxy_ip = kwargs.get("proxy_ip", None)
        proxy_port = kwargs.get("proxy_port", None)
        ff_profile = None
        # if firefox is being used with proxy, set the profile here
        # if firefox_proxy details are not given, set profile_dir
        # as the ff_profile.
        if proxy_ip is not None and proxy_port is not None:
            ff_profile = self.set_firefox_proxy(profile_dir, proxy_ip,
                                                proxy_port)
        else:
            ff_profile = profile_dir
        log_dir = get_object_from_datarepository("wt_logsdir") if \
                  gecko_log in [None, False] else gecko_log
        log_dir = os.path.join(
            log_dir, "gecko_" + kwargs.get("browser_name", "default") + ".log")

        browser = None
        try:
            if webdriver_remote_url:
                browser = self._create_remote_web_driver(
                    webdriver.DesiredCapabilities.FIREFOX,
                    webdriver_remote_url, desired_capabilites, ff_profile)
            else:
                optional_args = {}
                ff_capabilities = webdriver.DesiredCapabilities.FIREFOX
                # This is for internal testing needs...some https cert is not secure
                # And firefox will need to know how to handle it
                ff_capabilities['acceptInsecureCerts'] = True

                if binary not in [False, None]:
                    if not fileExists(binary):
                        print_warning(
                            "Given firefox binary '{}' does not exist, default "
                            "firefox will be used for execution.".format(
                                binary))
                        binary = None
                else:
                    print_info("No value given for firefox binary, default "
                               "firefox will be used for execution.")

                # Force disable marionette, only needs in Selenium 3 with FF ver < 47
                # Without these lines, selenium may encounter capability not found issue
                # https://github.com/seleniumhq/selenium/issues/2739
                # https://github.com/SeleniumHQ/selenium/issues/5106#issuecomment-347298110
                if self.get_firefox_version(binary) < LooseVersion("47.0.0"):
                    ff_capabilities["marionette"] = False
                else:
                    # gecko_log will only get generate if there is failure/error
                    # Need to specify log_path for geckodriver log
                    # Gecko driver will only launch if FF version is 47 or above
                    optional_args["log_path"] = log_dir

                ffbinary = FirefoxBinary(
                    binary) if binary is not None else None
                if gecko_path is not None:
                    optional_args["executable_path"] = gecko_path
                browser = webdriver.Firefox(firefox_binary=ffbinary,
                                            capabilities=ff_capabilities,
                                            firefox_profile=ff_profile,
                                            **optional_args)
        except WebDriverException as err:
            if "executable needs to be in PATH" in str(err):
                print_error("Please provide path for geckodriver executable")
            elif "Expected browser binary location" in str(err):
                print_error("Please provide path of firefox executable")
            print_error(err)
            traceback.print_exc()
        except Exception as err:
            print_error(err)
            traceback.print_exc()

        if browser is None and\
           any((LooseVersion(webdriver.__version__) < LooseVersion("3.5.0"), gecko_path is None)):
            print_info("Unable to create Firefox browser, one possible reason is because"\
                       "Firefox version >= 47.0.1 and Selenium version < 3.5"\
                       "In order to launch Firefox ver 47 and up, Selenium needs to be updated to >= 3.5"\
                       "and needs geckodriver > 0.16")

        return browser
Example #11
0
    def suite_summary(self, junit_file):
        """ To get the name, status and location of both test suite and test case"""
        tree = xml_Utils.get_tree_from_file(self.junit_file)
        suite_tc_list = []
        for values in tree.iter('testsuite'):
            suite_detail = values.attrib
            suite_name = suite_detail.get('name')
            suite_status = suite_detail.get('status')
            suite_location = suite_detail.get('suite_location')
            suite_result_dir = suite_detail.get('resultsdir')
            if suite_location is not None:
                suite_tc_list.append(
                    ["Suites", suite_name, suite_status, suite_location])
                testsuite_dir = os.path.dirname(suite_location)
                testcase_list = common_execution_utils.get_steps_lists(
                    suite_location, "Testcases", "Testcase", randomize=False)
                for tests in testcase_list:
                    tc_rel_path = testsuite_utils.get_path_from_xmlfile(tests)
                    if tc_rel_path is not None:
                        tc_path = Utils.file_Utils.getAbsPath(
                            tc_rel_path, testsuite_dir)
                    else:
                        tc_path = str(tc_rel_path)
                    if not file_Utils.fileExists(tc_path):
                        suite_tc_list.append([
                            "Testcase",
                            os.path.basename(tc_path), "ERROR", tc_path
                        ])
            #to add Setup results in suite summary
            for value in tree.iter('Setup'):
                setup_details = value.attrib
                setup_status = setup_details.get('status')
                setup_name = setup_details.get('name') + ".xml"
                setup_location = setup_details.get('testcasefile_path')
                case_result_dir_with_tc_name = setup_details.get('resultsdir')
                if case_result_dir_with_tc_name is not None:
                    case_result_dir = os.path.dirname(
                        case_result_dir_with_tc_name)
                    # suite junit element will not have resultsdir attrib for case execution
                    if suite_result_dir is None or suite_result_dir == case_result_dir:
                        suite_tc_list.append([
                            "Setup", setup_name, setup_status, setup_location
                        ])
            for value in tree.iter('testcase'):
                testcase_details = value.attrib
                testcase_status = testcase_details.get('status')
                testcase_name = testcase_details.get('name') + ".xml"
                testcase_location = testcase_details.get('testcasefile_path')
                case_result_dir_with_tc_name = testcase_details.get(
                    'resultsdir')
                testcase_datafile = testcase_details.get('data_file')
                if case_result_dir_with_tc_name is not None:
                    case_result_dir = os.path.dirname(
                        case_result_dir_with_tc_name)
                    # suite junit element will not have resultsdir attrib for case execution
                    if suite_result_dir is None or suite_result_dir == case_result_dir:
                        suite_tc_list.append([
                            "Testcase", testcase_name, testcase_status,
                            testcase_location, testcase_datafile
                        ])
            #to add debug results in suite summary
            for value in tree.iter('Debug'):
                debug_details = value.attrib
                debug_status = debug_details.get('status')
                debug_name = debug_details.get('name') + ".xml"
                debug_location = debug_details.get('testcasefile_path')
                case_result_dir_with_tc_name = debug_details.get('resultsdir')
                if case_result_dir_with_tc_name is not None:
                    case_result_dir = os.path.dirname(
                        case_result_dir_with_tc_name)
                    # suite junit element will not have resultsdir attrib for case execution
                    if suite_result_dir is None or suite_result_dir == case_result_dir:
                        suite_tc_list.append([
                            "Debug", debug_name, debug_status, debug_location
                        ])
            #to add Cleanup results in suite summary
            for value in tree.iter('Cleanup'):
                cleanup_details = value.attrib
                cleanup_status = cleanup_details.get('status')
                cleanup_name = cleanup_details.get('name') + ".xml"
                cleanup_location = cleanup_details.get('testcasefile_path')
                case_result_dir_with_tc_name = cleanup_details.get(
                    'resultsdir')
                if case_result_dir_with_tc_name is not None:
                    case_result_dir = os.path.dirname(
                        case_result_dir_with_tc_name)
                    # suite junit element will not have resultsdir attrib for case execution
                    if suite_result_dir is None or suite_result_dir == case_result_dir:
                        suite_tc_list.append([
                            "Cleanup", cleanup_name, cleanup_status,
                            cleanup_location
                        ])

        # suite_tc_list appends suites and test cases as per execution order
        return suite_tc_list
    def set_line_objs(self):
        """ call to create a new obj per item"""
        self.lineCount = 0
        project_node_list = [self.junit_root]
        for project_node in project_node_list:
            self.create_line_result(project_node, "Project")
            for pro_node in project_node.findall("property"):
                if pro_node.get('name') == 'location':
                    pro_location = pro_node.get('value')

                    testsuite_list = common_execution_utils.get_steps_lists(
                        pro_location, "Testsuites", "Testsuite")
                    project_dir = os.path.dirname(pro_location)
                    for testsuite in testsuite_list:
                        testsuite_rel_path = testsuite_utils.get_path_from_xmlfile(
                            testsuite)
                        if testsuite_rel_path is not None:
                            testsuite_path = Utils.file_Utils.getAbsPath(
                                testsuite_rel_path, project_dir)
                        else:
                            testsuite_path = str(testsuite_rel_path)
                        if not file_Utils.fileExists(testsuite_path):
                            self.create_line_result(
                                {
                                    'name':
                                    os.path.splitext(
                                        os.path.basename(testsuite_path))[0],
                                    'status':
                                    'ERROR'
                                }, "InvalidTestsuite")
            for testsuite_node in project_node.findall("testsuite"):
                self.create_line_result(testsuite_node, "Testsuite")
                all_testcases = []
                if testsuite_node.get('suite_location'):
                    testsuite_dir = os.path.dirname(
                        testsuite_node.get('suite_location'))
                    testcase_list = common_execution_utils.get_steps_lists(
                        testsuite_node.get('suite_location'),
                        "Testcases",
                        "Testcase",
                        randomize=False)
                    for tests in testcase_list:
                        tc_rel_path = testsuite_utils.get_path_from_xmlfile(
                            tests)
                        if tc_rel_path is not None:
                            tc_path = Utils.file_Utils.getAbsPath(
                                tc_rel_path, testsuite_dir)
                        else:
                            tc_path = str(tc_rel_path)
                        if not file_Utils.fileExists(tc_path):
                            all_testcases.append({
                                'name':
                                os.path.splitext(os.path.basename(tc_path))[0],
                                'status':
                                'ERROR'
                            })
                full_testcasess = all_testcases + testsuite_node.findall(
                    "testcase")
                #to add setup result in html file
                for setup_node in testsuite_node.findall("Setup"):
                    self.create_line_result(setup_node, "Setup")
                    self.steps = 0
                    for step_node in setup_node.findall("properties"):
                        for node in step_node.findall("property"):
                            if node.get('type') == 'keyword':
                                self.steps += 1
                                self.create_line_result(node, "Keyword")
                for testcase_node in full_testcasess:
                    self.create_line_result(testcase_node, "Testcase")
                    self.steps = 0
                    if testcase_node.get('status') != 'ERROR':
                        for step_node in testcase_node.findall("properties"):
                            for node in step_node.findall("property"):
                                if node.get('type') == 'keyword':
                                    self.steps += 1
                                    self.create_line_result(node, "Keyword")
                #to add debug result in html file
                for debug_node in testsuite_node.findall("Debug"):
                    self.create_line_result(debug_node, "Debug")
                    self.steps = 0
                    for step_node in debug_node.findall("properties"):
                        for node in step_node.findall("property"):
                            if node.get('type') == 'keyword':
                                self.steps += 1
                                self.create_line_result(node, "Keyword")
                #to add cleanup result in html file
                for cleanup_node in testsuite_node.findall("Cleanup"):
                    self.create_line_result(cleanup_node, "Cleanup")
                    self.steps = 0
                    for step_node in cleanup_node.findall("properties"):
                        for node in step_node.findall("property"):
                            if node.get('type') == 'keyword':
                                self.steps += 1
                                self.create_line_result(node, "Keyword")