2017-04-04 55 views
4

我正在嘗試做一些量角器測試,並且承諾沒有在for循環中解決。如何在for循環中處理量角器承諾?

在我的測試案例中,我想找到一個ng-repeat元素中的特定節點。

下面是代碼找到這樣一個節點:

var firstProfileNode = function(nodename, profile){ 
    element.all(by.repeater('node in tree_nodes')).then(function(treeNodes){ 
     for(var i=0; i<treeNodes.length; i++){ 
      var node = treeNodes[i].element(by.css('.tree-dnd-handle')); 
      node.getText().then(function(text){ 

       console.log(i+" : "+text); 
       if (profile){ 
        var pattern = '^' +nodename+' \\(\\d+ devices\\)$'; 
        var regx = new RegExp(pattern); 
        if(regx.test(text)){ 
         console.log('found') 
         return node; 
        } 
       }else{ 
        if(text === nodename){ 
         return node; 
        } 
       } 
       }); 
     } 
    }); 
    }; 
var test = firstProfileNode('ISR', true); 

這裏是控制檯輸出:

23 : edison (4 devices) 
23 : ed21-mbr2 
23 : ed22-mbr1 
23 : ed22-mbr2 
23 : ed21-mbr1 
23 : c2800-12 
23 : L1 (4 devices) 
23 : c887VAM-1 
23 : c891-1 
23 : c887-1 
23 : c3850-1 
23 : ISR (3 devices) 
found 
23 : 3700 (2 devices) 
23 : c3745-2 
23 : c3745-1 
23 : c2921-1 
23 : c2800-11 
23 : N7K (3 devices) 
23 : n7k-2 
23 : n7k-1 
23 : n7k-3 
23 : c2800-13 
23 : c2800-14 

的問題是,對於循環完成後的getText()承諾解決。證據顯示,記錄的「i」值爲23,即最終計數。我正在尋找一種方法讓for循環等待承諾或另一種方式來完全找到節點。

回答

2

您期待的代碼是從上到下同步執行的,但它實際上是異步的 - 在解決第一個getText()時,循環將結束。

我想你需要的是一個filter()

var firstProfileNode = function(nodename, profile) { 
    return element.all(by.repeater('node in tree_nodes')).filter(function(treeNode) { 
     return treeNode.element(by.css('.tree-dnd-handle')).getText().then(function(text) { 
      if (profile) { 
       var pattern = '^' +nodename+' \\(\\d+ devices\\)$'; 
       var regx = new RegExp(pattern); 
       return regx.test(text); 
      } else { 
       return text === nodename; 
      } 
     }); 
    }).first(); 
}; 

firstProfileNode()函數將返回對應於所需過濾node元素的ElementFinder實例。

+0

由於這是一個測試用例,我需要驗證過濾器不會返回'ElementFinder'指向什麼。這對我有用:'expect(test.isPresent())。toBe(true);' – xsdf

0

這是一個很常見的情況。

的承諾,決心非同步整個的循環之後已運行並返回,因此只有最後一個節點(和i總是23)

一種常見的做法是封閉的回調(IE)

function fooBar(node, i) { 
     node.getText().then(function(text){ 
      console.log(i+" : "+text); 
      if (profile){ 
       var pattern = '^' +nodename+' \\(\\d+ devices\\)$'; 
       var regx = new RegExp(pattern); 
       if(regx.test(text)){ 
        console.log('found') 
        return node; 
       } 
      }else{ 
       if(text === nodename){ 
        return node; 
       } 
      } 
     });  
} 

在一個單獨的方法,以便在該方法中每個nodei變量是closed in scope並且不會更改。然後簡單地調用該方法。

0

你可以嘗試這樣的事情:

var firstProfileNode = function(nodename, profile){ 
    element.all(by.repeater('node in tree_nodes')).then(function(treeNodes){ 
     for(var i=0; i<treeNodes.length; i++){ 
      var node = treeNodes[i].element(by.css('.tree-dnd-handle')); 
      getNodeText(i, node); 
     } 
    }); 
    }; 

var getNodeText = function(i, node) { 
node.getText().then(function(text){ 

       console.log(i+" : "+text); 
       if (profile){ 
        var pattern = '^' +nodename+' \\(\\d+ devices\\)$'; 
        var regx = new RegExp(pattern); 
        if(regx.test(text)){ 
         console.log('found') 
         return node; 
        } 
       }else{ 
        if(text === nodename){ 
         return node; 
        } 
       } 
       });} 
var test = firstProfileNode('ISR', true);