class MainFrame(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.__browser = None self.__tmp_dir = mkdtemp() self.SetTitle("Easy Selenium UI") self.SetSize((800, 600)) self.__create_widgets() self.Bind(EVT_CLOSE, self.__on_close) def __create_widgets(self): panel = Panel(self) sizer = GridBagSizer(5, 5) row = 0 col = 0 label = StaticText(panel, label=u'Root folder:') sizer.Add(label, pos=(row, col)) col += 1 col_width = 4 self.__txt_root_path = TextCtrl(panel) sizer.Add(self.__txt_root_path, pos=(row, col), span=(1, col_width), flag=FLAG_ALL_AND_EXPAND) col += col_width self.__btn_set_root = Button(panel, label=u'Set root folder') self.__btn_set_root.Bind(EVT_BUTTON, self.__set_root_folder) sizer.Add(self.__btn_set_root, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) row += 1 col = 0 label = StaticText(panel, label=u'Url:') sizer.Add(label, pos=(row, col)) col += 1 self.__txt_url = TextCtrl( panel, value=u'https://www.google.com/') # TODO: remove url sizer.Add(self.__txt_url, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) col += 1 label = StaticText(panel, label=u'Browser:') sizer.Add(label, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) col += 1 self.__cb_browser = Choice(panel, choices=Browser.get_supported_browsers()) self.__cb_browser.Select(0) sizer.Add(self.__cb_browser, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) col += 1 self.bth_open_url = Button(panel, label=u'Open url') self.bth_open_url.Bind(EVT_BUTTON, self.__open_url) sizer.Add(self.bth_open_url, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) col += 1 self.bth_close_url = Button(panel, label=u'Close browser') self.bth_close_url.Bind(EVT_BUTTON, self.__close_browser) sizer.Add(self.bth_close_url, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) row += 1 col = 0 tabs = Tabs(panel, [(GeneratorTab, "Generator"), (EditorTab, "Editor"), (TestRunnerTab, "Test runner"), (SelectorFinderTab, "Selector finder")]) sizer.Add(tabs, pos=(row, col), span=(1, 6), flag=FLAG_ALL_AND_EXPAND) sizer.AddGrowableCol(1, 1) sizer.AddGrowableRow(2, 1) panel.SetSizer(sizer) self.Layout() def get_root_folder(self): text = self.__txt_root_path.GetValue() if text and len(text) > 0: return text else: return None def __set_root_folder(self, evt): dialog = DirDialog(self) if dialog.ShowModal() == ID_OK: path = dialog.GetPath() RootFolder.prepare_folder(path) self.__txt_root_path.SetValue(path) def __open_url(self, evt): url = self.__txt_url.GetValue() if StringUtils.is_url_correct(url): self.bth_open_url.Disable() name = self.get_browser_initials() try: if self.__browser and self.__browser.get_browser_initials( ) != name: self.__browser.quit() self.__browser = Browser(name) elif not self.__browser: self.__browser = Browser(name) except Exception: show_error_dialog(self, traceback.format_exc(), u'Failed to open browser') self.__browser = None if self.__browser: self.__browser.open(url) # TODO: if generator or selector -> load image self.bth_open_url.Enable() else: show_dialog(self, u'Bad url: %s' % url, u'Bad url') def __close_browser(self, evt): if self.__browser: self.__browser.quit() self.__browser = None def __on_close(self, evt): self.__close_browser(evt) shutil.rmtree(self.__tmp_dir) self.Destroy() def get_url(self): return self.__txt_url.GetValue() def set_url(self, url): self.__txt_url.SetValue(url) def get_browser(self): return self.__browser def get_browser_initials(self): return self.__cb_browser.GetStringSelection() def get_tmp_dir(self): return self.__tmp_dir
class TestRunnerTab(Panel): def __init__(self, *args, **kwargs): Panel.__init__(self, *args, **kwargs) sizer = GridBagSizer(5, 5) row = 0 col = 0 self.cb_html_output = CheckBox(self, label=u'Report in HTML') self.cb_html_output.Bind(EVT_CHECKBOX, self.__on_check) sizer.Add(self.cb_html_output, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) col += 1 self.txt_html_report = TextCtrl(self, style=TE_READONLY) self.txt_html_report.Disable() sizer.Add(self.txt_html_report, pos=(row, col), span=(1, 3), flag=FLAG_ALL_AND_EXPAND) col += 3 self.btn_select_html = Button(self, label=u'Select HTML file') self.btn_select_html.Disable() self.btn_select_html.Bind(EVT_BUTTON, self.__on_select_file) sizer.Add(self.btn_select_html, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) row += 1 col = 0 self.cb_xml_output = CheckBox(self, label=u'Report in XML') self.cb_xml_output.Bind(EVT_CHECKBOX, self.__on_check) sizer.Add(self.cb_xml_output, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) col += 1 self.txt_xml_report = TextCtrl(self, style=TE_READONLY) self.txt_xml_report.Disable() sizer.Add(self.txt_xml_report, pos=(row, col), span=(1, 3), flag=FLAG_ALL_AND_EXPAND) col += 3 self.btn_select_xml = Button(self, label=u'Select XML file') self.btn_select_xml.Disable() self.btn_select_xml.Bind(EVT_BUTTON, self.__on_select_file) sizer.Add(self.btn_select_xml, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) row += 1 col = 0 self.cb_options = CheckBox(self, label=u'Additional options') self.cb_options.Bind(EVT_CHECKBOX, self.__on_check) sizer.Add(self.cb_options, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) col += 1 self.txt_options = TextCtrl(self) self.txt_options.Disable() sizer.Add(self.txt_options, pos=(row, col), span=(1, 3), flag=FLAG_ALL_AND_EXPAND) col += 3 self.btn_nose_help = Button(self, label=u'Show help') self.btn_nose_help.Bind(EVT_BUTTON, self.__on_show_help) sizer.Add(self.btn_nose_help, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) row += 1 col = 0 self.btn_load_tests_from_files = Button(self, label=u'Load tests from files') self.btn_load_tests_from_files.Bind(EVT_BUTTON, self.__load_tests_from_files) sizer.Add(self.btn_load_tests_from_files, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) col += 1 self.btn_load_tests_from_dir = Button( self, label=u'Load tests from directory') self.btn_load_tests_from_dir.Bind(EVT_BUTTON, self.__load_tests_from_directory) sizer.Add(self.btn_load_tests_from_dir, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) col += 1 dummy_label = StaticText(self) sizer.Add(dummy_label, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) col += 1 self.cb_browser = Choice(self, choices=Browser.get_supported_browsers()) self.cb_browser.Select(0) sizer.Add(self.cb_browser, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) col += 1 self.btn_run = Button(self, label=u'Run test cases') self.btn_run.Bind(EVT_BUTTON, self.__run_tests) sizer.Add(self.btn_run, pos=(row, col), flag=FLAG_ALL_AND_EXPAND) row += 1 col = 0 window = SplitterWindow(self, style=SP_3D | SP_LIVE_UPDATE) self.tree_ctrl = CustomTreeCtrl( window, style=TR_SINGLE | TR_HAS_BUTTONS | TR_AUTO_CHECK_CHILD | TR_AUTO_CHECK_PARENT | TR_AUTO_TOGGLE_CHILD) self.tree_ctrl.SetBackgroundColour(self.GetBackgroundColour()) self.tree_ctrl.SetForegroundColour(self.GetForegroundColour()) self.tree_ctrl.Bind(EVT_TREE_ITEM_CHECKED, self.__on_tree_check) self.txt_ctrl = TextCtrl(window, style=TE_MULTILINE | TE_READONLY | HSCROLL | VSCROLL) font_size = self.txt_ctrl.GetFont().GetPointSize() self.txt_ctrl.SetFont( Font(font_size, FONTFAMILY_TELETYPE, NORMAL, NORMAL)) window.SplitVertically(self.tree_ctrl, self.txt_ctrl) sizer.Add(window, pos=(row, col), span=(1, 5), flag=FLAG_ALL_AND_EXPAND) sizer.AddGrowableCol(2, 1) sizer.AddGrowableRow(row, 1) self.SetSizerAndFit(sizer) def __on_show_help(self, evt): text = check_output(['nosetests', '--help']) DialogWithText(self, u'Help for nosetests', text).ShowModal() def __on_select_file(self, evt): folder = self.__get_safe_path_from_root_folder(RootFolder.REPORTS) obj = evt.GetEventObject() txt_ctrl = None if obj == self.btn_select_html: wildcard = u'*.html' txt_ctrl = self.txt_html_report elif obj == self.btn_select_xml: wildcard = u'*.xml' txt_ctrl = self.txt_xml_report else: wildcard = u'*.*' dialog = FileDialog(self, defaultDir=folder, style=FD_SAVE | FD_OVERWRITE_PROMPT, wildcard=wildcard) if dialog.ShowModal() == ID_OK and txt_ctrl: txt_ctrl.SetValue(dialog.GetPath()) def __on_check(self, evt): cb_obj = evt.GetEventObject() checkboxes_and_txt_ctrls = { self.cb_html_output: self.txt_html_report, self.cb_options: self.txt_options, self.cb_xml_output: self.txt_xml_report } checkboxes_and_btns = { self.cb_html_output: self.btn_select_html, self.cb_xml_output: self.btn_select_xml } txt_ctrl = checkboxes_and_txt_ctrls[cb_obj] btn = checkboxes_and_btns.get(cb_obj) if txt_ctrl.IsEnabled(): txt_ctrl.Disable() if btn: btn.Disable() else: txt_ctrl.Enable() if btn: btn.Enable() def __on_tree_check(self, evt): # styles doesn't work: TR_AUTO_CHECK_CHILD | TR_AUTO_CHECK_PARENT | TR_AUTO_TOGGLE_CHILD # TODO: fix if all children are check then one child is uncheck - parent is checked item = evt.GetItem() checked = item.IsChecked() parent = item.GetParent() def all_children_are_checked(_parent): states = [child.IsChecked() for child in _parent.GetChildren()] uniq_states = list(set(states)) return len(uniq_states) == 1 and uniq_states[0] is True self.tree_ctrl.AutoCheckChild(item, checked) if parent: self.tree_ctrl.AutoCheckParent(item, all_children_are_checked(parent)) def __get_safe_path_from_root_folder(self, subfolder=None): folder = self.GetTopLevelParent().get_root_folder() if subfolder and folder: path_for_subfolder = os.path.join(folder, subfolder) if os.path.exists(path_for_subfolder): return path_for_subfolder return folder if folder else '.' def __load_tests_to_tree(self, file_paths=None, dir_path=None): if file_paths: python_files = file_paths elif dir_path: python_files = [f for f in get_list_of_files(dir_path, True)] else: python_files = [] python_files = [ f for f in python_files if 'test' in os.path.basename(f) and os.path.splitext(f)[-1] == '.py' ] if len(python_files) > 0: syspath = list(os.sys.path) try: root_folder = self.__get_safe_path_from_root_folder() if root_folder not in os.sys.path: os.sys.path.append(root_folder) checkbox_type = 1 self.tree_ctrl.DeleteAllItems() root = self.tree_ctrl.AddRoot('All test cases', checkbox_type) for python_file in python_files: top_item = self.tree_ctrl.AppendItem( root, os.path.abspath(python_file), checkbox_type) parsed_classes = ParsedClass.get_parsed_classes( python_file) for parsed_class in parsed_classes: item = self.tree_ctrl.AppendItem( top_item, parsed_class.name, checkbox_type) test_methods = [ k for k in parsed_class.methods.keys() if k.startswith('test_') ] for tc_name in test_methods: self.tree_ctrl.AppendItem(item, tc_name, checkbox_type) self.tree_ctrl.ExpandAll() except Exception: show_error_dialog(self, traceback.format_exc(), 'Cannot add test cases') finally: os.sys.path = syspath def __load_tests_from_directory(self, evt): folder = self.__get_safe_path_from_root_folder(RootFolder.TESTS_FOLDER) if folder: dialog = DirDialog(self, defaultPath=folder, style=DD_DIR_MUST_EXIST) if dialog.ShowModal() == ID_OK: self.__load_tests_to_tree(dir_path=dialog.GetPath()) else: show_dialog_path_doesnt_exist(self, folder) def __load_tests_from_files(self, evt): folder = self.__get_safe_path_from_root_folder(RootFolder.TESTS_FOLDER) if folder: dialog = FileDialog(self, defaultDir=folder, style=FD_OPEN | FD_FILE_MUST_EXIST | FD_MULTIPLE, wildcard=u'*.py') if dialog.ShowModal() == ID_OK: self.__load_tests_to_tree(file_paths=dialog.GetPaths()) else: show_dialog_path_doesnt_exist(self, folder) def __get_nose_command(self): root = self.tree_ctrl.GetRootItem() tests = [] for _file in root.GetChildren(): for _class in _file.GetChildren(): for test_case in _class.GetChildren(): if test_case.IsChecked(): # TODO: fix for files that contain spaces tests.append(u'%s:%s.%s' % (_file.GetText(), _class.GetText(), test_case.GetText())) args = [ '--with-path="%s"' % self.__get_safe_path_from_root_folder(), '--logging-level=INFO' ] use_html_report = (self.cb_html_output.IsChecked() and len(self.txt_html_report.GetValue()) > 0) if use_html_report: report_path = self.txt_html_report.GetValue() args.append('--with-html --html-file="%s"' % report_path) use_xml_report = (self.cb_xml_output.IsChecked() and len(self.txt_xml_report.GetValue()) > 0) if use_xml_report: report_path = self.txt_xml_report.GetValue() args.append('--with-xunit --xunit-file="%s"' % report_path) use_options = (self.cb_options.IsChecked() and len(self.txt_options.GetValue()) > 0) if use_options: report_path = self.txt_options.GetValue() args.append(report_path) nose_cmd = [u'nosetests'] + args + tests return nose_cmd def __run_tests(self, evt): # TODO: do not run if root folder is not selected self.txt_ctrl.Clear() dialog = InfiniteProgressBarDialog( self, u'Running test cases', u'Running selected test cases... Please wait...') def wrap_func(): stdout = os.sys.stdout stderr = os.sys.stderr redirected = RedirectText(self.txt_ctrl) os.sys.stdout = redirected os.sys.stderr = redirected try: nose_cmd = self.__get_nose_command() browser_name = self.cb_browser.GetStringSelection() Browser.DEFAULT_BROWSER = browser_name report_folder = self.__get_safe_path_from_root_folder( RootFolder.REPORTS) BaseTest.FAILED_SCREENSHOT_FOLDER = report_folder easy_selenium_cmd = u" ".join(nose_cmd).replace( "nosetests", "easy_selenium_cli.py -b " + browser_name) print(u"Executing command:\n%s" % easy_selenium_cmd) print(u"Nose output:") run(argv=nose_cmd[1:]) finally: dialog.close_event.set() os.sys.stdout = stdout os.sys.stderr = stderr run_in_separate_thread(wrap_func) dialog.ShowModal()
class MainDialog(Dialog): """ Main window. Hit a button to profile the system, then another to scan what was plugged in """ def __init__(self): """Constructor""" Dialog.__init__(self, None, title="Bad Cop", size=Size(500, 100)) ico = Icon('logo.ico', BITMAP_TYPE_ICO) self.SetIcon(ico) self.message = StaticText( self, label="Click Profile, then insert device and click Test") self.profile = Button(self, label="Profile") self.test = Button(self, label="Test") self.test.Disable() self.profile.Bind(EVT_BUTTON, self.profileusb) self.test.Bind(EVT_BUTTON, self.testusb) self.Bind(EVT_CLOSE, self.onclose) main_sizer = BoxSizer(VERTICAL) t_sizer = BoxSizer(HORIZONTAL) p_sizer = BoxSizer(HORIZONTAL) t_sizer.Add(self.message, 0, ALL | CENTER, 5) p_sizer.Add(self.profile, 0, ALL | CENTER, 5) p_sizer.Add(self.test, 0, ALL | CENTER, 5) main_sizer.Add(p_sizer, 0, ALL | CENTER, 5) main_sizer.Add(t_sizer, 0, ALL | EXPAND | CENTER, 5) self.SetSizer(main_sizer) def profileusb(self, other): del other dev = find(find_all=True) devices = [] for cfg in dev: devclass = str(cfg.bDeviceClass) product = str(cfg.iProduct) vid = hex(cfg.idVendor) pid = hex(cfg.idProduct) for line in Configuration(find(idVendor=cfg.idVendor)): line = str(line) linestrip = line.strip() linesplit = linestrip.split('\n') linesplit = [x.split(':') for x in linesplit] lines = [] for w in linesplit: lines.append([y.strip(' ') for y in w]) for e in lines: if 'bInterfaceClass' in e[0]: intclass = e[1] devices.append([devclass, product, vid, pid, intclass]) with open('devices.pkl', 'wb') as f: dump(devices, f) self.profile.SetLabel("Done!") self.profile.Disable() self.test.Enable() def testusb(self, other): del other with open('devices.pkl', 'rb') as f: benchmark = load(f) dev = find(find_all=True) devices = [] for cfg in dev: devclass = str(cfg.bDeviceClass) product = str(cfg.iProduct) vid = hex(cfg.idVendor) pid = hex(cfg.idProduct) for line in Configuration(find(idVendor=cfg.idVendor)): line = str(line) linestrip = line.strip() linesplit = linestrip.split('\n') linesplit = [x.split(':') for x in linesplit] lines = [] for w in linesplit: lines.append([y.strip(' ') for y in w]) for e in lines: if 'bInterfaceClass' in e[0]: intclass = e[1] devices.append([devclass, product, vid, pid, intclass]) first_tuple_list = [tuple(lst) for lst in benchmark] secnd_tuple_list = [tuple(lst) for lst in devices] first_set = set(first_tuple_list) secnd_set = set(secnd_tuple_list) output = "" height = 100 first = 0 for devclass, product, vid, pid, usbtype in first_set.symmetric_difference( secnd_set): if usbtype == "0xa CDC Data": devicedesc = "Virtual Data Port (Network)" elif usbtype == "0xe0 Wireless Controller": devicedesc = "Wireless Internet Or Bluetooth" elif usbtype == "0x8 Mass Storage": devicedesc = "Data Storage Device" elif usbtype == "0x9 Hub": devicedesc = "USB Hub" elif usbtype == "0x3 Human Interface Device": devicedesc = "Keyboard, Mouse, or Other Input Device" elif usbtype == "0x2 CDC Communication": devicedesc = "Vitual Communications Port (Network)" else: devicedesc = usbtype + " device " if first == 0: output += "This appears to be a: \n " + devicedesc + " \n" else: output += " " + devicedesc + " \n" height = height + 30 first = 1 self.SetSize((500, height)) self.message.SetLabel(output) def onclose(self, event): del event try: remove('devices.pkl') except: print('file missing') self.Destroy() exit("Application Exited")