使用ElementArrayFinder.filter()和async / await

Webdriver的Control Flow启用时,我一直使用下面的函数来过滤元素数组:

filterElementsByText (elemList, comparator, locator) { return elemList.filter((elem) => { let searchTarget = locator ? elem.element(locator) : elem return searchTarget.getText().then((text) => text === comparator) }) } 

我现在试图迁移我的回购使用async / await需要closures控制stream。

这个转换大部分都是成功的,但是我在上面的函数中遇到了麻烦。 间歇性地,我看到这个错误:

失败:java.net.ConnectException:连接被拒绝:连接

我能够用我写的一个testing用例https://angularjs.org来重现这个问题,虽然它发生的频率比我自己的应用要高得多。

 let todoList = element.all(by.repeater('todo in todoList.todos')) let todoText = element(by.model('todoList.todoText')) let todoSubmit = element(by.css('[value="add"]')) let addItem = async (itemLabel = 'write first protractor test') => { await todoText.sendKeys(itemLabel) return todoSubmit.click() } let filterElementsByText = (elemList, comparator, locator) => { return elemList.filter((elem) => { let searchTarget = locator ? elem.element(locator) : elem return searchTarget.getText().then((text) => { console.log(`Element text is: ${text}`) return text === comparator }) }) } describe('filter should', () => { beforeAll(async () => { browser.ignoreSynchronization = true await browser.get('https://angularjs.org') for (let i = 0; i < 10; i++) { await addItem(`item${i}`) } return addItem() }) it('work', async () => { let filteredElements = await filterElementsByText(todoList, 'write first protractor test') return expect(filteredElements.length).toEqual(1) }) }) 

这是在Protractor的conf文件中设置的以下内容:

 SELENIUM_PROMISE_MANAGER: false 

在简化的testing案例中,似乎发生在5-10%的执行情况(虽然,有趣的是,它似乎在第一次发生时更频繁地发生)

我的问题是,这感觉像Webdriver中的错误,但我不知道什么样的条件会导致这个错误,所以我不知道如何进行。

对于任何人阅读和想知道,我自己的应用程序的问题是双重的。

首先,如原始问题的注释中所述,ElementArrayFinder.filter()会导致此错误,因为它会为数组中的每个元素运行并行请求。

其次(在原始问题中并不明显),而不是按照这个testing案例中所描述的那样传递一个ElementArrayFinder,而是实际上传入了数组中每个元素的链接子元素,如:

 element.all(by.repeater('todo in todoList.todos').$$('span') 

看到Webdriver输出,因为这发生,我注意到,这导致所有这些定位器并行检索导致相同的错误。

我能够通过这种方式来解决这两个问题:

 let filterElementsByText = async (elemList, comparator, locator) => { let filteredElements = [] let elems = await elemList for (let i = 0; i < elems.length; i++) { let elem = await elems[i] let searchTarget = locator ? elem.element(locator) : elem let text = await searchTarget.getText() if (text === comparator) { filteredElements.push(elem) } } return filteredElements } 

这可以解除阻止我,但它仍然觉得这些function只是async / await不可用。