Selenium和Angularjs等到做一些动作

时间:2016-07-27 19:19:13

标签: javascript java angularjs selenium selenium-webdriver

我使用selenium来测试AngularJS应用程序。我面临的问题是,在完全加载之前,我无法在页面上执行任何操作。我可以把Thread.sleep(),但这不是我所知道的好解决方案。有很多方法可以等到页面加载(我谷歌它),但我想我尝试了所有这些仍然没有运气。在我的应用程序中,当转到网页时,所有内容看起来都是加载的(从可视角度来看),但在完整页面加载(大约1秒)之前我无法进行任何活动。 你们可以分享你的实施方式吗?你实际上是如何工作的

谢谢

我的代码:

public By ngWait(final By by) {
    return new FluentBy() {
        @Override
        public void beforeFindElement(WebDriver driver) {
            driver.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS);
            ((JavascriptExecutor) driver).executeAsyncScript("var callback = arguments[arguments.length - 1];" +
                    "angular.element(document.body).injector().get('$browser').notifyWhenNoOutstandingRequests(callback);");
            super.beforeFindElement(driver);
        }

        @Override
        public List<WebElement> findElements(SearchContext context) {
            return by.findElements(context);
        }

        @Override
        public WebElement findElement(SearchContext context) {
            return by.findElement(context);
        }

        @Override
        public String toString() {
            return "ngWait(" + by.toString() + ")";
        }
    };
}

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:3)

我在使用selenium对角应用程序编写测试时遇到了类似的情况。实际上,在角度应用程序中,页面的骨架或视图会立即加载,但它会在后台调用$http请求以获取数据。一旦角度应用程序完成$http调用,它就会以$ http call的响应呈现视图。因此,像waitUntilPageToBeLoad那样经常等待硒,waitUntilElementToBeClickable根本不起作用。另一个解决方案是拥有Thread.Sleep(),但正如您所提到的,这不是一个智能等待。

那么为什么没有等待方法来确保$http调用在后台完成。你可以尝试下面的等待方法,它对我有用。我希望它也适合你!

    public void untilAngularFinishHttpCalls() {
        final String javaScriptToLoadAngular =
                "var injector = window.angular.element('body').injector();" + 
                "var $http = injector.get('$http');" + 
                "return ($http.pendingRequests.length === 0)";

        ExpectedCondition<Boolean> pendingHttpCallsCondition = new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver driver) {
                return ((JavascriptExecutor) driver).executeScript(javaScriptToLoadAngular).equals(true);
            }
        };
        WebDriverWait wait = new WebDriverWait(driver, 20); // timeout = 20 secs
        wait.until(pendingHttpCallsCondition);
    }

答案 1 :(得分:1)

抱歉,我还不能发表评论,所以这是我的帮助作为答案。

关于对Priyanshu Shekhar的回答的评论错误,所有这意味着jqLit​​e(Angular的基本jquery版本)不足以完成该代码试图做的事情。

在页面中包含完整的jquery版本可以解决这个问题。