class XpathShell(object): def __init__(self, logger=None): self.log = logger or Logger('Xpath Shell') def get(self, url): u = urlparse.urlparse(url) if not u.scheme: u = ('http', u.netloc, u.path, u.params, u.query, u.fragment) url = urlparse.urlunparse(u) self.browser.get_url(url) self.log.i('Current url: %r' % self.browser.current_url()) def run_shell(self, url=None): self.level_mngr = WebdriverManager().enter_level(level=PROCESS_LIFE) browser = self.browser = self.level_mngr.get_xpathbrowser(name='Browser') #Aliases #TODO: add ipython extension ex = extract = browser.extract_xpath exs = xsingle = browser.extract_xsingle get = self.get def reset_browser(): self.level_mngr.exit_level() self.level_mngr = WebdriverManager().enter_level(level=PROCESS_LIFE) if url: self.get(url) print('Available objects/commands %s' % sorted(locals())) IpythonEmbedder().embed() self.level_mngr.exit_level() WebdriverManager().stop_display()
class TestXpathBrowser(unittest.TestCase): def setUp(self): # We need to enter "single test level" of life for each test # It will initialize the webdriver if no webdriver is present from upper levels self._level_mngr = WebdriverManager().enter_level(level=SINGLE_TEST_LIFE) # Get Xpath browser self.browser = self._level_mngr.get_xpathbrowser(name=__name__) def tearDown(self): # Make sure we quit those webdrivers created in this specific level of life self._level_mngr.exit_level() def test_select(self): # Load a local page for the demo self.get_local_page('xpath_browser_demo.html') # Do 2 type of selection self.browser.select_xpath('//div') # Xpath must be present, but no inner element may be returned self.browser.select_xsingle('//div') # Xpath must be present and at least 1 element must be present def test_extract(self): # Load a local page for the demo self.get_local_page('xpath_browser_demo.html') # Do 2 type of selection self.browser.select_xpath('//div') # Xpath must be present, but no inner element may be returned self.browser.extract_xsingle('//div') # Xpath must be present and at least 1 element must be present def get_local_page(self, file_name): # Auxiliary method root_dir = os.path.abspath(os.path.dirname(__file__)) url = 'file://' + os.path.join(root_dir, 'html', file_name) self.browser.get_url(url)
def run_shell(self, url=None): level_mngr = WebdriverManager().enter_level(level=PROCESS_LIFE) browser = self.browser = level_mngr.get_xpathbrowser(name='Browser') #Aliases #TODO: add ipython extension ex = extract = browser.extract_xpath exs = xsingle = browser.extract_xsingle get = self.get if url: self.get(url) IpythonEmbedder().embed() level_mngr.exit_level() WebdriverManager().stop_display()
class WebUnitTestBase(unittest.TestCase): def _get_local_html_path(self, name): return os.path.join(os.path.dirname(__file__), 'html', name) def _local_path_to_url(self, path): return 'file://' + path def get_local_page(self, path): self.browser.get_url(self._local_path_to_url(path)) @contextmanager def create_html(self, name, body, jquery=True, **kwargs): templ = ''' <!DOCTYPE html> <html> <head> hotexamples_com <title>{name}</title> </head> <body> {body} </body> </html> ''' if jquery: jquery = '' else: jquery = '' kwargs.update(locals()) html = templ.format(**kwargs) path = self._get_local_html_path(name + '.html') with open(path, 'w') as fh: fh.write(html) try: yield path except: raise finally: os.remove(path) def setUp(self): self.__level_mngr = WebdriverManager().enter_level( level=SINGLE_TEST_LIFE) webdriver = self.__level_mngr.acquire_driver() logger = Logger(__name__) self.browser = XpathBrowser('', webdriver, logger, settings={}) def tearDown(self): self.__level_mngr.exit_level()
class WebUnitTestBase(unittest.TestCase): def _path_to_url(self, path): return "file://" + path def get_local_page(self, path): self.browser.get_url(self._path_to_url(path)) @contextmanager def create_html(self, name, body, **kwargs): templ = """ <!DOCTYPE html> <html> <head> hotexamples_com <title>{name}</title> </head> <body> {body} </body> </html> """ jquery = "" kwargs.update(locals()) html = templ.format(**kwargs) if not self._tempdir: self._tempdir = tempfile.mkdtemp(prefix="smoothtest") path = os.path.join(self._tempdir, name + ".html") # Create html page in temporary dir with open(path, "w") as fh: fh.write(html) try: yield path except: raise finally: os.remove(path) def setUp(self): self.__level_mngr = WebdriverManager().enter_level(level=SINGLE_TEST_LIFE) webdriver = self.__level_mngr.acquire_driver() logger = Logger(__name__) self.browser = XpathBrowser("", webdriver, logger, settings={}) # Temp dir to save pages self._tempdir = None def tearDown(self): self.__level_mngr.exit_level() if self._tempdir: shutil.rmtree(self._tempdir, ignore_errors=True) self._tempdir = None
class TestXpathBrowser(unittest.TestCase): def setUp(self): # We need to enter "single test level" of life for each test # It will initialize the webdriver if no webdriver is present from upper levels self.__level_mngr = WebdriverManager().enter_level( level=SINGLE_TEST_LIFE) # Get Xpath browser self.browser = self.__level_mngr.get_xpathbrowser(name=__name__) # Line above is equivalent to doing: # from smoothtest.Logger import Logger # from smoothtest.webunittest.XpathBrowser import XpathBrowser # # Once we make sure there is a webdriver available, we acquire it # # and block usage from other possible users # webdriver = self.__level_mngr.acquire_driver() # # Initialize the XpathBrowser class # logger = Logger(__name__) # self.browser = XpathBrowser('', webdriver, logger, settings={}) def tearDown(self): # Make sure we quit those webdrivers created in this specific level of life self.__level_mngr.exit_level() def test_select(self): # Load a local page for the demo self.get_local_page('xpath_browser_demo.html') # Do 2 type of selection self.browser.select_xpath( '//div' ) # Xpath must be present, but no inner element may be returned self.browser.select_xsingle( '//div' ) # Xpath must be present and at least 1 element must be present def test_extract(self): # Load a local page for the demo self.get_local_page('xpath_browser_demo.html') # Do 2 type of selection self.browser.select_xpath( '//div' ) # Xpath must be present, but no inner element may be returned self.browser.extract_xsingle( '//div' ) # Xpath must be present and at least 1 element must be present def get_local_page(self, file_name): # Auxiliary method root_dir = os.path.abspath(os.path.dirname(__file__)) url = 'file://' + os.path.join(root_dir, 'html', file_name) self.browser.get_url(url)
class TestChat(unittest.TestCase): @classmethod def setUpClass(cls): # It will initialize the webdriver if no webdriver is present from upper levels # Since we don't want to initialize a webdriver for each single test # we create the webdriver one level upper SINGLE_TEST_LIFE cls.cls_level_mngr = WebdriverManager().enter_level(level=TEST_ROUND_LIFE) @classmethod def tearDownClass(cls): cls.cls_level_mngr.exit_level() def setUp(self): # The webdriver is already initialized on previous level # We simply manage it's context with this new _level_mngr self._level_mngr = WebdriverManager().enter_level(level=SINGLE_TEST_LIFE) # Lock webdriver and build XpathBrowser API self.browser = self._level_mngr.get_xpathbrowser(name=__name__) self.browser.set_base_url(base_url) def tearDown(self): # Release webdriver, we are not longer using it. self._level_mngr.exit_level() def test_loaded(self): b = self.browser b.get_page('/') # Make sure there is at least 1 element b.select_xsingle(".//*[@id='input_area']") def test_send_msg(self): browser1 = self.browser path = '/' with WebdriverManager().enter_level(level=SINGLE_TEST_LIFE, name='Browser2') \ as browser2: browser1.get_page(path) browser2.set_base_url(base_url) browser2.get_page(path) username = '******' message = 'my message' browser1.fill_input(".//*[@id='username']", username) browser1.fill_input(".//*[@id='message']", message) browser1.click(".//*[@id='input_area']/button") msgs_xpath = ".//*[@id='chat']/div" msg_recv = browser1.extract_xpath(msgs_xpath)[-1] self.assertEqual(msg_recv, '%s: %s' % (username, message)) msg_recv2 = browser2.extract_xpath(msgs_xpath)[-1] self.assertEqual(msg_recv, msg_recv2)
def test(self, test_paths, argv=[], smoke=False): ''' :param test_paths: iterable like ['package.module.test_class.test_method', ...] ''' results = TestResults() if smoke or not test_paths: self.log.i('Ignoring %r \n (smoke mode or no tests found)' % list(test_paths)) return results level_mngr = WebdriverManager().enter_level(level=TEST_ROUND_LIFE) for tpath in test_paths: class_ = self._import_test(tpath) if isinstance(class_, TestException): results.append_result(tpath, class_) else: result = self._run_test(tpath, argv, class_) results.append_result(tpath, result) level_mngr.exit_level() return results
def test(self, test_paths, argv=[], smoke=False): ''' :param test_paths: iterable like ['package.module.test_class.test_method', ...] ''' results = TestResults() if smoke or not test_paths: self.log.i('Ignoring %r \n (smoke mode or no tests found)' % list(test_paths)) return results level_mngr = WebdriverManager().enter_level(level=TEST_ROUND_LIFE) for tpath in test_paths: class_ = self._import_test(tpath) if isinstance(class_, TestException): results.append_result(tpath, class_) else: result = self._run_test(tpath, argv, class_) results.append_result(tpath, result) level_mngr.exit_level() return results
class SearchEnginesDemo(unittest.TestCase): def setUp(self): # We need to enter "single test level" of life for each test # It will initialize the webdriver if no webdriver is present from upper levels self._level_mngr = WebdriverManager().enter_level(level=SINGLE_TEST_LIFE) # Get Xpath browser self.browser = self._level_mngr.get_xpathbrowser(name=__name__) def tearDown(self): # Make sure we quit those webdrivers created in this specific level of life self._level_mngr.exit_level() def test_duckduckgo(self): # Load a local page for the demo self.browser.get_url('https://duckduckgo.com/') # Type smoothtest and press enter self.browser.fill(".//*[@id='search_form_input_homepage']", 'smoothtest\n') result_link = './/a[@title="smoothtest "]' # Wait for the result to be available self.browser.wait_condition(lambda brw: brw.select_xpath(result_link)) # Click on result self.browser.click(result_link) # First result should point to github expected_url = 'https://github.com/joaduo/smoothtest' wait_url = lambda brw: brw.current_url() == expected_url # Make sure we end up in the right url self.assertTrue(self.browser.wait_condition(wait_url)) def test_google(self): # go to google self.browser.get_url('https://www.google.com/') # search for smoothtest and press enter self.browser.fill(".//*[@id='lst-ib']", 'smoothtest\n') first_result = './/a[contains(text(),"smoothtest 0.1.3")]' # Wait for first result self.browser.wait_condition(lambda brw: brw.select_xpath(first_result)) # Click first result self.browser.click(first_result) # Make sure we went to pypi wait_pypi_url = lambda brw: brw.current_url() == 'https://pypi.python.org/pypi/smoothtest/0.1.3' self.assertTrue(self.browser.wait_condition(wait_pypi_url))
class TestXpathBrowser(unittest.TestCase): def setUp(self): # We need to enter "single test level" of life for each test # It will initialize the webdriver if no webdriver is present from upper levels self.__level_mngr = WebdriverManager().enter_level(level=SINGLE_TEST_LIFE) # Get Xpath browser self.browser = self.__level_mngr.get_xpathbrowser(name=__name__) # Line above is equivalent to doing: # from smoothtest.Logger import Logger # from smoothtest.webunittest.XpathBrowser import XpathBrowser # # Once we make sure there is a webdriver available, we acquire it # # and block usage from other possible users # webdriver = self.__level_mngr.acquire_driver() # # Initialize the XpathBrowser class # logger = Logger(__name__) # self.browser = XpathBrowser('', webdriver, logger, settings={}) def tearDown(self): # Make sure we quit those webdrivers created in this specific level of life self.__level_mngr.exit_level() def test_select(self): # Load a local page for the demo self.get_local_page('xpath_browser_demo.html') # Do 2 type of selection self.browser.select_xpath('//div') # Xpath must be present, but no inner element may be returned self.browser.select_xsingle('//div') # Xpath must be present and at least 1 element must be present def test_extract(self): # Load a local page for the demo self.get_local_page('xpath_browser_demo.html') # Do 2 type of selection self.browser.select_xpath('//div') # Xpath must be present, but no inner element may be returned self.browser.extract_xsingle('//div') # Xpath must be present and at least 1 element must be present def get_local_page(self, file_name): # Auxiliary method root_dir = os.path.abspath(os.path.dirname(__file__)) url = 'file://' + os.path.join(root_dir, 'html', file_name) self.browser.get_url(url)
class TestRunner(ChildBase, TestRunnerBase): ''' Responsabilities - Import the Test Class - Run test over all methods or specific methods - Report any errors ''' def __init__(self): super(TestRunner, self).__init__() self._level_mngr = WebdriverManager().enter_level( level=TEST_RUNNER_LIFE) def test(self, test_paths, argv=[], smoke=False): ''' :param test_paths: iterable like ['package.module.test_class.test_method', ...] ''' results = TestResults() if smoke or not test_paths: self.log.i('Ignoring %r \n (smoke mode or no tests found)' % list(test_paths)) return results level_mngr = WebdriverManager().enter_level(level=TEST_ROUND_LIFE) for tpath in test_paths: class_ = self._import_test(tpath) if isinstance(class_, TestException): results.append_result(tpath, class_) else: result = self._run_test(tpath, argv, class_) results.append_result(tpath, result) level_mngr.exit_level() return results def io_loop(self, conn, stdin=None, stdout=None, stderr=None): while True: self._dispatch_cmds(conn) def _receive_kill(self, *args, **kwargs): self._tear_down_process() self._level_mngr.exit_level() def _run_test(self, test_path, argv, class_): try: _, _, methstr = self._split_path(test_path) suite = unittest.TestSuite() suite.addTest(class_(methstr)) runner = unittest.TextTestRunner() self._setup_process(class_, test_path, argv) return runner.run(suite) except Exception as e: return self.reprex(e) def _split_path(self, test_path): return self.split_test_path(test_path, meth=True) def _import_test(self, test_path): modstr, clsstr, _ = self._split_path(test_path) try: module = importlib.import_module(modstr) module = reload(module) class_ = getattr(module, clsstr) return class_ except Exception as e: return self.reprex(e)
class TestRunner(ChildBase, TestRunnerBase): ''' Responsabilities - Import the Test Class - Run test over all methods or specific methods - Report any errors ''' def __init__(self): super(TestRunner, self).__init__() self._level_mngr = WebdriverManager().enter_level(level=TEST_RUNNER_LIFE) def test(self, test_paths, argv=[], smoke=False): ''' :param test_paths: iterable like ['package.module.test_class.test_method', ...] ''' results = TestResults() if smoke or not test_paths: self.log.i('Ignoring %r \n (smoke mode or no tests found)' % list(test_paths)) return results level_mngr = WebdriverManager().enter_level(level=TEST_ROUND_LIFE) for tpath in test_paths: class_ = self._import_test(tpath) if isinstance(class_, TestException): results.append_result(tpath, class_) else: result = self._run_test(tpath, argv, class_) results.append_result(tpath, result) level_mngr.exit_level() return results def io_loop(self, conn, stdin=None, stdout=None, stderr=None): while True: self._dispatch_cmds(conn) def _receive_kill(self, *args, **kwargs): self._tear_down_process() self._level_mngr.exit_level() def _run_test(self, test_path, argv, class_): try: _, _, methstr = self._split_path(test_path) suite = unittest.TestSuite() suite.addTest(class_(methstr)) runner = unittest.TextTestRunner() self._setup_process(class_, test_path, argv) return runner.run(suite) except Exception as e: return self.reprex(e) def _split_path(self, test_path): return self.split_test_path(test_path, meth=True) def _import_test(self, test_path): modstr, clsstr, _ = self._split_path(test_path) try: module = importlib.import_module(modstr) module = reload(module) class_ = getattr(module, clsstr) return class_ except Exception as e: return self.reprex(e)