Selenium webdriver 是否有一个量角器.promise.when()方法?

Selenium webdriver 是否有一个量角器.promise.when()方法?,selenium-webdriver,protractor,Selenium Webdriver,Protractor,我知道我可以使用量角器.promise.all()。是否有一个量角器.promise.when()?我在哪里可以找到更多关于它的信息以及如何使用它 我的问题是,我需要解决所有getText()承诺,确定哪些承诺失败,并为失败的承诺提供空白 例如: function getValues() { let pFirstName = $('#firstname').getText(); let pLastName = $('#lastname').getText(); let p

我知道我可以使用
量角器.promise.all()
。是否有一个
量角器.promise.when()
?我在哪里可以找到更多关于它的信息以及如何使用它

我的问题是,我需要解决所有
getText()
承诺,确定哪些承诺失败,并为失败的承诺提供空白

例如:

function getValues() {
    let pFirstName = $('#firstname').getText();
    let pLastName = $('#lastname').getText();
    let pSSN = $('#ssn').getText();
    return protractor.promise.when([pFirstName, pLastName, pSSN])
        .then(function(values) {
            return {
                "first": values[0],
                "last": values[1],
                "ssn": values[2]    // This value may or may not be on the DOM, how do I check it and provide an alternate value?
            };
        });
}
更新:
当我继续我的研究时,我发现这更像是一个网络驱动程序的问题。也许我需要把蓝鸟拉进来。我不确定

回答下面的问题,“你说哪些失败是什么意思?” 假设
$('#ssn')
ElementFinder实际上没有找到与
#ssn
匹配的元素。
getText()
方法将拒绝承诺并传递一个元素未找到错误。因此,我将考虑以下两种情况:

<span id="firstname">Joe</span>
<span id="lastname">Smith</span>
<span id="ssn">123-45-6789</span>
将返回
{“first”:“Joe”,“last”:“Smith”,“ssn”:“123-45-6789”}

在以下情况下,如果用户不应该看到SSN,angular甚至不创建元素,我们可能会:

<span id="firstname">Joe</span>
<span id="lastname">Smith</span>

我希望返回值应该是:
{“first”:“Joe”,“last”:“Smith”}
{“first”:“Joe”,“last”:“Smith”,“ssn”:“}

除非出现更好的答案,否则我认为这可能就是答案(只需在getText()调用期间捕获拒绝)

至少,当我在JSFIDLE中执行类似操作时,它会起作用:

函数iffy(rVal,cond){
返回新承诺(功能(解决、拒绝){
如果(秒){
解决(rVal);
}否则{
拒绝(新错误(“这是错误”);
}
});
}
让pTruthy=iffy(“真”,真)
.catch(()=>“捕获错误”);
设pFalsy=iffy(“false”,false)
.catch(()=>“捕获错误”);
承诺。所有([pTruthy,pFalsy])
.then(值=>console.log(值))
.catch(err=>console.log(err));
不确定(“假”,假)
.then(val=>console.log(val))

.catch(err=>console.log(err.toString())不是非常通用的方法,但是您可以检查SSN字段是否显式存在。大致如下:

function getValues() {
    let pFirstName = $('#firstname').getText();
    let pLastName = $('#lastname').getText();
    let isSSNPresent = $('#ssn').isPresent();
    return protractor.promise.all([pFirstName, pLastName, isSSNPresent]).then(function(values) {
        let result = {
            "first": values[0],
            "last": values[1]
        };

        if (values[2]) {
            $('#ssn').getText().then(function (ssn) {
                result.ssn = ssn
            });
        } 
        return result;
    });
}

(未测试)

这里有另一个想法-更通用的想法-获取所有相关的
span
元素,并使用它返回带有输入ID和文本的对象:

var inputs = $$("span[id]");  // TODO: make the locator more specific
var values = inputs.reduce(function (obj, input) {
    return input.getAttribute("id").then(function (fieldName) {
        return input.getText().then(function (fieldValue) {
            obj[fieldName] = fieldValue;
        });
    });
}, {});

您还可以将
{}
更改为,例如,
{“firstname”:““lastname”:““ssn”:“}
,使不存在的字段具有默认值。

您所说的
哪些字段失败是什么意思?我看到的问题是,它看起来会在解决if语句中的getText()之前返回结果。这是真的还是我误解了流程?@Machtyn这也是我害怕的……我会测试它。谢谢,说得好@Machtyn刚在本地检查过,它对我有效!内部
getText()
调用设置的附加字段也正在设置中。这对你有用吗?我很喜欢这种方法。我必须查看id如何与我正在测试的应用程序结果上所需的属性名称对齐。这个解决方案只包括存在的东西,而不包括其他任何东西。而我上面的解决方案为不存在的属性提供了空白值。@Machtyn谢谢,因为默认值已用一种方法更新。或者,您可以对
值进行后处理
并填写缺少的字段。
function getValues() {
let pFirstName = $('#firstname').getText().catch(() => "");
let pLastName = $('#lastname').getText().catch(() => "");
let pSSN = $('#ssn').getText().catch(() => "");

return protractor.promise.when([pFirstName, pLastName, pSSN])
    .then(function(values) {
        return {
            "first": values[0],
            "last": values[1],
            "ssn": values[2]
        };
    });
}
function getValues() {
    let pFirstName = $('#firstname').getText();
    let pLastName = $('#lastname').getText();
    let isSSNPresent = $('#ssn').isPresent();
    return protractor.promise.all([pFirstName, pLastName, isSSNPresent]).then(function(values) {
        let result = {
            "first": values[0],
            "last": values[1]
        };

        if (values[2]) {
            $('#ssn').getText().then(function (ssn) {
                result.ssn = ssn
            });
        } 
        return result;
    });
}
var inputs = $$("span[id]");  // TODO: make the locator more specific
var values = inputs.reduce(function (obj, input) {
    return input.getAttribute("id").then(function (fieldName) {
        return input.getText().then(function (fieldValue) {
            obj[fieldName] = fieldValue;
        });
    });
}, {});