我怎么能等待病情?

时间:2014-02-27 15:02:58

标签: javascript angularjs selenium-webdriver protractor automated-tests

我是量角器的新手,我正在尝试实施e2e测试。 我不知道这是否是正确的方法,但...... 我要测试的页面不是基于完整的角度页面,所以......我遇到了一些麻烦。

根据我的第一个规范:

describe('should open contact page', function() {
var ptor = protractor.getInstance();

beforeEach(function(){

   var Login = require('./util/Login');
   new Login(ptor);
});

我已创建此Login类,但在登录后我想打开联系页面,但量角器会在页面完全加载之前立即尝试查找元素。

我试过用:

browser.driver.wait(function() {

    expect(browser.findElement(by.xpath("//a[@href='#/contacts']")).isDisplayed());
    ptor.findElement(by.xpath("//a[@href='#/contacts']")).click();

});

但它不起作用......它总是试图在页面加载之前找到元素。 我也试过这个:

browser.driver.wait(function() {
    expect(ptor.isElementPresent(by.xpath("//a[@href='#/contacts']")));          
    ptor.findElement(by.xpath("//a[@href='#/contacts']")).click();
});

我可以使用browser.sleep();来做到这一点,但我不认为这是一个不错的选择。任何的想法?在我的登录课上,我有:

ptor.ignoreSynchronization = true;

在量角器尝试点击它之前,我该如何等待@href='#/contacts

9 个答案:

答案 0 :(得分:51)

量角器1.7.0还引入了一项新功能:Expected Conditions

有几个预先定义的条件要明确等待。如果您想等待元素出现:

var EC = protractor.ExpectedConditions;

var e = element(by.id('xyz'));
browser.wait(EC.presenceOf(e), 10000);

expect(e.isPresent()).toBeTruthy();

另见:

答案 1 :(得分:33)

我终于找到了......

   var waitLoading = by.css('#loading.loader-state-hidden');

   browser.wait(function() {
       return ptor.isElementPresent(waitLoading);
   }, 8000);

   expect(ptor.isElementPresent(waitLoading)).toBeTruthy();

   var openContact = by.xpath("//a[@href='#/contacts']");
   element(openContact).click();

使用此量角器可以等待该元素,直到加载页面消失。 感谢那些试图帮助XD的人。

答案 2 :(得分:23)

我在使用量角器的过程中遇到了同样的问题。在我的e2e测试中,我从非角度app开始,然后进入角度部分,然后返回到非角度部分。让事情变得棘手。关键是要了解承诺及其运作方式。以下是我在运行的e2e测试中的真实世界代码的一些示例。希望这能让您了解如何构建测试。可能在这段代码中有一些不好的做法,请随意改进,但我知道它有效,也许不是最好的方法。

要使用角度我使用

var ptor;
var events = require('events');
var eventEmitter = new events.EventEmitter();
var secondClick = require('./second-click');

beforeEach(function () {
    browser.driver.get('http://localhost:8080/');
},10000);

it("should start the test", function () {
    describe("starting", function () {
        it("should find the  link and start the test", function(){
            var elementToFind = by.linkText('Start'); //what element we are looking for
            browser.driver.isElementPresent(elementToFind).then(function(isPresent){
                expect(isPresent).toBe(true); //the test, kind of redundant but it helps pass or fail
                browser.driver.findElement(elementToFind).then(function(start){
                    start.click().then(function(){ //once we've found the element and its on the page click it!! :) 
                        ptor = protractor.getInstance(); //pass down protractor and the events to other files so we can emit events
                        secondClick(eventEmitter, ptor); //this is your callback to keep going on to other actions or test in another file
                    });
                });
            });
        });
    });
},60000);

虽然处于角度,但此代码可以正常工作

 describe("type in a message ", function(){
        it("should find and type in a random message", function(){
            var elementToFind = by.css('form textarea.limited');
            browser.driver.isElementPresent(elementToFind).then(function(isPresent){
                element(elementToFind).sendKeys(randomSentence).then(function(){
                    console.log("typed in random message");
                    continueOn();
                });
            });
        });
    },15000);

退出角度后

browser.driver.wait(function(){
   console.log("polling for a firstName to appear");
   return    browser.driver.isElementPresent(by.name('firstName')).then(function(el){
         return el === true;
       });
     }).
   then(function(){
       somefunctionToExecute()
    });

希望能提供一些指导并帮助你!

答案 3 :(得分:9)

browser.driver.wait(function() {
    return browser.driver.isElementPresent(by.xpath("//a[@href='#/contacts']"));
});

这也适用于我(没有超时参数)..

有关详细信息,请参阅http://angular.github.io/protractor/#/api?view=webdriver.WebDriver.prototype.wait

答案 4 :(得分:1)

感谢上面的回答,这是我的简化和更新用法

function waitFor (selector) {
  return browser.wait(function () {
    return browser.isElementPresent(by.css(selector));
  }, 50000);
}

答案 5 :(得分:1)

browser.wait 可能听起来太普通了,但事实并非如此!

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` // comment on error
);

确保使用await

您还可以使用名为 ExpectedConditions 的现有库,该库具有许多要等待的预定义条件

你无法想象你能用它做什么......

我最喜欢的几个:

等到浏览器的标签页数为 2

// wait until the number of browser's tab's is 2
await browser.wait(
  async () => {
    let tabCount = await browser.getAllWindowHandles();
    return tabCount.length === 2;
  },
  5000,
  'the url didnt open in a new window'
);

等待加载动画消失最后 750 毫秒

// wait until the loading animation is gone for at last 750ms
await browser.wait(
  async () => (await this.$$loadAnimations.count()) === 0 && !(await browser.sleep(750)) && (await this.$$loadAnimations.count()) === 0,
  5000,
  `waiting timeout`
);

等待任何数量的元素出现

// wait for any number of elements to be present
async waitForElements($elem, timeout = 120000, start = +new Date()) {
    let conditions = [];

    for (let i = 0; i < $elem.length; i++) {
        conditions.push(ExpectedConditions.presenceOf($elem[i]));
    }

    await browser.wait(
        ExpectedConditions.and(...conditions), 
        remainingTimeout(timeout, start), 
        `wait for all elements`
    );
}

// and use

await waitForElements([
  $usernameField, 
  $passwordFiend, 
  $submitButton
])

答案 6 :(得分:0)

您是否尝试将ng-app放入<html>标记中(假设此部分代码在您的控制范围内)?这为我解决了很多初始化时序问题。

答案 7 :(得分:0)

在量角器中使用等待条件的最佳方法,如果测试用例失败,该方法有助于向特定元素显示正确的错误消息

const EC = ExpectedConditions;
const ele = element(by.xpath(your xpath));

return browser.wait(EC.visibilityOf(ele),9000,'element not found').then(() => {
            ele.click();
         });

答案 8 :(得分:0)

我很惊讶没有人添加此解决方案。基本上,如果您正在使用模式对话框,则通常会看到一个可见的元素,并且可以单击该元素,但由于模式对话框位于其前面而无法单击。发生这种情况是因为量角器的移动速度快于角度,并且可以随时单击下一个元素,而角度仍在关闭模态。

我建议使用

public async clickElementBug(elementLocator: Locator) {
const elem = await element(elementLocator);
await browser.wait(
  async function() {
    try {
      await elem.click();
      return true;
    } catch (error) {
      return false;
    }
  },
  this.TIMEOUT_MILLIS,
  'Clicking of element failed: ' + elem
);

}