问题摘要:我正在编写几个测试套件(使用Jest和Puppeteer)以自动化对AngularJS应用程序主页的测试。我要自动化的测试之一是用几个md-select
字段填写表单,而在自动化选择特定md-option
时遇到了一些麻烦。由于某些无法解释的原因,似乎Puppeteer在单击md-select
打开选项对话框后只是找不到该选项。这是我的html外观,因此您可以大致了解我正在处理的内容:
免责声明:为了向该社区提供minimal, reproducible example,我选择不复制并粘贴原始代码,而是编写了一个更简单的示例。因此,如果您发现错字,我可以向您保证,这不是问题的根源,因为我已经非常仔细地检查了原始代码是否有错字。对于以下代码中的任何拼写错误,我们深表歉意。我保持警惕,但我是人,所以我会犯错。
<!-- index.html -->
<html>
<body ng-app="myApp" ng-controller="myCtrl">
<form name="myForm">
<md-dialog-content>
<md-input-container id="animalSelect">
<md-select>"Kittens"</md-select>
</md-input-container>
<md-input-container id="nameSelect">
<md-select>"Cosmo"</md-select>
</md-input-container>
</md-dialog-content>
</form>
<!-- this dialog appears when first <md-select> is clicked -->
<div class="md-select-menu-container">
<md-select-menu>
<md-content>
<md-option value="Kittens">Kittens</md-option>
<md-option value="Puppies">Puppies</md-option>
</md-content>
</md-select-menu>
</div>
<!-- this dialog appears when second <md-select> is clicked -->
<div class="md-select-menu-container">
<md-select-menu>
<md-content>
<md-option value="Cosmo">Cosmo</md-option>
<md-option value="Scout">Scout</md-option>
</md-content>
</md-select-menu>
</div>
</body>
</html>
背景:我正在使用Jest(v24.8.0)作为测试框架。我正在使用Puppeteer(v1.19.0)启动并控制无头的Chromium浏览器。
我的断码:
// index.spec.js
test('submit form', async() => {
let formSelector = 'form[name="myForm"]';
let animalSelector = '#animalSelect md-select';
let animalOptionSelector = 'md-option[value="Puppies"]';
let nameSelector = '#nameSelect md-select';
let nameOptionSelector = 'md-option[value="Scout"]';
await page.waitForSelector(formSelector, {timeout: 3000});
await page.waitForSelector(animalSelector, {timeout: 3000});
await page.waitForSelector(nameSelector, {timeout: 3000});
// this works fine
await page.click(animalSelector);
await page.waitForSelector(animalOptionSelector, {timeout: 3000});
await page.click(animalOptionSelector);
// this fails: Jest says nameOptionSelector is not in the DOM (see error below)
await page.click(nameSelector);
await page.waitForSelector(nameOptionSelector, {timeout: 3000});
await page.click(nameOptionSelector);
});
运行测试的结果:
在运行上述测试后,Jest说
'submit form'
失败并提供了以下错误消息:Node is either not visible or not an HTMLElement
await page.click(nameOptionSelector);
^
这意味着当Puppeteer单击
nameOptionSelector
时,在DOM中找不到它。但是page.waitForSelector(nameOptionSelector, {timeout: 3000})
似乎成功了,这告诉我nameOptionSelector
在调用page.click
时在DOM中是WAS。故障排除尝试:
我可以通过
'submit form'
的唯一方法是在page.click(nameOptionSelector)
上方添加以下行:// this line tells the test to pause for 1 second before clicking
await page.waitFor(1000);
...但是这是一个不好的解决方案,因为它不精确并且无法解决问题的根源。
我还阅读了有关Puppeteer的page.select方法的信息,但由于我未使用本机HTML
<select>
元素,因此无法使用。问题:你们当中的Jest / Puppeteer黑客是否知道此解决方案?
最佳答案
不幸的是,我也遇到了类似的问题,因为您和await page.waitFor(3000)
在大多数情况下帮助了我。这是我用来不断向下滚动直到到达动态内容不断添加的页面底部的代码片段:
let preCount = 0;
let postCount = 0;
do {
preCount = await getCount(page);
await scrollDown(page);
await page.waitFor(3000);
postCount = await getCount(page);
} while (postCount > preCount);
await page.waitFor(3000);
当我尝试将等待时间从3秒降低到1或2秒时,有时我无法进入页面底部。我知道这一点是因为我在启动puppeteer时禁用了无头模式,因此我可以查看浏览器中正在发生的情况:
{
headless: false,
defaultViewport: null,
args: ['--window-size=800,600']
}
关于javascript - 玩笑测试通常会失败,因为Puppeteer无法单击DOM中的元素,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57438947/