Els*_*rit 6 javascript jestjs puppeteer
问题总结:我正在编写几个测试套件(使用 Jest 和 Puppeteer)来自动化我的 AngularJS 应用程序主页的测试。我想要自动化的测试之一是用户按下页面上的按钮删除 DOM 中的元素。不幸的是,这个元素是用来显示大量数据的,所以为了删除元素,客户端首先需要向我的服务器发出POST请求从db中删除数据,然后才能删除元素从 DOM 中删除。总而言之,整个过程大约需要一两秒钟。更重要的是,我尝试删除的这个元素是动态添加到 DOM 中的,所以我能够访问该元素的唯一方法是使用 XPath,它通过它包含的文本来标识元素,而不是传统的 CSS 选择器. 现在这是我的问题:
这是我的 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>
Run Code Online (Sandbox Code Playgroud)
背景:我使用 Jest (v24.8.0) 作为我的测试框架。我正在使用 Puppeteer (v1.19.0) 来启动和控制无头 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);
});
Run Code Online (Sandbox Code Playgroud)
我可以做这样的事情:
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);
});
Run Code Online (Sandbox Code Playgroud)
...但我希望能够摆脱我的await delay线路,并让测试准确地等待元素消失。问题await delay在于它是不可靠的,因为取决于元素显示的数据量,它可能需要比await delay指定的更多或更少的时间来删除。
结论: 你们中的任何一个 Jest/Puppeteer 黑客以前遇到过这样的问题并且知道任何聪明的解决方案吗?
您可以使用page.waitForXPathwith 选项{ hidden: true }或page.waitForFunction通过编写一个测试元素是否不存在的函数来使用。
page.waitForXPath 与 hidden:true
await page.waitForXPath(elemXPath, { hidden: true });
Run Code Online (Sandbox Code Playgroud)
替代方案:page.waitForFunction
或者,您可以使用以下代码来使用简单的选择器:
await page.waitForFunction(() => !document.querySelector('#selector-of-element'));
Run Code Online (Sandbox Code Playgroud)
如果要使用 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
);
Run Code Online (Sandbox Code Playgroud)
这将您的选择器传递给函数并使用document.evaluate函数在浏览器上下文中运行 XPath 表达式。
| 归档时间: |
|
| 查看次数: |
4162 次 |
| 最近记录: |