class LogViewerApp(AbstractRwbGui): def __init__(self): args = self._parse_args() AbstractRwbGui.__init__(self, NAME, DEFAULT_SETTINGS, args) self._create_menubar() self._create_toolbar() self._create_statusbar() vsb = ttk.Scrollbar(self, orient="vertical") self.viewer = LogTree(self, fail_only=self.args.fail_only, condensed=self.args.condensed) vsb.configure(command=self.viewer.tree.yview) self.viewer.tree.configure(yscrollcommand=vsb.set) self.toolbar.pack(side="top", fill="x") self.statusbar.pack(side="bottom", fill="x") vsb.pack(side="right", fill="y") self.viewer.pack(side="top", fill="both", expand=True) self.viewer.tree.bind("<<TreeviewSelect>>", self._on_select) if self.args.file != None: self.after_idle(self.after, 1, lambda path=self.args.file: self.open(path)) # self.after_idle(self.after, 1, lambda path=sys.argv[1]: self.open(path)) self.wm_protocol("WM_DELETE_WINDOW", self.on_delete_window) def _parse_args(self): '''Parse command line arguments''' parser = argparse.ArgumentParser(prog="rwb.logviewer") parser.add_argument("file",nargs="?", help="the path to a robot output file (eg: output.xml)") parser.add_argument("-f", "--fail-only", action="store_true", help="only display failed suites, tests and keywords") parser.add_argument("-c", "--condensed", action="store_true", help="don't auto-expand failed keyworeds") return parser.parse_args() def _on_select(self, event): selection = self.viewer.tree.selection() self.log.debug("selection: %s" % selection) if len(selection) > 0: item = selection[0] self.log.debug("item: %s" % item) self.log.debug("tags: %s" % ",".join(self.viewer.tree.item(item, "tags"))) self.log.debug("values: %s" % ",".join(self.viewer.tree.item(item, "values"))) x = self.viewer.tree.item(item, "values")[-1] def _create_toolbar(self): self.toolbar = ttk.Frame(self) suite_button = ToolButton(self.toolbar, text="Suites", width=0, tooltip="Expand to show all suites", command=self._on_expand_suites) test_button = ToolButton(self.toolbar, text="Test Cases", width=0, tooltip="Expand to show all suites and test cases", command=self._on_expand_tests) kw_button = ToolButton(self.toolbar, text="Test Keywords", width=0, tooltip="Expand to show all suites, test cases, and their keywords", command=self._on_expand_test_keywords) all_button = ToolButton(self.toolbar, text="Expand All Keywords", width=0, tooltip="Expand to show all suites, test cases, and keywords", command=self._on_expand_all) # this is just for experimentation; I don't really plan to have this on the toolbar next_fail = ToolButton(self.toolbar, text="Next Failure", width=0, tooltip="Go to next failed keyword", command=self._on_next_fail) prev_fail = ToolButton(self.toolbar, text="Previous Failure", width=0, tooltip="Go to previous failed keyword", command=self._on_previous_fail) suite_button.pack(side="left") test_button.pack(side="left") kw_button.pack(side="left") all_button.pack(side="left") ttk.Separator(self.toolbar, orient="vertical").pack(side="left", padx=4, pady=2, fill="y") next_fail.pack(side="left") prev_fail.pack(side="left") def _on_next_fail(self): item = self.viewer.next_with_tag("FAIL") if item is not None and item != "": self.viewer.tree.see(item) if self.viewer.tree.bbox(item) == "": # for some reason, that previous call to .see() doesn't always # scroll the item into view. If we detect that, it means it # is off screen so lets call see() again, then scroll up a # few lines to show some context. self.after_idle(self.viewer.tree.see, item) self.after_idle(self.viewer.tree.yview_scroll,4, "units") self.viewer.tree.focus(item) self.viewer.tree.selection_set(item) def _on_previous_fail(self): item = self.viewer.previous_with_tag("FAIL") if item is not None and item != "": self.viewer.tree.see(item) if self.viewer.tree.bbox(item) == "": # for some reason, that previous call to .see() doesn't always # scroll the item into view. If we detect that, it means it # is off screen so lets call see() again, then scroll up a # few lines to show some context. self.after_idle(self.viewer.tree.see, item) self.after_idle(self.viewer.tree.yview_scroll,-4, "units") self.viewer.tree.focus(item) self.viewer.tree.selection_set(item) def _create_menubar(self): self.menubar = tk.Menu(self) self.configure(menu=self.menubar) self.file_menu = tk.Menu(self.menubar, tearoff=False) self.file_menu.add_command(label="Open...", command=self._on_open) self.file_menu.add_separator() self.file_menu.add_command(label="Exit", command=self.on_exit) self.view_menu = tk.Menu(self.menubar, tearoff=False) self.view_menu.add_command(label="Expand Suites", underline=7, command=self._on_expand_suites) self.view_menu.add_command(label="Expand Test Cases", underline=7, command=self._on_expand_tests) self.view_menu.add_command(label="Expand Test Case Keywords", underline=17, command=self._on_expand_test_keywords) self.view_menu.add_command(label="Expand All Keywords", underline=7, command=self._on_expand_all) self.view_menu.add_separator() self.view_menu.add_command(label="Collapse all", underline=0, command=self._on_collapse_all) self.help_menu = tk.Menu(self, tearoff=False) self.help_menu.add_command(label="View help on the web", command=self._on_view_help) self.help_menu.add_separator() self.help_menu.add_command(label="About the robotframework workbench", command=self._on_about) self.menubar.add_cascade(menu=self.file_menu, label="File", underline=0) self.menubar.add_cascade(menu=self.view_menu, label="View", underline=0) self.menubar.add_cascade(menu=self.help_menu, label="Help", underline=0) def _create_statusbar(self): self.statusbar = Statusbar(self) def _on_open(self): formats = [('XML files', '*.xml'), ('All files', '*.*'), ] initialdir = os.getcwd() initialfile = "output.xml" filename = tkFileDialog.askopenfilename(parent=self, filetypes=formats, initialfile = initialfile, initialdir = initialdir, title="Open") if filename is not None and filename != "": self.open(filename) def open(self, path): try: self.viewer.refresh(path) self.wm_title("%s - Robot Framework Workbench Log Viewer" % path) except Exception, e: tkMessageBox.showwarning("Unable to open the file\n\n%s" % str(e)) self.wm_title("Robot Framework Workbench Log Viewer")