简体   繁体   中英

Function to wait for promise and retrieve result

I have a Protractor call that returns a promise, and the promise wraps a value.

var e = element.all(by.css("selector")).first();

e.getAttribute('id').then(function (text) {
  console.log(text); 
});

I want to do a blocking wait on the promise returned from getAttribute() and retrieve the resulting text.

This needs to be a blocking function; adding then would require rewriting many of our existing tests. How can I write this?

Edit:

What I am trying to do is to retrieve a value from the page and use it to build an element selector. So:

  1. Find the dynamic ID of element one: element.all(by.css("...")).first().getAttribute('id')
  2. Build a selector based on that value: var elementSelector = '#X' + elementOneID + '-Y';
  3. Find and do something with element two: element(by.css(elementSelector))...

I will accept any answer that allows me to do this.

Edit 2:

Apparently this is not possible without a callback. I ended up revising my CSS selectors .

You mean this?

var e = element.all(by.css("selector")).first();
browser.wait(function() {
        return e.getAttribute('id').then(function (id) {
              if(id === 'oneIWant') {
                  return true;
              } else {
                  return false;
              }
          });
},3000,'Waiting for the id value to be something awesome');

Edit1

From WebDriverJS documentation here you can find below quote. So if you have a series of selenium-webdriver commands, they will be pushed to the promise manager queue and they will be executed one after the other. When you say wait is not blocking the next command, it certainly means that your wait condition is incorrect.

The promise manager maintains a queue of scheduled tasks, executing each once the one before it in the queue is finished. The WebDriver API is layered on top of the promise manager

Edit2

Please check protractor expected conditions here

var EC = protractor.ExpectedConditions;

var e = element.all(by.css("...")).first();
browser.wait(EC.presenceOf(e), 10000);

if(e.isPresent()) {
  e.getAttribute('id').then(function(elementOneID) {
     var elementSelector = '#X' + elementOneID + '-Y';
     var el = element(by.css(elementSelector));
     browser.wait(EC.presenceOf(el), 10000);
     el.click(); //or do stuff
  });
}

You can't actually block. Since JavaScript is single threaded, nothing can happen while you wait. Protractor will never resolve the promise if you were to block. see this answer to a similar question

You can get the appearance of blocking on promises with es7's async await , but that feature is only available if you use a transpiler such as babel.

But, I believe @nilesh's answer is what you are looking for. browser.wait will basically run a function over and over until it returns true , or it times out, but it will not block the thread.

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