Is there a way to resolve multiple promises with P

2020-02-28 02:32发布

问题:

I have this:

element(by.id('x')).sendKeys('xxx').then(function(text) {
  element(by.id('y')).sendKeys('yyy').then(function(text) {
     element(by.id('z')).sendKeys('zzz').then(function(text) {
        expect(element(by.id('myButton')).isEnabled()).toBe(true);
     })
  });
});

The button 'myButton' is enabled when the elements 'x', 'y' and 'z' all have values. It's my understanding that sendKeys returns a promise.

So is this the only way that I can check if 'myButton' which depends on data in all the three fields is enabled?

回答1:

You don't need to chain any promises because protractor will wait until all the statements are done: https://github.com/angular/protractor/blob/master/docs/control-flow.md

element(by.id('x')).sendKeys('xxx');
element(by.id('y')).sendKeys('yyy');
element(by.id('z')).sendKeys('zzz');
expect(element(by.id('myButton'));

If you want to resolve multiple promises use:

var webdriver = require('selenium-webdriver');
webdriver.promise.fullyResolved(promises);

For example: https://github.com/angular/protractor/blob/d15d35a82a5a2/lib/protractor.js#L327



回答2:

this is a bit after the fact, but:

var x = element(by.id('x')).sendKeys('xxx');
var y = element(by.id('y')).sendKeys('yyy');
var z = element(by.id('z')).sendKeys('zzz');

myFun(x,y,z).then(function(){
   expect(element(by.id('myButton')).isEnabled()).toBe(true);
});


// in a common function library
function myFun(Xel,Yel,Zel) {
  return protractor.promise.all([Xel,Yel,Zel]).then(function(results){
     var xText = results[0];
     var yText = results[1];
     var zText = results[2];

  });
}

but an even better way:

var x = element(by.id('x')).sendKeys('xxx');
var y = element(by.id('y')).sendKeys('yyy');
var z = element(by.id('z')).sendKeys('zzz');

myFun(x,y,z);
//isEnabled() is contained in the expect() function, so it'll wait for
// myFun() promise to be fulfilled
expect(element(by.id('myButton')).isEnabled()).toBe(true);


// in a common function library
function myFun(Xel,Yel,Zel) {
  return protractor.promise.all([Xel,Yel,Zel]).then(function(results){
     var xText = results[0];
     var yText = results[1];
     var zText = results[2];

  });
}

another way is to chain the .thens together:

element(by.id('x')).sendKeys('xxx').
  then(function(xtext){
    element(by.id('y')).sendKeys('yyy');

  }).then(function(ytext){
     element(by.id('z')).sendKeys('zzz');

  }).then(function(ztext){
    expect(element(by.id('myButton')).isEnabled()).toBe(true);

  });


回答3:

it seems protractor supports all - protractor.promise.all

read more at:

https://github.com/angular/protractor/issues/2062#issuecomment-94030055

describe('promise.all', function() {
  it('should greet the named user', function() {
    browser.get('http://juliemr.github.io/protractor-demo');

    $('div').click().then(function () {
      return protractor.promise.all([
          $('h3').getText(),
          $('h4').getText()
      ]);
    }).then(function (params) {
      console.log('A');
    });
  });

  it('does something else', function() {
    console.log('B');
  });

If you want to return an object instead of a list, seems you can also do that - used it and it's awesome

element.all(by.css('.fc-event-inner')).map(function(el) {
  return {
    time: el.findElement(by.className('fc-event-time')).getText(),
    title: el.findElement(by.className('fc-event-title')).getText()
  }
});

See the properties are actually promises.. protractor will resolve them.



标签: protractor