在另一个嵌套的promise中使用一个promise的结果

时间:2016-10-13 22:11:50

标签: javascript html angularjs protractor

我正在使用量角器进行e2e测试。我有一个我想测试的搜索字段。我想确保每次搜索表格中显示的关键字时,搜索都会过滤掉其他所有内容。

为了达到这个目的,我使用了两个for循环:第一个循环,循环显示正在显示的项目。它抓取项目并在搜索字段中键入它。表格显示动态更新。第二个循环遍历更新的显示表,以确保字段的值与我们在搜索框中放置的值相匹配。

我的问题是第二个for循环(在第二个promise中)使用第一个promise的结果:" testingSuit"。 " testingSuit"是执行第二个promise时的固定值,因为它不在嵌套循环中。

如何在另一个嵌套的promise中使用一个promise的结果?

describe('Test Suit Search', function () {        
    it('Testing Hearts suits', function () {


        return element.all(by.className('view')).count().then(function(rowCount) {
            //for every suit that we have in the view do:
            for (i=0 ; i< rowCount; i++)
            {

                // first clear the suit search field and 
                element.all(by.className('suitSearch')).get(0).clear();
                //get the suit value
                var testingSuit = element(by.exactRepeater("card in cards").row(i).column("card.suit")).getText();

                // then insert the value in the search field 
                element.all(by.className('suitSearch')).get(0).sendKeys(testingSuit);

                //loop through the results:
                element.all(by.binding('card.suit')).count().then(function(resultRowCount ){
                    for ( j=0; j<resultRowCount; j++)
                    {
                        expect(testingSuit).toEqual(element.all(by.binding('card.suit')).get(j).getText());

                    }
                    return;
                })


            }
            return;
        })
    });

});

以下是HTML代码:

<select ng-model="orderProp">
<option class="option" value="suit">Suit</option>
<option class="option" value="numOrd">Number</option>
</select>
Number search: <input type="text" ng-model="searchTerm.card.number">
search: <input class="suitSearch" type="text" ng-model="searchTerm.card.suit">
<table>

<tr><th><th><th>Number</th><th>Suit</th></tr>
<tr ng-repeat="card in cards | orderBy:orderProp |  filter:searchTerm.card ">
    <td><a class="view"                    href="#/home/number/{{card.number}}/suit/{{card.suit}}">View</a></td>
    <td><a class="delete" href="#/delete/number/{{card.number}}/suit/{{card.suit}}">Delete</a></td>
    <td>{{card.number}}</td>
    <td class="blah" >{{card.suit}}</td>
</tr>


1 个答案:

答案 0 :(得分:0)

这里的问题是下面的匿名函数位于then

之内
element.all(by.binding('card.suit')).count().then(function(resultRowCount ){
    for ( j=0; j<resultRowCount; j++) {
            expect(testingSuit).toEqual(element.all(by.binding('card.suit')).get(j).getText());
    }
    // return; // this return is redundant
});

当第一行执行时,then函数立即执行,并将正在传递给它的匿名函数关联,稍后将执行该函数(假设已解决,而不是拒绝)。也就是说,创建了匿名函数,但尚未执行。当匿名函数最终执行时,它会在函数执行时使用testingSuit的值 ,而不是在创建函数时。

解决此类问题的常用方法是使用IIFE(Imediately Invoked Function Execution),如下所示:

(function(suit) {
    element.all(... for (j=0 ... expect(suit) ...  /
 })(testingSuit);

也就是说,这里的第二行是element.all的整个代码块,但用引入的参数testingSuit替换suit。这定义了一个匿名函数,然后立即执行,向其传递testingSuit

的值

这个工作的原因是你传递的函数然后不再引用外部变量testingSuit,而是一个新的变量`suit'仍然保存函数时传递的值创建了。 “持有”价值处于收盘状态。

要查看此内容,请在执行suit之前将testingSuitconsole.log同时输出expect