简体   繁体   中英

Protractor break while of for loop

I need help with loop beaking.

For my check I did the simple test:

while(i < 10) {
    element(by.xpath("//a[contains(@id, 'ma-apply')]")).isPresent().then(function(result) {
        if(!result) {
            helper.one_page_ahead();
        } else {
            console.log('there is on the page');
            break;
        }
    });
    i++;
};

This code leads to the error.

I tried to follow advice via StackOverflow and changed break to return. But this leads to full loop execution (up to 10).

Here is the output:

[14:17:46] I/launcher - Running 1 instances of WebDriver Started user skills: AJAX there is on the page there is on the page there is on the page there is on the page there is on the page there is on the page there is on the page there is on the page .

1 spec, 0 failures Finished in 37.93 seconds

I tried the same with for loop like

for(i = 0; i < 10; i++) {
    //code
    break;
}

Would be glad to find the answer.

This is some commentary about why the while statement does not work: When you call isPresent you are returned a webdriver.promise.Promise<boolean> . Since you are in the webdriver control flow, you'll need to throw an error,

      browser.get('http://angularjs.org');
      var i = 0;
      var running = true;
      while(i < 3 && running) {
        console.log('while: ' + running + ' ' + i);
        element(by.model('username')).isPresent().then((result) => {
          console.log('element: ' + running + ' ' + i);

          if (result) {
            // huzzah we found it, so lets break the element after the first test
            browser.get('https://docs.angularjs.org/tutorial');
          } else {
            running = false;
            throw new Error('no username')
          }

        }).catch((err) => {
          console.log(err);
        });
        i++;
      }

This basically prints out:

[19:07:18] I/hosted - Using the selenium server at http://localhost:4444/wd/hub
[19:07:18] I/launcher - Running 1 instances of WebDriver
Started
while: true 0
while: true 1
while: true 2
element: true 3
[Error: no username]
element: false 3
[Error: no username]
element: false 3
[Error: no username]

So basically your while loop queues up items in the control flow to execute. These then will get executed asynchronously in order.

I like the suggestion by Sudharsan Selvaraj to do this recursively.

You need to implement a recursive method to achieve what you want, try the below piece of code,

function runTillElementFound(totalCount,currentCount){
  var self = this;
  var _element = element(by.xpath("//a[contains(@id, 'ma-apply')]"));
  if(currentCount < totalCount){
     return _element.isPresent().then(function(isElementPresent){
        if(isElementPresent){
           return;
         }else{
           helper.one_page_ahead();
           self.runTillElementFound(totalCount,currentCount++);
         }
      })
  }else{
     return false; //if element not present after Max count reached.
   }
}

this.runTillElementFound(10,0); //this will execute the method untill the required element found on the page.

If you want to avoid recursion you could modify the index variable inside the returned promised

while(i < 10) {
element(by.xpath("//a[contains(@id, 'ma-apply')]")).isPresent().then(function(result) {
    if(!result) {
        helper.one_page_ahead();
    } else {
        console.log('there is on the page');
        i = 10;
    }
});
i++;

};

And I would add a browser.sleep(x) in between each repetion to avoid the code to be run before the result from the promise is evaluated.

i = 10; is not effecting, Still loop iterating

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM