Selenium等待特定的XHR请求完成

huangapple go评论108阅读模式
英文:

Selenium wait for specific XHR request to be complete

问题

你好,我正在进行一个Selenium项目,我所遇到的主要困难是等待XHR请求完成。我目前正在使用以下预期条件等待请求被发出,

  1. public ExpectedCondition<Boolean> jQueryExpect(int expectedActive) {
  2. ExpectedCondition<Boolean> jQLoad = new ExpectedCondition<Boolean>() {
  3. @Override
  4. public Boolean apply(WebDriver dr) {
  5. try {
  6. logger.log(Level.INFO, "Checking number of jQueries Active");
  7. Long active = (Long) ((JavascriptExecutor) driver).executeScript("return jQuery.active");
  8. logger.log(Level.INFO, "jQuery's active: {0}", active);
  9. return (active >= expectedActive);
  10. } catch (Exception e) {
  11. logger.log(Level.WARNING, "Error executing script in jQueryLoad method");
  12. // no jQuery present
  13. return true;
  14. }
  15. }
  16. };
  17. return jQLoad;
  18. }

然后,我使用以下预期条件等待jQuery加载完成:

  1. public ExpectedCondition<Boolean> jQueryLoad(int expectedActive) {
  2. ExpectedCondition<Boolean> jQLoad = new ExpectedCondition<Boolean>() {
  3. @Override
  4. public Boolean apply(WebDriver dr) {
  5. try {
  6. logger.log(Level.INFO, "Checking number of jQueries Active");
  7. Long active = (Long) ((JavascriptExecutor) driver).executeScript("return jQuery.active");
  8. logger.log(Level.INFO, "jQuery's active: {0}", active);
  9. return (active <= expectedActive);
  10. } catch (Exception e) {
  11. logger.log(Level.WARNING, "Error executing script in jQueryLoad method");
  12. // no jQuery present
  13. return true;
  14. }
  15. }
  16. };
  17. return jQLoad;
  18. }

这个方法目前效果还不错,因为我知道有多少个请求要等待。但正如您已经注意到的,由于某些原因请求的数量发生变化,这个方法未来很容易失效。

我一直在查阅Cypress文档,发现了这个。根据Cypress文档,它等待指定的请求被发出。

  1. cy.wait(['@getUsers', '@getActivities', '@getComments']).then((xhrs) => {
  2. // xhrs现在将是匹配的XHR数组
  3. // xhrs[0] <-- getUsers
  4. // xhrs[1] <-- getActivities
  5. // xhrs[2] <-- getComments
  6. })

Selenium中是否有类似的方法?或者是否有实现这个的方法?到目前为止,根据我的搜索,我什么都没有找到。所以,任何帮助将不胜感激。

英文:

Hi i am working on a selenium project and the top difficulty that i am having was waiting for XHR request to be completed. What i am currently doing is i wait for a request to be made using following expected condition,

  1. public ExpectedCondition&lt;Boolean&gt; jQueryExpect (int expectedActive) {
  2. ExpectedCondition&lt;Boolean&gt; jQLoad = new ExpectedCondition&lt;Boolean&gt;() {
  3. @Override
  4. public Boolean apply(WebDriver dr) {
  5. try {
  6. logger.log(Level.INFO,&quot;Checking number of jQueries Active&quot;);
  7. Long active = (Long) ((JavascriptExecutor) driver).executeScript(&quot;return jQuery.active&quot;);
  8. logger.log(Level.INFO,&quot;jQuery&#39;&#39;s active: {0}&quot;,active);
  9. return (active &gt;= expectedActive);
  10. }
  11. catch (Exception e) {
  12. logger.log(Level.WARNING,&quot;Error executing script in jQueryLoad method&quot;);
  13. // no jQuery present
  14. return true;
  15. }
  16. }
  17. };
  18. return jQLoad;
  19. }

And then i wait for the jQuery to load using this expected condition

  1. public ExpectedCondition&lt;Boolean&gt; jQueryLoad (int expectedActive) {
  2. ExpectedCondition&lt;Boolean&gt; jQLoad = new ExpectedCondition&lt;Boolean&gt;() {
  3. @Override
  4. public Boolean apply(WebDriver dr) {
  5. try {
  6. logger.log(Level.INFO,&quot;Checking number of jQueries Active&quot;);
  7. Long active = (Long) ((JavascriptExecutor) driver).executeScript(&quot;return jQuery.active&quot;);
  8. logger.log(Level.INFO,&quot;jQuery&#39;&#39;s active: {0}&quot;,active);
  9. return (active &lt;= expectedActive);
  10. }
  11. catch (Exception e) {
  12. logger.log(Level.WARNING,&quot;Error executing script in jQueryLoad method&quot;);
  13. // no jQuery present
  14. return true;
  15. }
  16. }
  17. };
  18. return jQLoad;
  19. }

This method is working pretty solid for now since i know how many requests to expect. But as you have already noticed it can easily break in future as number of requests made are changed for some reason.

I been looking at cypress documentation and found this. According to cypress documentation this waits for the specified requests to be made.

  1. cy.wait([&#39;@getUsers&#39;, &#39;@getActivities&#39;, &#39;@getComments&#39;]).then((xhrs) =&gt; {
  2. // xhrs will now be an array of matching XHR&#39;s
  3. // xhrs[0] &lt;-- getUsers
  4. // xhrs[1] &lt;-- getActivities
  5. // xhrs[2] &lt;-- getComments
  6. })

Is there any such method available in Selenium? or Is there any way this can be implemented? So far from what i have googled i got nothing. So any help will be appreciated.

答案1

得分: 1

你可以定位元素并等待元素。在Selenium中有隐式等待和显式等待。

你可以使用以下任一方法:

  1. WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
  2. wait.until(ExpectedConditions.visibilityOfElementLocated(By.id&lt;locator&gt;));

或者

  1. wait.until(ExpectedConditions.elementToBeClickable(By.id&lt;locator&gt;));

更多信息请参见:此答案链接

英文:

You can locate Element and wait for element
There are Implicit and Explicit waits in selenium.

You can use either

  1. WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
  2. wait.until(ExpectedConditions.visibilityOfElementLocated(By.id&lt;locator&gt;));

or

  1. wait.until(ExpectedConditions.elementToBeClickable(By.id&lt;locator&gt;));

More information: on this answer

huangapple
  • 本文由 发表于 2020年9月17日 14:59:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63932825.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定