def test_password_update_ok(selenium: WebDriver) -> None: user_infos = register_valid_user(selenium) menus = selenium.find_elements_by_class_name('menu') menus[2].click() login_valid_user(selenium, user_infos) # click on user name menus = selenium.find_elements_by_class_name('menu') menus[0].click() # click on 'Change password' submit_button = selenium.find_element_by_tag_name('button') submit_button.click() # update password new_password = '******' password = selenium.find_element_by_id('oldPassword') password.send_keys(user_infos.get('password')) password = selenium.find_element_by_id('password') password.send_keys(new_password) password_conf = selenium.find_element_by_id('confirm-password') password_conf.send_keys(new_password) submit_button = selenium.find_element_by_tag_name('button') submit_button.click() # log out menus = selenium.find_elements_by_class_name('menu') menus[2].click() # log in user_infos['password'] = user_infos['password_conf'] = new_password login_valid_user(selenium, user_infos)
def test_settings_update_tags(selenium: WebDriver) -> None: register_valid_user(selenium) selenium.get(f'{URL}settings/tags') add_button = selenium.find_elements_by_tag_name('button')[1] add_button.click() # add a tag fill_form(selenium, {'name': 'python'}, is_category=False) tbody_td = selenium.find_element_by_tag_name( 'tbody').find_elements_by_tag_name('td') assert 'python' in tbody_td[1].text assert '0' in tbody_td[2].text edit_icon = tbody_td[3].find_element_by_class_name('fa-pencil') assert len(tbody_td[3].find_elements_by_class_name('fa-trash')) == 1 # edit the tag edit_icon.click() fill_form(selenium, {'name': 'tests'}, is_category=False) tbody_td = selenium.find_element_by_tag_name( 'tbody').find_elements_by_tag_name('td') assert 'tests' in tbody_td[1].text # delete the tag tbody_td[3].find_element_by_class_name('fa-trash').click() tbody_td = selenium.find_element_by_tag_name( 'tbody').find_elements_by_tag_name('td') assert tbody_td == []
def test_settings_update_categories(selenium: WebDriver) -> None: register_valid_user(selenium) selenium.get(f'{URL}settings/categories') add_button = selenium.find_elements_by_tag_name('button')[1] add_button.click() # add a category form_values = {'name': 'news', 'description': 'News category'} fill_form(selenium, form_values) tbody_td = selenium.find_element_by_tag_name( 'tbody').find_elements_by_tag_name('td') assert 'default' in tbody_td[1].text assert (len( tbody_td[1].find_elements_by_class_name('badge-rdltr-small')) == 1) assert 'Default category' in tbody_td[2].text assert '0' in tbody_td[3].text assert 'news' in tbody_td[6].text assert tbody_td[6].find_elements_by_class_name('badge-rdltr-small') == [] assert 'News category' in tbody_td[7].text assert '0' in tbody_td[8].text assert len(tbody_td[9].find_elements_by_class_name('fa-trash')) == 1 # edit the category tbody_td[9].find_element_by_class_name('fa-pencil').click() form_values = { 'name': 'sports', 'description': 'All articles about sports', } fill_form(selenium, form_values) tbody_td = selenium.find_element_by_tag_name( 'tbody').find_elements_by_tag_name('td') assert 'default' in tbody_td[1].text assert (len( tbody_td[1].find_elements_by_class_name('badge-rdltr-small')) == 1) assert 'Default category' in tbody_td[2].text assert '0' in tbody_td[3].text assert 'sports' in tbody_td[6].text assert tbody_td[6].find_elements_by_class_name('badge-rdltr-small') == [] assert 'All articles about sports' in tbody_td[7].text assert '0' in tbody_td[8].text # delete the category tbody_td[9].find_element_by_class_name('fa-trash').click() tbody_td = selenium.find_element_by_tag_name( 'tbody').find_elements_by_tag_name('td') assert len(tbody_td) == 5 assert 'default' in tbody_td[1].text assert (len( tbody_td[1].find_elements_by_class_name('badge-rdltr-small')) == 1) assert 'Default category' in tbody_td[2].text
def verificar_elemento_html_hasta_no_existir_en_el_dom_html( web_driver: WebDriver, time=5, id=None, xpath=None, link_text=None, partial_link_text=None, name=None, tag_name=None, class_name=None, css_selector=None): msg_selector_html_a_localizar = HtmlActions.generar_identificador_excepcion( id, xpath, link_text, partial_link_text, name, tag_name, class_name, css_selector) tiempo_inicial = Temporizador.obtener_tiempo_timer() while True: try: if id is not None: web_driver.find_element_by_id(id) elif xpath is not None: web_driver.find_element_by_xpath(xpath) elif link_text is not None: web_driver.find_element_by_link_text(link_text) elif partial_link_text is not None: web_driver.find_element_by_partial_link_text( partial_link_text) elif name is not None: web_driver.find_element_by_name(name) elif tag_name is not None: web_driver.find_element_by_tag_name(tag_name) elif class_name is not None: web_driver.find_element_by_class_name(class_name) elif css_selector is not None: web_driver.find_element_by_css_selector(css_selector) segundos_transcurridos = Temporizador.obtener_tiempo_timer( ) - tiempo_inicial if segundos_transcurridos > time: e = TimeoutException() e.msg = webdriver_actions_constantes.WEBDRIVER_WAIT_UNTIL_NOT_TIMEOUT_EXCEPTION.format( time, msg_selector_html_a_localizar, e.msg) raise e else: pass except NoSuchElementException: break
def take_screenshot(driver: WebDriver, page_name: str = None): """Will take a screenshot of current page.""" if TAKE_SCREENSHOTS: if BROWSER == "firefox": # Ref: https://stackoverflow.com/a/52572919/ original_size = driver.get_window_size() required_width = driver.execute_script( "return document.body.parentNode.scrollWidth") required_height = driver.execute_script( "return document.body.parentNode.scrollHeight") driver.set_window_size(required_width, required_height) element = driver.find_element_by_tag_name("body") screenshot_png = element.screenshot_as_png screenshot_jpg = convert_png_to_jpg(screenshot_png) elif BROWSER == "chrome": screenshot_jpg = fullpage_screenshot(driver) if page_name: page_name = page_name.lower().replace(" ", "_")[0:200] allure.attach( screenshot_jpg, name=page_name or "screenshot.jpg", attachment_type=allure.attachment_type.JPG, ) if BROWSER == "firefox": driver.set_window_size(original_size["width"], original_size["height"]) else: logging.debug( f"Taking screenshots is disabled. In order to turn it on " f"please set an environment variable TAKE_SCREENSHOTS=true")
def scrape_follow_type(self, driver: WebDriver, user_name: str, query_hash: str) -> Set[InstaUser]: self.init_driver() self.logger.info('Scraping follow type') driver.get("http://www.instagram.com/{0}".format(user_name)) data_key = 'edge_followed_by' if query_hash == QueryHashes.FOLLOWERS else 'edge_follow' validation_func = partial(self.is_valid_body, data_key=data_key) user_id = self.parse_user_id_from_profile(driver) request_url = self.create_url(query_hash, user_id) all_users = set() # type: Set[InstaUser] while True: body = self.get_url_data(request_url, validation_func) try: data = json.loads(body)['data']['user'][data_key] end_cursor = data['page_info']['end_cursor'] if data[ 'page_info']['has_next_page'] else None users = { InstaUser.from_dict(user['node']) for user in data['edges'] } except Exception as e: self.logger.exception("driver body: {0}".format( driver.find_element_by_tag_name('body').text)) raise e self.logger.info('Currently scraped %d users', len(users)) all_users.update(users) if end_cursor is None: break request_url = self.create_url(query_hash, user_id, end_cursor) self.logger.info('Done scraping users. found %d users', len(all_users)) return all_users
def test_logout_and_login_ok(selenium: WebDriver) -> None: user_infos = register_valid_user(selenium) nav = selenium.find_element_by_tag_name('nav') nav_text = nav.text assert 'Register' not in nav_text assert 'Log in' not in nav_text assert 'Logout' in nav_text menus = nav.find_elements_by_class_name('menu') menus[2].click() login_valid_user(selenium, user_infos) nav = selenium.find_element_by_tag_name('nav') nav_text = nav.text assert user_infos['username'] in nav_text assert 'Settings' in nav_text assert 'Logout' in nav_text
def test_get_url(): sleep(10) TEST_URL = "http://httpbin/html" driver = WebDriver("http://%s:%s/wd/hub" % (SELENIUM_HOST, SELENIUM_PORT), desired_capabilities={"browserName": "phantomjs"}) driver.get(TEST_URL) elem = driver.find_element_by_tag_name("h1") assert "Moby-Dick" in elem.text
def wait_for_page_load(driver: WebDriver, timeout: int = 30): """Alternative Context manager for waiting for page to load. src: http://www.obeythetestinggoat.com/how-to-get-selenium-to-wait-for-page-load-after-a-click.html """ old_page = driver.find_element_by_tag_name("html") yield logging.debug("WAITING FOR STALENESS OF OLD PAGE %s", driver.current_url) WebDriverWait(driver, timeout).until(staleness_of(old_page))
def wait_for_page_load(browser: WebDriver): old_page = browser.find_element_by_tag_name('html') yield def page_has_loaded(): new_page = browser.find_element_by_tag_name('html') return new_page.id != old_page.id wait_for(page_has_loaded)
def tick_captcha_checkbox(driver: WebDriver): im_not_a_robot = Selector(By.CSS_SELECTOR, "#recaptcha-anchor") iframe = driver.find_element_by_tag_name("iframe") scroll_to(driver, iframe) driver.switch_to.frame(iframe) captcha = find_element(driver, im_not_a_robot) captcha.click() # wait 4s after user clicks on the CAPTCHA checkbox # otherwise the test might fail time.sleep(4) driver.switch_to.parent_frame()
def fill_form(selenium: WebDriver, form_values: Dict, is_category: bool = True) -> None: name = selenium.find_element_by_id('name') name.clear() name.send_keys(form_values['name']) if is_category: description = selenium.find_element_by_id('description') description.clear() description.send_keys(form_values['description']) submit_button = selenium.find_element_by_tag_name('button') submit_button.click()
def test_index_ok(selenium: WebDriver) -> None: selenium.get(URL) header = selenium.find_element_by_tag_name('header') logo = header.find_element_by_class_name('logo').text assert 'rdltr a simple "read-it later"' in logo nav = header.find_element_by_tag_name('nav').text assert 'Register' in nav assert 'Log in' in nav connexion_form = selenium.find_element_by_id('actionType').text assert 'Email' in connexion_form assert 'Password' in connexion_form
def login(selenium: WebDriver, user_infos: Dict, redirect_to_url: bool = False) -> None: if redirect_to_url: selenium.get(f'{URL}login') menus = selenium.find_elements_by_class_name('menu') assert "Log in" in menus[1].text menus[1].click() email = selenium.find_element_by_id('email') email.send_keys(user_infos.get('email')) password = selenium.find_element_by_id('password') password.send_keys(user_infos.get('password')) submit_button = selenium.find_element_by_tag_name('button') submit_button.click()
def test_login_not_existing_user(selenium: WebDriver) -> None: user_name = random_string() user_infos = { 'username': user_name, 'email': f'{user_name}@example.com', 'password': '******', 'password_conf': 'p@ssw0rd', } login(selenium, user_infos, True) nav = selenium.find_element_by_tag_name('nav') nav_text = nav.text assert 'Register' in nav_text assert 'Log in' in nav_text errors = selenium.find_element_by_class_name('alert-danger').text assert 'Invalid credentials.' in errors
def register(selenium: WebDriver, user_infos: Dict) -> None: selenium.get(f'{URL}register') menus = selenium.find_elements_by_class_name('menu') assert 'Register' in menus[0].text menus[0].click() username = selenium.find_element_by_id('username') username.send_keys(user_infos.get('username')) email = selenium.find_element_by_id('email') email.send_keys(user_infos.get('email')) password = selenium.find_element_by_id('password') password.send_keys(user_infos.get('password')) password_conf = selenium.find_element_by_id('confirm-password') password_conf.send_keys(user_infos.get('password_conf')) submit_button = selenium.find_element_by_tag_name('button') submit_button.click()
def get_video_suggestions( driver: WebDriver, suggestion_count: int = 1) -> List[ClickableVideoElement]: """ Get suggestion_count number of video suggestions from the sidebar of the current video. """ WebDriverWait(driver, 20).until( EC.element_to_be_clickable(( By.CSS_SELECTOR, "ytd-compact-video-renderer.ytd-watch-next-secondary-results-renderer", ))) yt_app = driver.find_element_by_tag_name("ytd-app") suggestions = [] prev_suggestion_count = -1 # Video suggestions are generated lazily while scrolling. # So we need to scroll far enough to get the number of suggestions we want. while suggestion_count > len(suggestions) > prev_suggestion_count: driver.execute_script( f'window.scrollTo(0, {int(yt_app.get_attribute("scrollHeight"))});' ) # Give YouTube a bit of time to load suggestions time.sleep(1) try: WebDriverWait(driver, 20).until_not( EC.visibility_of_element_located( (By.CSS_SELECTOR, "paper-spinner.yt-next-continuation#spinner"))) except: logging.warning("Suggestion scroller failed to detect spinner") prev_suggestion_count = len(suggestions) # Suggestions are not recycled, the total amount of elements is accurate suggestions = driver.find_elements_by_css_selector( "ytd-compact-video-renderer.ytd-watch-next-secondary-results-renderer" ) # Enough suggestions are displayed, we can collect them videos = [] for element in suggestions[0:suggestion_count]: if not is_livestream(element): videos.append(ClickableVideoElement(element)) return videos
class ElementEqualityTest(unittest.TestCase): """Tests that the server properly checks element equality.""" def setUp(self): self._launcher = ChromeDriverLauncher(root_path=os.path.dirname(__file__)) self._driver = WebDriver(self._launcher.GetURL(), {}) def tearDown(self): self._driver.quit() self._launcher.Kill() def testElementEquality(self): self._driver.get(self._launcher.GetURL() + "/test_page.html") body1 = self._driver.find_element_by_tag_name("body") body2 = self._driver.execute_script("return document.body") # TODO(jleyba): WebDriver's python bindings should expose a proper API # for this. result = body1._execute(Command.ELEMENT_EQUALS, {"other": body2.id}) self.assertTrue(result["value"])
def decode_captcha(self, driver): logging.info("decode_captcha begin") tmp_driver = None for i in range(5): try: # 如果已通过验证 if '查验时间' in driver.page_source: logging.info('decode_captcha success with tax content') return True # 截取验证码图片,这里先提取验证码和文字提示,通过新窗口打开并截屏 def wait1(driver): return '请输入验证码图片' in driver.page_source or '请输入验证码文字' in driver.page_source try: WebDriverWait(driver, 10).until(wait1, 'decode_captcha fail to find yzm') except: # 如果不显示验证码,刷新页面 driver.refresh() self.fill_field(driver) continue yzminfo_html = driver.find_element_by_id("yzminfo").get_attribute('outerHTML') captcha_html = driver.find_element_by_id("yzm_img").get_attribute('outerHTML') # 提取出来的display设置了none,这里修改下 # print(yzminfo_html, captcha_html) captcha_html = captcha_html.replace('display: none;', 'display: inline;') # tmp_driver = webdriver.Firefox() tmp_driver = WebDriver( command_executor=env.HUB_URL, desired_capabilities=DesiredCapabilities.FIREFOX.copy() ) # 使用一个空白html打开,图像src是base64数据打开无法截屏 # tmp_driver.get(captcha_image.get_attribute('src')) tmp_driver.get('http://www.baidu.com') # 将提取的验证码和提示拼接到html tmp_driver.execute_script(""" document.body.innerHTML = arguments[0] """, yzminfo_html + '<br>' + captcha_html) screenshotName = tools.getScreenshotName(__file__) tmp_driver.save_screenshot(screenshotName) logging.info('decode_captcha save_screenshot') captcha_image = tmp_driver.find_element_by_tag_name("img") location = captcha_image.location size = captcha_image.size left = location['x'] top = location['y'] right = left + size['width'] + 120 bottom = top + size['height'] + 20 im = Image.open(screenshotName) im = im.crop((0, 0, right, bottom)) captchaName = tools.getCaptchaName(__file__) im.save(captchaName) start_time = time.time() errcode, result = Recoginze(captchaName, 8023) if result[0] == "#": # 解码超时或出错时刷新验证码 driver.find_element_by_id("yzm_img").click() time.sleep(3) raise Exception("91打码解析验证码失败 [errcode=%s, result=%s]" % (errcode, result)) cost_time = round(time.time() - start_time) logging.info('decode_captcha [result=%s, costtime=%s]' % (result, cost_time)) yzm = driver.find_element_by_id("yzm") yzm.clear() yzm.send_keys(result) time.sleep(1) driver.find_element_by_id("checkfp").click() logging.info('decode_captcha commit') time.sleep(2) # 如果验证失败 if 'popup_message' in driver.page_source: # 如果验证次数过多 if '超过该张发票当日查验次数' in driver.page_source: logging.warning('query too much times') return False logging.info('decode_captcha fail, decode again') driver.find_element_by_id("popup_ok").click() time.sleep(1) driver.find_element_by_id("yzm_img").click() time.sleep(3) continue def wait2(driver): return '查验时间' in driver.page_source WebDriverWait(driver, 10).until(wait2, 'decode_captcha fail to find tax content') logging.info('decode_captcha success') return True except Exception as err: logging.exception('decode_captcha error') time.sleep(2) finally: if tmp_driver: logging.info('close selenium driver') tmp_driver.quit() return False