JavaScript

时间:2016-06-29 13:04:19

标签: javascript closures nested-loops

背景
我正在用JavaScript编写UI测试,使用Appium,用于iOS应用程序。它们具有类似的结构,例如this example

我想要实现的目标
初始屏幕包含元素列表(UITableView in iOS)的测试。从这个列表中,我想在某个级别(不知道有多少)深入导航,直到满足条件。这应该发生在该列表中的前3个元素(让我们称之为L0)。

实施例
L0(第1要素) - > L1 - > L2 - > L3-> L4 - > L5 - >条件满足 - >导航回L0
L0(第2要素) - > L1 - > L2 - >条件满足 - >导航回L0
L0(第3元素) - > L1 - > L2 - > L3->条件满足 - >导航回L0

显示代码

//the test
it('Browse list', function() {
    return driver
    .navigateToL0()
    .navigateToPageDetail(1, 3);
});

//the function with the issue
navigateToPageDetail: function(driver, startIndex, endIndex) {
    var listItemName;
    var navigationBarItemName;
    var hasListItemName = false;
    var navigationLevelCount = 0;
    var currentRootListElementIndex = startIndex;
    var currentListElementIndex = endIndex;
    var chain = driver;
    do {

      do {
        chain = chain
          .hasElementInListAtIndex(currentListElementIndex)
          .then(function(assertion) {
            hasListItemName = assertion;
            if (assertion == true) {
              return driver
                .getExpectedElementName(currentListElementIndex, function (name) {
                  listItemName = name;
                })
                .clickElementInListAtIndex(currentListElementIndex)
                .getActualElementName(function (name) {
                  navigationBarItemName = name;
                  listItemName.should.contain(navigationBarItemName);
                  navigationLevelCount ++;
                });
            }
            if (currentListElementIndex != 1) {
              currentListElementIndex = 1;
            }
          });
      } while (hasListItemName && (listItemName == navigationBarItemName));

      for (var j = 0; j <= navigationLevelCount; j++) {
        chain = chain.goBack();
      }
      currentRootListElementIndex++;
      currentListElementIndex = currentRootListElementIndex;

    } while  (currentRootListElementIndex <= endIndex);
    return chain;
}

有什么问题?

内部do while只运行一次,因为while中的条件始终为false 所以currentListElementIndex = 4然后它从L0导航3次到L1并返回。 (L0中的第4个元素)

我了解这是closures inside loops的问题,但我不明白如何修复内部do while问题。

您尝试了什么?

我尝试使用Avoiding the Reference Problem。 所以我的代码变成了:

navigateToPageDetail: function(driver, startIndex, endIndex) {
    var listItemName;
    var navigationBarItemName;
    var hasListItemName = false;
    var navigationLevelCount = 0;
    var currentRootListElementIndex = startIndex;
    var currentListElementIndex = endIndex;
    var chain = driver;
    do {

      (function(currentListElementIndex_v2) {  //added line

      do {
        chain = chain
          .hasElementInListAtIndex(currentListElementIndex_v2)
          .then(function(assertion) {
            hasListItemName = assertion;
            if (assertion == true) {
              return driver
                .getExpectedElementName(currentListElementIndex_v2, function (name) {
                  listItemName = name;
                })
                .clickElementInListAtIndex(currentListElementIndex_v2)
                .getActualElementName(function (name) {
                  navigationBarItemName = name;
                  listItemName.should.contain(navigationBarItemName);
                  navigationLevelCount ++;
                });
            }
            if (currentListElementIndex_v2 != 1) {
              currentListElementIndex_v2 = 1;
            }
          });
      } while (hasListItemName && (listItemName == navigationBarItemName));

      })(currentListElementIndex);  //added line

      for (var j = 0; j <= navigationLevelCount; j++) {
        chain = chain.goBack();
      }
      currentRootListElementIndex++;
      currentListElementIndex = currentRootListElementIndex;

    } while  (currentRootListElementIndex <= endIndex);
    return chain;
}

这使我更接近预期的行为,因为currentListElementIndex现在得到正确的值(1,2,3) 尽管如此,内部do while只运行一次,因为while中的条件始终为false。

有什么问题?

如何修复我的代码,以便我的内部do while循环按预期运行? 如果问题不明确,请告诉我,我会改进不清楚的部分。

0 个答案:

没有答案