问题
First of all, I've already checked various post and blogs concerning that point and I still can't figure out how to make it correctly.
I have tried many different combinaison of :
- browser wait
- protractor.controlFlow().execute
- protractor.controlFlow().await(
...Still no success..
My problem
Within my beforeEach function, I'd like to call a protractor promise and wait for it to resolve before performing the rest of my code.
My Code
I've prepared this simple test for anyone willing to help me
describe('testAsync', function() {
beforeEach(function() {
console.log('beforeEach - step 1 ')
browser.get("https://angularjs.org/");
console.log('beforeEach - step 2 ')
testFunc()
console.log('beforeEach - after testFunc - step 3')
});
var testFunc = function(){
console.log("testFunc - step 1")
browser.wait(function() {
var deferred = protractor.promise.defer();
element(by.id('twitter-widget-1')).isPresent()
.then(function (isPresent) {
console.log("testFunc - step 2")
deferred.fulfill(isPresent);
});
return deferred.promise;
});
console.log("testFunc - step 3")
}
it('test after BeforeEach', function() {
console.log("Last trace")
});
});
Current Output
[launcher] Running 1 instances of WebDriver
beforeEach - step 1
beforeEach - step 2
testFunc - step 1
testFunc - step 3
beforeEach - after testFunc - step 3
testFunc - step 2
Last trace
Expected Output
[launcher] Running 1 instances of WebDriver
beforeEach - step 1
beforeEach - step 2
testFunc - step 1
testFunc - step 2 // <------ This is within the promise resolve
testFunc - step 3
beforeEach - after testFunc - step 3
Last trace
回答1:
I think this will get the output you want:
describe('testAsync', function() {
beforeEach(function() {
console.log('beforeEach - step 1 ');
// `get` implicitly registers a promise with the control flow
browser.get("https://angularjs.org/");
console.log('beforeEach - step 2 '); // runs "before" get above returns!
testFunc().then(function() {
// use a then to explicitly chain a dependency off a promise
console.log('beforeEach - after testFunc - step 3');
})
protractor.promise.controlFlow().execute(function() {
console.log('beforeEach - after testFunc, via controlFlow - step 4');
});
console.log('beforeEach - end of beforeEach - everything registered, nothing done');
});
var testFunc = function(){
console.log("testFunc - step 1")
// return browser wait promise to caller
// `wait` also implicitly registers with the control flow
return browser.wait(function() {
return element(by.id('twitter-widget-1')).isPresent()
.then(function (isPresent) {
console.log("testFunc - step 2")
return true; // tell wait its done by resolving then promise->element promise->wait
});
});
}
it('test after BeforeEach', function() {
console.log("Last trace")
});
});
回答2:
The two console.log
s (steps 1 & 3)in your testFunc
, that are not wrapped in the promise, will fire immediately when you call the function. Which is proven by your output. Then your promise (which looks to be working great!), returns the step 2 log when the promise is resolved (but after the logs have already fired).
And thus, it looks like this is doing what you want? I.e. your beforeEach
does indeed look like it's firing the async function before hitting your first spec.
来源:https://stackoverflow.com/questions/30949576/protractor-wait-for-async-promise-before-doing-next