当前位置: 首页 > 面试题库 >

在循环中使用量角器

阎知
2023-03-14
问题内容

i当我在循环中使用Protractor时,循环索引()不是我期望的。

症状:

失败:索引超出范围。尝试访问索引为’x’的元素,但是只有’x’个元素

要么

索引是静态的,并且始终等于最后一个值

我的密码

for (var i = 0; i < MAX; ++i) {
  getPromise().then(function() {
    someArray[i] // 'i' always takes the value of 'MAX'
  })
}

例如:

var expected = ['expect1', 'expect2', 'expect3'];
var els = element.all(by.css('selector'));
for (var i = 0; i < expected.length; ++i) {
  els.get(i).getText().then(function(text) {
    expect(text).toEqual(expected[i]); // Error: `i` is always 3. 
  })
}

要么

var els = element.all(by.css('selector'));
for (var i = 0; i < 3; ++i) {
  els.get(i).getText().then(function(text) {
    if (text === 'should click') {
      els.get(i).click(); // fails with "Failed: Index out of bound. Trying to access element at index:3, but there are only 3 elements"
    }
  })
}

要么

var els = element.all(by.css('selector'));
els.then(function(rawelements) {
  for (var i = 0; i < rawelements.length; ++i) {
    rawelements[i].getText().then(function(text) {
      if (text === 'should click') {
        rawelements[i].click(); // fails with "Failed: Index out of bound. Trying to access element at index:'rawelements.length', but there are only 'rawelements.length' elements"
      }
    })
  }
})

问题答案:

发生这种情况的原因是因为量角器使用了诺言。

阅读https://github.com/angular/protractor/blob/master/docs/control-
flow.md

当基础值准备就绪时element(by...),承诺(即element.all(by...))执行其then功能。这意味着首先对所有承诺进行调度,然后then在结果准备就绪时运行功能。

当您运行以下命令时:

for (var i = 0; i < 3; ++i) {
  console.log('1) i is: ', i);
  getPromise().then(function() {
    console.log('2) i is: ', i);
    someArray[i] // 'i' always takes the value of 3
  })
}
console.log('*  finished looping. i is: ', i);

发生的情况是getPromise().then(function() {...}),在答应准备就绪之前立即返回,而没有在内部执行函数then。因此,首先循环运行3次,调度所有getPromise()调用。然后,随着承诺解决,将then运行相应的。

控制台看起来像这样:

1) i is: 0 // schedules first `getPromise()`
1) i is: 1 // schedules second `getPromise()`
1) i is: 2 // schedules third `getPromise()`
*  finished looping. i is: 3
2) i is: 3 // first `then` function runs, but i is already 3 now.
2) i is: 3 // second `then` function runs, but i is already 3 now.
2) i is: 3 // third `then` function runs, but i is already 3 now.

那么,如何循环运行量角器?通用的解决方案是关闭。

for (var i = 0; i < 3; ++i) {
  console.log('1) i is: ', i);
  var func = (function() {
    var j = i; 
    return function() {
      console.log('2) j is: ', j);
      someArray[j] // 'j' takes the values of 0..2
    }
  })();
  getPromise().then(func);
}
console.log('*  finished looping. i is: ', i);

但这不是那么好读。幸运的是,你还可以用量角器功能filter(fn)get(i)first()last(),和这样一个事实expect修补采取的承诺,来处理这个。

回到前面提供的示例。第一个示例可以重写为:

var expected = ['expect1', 'expect2', 'expect3'];
var els = element.all(by.css('selector'));
for (var i = 0; i < expected.length; ++i) {
  expect(els.get(i).getText()).toEqual(expected[i]); // note, the i is no longer in a `then` function and take the correct values.
}

第二个和第三个示例可以重写为:

var els = element.all(by.css('selector'));
els.filter(function(elem) {
  return elem.getText().then(function(text) {
    return text === 'should click';
  });
}).click(); 
// note here we first used a 'filter' to select the appropriate elements, and used the fact that actions like `click` can act on an array to click all matching elements. The result is that we can stop using a for loop altogether.

换句话说,量角器有很多方法可以迭代或访问元素,i因此您无需使用循环和i。但是,如果必须使用for循环和i,则可以使用闭包解决方案。



 类似资料:
  • 我在用量角器5.2.0(节点8.4.0,角度1.5)定位ng-repeat循环中的一个元素时遇到了麻烦。UI代码如下所示: 我的量角器conf文件如下所示:

  • 问题内容: 我想用这样的for循环遍历$ scope变量。在此示例中,$ scope对象包括一个包含 5个对象的对象 帐户 ,这些对象的名称是从1到5的数字。每个对象都有一个名称。 问题: $ scope.accounts.i 是 未定义的, 因为在 $ scope 变量内我不算为变量。它算作字母i,因此我看不到有机会用for循环遍历作用域。当我在$ scope变量周围使用“”时,它将仅显示为纯h

  • 问题内容: 如何使用循环命名变量?例如,如果我想让变量 double_1 = 2 , double_2 = 4 一直到 double_12 = 24 ,我该怎么写?我感觉会是这样的: 显然,这是行不通的,但是将循环号实现为变量名的正确语法是什么?我已经有一段时间没有编码了,但是我确实记得有一种方法可以做到这一点。 问题答案: 请改用字典。例如: 或者,如果您 绝对 必须 这样做 ,并且仅在完全了解

  • 问题内容: 列表中的每封电子邮件都将发送到服务器,并从服务器获得响应(如果它是有效的电子邮件)。 因此,在检查完所有电子邮件之后,数组应具有: 循环发送电子邮件到服务器的代码如下: 但是问题在于调用是异步的,因此,假设i = 0,则当i为0时控件将不会进入函数。因此,当i进入函数时,i的值可以是任何值,通常大于数组的长度,因此isEmailValidList [i]未定义。如果呼叫是同步的,则它将

  • 问题内容: 当我使用量角器执行以下代码时,它可以工作。我将嵌套的json传递给for循环。由于for循环的异步工作,它将打印变量i的所有值并达到最后一个值,因此它始终访问最后一对用户名和密码。我该如何解决这个问题? 问题答案: 您需要牢记,不能将-loop与promises一起使用。一切都是异步的,所以 最终它会咬到你 ,这意味着它已经准备好了,但测试还没有。 根据您的示例,建议创建一个名为例如的

  • 问题内容: 我正在使用量角器和黄瓜框架;如何突破.filter或.map循环?如果找到匹配项,我不想继续进行迭代! 上面的代码找到了元素,但是继续进行迭代直到结束,而不是在存在匹配项时停止并通过调用 errorCallback 函数进行 中断 。 鉴于.map函数返回“ 解析为map函数返回的值数组的诺言 ” http://www.protractortest.org/#/api?view=Ele