diff options
Diffstat (limited to 'uitest/loginterpreter.py')
-rwxr-xr-x | uitest/loginterpreter.py | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/uitest/loginterpreter.py b/uitest/loginterpreter.py new file mode 100755 index 0000000000..e84d9a0ed7 --- /dev/null +++ b/uitest/loginterpreter.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python3 +# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +import os +import sys +import argparse + +def parse_line(line): + """ + This function parses a line from log file + and returns the parsed values as a python dictionary + """ + if (line == ""): + return + dict = {} + if "{" in line: + start_index_of_parameters = line.find("{") + end_index_of_parameters = line.find("}") + 1 + parameters = line[start_index_of_parameters:end_index_of_parameters] + if parameters != "": + dict["parameters"] = parameters + line = line[:start_index_of_parameters-1] + word_list = line.split() + dict["keyword"] = word_list[0] + + for index in range(1,len(word_list)): + key, val = word_list[index].split(":",1) + dict[key] = val + return dict + +def parse_args(): + """ + This function parses the command-line arguments + to get the input and output file details + """ + parser = argparse.ArgumentParser(description = "Generate a UI test file from log") + parser.add_argument("input_address", type = str, help = "The log file address") + parser.add_argument("output_address", type = str, help = "The test file address") + parser.add_argument("-d", "--document", metavar = "", help = "Address of the document to be opened") + args = parser.parse_args() + return args + +def get_log_file(input_address): + try: + with open(input_address) as f: + content = f.readlines() + except IOError as err: + print("IO error: {0}".format(err)) + print("Use " + os.path.basename(sys.argv[0]) + " -h to get usage instructions") + sys.exit(1) + + content = [x.strip() for x in content if not x.startswith("Action on element")] + return content + +def initiate_test_generation(address): + try: + f = open(address,"w") + except IOError as err: + print("IO error: {0}".format(err)) + print("Use " + os.path.basename(sys.argv[0]) + " -h to get usage instructions") + sys.exit(1) + initial_text = \ + "# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-\n\n" + \ + "from uitest.framework import UITestCase\n" + \ + "from libreoffice.uno.propertyvalue import mkPropertyValues\n" + \ + "import importlib\n\n" + \ + "class TestClass(UITestCase):\n" + \ + " def test_function(self):\n" + f.write(initial_text) + return f + +def get_coupling_type(line1, line2): + """ + This function checks if two consecutive lines of log file + refer to the same event + """ + action_dict1 = parse_line(line1) + action_dict2 = parse_line(line2) + + if action_dict1["keyword"] == "CommandSent" and \ + action_dict2["keyword"] == "ModalDialogExecuted": + return "COMMAND_MODAL_COUPLE" + + elif action_dict1["keyword"] == "CommandSent" and \ + action_dict2["keyword"] == "ModelessDialogConstructed": + return "COMMAND_MODELESS_COUPLE" + + elif action_dict1["keyword"] == "ButtonUIObject" and \ + action_dict2["keyword"] == "DialogClosed": + return "BUTTON_DIALOGCLOSE_COUPLE" + + elif "parameters" in action_dict1 and \ + "KEYCODE" in action_dict1["parameters"] and \ + action_dict2["keyword"] == "CommandSent": + return "REDUNDANT_COUPLE" + + return "NOT_A_COUPLE" + +def check_app_starting_action(action_dict): + app_starter_button_ids = \ + set(["draw_all", "impress_all", "calc_all" , "writer_all", "database_all", "math_all"]) + + if action_dict["keyword"] == "ButtonUIObject" and action_dict["Action"] == "CLICK" and \ + action_dict["Id"] in app_starter_button_ids: + return True + return False + +def get_test_line_from_one_log_line(log_line): + action_dict = parse_line(log_line) + test_line = " " + if action_dict["keyword"].endswith("UIObject"): + parent = action_dict["Parent"] + if (check_app_starting_action(action_dict)): + test_line +=\ + "MainDoc = self.ui_test.create_doc_in_start_center(\"" + \ + action_dict["Id"][:-4] +"\")\n MainWindow = " + \ + "self.xUITest.getTopFocusWindow()\n" + return test_line + else: + if (parent == ""): + parent = "MainWindow" + test_line += \ + action_dict["Id"] + " = " + parent + ".getChild(\"" + \ + action_dict["Id"] + "\")\n " + \ + action_dict["Id"] + ".executeAction(\"" + \ + action_dict["Action"] + "\"" + if "parameters" in action_dict: + test_line += ", mkPropertyValues(" + \ + action_dict["parameters"] + "))\n" + else: + test_line += ",tuple())\n" + return test_line + elif action_dict["keyword"] == "CommandSent": + if "parameters" not in action_dict: + test_line += "self.xUITest.executeCommand(\"" + \ + action_dict["Name"] + "\")\n" + return test_line + else: + test_line += "self.xUITest.executeCommandWithParameters(\"" + \ + action_dict["Name"] + "\", mkPropertyValues(" + action_dict["parameters"] + \ + "))\n" + return test_line + elif action_dict["keyword"] == "ModalDialogExecuted" or \ + action_dict["keyword"] == "ModelessDialogConstructed": + test_line += action_dict["Id"] + " = " + "self.xUITest.getTopFocusWindow()\n" + return test_line + + return "" + +def get_test_line_from_two_log_lines(log_line1,log_line2): + coupling_type = get_coupling_type(log_line1, log_line2) + action_dict1 = parse_line(log_line1) + action_dict2 = parse_line(log_line2) + test_line = " " + if coupling_type == "COMMAND_MODAL_COUPLE": + test_line += \ + "self.ui_test.execute_dialog_through_command(\"" + \ + action_dict1["Name"] + "\")\n " + \ + action_dict2["Id"] + " = self.xUITest.getTopFocusWindow()\n" + elif coupling_type == "COMMAND_MODELESS_COUPLE": + test_line += \ + "self.ui_test.execute_modeless_dialog_through_command(\"" + \ + action_dict1["Name"] + "\")\n " + \ + action_dict2["Id"] + " = self.xUITest.getTopFocusWindow()\n" + elif coupling_type == "BUTTON_DIALOGCLOSE_COUPLE": + test_line += \ + action_dict1["Id"] + " = " + action_dict1["Parent"] + ".getChild(\"" + \ + action_dict1["Id"] + "\")\n self.ui_test.close_dialog_through_button(" + \ + action_dict1["Id"] + ")\n" + return test_line + +def main(): + args = parse_args() + log_lines = get_log_file(args.input_address) + output_stream = initiate_test_generation(args.output_address) + if args.document is not None: + output_line = " pathmodule = importlib.import_module(\"uitest.path\")\n" + \ + " doc_path = pathmodule.get_srcdir_url() + \"" + args.document + "\"\n" + \ + " MainDoc = self.ui_test.load_file(doc_path)\n" + \ + " MainWindow = self.xUITest.getTopFocusWindow()\n" + output_stream.write(output_line) + line_number = 0 + while line_number < len(log_lines): + if line_number == len(log_lines)-1 or \ + get_coupling_type(log_lines[line_number],log_lines[line_number + 1]) == "NOT_A_COUPLE": + test_line = get_test_line_from_one_log_line(log_lines[line_number]) + output_stream.write(test_line) + line_number += 1 + elif get_coupling_type(log_lines[line_number],log_lines[line_number + 1]) == "REDUNDANT_COUPLE": + line_number += 1 + else: + test_line = get_test_line_from_two_log_lines(log_lines[line_number],log_lines[line_number + 1]) + output_stream.write(test_line) + line_number += 2 + output_stream.write(" self.ui_test.close_doc()") + output_stream.write("\n\n# vim: set shiftwidth=4 softtabstop=4 expandtab:") + output_stream.close() + +if __name__ == '__main__': + main() + +# vim: set shiftwidth=4 softtabstop=4 expandtab: |