Force Selenium to wait for AngularJS
我怎么能强制python Selenium等待一秒钟,直到AngularJS完成页面解析并加载它需要的东西。
或者如何在按钮单击后强制Selenium等待1秒钟,这会导致对服务器的ajax请求,由AngularJS处理。 我需要在导航到其他页面之前进行服务器端操作。
通过Selenium访问AngularJS范围 - 很可能该状态已经在Scope / IsolatedScope中保存。
我构建了一些扩展来帮助解决这个问题,可以转换为python。
1 2 | webDriver.NgWaitFor(productDiv,"scope.Data.Id != 0"); webDriver.NgWaitFor(partialElement,"scope.IsBusyLoadingTemplate == false"); |
https://github.com/leblancmeneses/RobustHaven.IntegrationTests/blob/master/NgExtensions/NgWebDriverExtensions.cs
当你使用angularjs $ http和jquery我使用时处理ajax请求:
1 | webDriver.WaitFor("window.isBrowserBusy() == false"); |
要求您在angularjs和jquery中设置拦截以管理xhr请求的计数。
这是我们在项目中使用的框架:(您可能希望从中提取更多部分)
https://github.com/leblancmeneses/RobustHaven.IntegrationTests
如果应用程序中的某些异步行为足够重要,真正的用户应该等待它,那么您应该告诉他们。同样,您的脚本可以在继续之前等待相同的指示。
例如,如果用户单击触发API调用以创建记录的按钮,并且用户需要等待创建该记录,则应向他们显示一条消息,指示其成功完成的时间,例如"记录创建成功""。然后,您的脚本可以等待同一文本出现,就像用户一样。
重要的是,应用程序的实现方式无关紧要。重要的是您的用户可以使用您的应用程序 - 而不是它调用某些AngularJS API或React API等。
1.使用Selenium
Selenium包含
1 2 3 4 5 6 7 8 9 10 11 12 | from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait TIMEOUT = 5 # ... WebDriverWait(driver, TIMEOUT).until( EC.text_to_be_present_in_element( [By.CLASS_NAME,"alert"], "Record created successfully")) |
2.使用Capybara(使用Selenium)
正如您在上面所看到的,裸露的Selenium是复杂而挑剔的。 capybara-py摘要大部分内容:
1 2 3 4 5 | from capybara.dsl import page # ... page.assert_text("Record created successfully") |
我有同样的问题,这就是我解决它的方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | from datetime import datetime, timedelta from time import sleep from selenium import webdriver from selenium.common.exceptions import WebDriverException class MyDriver(webdriver.Chrome): def __init__(self, executable_path="chromedriver", port=0, chrome_options=None, service_args=None, desired_capabilities=None, service_log_path=None): super().__init__(executable_path, port, chrome_options, service_args, desired_capabilities, service_log_path) def wait_until_angular(self, seconds: int = 10) -> None: java_script_to_load_angular ="var injector = window.angular.element('body').injector();" \ "var $http = injector.get('$http');" \ "return ($http.pendingRequests.length === 0);" end_time = datetime.utcnow() + timedelta(seconds=seconds) print("wait for Angular Elements....") while datetime.utcnow() < end_time: try: if self.execute_script(java_script_to_load_angular): return except WebDriverException: continue sleep(1) raise TimeoutError("waiting for angular elements for too long") |
它对我有用
希望这对你有所帮助!!!