Selenium和Angularjs等到执行一些操作 [英] Selenium and Angularjs wait until to do some actions

查看:230
本文介绍了Selenium和Angularjs等到执行一些操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用硒来测试AngularJS应用程序.我遇到的问题是,在页面完全加载之前,我无法在页面上执行任何操作.我可以放入Thread.sleep(),但这并不是我所知道的好解决方案.有很多方法可以等到页面被加载(我用谷歌搜索),但是我想我尝试了所有方法,但还是没有运气.在我的应用程序中,当转到网页时,所有内容看上去都已加载(从视觉角度来看),但是直到整页加载(大约1秒)后,我才能进行任何活动. 你们能分享您的实施过程,您是如何做到的?

I'm using selenium to test AngularJS application. I'm facing issue that I cannot do any actions on the page until it loads fully. I can put Thread.sleep(), but this is not good solution as I know. There many ways to wait until page will be loaded(I google it), but I think I tried them all and still no luck. In my applications when go to webpage, everything looks loaded(from visual perspective), but I can not do any activities until full page loads(around 1 sec). Can you guys share your implementation how you did it that is actually works

谢谢

我的代码:

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() + ")";
        }
    };
}

推荐答案

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

I have faced similar situation while writing tests using selenium against angular app. Actually, in angular app the skeleton or view of page loads instantly but it keeps calling $http request in background to fetch the data. Once the angular app finishes the $http call, it renders the view with response of $http call.So having a classical wait of selenium like waitUntilPageToBeLoad, waitUntilElementToBeClickable do not work here at all. The other solution is to have Thread.Sleep() but as you mentioned that is not an intelligent wait.

所以为什么不使用wait方法来确保$http调用在后台完成.您可以尝试以下等待方法,它对我有用.我希望它也对您有用!

So why not have wait method to ensure that $http calls are finished in background. You can try below wait method,it worked for me.I Hope it works for you too!

    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);
    }

这篇关于Selenium和Angularjs等到执行一些操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆