下面的代码找到一个带有量角器的webElement(一个身份验证按钮),并尝试使用该元素作为参数解析一个promise。
function someFunc() {
var deferred = q.defer();
browser.findElement(by.css('[data-aid="buttons.authenticate"]')).then(
function(e) {
console.log('element found: ' + e);
deferred.resolve(e);
}
);
return deferred.promise;
}
someFunc().then(
function(elem) {
console.log('got elem ' + elem);
elem.click();
}
);
输出:
element found: [object Object]
所以从不调用then函数。当我用其他值(int,string,array,map)替换resolve()时,它可以正常工作。那为什么我不能返回一个WebElement对象?
谢谢
答案 0 :(得分:2)
要实际执行您的要求,我怀疑您应该使用q
而不是Webdriver Promise API,而protractor.promise
var deferred = protractor.promise.defer();
使用fulfill
function而非resolve
:
deferred.fulfill(e);
然而... 的
如果您通过defer
创建承诺只是为了对一个或多个现有承诺执行某些操作,那么这通常表明您没有使用承诺链或可用的API函数。链接可以通过返回a)您想要从then
回调中解决的内容和b)返回then
函数的结果来完成:
function someFunc() {
return browser.findElement(by.css('[data-aid="buttons.authenticate"]')).then(function(e) {
console.log('element found: ' + e);
return e;
});
}
someFunc().then(function(elem) {
console.log('got elem ' + elem);
elem.click();
});
但是因为在这个例子中,你准确地回复了承诺的履行价值,所以可以进一步简化:
function someFunc() {
return browser.findElement(by.css('[data-aid="buttons.authenticate"]'));
}
someFunc().then(function(elem) {
console.log('got elem ' + elem);
elem.click();
});
并且,因为click
实际上公开了findElement
的承诺结果,所以可以进一步简化为
browser.findElement(by.css('[data-aid="buttons.authenticate"]').click();
你在评论中说你不能做上述事情,因为你想“包装”这个承诺。这不太清楚这意味着什么,但是说你想要有两个元素可用,可以使用protractor.promise.all
,而不是通过defer
手动创建一个承诺:
var button1 = browser.findElement(by.css('[data-aid="buttons.authenticate"]');
var button2 = browser.findElement(by.css('[data-aid="buttons.confirm"]');
protractor.promise.all([button1, button2]).then(function(buttons) {
var button1 = buttons[0];
var button2 = buttons[1];
// Do something with both buttons
});
还有其他功能可以通过各种方式操纵承诺Webdriver's Promise API。 'map'和'filter'我认为是我用过的。