javascript - Puppeteer 无法单击 DOM 中 XPath 指定的元素

标签 javascript angularjs xpath jestjs puppeteer

问题摘要:我正在编写几个测试套件(使用 Jest 和 Puppeteer)来自动测试我的 AngularJS 应用程序的主页。我想要自动化的测试之一是单击 md-tab-item。听起来很容易,对吧?不幸的是,这个简单的测试已经成为一个大问题,我能够想出的唯一解决方案来修复它(在我的测试中添加暂停功能)使我的测试变得非常慢。我还应该注意,我的 md-tab-item 是动态添加的,因此选择它们的唯一方法是通过 XPath 选择器,该选择器根据其包含的文本选择目标选项卡。这使得单击选项卡变得稍微困难​​,因为我首先必须使用 Puppeteer 的 page.$x 方法将选项卡转换为可单击的 ElementHandle (下面的代码说明了我的意思)。

背景:我使用 Jest (v24.8.0) 作为我的测试框架。我正在使用 Puppeteer (v1.19.0) 来启动和控制 headless Chromium 浏览器。

免责声明:为了向此社区提供 minimal, reproducible example我选择不复制和粘贴原始代码,而是编写一个更简单的示例。因此,如果您发现拼写错误,我可以向您保证这不是问题的根源,因为我已经非常仔细地检查了原始代码是否有拼写错误。对于以下代码中的任何拼写错误,我提前表示歉意。我很警惕,但我也是人,所以我会犯错误。

损坏的代码:

<!-- index.html -->
<html>
  <body ng-app="myApp" ng-controller="myCtrl">
    <md-content>
      <md-toolbar>
        <div class='md-toolbar-tools'>
          <h2>My Toolbar</h2>
        </div>
      </md-toolbar>
      <md-progress-linear></md-progress-linear>
      <md-tabs>
        <md-tabs-canvas>
          <md-pagination-wrapper>
            <md-tab-item>Tab 1</md-tab-item>
            <md-tab-item>Tab 2</md-tab-item>
            <md-tab-item>Tab 3</md-tab-item>
          </md-pagination-wrapper>
        </md-tabs-canvas>
      </md-tabs>
      <div><!-- Displays tab content based on which tab is clicked --></div>
    </md-content>
  </body>
</html>
// index.spec.js
test('click on second tab', async() => {

  // check if tab exists: this ALWAYS passes
  tabXPath = '//md-tab-item[contains(text(), "Tab 2")]|//md-tab-item[contains(text(), "tab 2")]';
  const tabExists = await page.waitForXPath(tabXPath, {timeout: 3000}) ? true : false;
  expect(tabExists).toBe(true);

  // use tab's XPath to create a clickable ElementHandle
  let clickableTab = await page.$x(tabXPath);

  // bug: tab cannot be clicked unless I wait - increases test time by 1s :(
  await page.waitFor(1000);

  // click on this ElementHandle
  await clickableTab[0].click();

}); 

问题:

  1. 你们中的 Jest/Puppeteer 专家知道为什么我必须等待才能点击我的选项卡吗?如果是这样,我如何改进我的代码,以便我不再需要依赖 page.waitFor 来让测试通过?
  2. 是否有更好的方法来单击 XPath 选择器指定的元素,我可以尝试?

最佳答案

  1. 使用 Puppeteer,您需要等待,否则代码的其他部分将在您需要的网页元素加载之前执行。但是,不要执行 waitFor,而是尝试 waitForSelector(此处为 css 选择器)或 waitForNavigation - 那么您只需等待特定位的加载。

  2. 这几乎是 Puppeteer 根据其文档支持执行此操作的唯一方式,this可能会有所帮助。

关于javascript - Puppeteer 无法单击 DOM 中 XPath 指定的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57467997/

相关文章:

xslt - 在 XSLT 中,为什么我无法使用 xsl :attribute, 设置值的选择属性,有什么好的选择?

html - 如何检索内部文本

javascript - 如何配置进度条来指示搜索查询进度?

Javascript-使用 boolean 值设置超时

javascript - 使用钩子(Hook)检测 React 组件外部的点击

javascript - ng-if 不使用简单的 javascript

javascript - angularjs拖放html内容

javascript - 为什么 useState 不触发重新渲染?

javascript - 根据表(索引)的行删除 localStorage 键

使用 idref 的 XPath 表达式