Esempio n. 1
0
 def readConfig(self):
     """ Read existing mail.ini file if not exist then will write one with empty values"""
     self.globalSettings = {}
     config = configparser.ConfigParser()
     managedPaths = ManagedPaths()
     config_file = managedPaths.getOrSetIni().joinpath("mail.ini")
     if not os.path.exists(config_file):
         self.write_config(config_file)
     config.read(config_file)
     self.globalSettings["SendMailTo"] = config["Default"].get("SendMailTo"
                                         ) or self.write_config(config_file, "SendMailTo", "")
     self.globalSettings["NotificationWithAttachment"] = config["Default"].get("NotificationWithAttachment"
                                         ) or self.write_config(config_file, "NotificationWithAttachment", False)
     self.globalSettings["MsWebHook"] = config["Default"].get("MsWebHook"
                                         ) or self.write_config(config_file, "MsWebHook", "")
     self.globalSettings["SlackWebHook"] = config["Default"].get("SlackWebHook"
                                         ) or self.write_config(config_file, "SlackWebHook", "")
     self.globalSettings["TelegramBot"] = config["Default"].get("TelegramBot"
                                                                 ) or self.write_config(config_file, "TelegramBot",
                                                                                        "")
     self.globalSettings["TelegramChannel"] = config["Default"].get("TelegramChannel"
                                                                 ) or self.write_config(config_file, "TelegramChannel",
                                                                                        "")
     self.globalSettings["Confluence-Base-Url"] = config["Default"].get("Confluence-Base-Url") or self.write_config(
         config_file, "Confluence-Base-Url", "")
Esempio n. 2
0
class UI:
    """
    Provides a simple UI for Testrun-Execution
    """
    def __init__(self):
        self.configFile = None
        self.tempConfigFile = None
        self.configFiles = []
        self.testRunFile = None
        self.testRunFiles = []
        self.configContents = {}
        self.window = None
        self.toggleAdditionalFieldsVisible = False

        self.iconFileWindow = b"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"
        self.directory = None
        self.mainWindowPosition = (None, None)
        self.managedPaths = ManagedPaths()

        self.readConfig()

        if not self.directory:
            self.directory = self.managedPaths.derivePathForOSAndInstallationOption(
            )  #.getcwd()

        self.getConfigFilesInDirectory()

        self.startWindow()

    # def getLayout(self):
    #
    #     lMenu = [['&File', ['&Open', '&Save', 'E&xit', 'Properties']],
    #              ['&Katalon Studio', ['Paste', ['Special', 'Normal', ], 'Undo'], ],
    #              ['&Help', '&About...'], ]
    #     # lMenu doesnt' work. It shows up in the Mac-Menu, but none of the buttons work. Even the
    #     # Mac-Button stops working until the window is closed
    #
    #     lColumnLeft = [[sg.Text("")],
    #                    [sg.Text("Path", size=(10,1), font="Helvetica 10 bold"),
    #                     sg.In(key="-directory-", size=(31,1), enable_events=True, default_text=self.directory, font="Helvetica 12"),
    #                     sg.FolderBrowse(initial_folder=os.getcwd(), font="Helvetica 10", enable_events=True, size=(10,1))]]
    #
    #     lColumnLeft.append([sg.Text("TestRun", size=(10, 1), font="Helvetica 10 bold"),
    #                     sg.InputCombo(self.testRunFiles, key="testRunFile", default_value=self.testRunFile,
    #                                   size=(29, 1), font="Helvetica 12"),
    #                     sg.Button("Execute", size=(10, 1), font="Helvetica 10", button_color=('white', 'darkgreen'))])
    #
    #     lColumnLeft.append([sg.Text("Settings", size=(10, 1), font="Helvetica 10 bold"),
    #                         sg.InputCombo(self.configFiles, key="configFile", default_value=self.configFile,
    #                                       enable_events=True, size=(29, 1), font="Helvetica 12"),
    #                         sg.Button("Details", size=(10, 1), font="Helvetica 10", key="ToggleFields")])
    #
    #     # Baangt Logo
    #     lPathLogo = Path(__file__).parent.parent.parent.joinpath("ressources").joinpath("baangtLogo2020Small.png")
    #     # when in pip-Package, this doesn't work.
    #     if not lPathLogo.exists():
    #         lPathLogo = Path(__file__).parent.parent.joinpath("ressources").joinpath("baangtLogo2020Small.png")
    #
    #     lColumnRight = [[sg.Image(filename=lPathLogo)]]
    #
    #     lLayout = [[sg.Menu(lMenu)],
    #                [sg.Col(lColumnLeft, pad=(0,0)),
    #                 sg.Col(lColumnRight, pad=(0,0), justification="right")]]
    #
    #     # Show the button to provide more details
    #     ttip_Recorder = 'Will start the Katalon Recorder Importer'
    #
    #     if self.configContents:
    #         lLayout.append([sg.Text(f"SETTINGS IN {self.configFile}", font="Helvetica 8 bold",
    #                                 visible=self.toggleAdditionalFieldsVisible)])
    #         for key, value in self.configContents.items():
    #             lLayout.append([sg.In(key, key="-attrib-" + key, size=(28,1), visible=self.toggleAdditionalFieldsVisible),
    #                             sg.In(key="-val-"+key, size=(34,1), default_text=value, visible=self.toggleAdditionalFieldsVisible)])
    #         for i in range(0,4):
    #             lLayout.append([sg.In(key=f"-newField-{i}", size=(28,1), visible=self.toggleAdditionalFieldsVisible),
    #                             sg.In(key=f"-newValue-{i}", size=(34,1), visible=self.toggleAdditionalFieldsVisible)])
    #
    #         lLayout.append([sg.Button('Save', size=(13,1)),
    #                         sg.Button("SaveAs", size=(13,1)),
    #                         sg.Button("Import Recorder", size=(13,1), tooltip=ttip_Recorder),
    #                         sg.Button("Import Katalon", size=(13,1), disabled=True),])
    #         lLayout.append([sg.T()])
    #
    #     return lLayout
    #
    # def startWindow(self):
    #     sg.theme("LightBrown1")
    #
    #     self.window = sg.Window("baangt Interactive Starter", layout=self.getLayout(), location=self.mainWindowPosition,
    #                             icon=self.iconFileWindow)  # size=(750,400)
    #     lWindow = self.window
    #     lWindow.finalize()
    #
    #     while True:
    #         lEvent, lValues = lWindow.read(timeout=200)
    #         if lEvent == "Exit":
    #             break
    #
    #         if not lEvent:       # Window was closed by "X"-Button
    #             break
    #
    #         self.mainWindowPosition = lWindow.CurrentLocation()
    #
    #         if lValues.get('-directory-') != self.directory:
    #             self.directory = lValues.get("-directory-")
    #             self.getConfigFilesInDirectory()
    #
    #         if lValues["testRunFile"]:
    #             self.testRunFile = lValues["testRunFile"]
    #
    #         if lValues["configFile"]:
    #             if lValues["configFile"] != self.configFile:
    #                 self.configFile = lValues['configFile']
    #                 self.readContentsOfGlobals()
    #                 lWindow = self.reopenWindow(lWindow)
    #
    #         if lEvent == 'Save':
    #             lWindow = self.saveConfigFileProcedure(lWindow, lValues)
    #
    #         if lEvent == 'SaveAs':
    #             self.configFile = sg.popup_get_text("New Name of Configfile:")
    #             if len(self.configFile) > 0:
    #                 lWindow = self.saveConfigFileProcedure(lWindow, lValues)
    #
    #         if lEvent == "Execute":
    #             self.modifyValuesOfConfigFileInMemory(lValues=lValues)
    #             self.runTestRun()
    #
    #         if lEvent == "Import Recorder":
    #             lRecorder = ImportKatalonRecorder(self.directory)
    #             self.getConfigFilesInDirectory()   # Refresh display
    #             lWindow['testRunFile'].update(values=self.testRunFiles,
    #                                           value=lRecorder.fileNameExport)
    #
    #         if lEvent == 'ToggleFields':
    #             lWindow = self.toggleAdditionalFieldsExecute(lWindow=lWindow)
    #
    #     self.saveInteractiveGuiConfig()
    #     lWindow.close()

    def saveConfigFileProcedure(self, lWindow, lValues):
        # receive updated fields and values to store in JSON-File
        self.modifyValuesOfConfigFileInMemory(lValues)
        self.saveContentsOfConfigFile()
        lWindow = self.reopenWindow(lWindow)
        return lWindow

    # def reopenWindow(self, lWindow):
    #     lSize = lWindow.Size
    #     lPosition = lWindow.CurrentLocation()
    #     lWindow.close()
    #     self.window = sg.Window("baangt Interactive Starter", layout=self.getLayout(),
    #                             location=lPosition, icon=self.iconFileWindow)
    #     lWindow = self.window
    #     lWindow.finalize()
    #     return lWindow
    #
    # def toggleAdditionalFieldsExecute(self, lWindow):
    #     if self.toggleAdditionalFieldsVisible:
    #         self.toggleAdditionalFieldsVisible = False
    #     else:
    #         self.toggleAdditionalFieldsVisible = True
    #
    #     lWindow = self.reopenWindow(lWindow=lWindow)
    #     return lWindow
    #
    # def runTestRun(self):
    #     if not self.configFile:
    #         sg.popup_cancel("No Config File selected - can't run")
    #         return
    #     if not self.testRunFile:
    #         sg.popup_cancel("No Testrun File selected - can't run")
    #         return
    #     runCmd = self._getRunCommand()
    #     if self.configContents.get("TX.DEBUG"):
    #         from baangt.base.TestRun.TestRun import TestRun
    #
    #         lTestRun = TestRun(f"{Path(self.directory).joinpath(self.testRunFile)}",
    #                            globalSettingsFileNameAndPath=f'{Path(self.directory).joinpath(self.tempConfigFile)}')
    #
    #     else:
    #         logger.info(f"Running command: {runCmd}")
    #         p = subprocess.run(runCmd, shell=True, close_fds=True)
    #
    #
    #     sg.popup_ok("Testrun finished")
    #     # Remove temporary Configfile, that was created only for this run:
    #     try:
    #         os.remove(Path(self.directory).joinpath(self.tempConfigFile))
    #     except Exception as e:
    #         logger.warning(f"Tried to remove temporary file but seems to be not there: "
    #                        f"{self.directory}/{self.tempConfigFile}")

    def _getRunCommand(self):
        """
        If bundled (e.g. in pyinstaller), then the executable is already sys.executable,
        otherwise we need to concatenate executable and Script-Name before we can start
        a subprocess.

        @return: Full path and filename to call Subprocess
        """
        lStart = sys.executable
        if "python" in sys.executable.lower():
            if len(Path(sys.argv[0]).parents) > 1:
                # This is a system where the path the the script is given in sys.argv[0]
                lStart = lStart + f" {sys.argv[0]}"
            else:
                # this is a system where we need to join os.getcwd() and sys.argv[0] because the path is not given in sys.argv[0]
                lStart = lStart + f" {Path(os.getcwd()).joinpath(sys.argv[0])}"

        self.__makeTempConfigFile()

        return f"{lStart} " \
               f"--run='{Path(self.directory).joinpath(self.testRunFile)}' " \
               f"--globals='{Path(self.directory).joinpath(self.tempConfigFile)}'"

    def __makeTempConfigFile(self):
        """
        Add parameters to the Config-File for this Testrun and save the file under a temporary name
        """
        self.configContents[GC.PATH_ROOT] = self.directory

        # self.configContents[GC.PATH_SCREENSHOTS] = str(Path(self.directory).joinpath(GC.PATH_SCREENSHOTS))
        # self.configContents[GC.PATH_EXPORT] = str(Path(self.directory).joinpath(GC.PATH_EXPORT))
        # self.configContents[GC.PATH_IMPORT] = str(Path(self.directory).joinpath(GC.PATH_IMPORT))
        self.tempConfigFile = UI.__makeRandomFileName()
        self.saveContentsOfConfigFile(self.tempConfigFile)

    @staticmethod
    def __makeRandomFileName():
        return "globals_" + utils.datetime_return() + ".json"

    def _getPythonExecutable(self):
        if hasattr(sys, '_MEIPASS'):
            # We're in an executable created by pyinstaller
            return sys.executable

        if platform.system().lower() == 'linux' or platform.system().lower(
        ) == 'darwin':
            lPython = 'python3'
        elif platform.system().lower() == 'windows':
            lPython = 'python'
        else:
            sys.exit(
                f"Unknown platform to run on: {platform.system().lower()}")
        return lPython

    def getConfigFilesInDirectory(self):
        """
        Reads JSON-Files from directory given in self.directory and builds 2 lists (Testrunfiles and ConfiFiles)
        """
        self.configFiles = []
        self.testRunFiles = []
        lcwd = os.getcwd()
        os.chdir(self.directory)
        fileList = glob.glob("*.json")
        fileList.extend(glob.glob("*.xlsx"))
        if not platform.system().lower() == 'windows':
            # On MAC and LINUX there may be also upper/lower-Case versions
            fileList.extend(glob.glob("*.JSON"))
            fileList.extend(glob.glob("*.XLSX"))
        for file in fileList:
            if file[0:4].lower(
            ) == 'glob':  # Global Settings for Testrun must start with global_*
                self.configFiles.append(file)
            else:
                self.testRunFiles.append(file)
            pass

        self.configFiles = sorted(self.configFiles)
        self.testRunFiles = sorted(self.testRunFiles)

        lWindow = self.window
        if lWindow:
            lWindow['configFile'].update(
                values=self.configFiles,
                value=self.configFile if self.configFile else "")
            lWindow['testRunFile'].update(
                values=self.testRunFiles,
                value=self.testRunFile if self.testRunFile else "")

        os.chdir(lcwd)

    def readContentsOfGlobals(self):
        self.configContents = utils.openJson(
            Path(self.directory).joinpath(self.configFile))
        # Prepare some default values, if not filled:
        if not self.configContents.get("TC." + GC.DATABASE_LINES):
            self.configContents["TC." + GC.DATABASE_LINES] = ""
        if not self.configContents.get("TC." + GC.EXECUTION_DONTCLOSEBROWSER):
            self.configContents["TC." + GC.EXECUTION_DONTCLOSEBROWSER] = ""
        if not self.configContents.get("TC." + GC.EXECUTION_SLOW):
            self.configContents["TC." + GC.EXECUTION_SLOW] = ""

    def saveContentsOfConfigFile(self, lFileName=None):
        if not lFileName:
            lFileName = self.configFile

        with open(str(Path(self.directory).joinpath(lFileName)),
                  'w') as outfile:
            json.dump(self.configContents, outfile, indent=4)

    def modifyValuesOfConfigFileInMemory(self, lValues):
        for key, value in lValues.items():
            if not isinstance(key, str):
                continue

            if '-attrib-' in key:
                # Existing field - update value from value
                lSearchKey = key.replace("-attrib-", "")
                if lSearchKey != value:
                    # an existing variable was changed to a new name. Delete the old one:
                    self.configContents.pop(lSearchKey)
                    lSearchKey = value
                    lSearchVal = lValues['-val-' + key.replace("-attrib-", "")]
                else:
                    lSearchVal = lValues['-val-' + lSearchKey]
                if len(lSearchKey) > 0:
                    self.configContents[lSearchKey] = lSearchVal
            elif '-newField-' in key:
                # New field needs to be added to memory:
                lSearchKey = value  # the new fieldname
                if len(lSearchKey) > 0:
                    lSearchVal = lValues['-newValue-' + key[-1]]
                    self.configContents[lSearchKey] = lSearchVal
            elif '-val-' in key or '-newValue-':
                pass  # Values have been used already above
            else:
                logger.critical(
                    f"Program error. Received something with key {key}, value {value} and no "
                    f"idea what to do with it")

    def saveInteractiveGuiConfig(self):
        config = configparser.ConfigParser()
        config["DEFAULT"] = {
            "path": self.directory,
            "testrun": UI.__nonEmptyString(self.testRunFile),
            "globals": UI.__nonEmptyString(self.configFile),
            "position": self.mainWindowPosition
        }
        with open(self.managedPaths.getOrSetIni().joinpath("baangt.ini"),
                  "w") as configFile:
            config.write(configFile)

    @staticmethod
    def __nonEmptyString(stringIn):
        if stringIn:
            return stringIn
        else:
            return ""

    def readConfig(self):
        config = configparser.ConfigParser()
        try:
            config.read(self.managedPaths.getOrSetIni().joinpath("baangt.ini"))
            self.directory = config["DEFAULT"]['path']
            self.testRunFile = config["DEFAULT"]['testrun']
            self.configFile = config["DEFAULT"]['globals']
            self.mainWindowPosition = UI.__convert_configPosition2Tuple(
                config["DEFAULT"]['position'])
            # Value in there is now a string of "(x-coordinates, y-coordinates)". We need a tuple (int:x, int:y)

            self.readContentsOfGlobals()
        except Exception as e:
            # if baangt.ini is not there. Default the directory to /examples.
            if Path(os.getcwd()).joinpath("examples").exists():
                self.directory = Path(os.getcwd()).joinpath("examples")
                self.testRunFile = 'simpleAutomationpractice.xlsx'
                self.configFile = 'globals.json'
                self.mainWindowPosition = (20, 30)
                self.readContentsOfGlobals()

    @staticmethod
    def __convert_configPosition2Tuple(inString):
        x = int(inString.split(",")[0].lstrip("("))
        y = int(inString.split(",")[1].rstrip(")"))

        return (x, y)