Home stale element references in loop after redirection to another page
Reply: 3

stale element references in loop after redirection to another page

Narco
1#
Narco Published in 2017-12-07 14:56:24Z

i am trying to choose a certain element of similar objects on a website, in my e2e tests, and to click it then to change to another site, related to that element. The Problem is that the loop is still going on after the page is changed because the promise resolves asynchronous (i'm new to all this stuff)

Here the code:

    goToCartridge(name){
    let done = false;
    element(by.id('dashboard')).all(by.className('card z-depth-1')).then( elems => {
      for(let i = 0; i < elems.length ; i++ ){
        if(done) break;
          elems[i].element(by.tagName('h2')).getText().then( text => {
            if(name === text) {
              element(by.id('cartridge-' + i)).click();
              done = true;
            }
          return;
        });
      }
    });
  }

How can i wait for the async part inside the loop before the next iteration starts? i searched alot for a solution, but couldnt find one yet.

Nizar Ahmed
2#
Nizar Ahmed Reply to 2017-12-07 15:16:45Z

u can skip the loop of elems and call check next element of elems from inside gettext() callback like this

goToCartridge(name){
    let done = false;
    element(by.id('dashboard')).all(by.className('card z-depth-1')).then( elems => {
    function check(i) {
      if( i >= elems.length ) return;
      elems[i].element(by.tagName('h2')).getText().then( text => {
        if(name === text) {
          element(by.id('cartridge-' + i)).click();
        }
        else {
          check(i+1);
        }
      });
    }
    check(0);
  });
}
HMR
3#
HMR Reply to 2017-12-07 15:18:05Z

Maybe this works, I changed the for loops to array.map and filter. Not sure if Array.from is going to work on elms:

goToCartridge(name){
  element(by.id('dashboard')).all(by.className('card z-depth-1'))
  .then( 
    elems => {
      Promise.all(
        Array.from(elems).map(
          element =>
            element.element(by.tagName('h2')).getText()
            .then( text => [text,element] )
        )
      ).then(
        result=> {
          let [_,index] = result.map(
            ([text,element],index)=>[name === text,index]
          ).filter(
            ([hasText,index])=>hasText
          )[0];
          if(index !== undefined){
            return element(by.id('cartridge-' + index)).click();
          }
          else{
            return Promise.reject("could not find element");
          }
        }
      )
    }
  });
}
Xotabu4
4#
Xotabu4 Reply to 2017-12-08 09:06:08Z

I would suggest to rewrite to something like this:

goToCartridge(name) {
    $$('#dashboard .card.z-depth-1 h2').each((card, index) => {
        card.getText().then(text=> {
            if (name === text) {
                $(`cartridge-${index}`).click()
            }
        })
    })
}
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.297991 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO