Beispiel #1
0
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()
Beispiel #3
0
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")