Skip to content
parserobotfile.py 5.2 KiB
Newer Older
import re
import os
from checks import Checks


class ParseRobotFile:
    def __init__(self, filename: str, execdir: str):
        self.test_suite = os.path.basename(filename).split('.')[0]

        with open(filename, 'r') as file:
            # Read the contents of the file
            self.file_contents = file.read()

        self.variables = dict()
        self.execdir = execdir
        self.resource_file = str()

        self.get_variables_data()
        self.get_apiutils_path()
        self.get_test_cases()

    def get_variables_data(self):
        string = self.get_substring(initial_string='*** Variables ***\n', final_string='*** ', include=False)

        regex = r"(\$\{.*\})\s*=\s*(.*)\n"

        matches = re.finditer(regex, string, re.MULTILINE)
        for match in matches:
            # Check that we have two groups matched
            if len(match.groups()) == 2:
                self.variables[match.group(1)] = match.group(2)
            else:
                print("Error, the variable is not following the format ${thing} = <value>")

    def get_expected_status_code(self, keyword: str):
        #     Check Response Status Code    ${expected_status_code}    ${response.status_code}
        #     Check Response Body Containing ProblemDetails Element Containing Type Element set to
        #     ...    ${response.json()}
        #     ...    ${ERROR_TYPE_LD_CONTEXT_NOT_AVAILABLE}
        string = self.get_substring(initial_string=keyword, final_string='\n', include=True)
        expected_status_code = string.split('    ')[1]

        if expected_status_code.isdigit():
            return expected_status_code
        else:
            return self.variables[expected_status_code]

    def get_apiutils_path(self):
        string = self.get_substring(initial_string='Resource', final_string='*** Variables ***', include=True)
        result = [item for item in string.split('\n') if 'ApiUtils.resource' in item and item[0] != '#']

        if len(result) == 1:
            regex = r"\s*Resource\s*(.*)\s*"

            matches = re.finditer(regex, result[0], re.MULTILINE)
            for match in matches:
                # Check that we have 1 group matched
                if len(match.groups()) == 1:
                    self.resource_file = match.group(1)
                else:
                    print("Error, unexpected format")

            self.resource_file = self.resource_file.replace('${EXECDIR}', self.execdir)

    def get_substring(self, initial_string: str, final_string: str, include: bool) -> str:
        index_start = self.file_contents.find(initial_string)

        if include:
            string = self.file_contents[index_start:]
        else:
            string = self.file_contents[index_start+len(initial_string):]

        if final_string is not '':
            index_end = string.find(final_string)
            string = string[:index_end]

        return string

    def get_test_cases(self):
        index_start = self.file_contents.find('*** Test Cases ***')
        string = self.file_contents[index_start+len('*** Test Cases ***')+1:]
        print(string)

        pattern = f'{self.test_suite}_\d+\s.*'
        matches = re.findall(pattern=pattern, string=string)

        indexes = list()
        self.test_case_names = list()
        for match in matches:
            name = match.strip()
            self.test_case_names.append(name)
            indexes.append(string.find(name))

        self.test_cases = dict()
        for i in range(0, len(indexes)-1):
            self.test_cases[self.test_case_names[i]] = string[indexes[i]:indexes[i+1]]

        self.test_cases[self.test_case_names[-1]] = string[indexes[-1]:]
        print()

    def get_checks(self, test_name, apiutils):
        data = Checks()

        test_content = self.test_cases[test_name]

        # Get The lines starting by 'Check'
        checks = list()
        param = dict()
        lines_starting_with_check = re.findall(r'^\s*Check.*', test_content, re.MULTILINE)
        for line in lines_starting_with_check:
            check, param = self.get_data_check(content=test_content, checks=data, line=line.strip())
            result = data.get_checks(checks=check, **param)
            checks.append(check)

        return checks

    def get_data_check(self, content, checks, line):
        content = line.split("    ")
        aux = len(content)
        position_params = checks.args[content[0]]

        if aux == 1:
            # We are in multiline classification of the Check, need to extract the parameter for the next lines
            self.find_attributes_next_line(content=content, name=content[0])
        elif aux > 1:
            # We are in one line definiton
            param = dict()
            for i in range(0, len(position_params['position'])):
                param_key = position_params['params'][i]
                param_position = position_params['position'][i]
                param_value = self.variables[content[param_position]]
                param[param_key] = param_value

                return content[0], param
        else:
            raise Exception("ERROR, line should contain data")

    def find_attributes_next_line(self, content, name):
        index_start = content.find(name)

        aux = content[index_start+len(name)+1:]