问题总结:我正在编写几个测试套件(使用 Jest 和 Puppeteer)来自动测试我的 AngularJS 应用程序的主页。我想要自动化的测试之一是用户按下页面上的按钮以删除 DOM 中的元素。不幸的是,该元素用于显示大量数据,因此为了删除该元素,客户端首先需要向我的服务器发出 POST 请求以从数据库中删除数据,然后才能删除该元素从 DOM 中删除。总而言之,整个过程大约需要一两秒钟。更重要的是,我试图删除的这个元素是动态添加到 DOM 的,所以我能够访问该元素的唯一方法是使用 XPath,它通过元素包含的文本来标识该元素,而不是传统的 CSS 选择器.现在这是我的问题:我如何使用 Jest 和 Puppeteer 的 Api 编写一些测试代码,等待该元素不再存在(即离开 DOM)。
下面是我的 HTML 的概览,以便您了解我正在使用的内容:
<html>
<body ng-app="myApp" ng-controller="myCtrl">
<!-- Dynamically added div -->
<div>My Data
<table><!-- Displays tons of data --></table>
</div>
<form>
<button type="submit">Delete</button>
</form>
</body>
</html>
背景:我使用 Jest (v24.8.0) 作为我的测试框架。我正在使用 Puppeteer (v1.19.0) 启动并控制 headless Chromium 浏览器。
到目前为止我尝试了什么:
目前,我有这段代码
test('deleted elem no longer exists', async() => {
elemXPath = '//div[contains(text(), "My Data")]';
// this is a function to pause the
// execution of the test for a given amount of milliseconds
// in order to wait for elem to be removed
await delay(2000);
// This fails because Puppeteer timeouts after 3000
// ms b/c elemXPath no longer exists
const elemExists = await page.waitForXPath(elemXPath, {timeout: 3000}) ? true : false;
expect(elemExists).toBe(false);
});
我可以这样做:
test('deleted elem no longer exists', async() => {
elemXPath = '//div[contains(text(), "My Data")]';
// wait for elem to be removed
await delay(2000);
try {
var elemExists = await page.waitForXPath(elemXPath, {timeout: 3000}) ? true : false;
} catch(err) {
var elemExists = false
}
expect(elemExists).toBe(false);
});
...但我希望能够摆脱我的 await delay
行,让测试精确地等待,直到元素消失。
await delay
的问题是它不可靠,因为根据元素显示的数据量,删除它可能需要比 await delay
指定的时间更多或更少的时间。
结论: 你们 Jest/Puppeteer 黑客以前有没有遇到过这样的问题并且知道任何聪明的解决方案?
最佳答案
您可以使用带有选项 { hidden: true }
的 page.waitForXPath
或使用 page.waitForFunction
为此,编写一个函数来测试该元素是否不存在。
page.waitForXPath with hidden:true
await page.waitForXPath(elemXPath, { hidden: true });
替代方案:page.waitForFunction
或者,您可以使用以下代码来使用简单的选择器:
await page.waitForFunction(() => !document.querySelector('#selector-of-element'));
如果你想使用XPath表达式,你可以使用这段代码:
const elemXPath = '//div[contains(text(), "My Data")]';
await page.waitForFunction(
xpath => !document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue,
{},
elemXPath
);
这会将您的选择器传递给函数并使用 document.evaluate
函数在浏览器上下文中运行 XPath 表达式。
关于javascript - 如何使用 Jest/Puppeteer 等待元素从 DOM 中移除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57400071/