首页 > 解决方案 > 如何使用 Protractor 从 TypeScript 中的函数返回数组?

问题描述

我有下面的代码,我需要用下拉列表元素填充一个数组并从函数中返回该数组,以便我从 jasmine 测试用例中断言该数组。

getAllCategoryName(): string[]{

        var usageCategoryFromPage: string[] =  [];

        E2EUtil.click(this.usageCategoriesPage.pageinationDropDownBtn);

        E2EUtil.click(this.usageCategoriesPage.highestPageRecords);

        element.all(by.xpath("//tbody[@class='ui-datatable-data ui-widget-content ui-datatable-hoverable-rows']/tr[*]/td[1]"))
            .each(function (element, index) {

                element.getText().then(function (text){
                    usageCategoryFromPage.push(text);
                })
            })

            .then(function(){

                console.log("Size of the array from inside the then block " + usageCategoryFromPage.length);

                usageCategoryFromPage.forEach(element => {
                     console.log("Usage Category Elements from inside the the function " + element);
                });

                return usageCategoryFromPage; // size here is 18
            });

        console.log("Usage Category size after the then block "  +usageCategoryFromPage.length)
        usageCategoryFromPage.forEach(element => {
              console.log("From Usage Category Page outside the then function" + element);
        });

        return usageCategoryFromPage; // size here is 0
    }

问题是usageCategoryFromPage数组在 then 块之外被返回为 0 。

Jasmine 测试用例如下所示:

it('Validate the Usage Category droplist values matches with the Usage Categories Table',() => {

        usageCategoriesPage.navigateTo();
        let allCategoryName = usageCategoriesPage.getAllCategoryName();
        allCategoryName.forEach(element => {
            console.log("Array elements printed from the test case " + element);
        });

有人可以帮忙吗?

标签: typescriptprotractor

解决方案


1) 所有量角器 API 都是异步的并返回承诺。

2)您需要在then().

3) 如果一个promise 遵循then()chain: a promise.then().then()....then(),promise 的最终值取决于链中最后一个的返回then()then()

例如:

element(all()).each() 
// return a promise and its eventual value is null

element(all()).getText() 
// return a promise and its eventual value is an String Array, 
// each String is the visible text of each found HTML element

var res = element(all()).getText()

.then(txts => {
    // the eventual value of promise: element(all()).getText()
    // will be passed-into the callback function of the next then() 
    // thus txts is the String Array
    // you can determine return anything or not return anything in this callback function

    // assume we return another String Array
    return ['a', 'b'];
})
// the return value in the previous `then()` callback function
// will be passed-into next `then()` callback function
.then(value => {
    // value = ['a', 'b']

    // assume we return the first String in Array
    return value[0]
});

res是一个承诺跟随then()链,它的最终价值取决于最后一个then()

res.then(value=>{
    console.log(value);
    // print out a
})

固定代码:

getAllCategoryName(): string[]{

    var usageCategoryFromPage: string[] =  [];

    E2EUtil.click(this.usageCategoriesPage.pageinationDropDownBtn);

    E2EUtil.click(this.usageCategoriesPage.highestPageRecords);

    // you missed `return` at here. 
    return element
        .all(by.xpath("//tbody[@class='ui-datatable-data ui-widget-content ui-datatable-hoverable-rows']/tr[*]/td[1]"))
        .each(function (element, index) {
            element.getText().then(function (text){
                usageCategoryFromPage.push(text);
            })
        })
        .then(function(){

            console.log("Size of the array from inside the then block " + usageCategoryFromPage.length);

            usageCategoryFromPage.forEach(element => {
                 console.log("Usage Category Elements from inside the the function " + element);
            });

            return usageCategoryFromPage; // size here is 18
        });
}

it('Validate the Usage Category droplist values matches with the Usage Categories Table',() => {

    usageCategoriesPage.navigateTo();

    let allCategoryName = usageCategoriesPage.getAllCategoryName(); 
    // getAllCategoryName() return a promise, 
    // thus you need to consume the eventual value of promise in then()

    allCategoryName.then(categories => {
        console.log("Array elements printed from the test case " + categories.join(', '));
    });
}

getAllCategoryName()通过的更简洁的实现element.all().getText()

getAllCategoryName(): string[]{

    E2EUtil.click(this.usageCategoriesPage.pageinationDropDownBtn);

    E2EUtil.click(this.usageCategoriesPage.highestPageRecords);

    return element
        .all(by.xpath("//tbody[@class='ui-datatable-data ui-widget-content ui-datatable-hoverable-rows']/tr[*]/td[1]"))
        .getText();
}

推荐阅读