首页 > 解决方案 > Selenium WebDriver WebElement .findElement 总是返回错误(JavaScript)

问题描述

“等到元素定位”有效,我可以获得容器的文本。但是,当我尝试通过循环遍历容器内的 WebElements 数组来获取产品标题时, .findElement() 总是拒绝错误:

#product_container 是动态生成的

<div id="product_container">
  <div class="product"><div class="wrapper"><span class="product_title">Title 1</span></div></div>
  <div class="product"><div class="wrapper"><span class="product_title">Title 2</span></div></div>
  <div class="product"><div class="wrapper"><span class="product_title">Title 3</span></div></div>
  <div class="product"><div class="wrapper"><span class="product_title">Title 4</span></div></div>
</div>
const {Builder, By, Key, until} = require('selenium-webdriver');

(async function example() {
  let driver = await new Builder().forBrowser('chrome').build();
  let container = By.css('#product_container');
  try {
    await driver.get('https://example.com/search/?q=mySearchText');
    
    await driver.wait(until.elementLocated(container), 10000); // <-- Success
    
    const result = await (await driver.findElement(container)).getText() // <-- Success
    console.log(result) // <-- Success
    
    const items = await (await driver.findElement(container)).findElements(By.css('.product')) // <-- Success

    items.forEach(async (item, i)=>{
      // Find the title of each product
      item
        .findElement(By.css('.product_title'))
        .then(()=>{
          console.log('success')
        })
        .catch(err=>{
          console.log('failed', err) // <-- Always rejected to here
        });
    })
  } finally {
    await driver.quit();
  }
})();

错误信息

失败错误:ECONNREFUSED 在 ClientRequest 处连接 ECONNREFUSED 127.0.0.1:56016。(/./node_modules/selenium-webdriver/http/index.js:262:15) 在 ClientRequest.emit (events.js:315:20) 在 Socket.socketErrorListener (_http_client.js:426:9) 在 Socket.emit (events.js:315:20) 在emitErrorNT (internal/streams/destroy.js:92:8) 在emitErrorAndCloseNT (internal/streams/destroy.js:60:3) 在processTicksAndRejections (internal/process/task_queues.js: 84:21)

标签: javascriptseleniumselenium-chromedriver

解决方案


我刚刚发现这实际上是 JavaScript 承诺和异步的问题。这是因为 items.forEach 不会等到 promise 在其异步函数中解决。我最终通过使用Promise.all()解决了它,如下所示:

await Promise
      .all(items.map(async (item)=>{
        let title = await (await item.findElement(By.css('.product_title'))).getText()
        return Promise.resolve(title)
      }))
      .then(function(result) {
        console.log('Array of title:', result)
      });

推荐阅读