【问题标题】:Protractor : How to wait for page complete after click a button?量角器:单击按钮后如何等待页面完成?
【发布时间】:2014-03-11 23:44:22
【问题描述】:

在测试规范中,我需要单击网页上的按钮,然后等待新页面完全加载。

emailEl.sendKeys('jack');
passwordEl.sendKeys('123pwd');

btnLoginEl.click();

// ...Here need to wait for page complete... How?

ptor.waitForAngular();
expect(ptor.getCurrentUrl()).toEqual(url + 'abc#/efg');

【问题讨论】:

  • 您能否在您等待的页面上更具体一些?您只是在等待页面更改或一些异步加载吗?

标签: jasmine protractor wait


【解决方案1】:

根据你想做什么,你可以尝试:

browser.waitForAngular();

btnLoginEl.click().then(function() {
  // do some stuff 
}); 

解决承诺。如果你能在beforeEach中做到这一点会更好。

注意:我注意到,expect() 会等待内部的 promise(即 getCurrentUrl)在比较之前得到解决。

【讨论】:

  • 感谢分享,帮助发现了一些奇怪的间歇性问题。
  • 我仍然有问题:等待异步脚本结果超时
  • 这并没有解决我在点击按钮后等待javascript完成修改页面的问题。按照建议的below 添加browser.driver.sleep(1000) 就可以了。
  • waitForAngular()should not be used。关于click().then(),它对我不起作用。我只能依靠browser.wait(//use of protractor.ExpectedConditions)
【解决方案2】:

我刚刚查看了源代码 - Protractor 仅在少数情况下等待 Angular(例如在调用 element.all 或设置/获取位置时)。

所以 Protractor 不会在每次命令后等待 Angular 稳定下来。

另外,在我的测试中,有时我会在 Angular 摘要循环和点击事件之间进行竞争,所以有时我必须这样做:

elm.click();
browser.driver.sleep(1000);
browser.waitForAngular();

使用睡眠等待执行进入AngularJS上下文(由click事件触发)。

【讨论】:

  • 量角器不同步.click(),它同步了下一个涉及ElementFinder/ElementArrayFinder的操作。
  • 我从经验中知道,在使用 expect 评估期望值时,量角器会等待角度。在其他情况下,我明确使用waitForAngular
  • 虽然你的帖子已经快两年了,但我发现你还是对的。我目前需要在量角器 element(by.css('my-css')).click() 之后添加一个 '.sleep(1000)' 。 .click 似乎没有等待,尽管返回了一个承诺。
  • 我总是使用承诺。例如:return elm.click().then(function () { return nextAction(); }
  • 我不建议使用显式睡眠,因为即使您的应用程序加载速度比配置的睡眠快,您也会进入睡眠状态。
【解决方案3】:

您无需等待。 Protractor 会自动等待 angular 准备好,然后执行控制流中的下一步。

【讨论】:

  • 理论上是的,因为 waitForAngular() 是在内部调用的,但我也必须为某些规格调用它。
  • 它会自动等待吗?看着像browser.get 这样的东西,它明确表示它的存在是为了覆盖它包装的东西。如果ElementFinder 没有click 方法,那么它似乎只是委托给webDriver.WebElementangular.github.io/protractor/#/api?view=ElementFinder
  • @Snekse Protractor 同步了 ElementFinder 和 ElementArrayFinder 上的所有操作。因此,每当您的测试尝试查找任何元素时,查找本身都会等待 angular 完成消化周期,然后将调用委托给 webdriver。在 expect() 调用中也会发生同样的情况。
  • 如果我们不需要等待,那么这个帖子不会被浏览 100,000 次。
【解决方案4】:

使用 Protractor,您可以使用以下方法

var EC = protractor.ExpectedConditions;
// Wait for new page url to contain newPageName
browser.wait(EC.urlContains('newPageName'), 10000);

所以你的代码看起来像,

emailEl.sendKeys('jack');
passwordEl.sendKeys('123pwd');

btnLoginEl.click();

var EC = protractor.ExpectedConditions;
// Wait for new page url to contain efg
ptor.wait(EC.urlContains('efg'), 10000);

expect(ptor.getCurrentUrl()).toEqual(url + 'abc#/efg');

注意:这可能并不意味着新页面已完成加载并且 DOM 已准备就绪。随后的“expect()”语句将确保 Protractor 等待 DOM 可用于测试。

参考:Protractor ExpectedConditions

【讨论】:

    【解决方案5】:

    在这种情况下,您可以使用:

    页面对象:

        waitForURLContain(urlExpected: string, timeout: number) {
            try {
                const condition = browser.ExpectedConditions;
                browser.wait(condition.urlContains(urlExpected), timeout);
            } catch (e) {
                console.error('URL not contain text.', e);
            };
        }
    

    页面测试:

    page.waitForURLContain('abc#/efg', 30000);
    

    【讨论】:

      【解决方案6】:

      我通常只是在控制流中添加一些东西,即:

      it('should navigate to the logfile page when attempting ' +
         'to access the user login page, after logging in', function() {
        userLoginPage.login(true);
        userLoginPage.get();
        logfilePage.expectLogfilePage();
      });
      

      日志文件页面:

      function login() {
        element(by.buttonText('Login')).click();
      
        // Adding this to the control flow will ensure the resulting page is loaded before moving on
        browser.getLocationAbsUrl();
      }
      

      【讨论】:

        【解决方案7】:

        用这个我觉得更好

           *isAngularSite(false);*
            browser.get(crmUrl);
        
        
            login.username.sendKeys(username);
            login.password.sendKeys(password);
            login.submit.click();
        
            *isAngularSite(true);*
        

        要使用 isAngularSite 的这个设置,应该把它放在你的 protractor.conf.js 中:

                global.isAngularSite = function(flag) {
                browser.ignoreSynchronization = !flag;
                };
        

        【讨论】:

          【解决方案8】:

          要等到点击本身完成(即解决 Promise),请使用 await 关键字

          it('test case 1', async () => {
            await login.submit.click();
          })
          

          这将停止命令队列,直到点击(sendKeys、sleep 或任何其他命令)完成

          如果您很幸运,并且您在构建良好且没有待处理的微观和宏观任务的角度页面上,那么 Protractor 应该自行等待,直到页面准备好。但有时您需要自己处理等待,例如通过非 Angular 页面登录时(阅读how to find out if page has pending tasks and how to work with non angular pages

          如果您手动处理等待,browser.wait 是您的最佳选择。只需将一个函数传递给它,该函数将具有等待的条件。例如等到页面上没有加载动画

          let $animation = $$('.loading');
          
          await browser.wait(
            async () => (await animation.count()) === 0, // function; if returns true it stops waiting; can wait for anything in the world if you get creative with it
            5000, // timeout
            `message on timeout`
          );
          
          

          请务必使用await

          【讨论】:

            【解决方案9】:

            你可以这样做

            emailEl.sendKeys('jack');
            passwordEl.sendKeys('123pwd');
            
            btnLoginEl.click().then(function(){
            browser.wait(5000);
            });

            【讨论】:

            • browser.wait(5000) 将返回“不可分配给类型函数”,因为 browser.wait 接受 >1 个参数,第一个是条件,第二个是时间...跨度>
            【解决方案10】:
            browser.waitForAngular();
            
            btnLoginEl.click().then(function() { Do Something });
            

            兑现承诺。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-12-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多