介绍几个自动化测验前端页面的时候运用到的,常用的 puppeteer
技巧,了解这些技巧,定能让你的自动化测验过程事半功倍。假如在此基础之上能够融会贯通,得心应手,则前端测验之旅岂不直接起飞,入无人之境?
1. puppeteer 代码根本框架
- 首要,经过
require
引进 puppeteer 模块。 - 界说要打开的页面 URL。
- 运用异步自履行函数进行浏览器和页面的操作。
- 经过
puppeteer.launch
启动浏览器实例,能够设置启动参数如--no-sandbox
和--disable-setuid-sandbox
用于 Docker 或无头环境。但注意,headless:'new'
是不正确的,应该是headless: true
或headless: false
。 - 运用
browser.newPage()
创立一个新页面。 - 运用
page.goto
导航到指定的 URL,并等待页面加载完结。这儿的waitUntil
数组界说了页面加载完结的标准。 - 在代码框架中编写自己的测验逻辑。
- 运用
browser.close()
封闭浏览器实例。 - 假如在过程中遇到过错,运用
console.error
输出过错信息,并运用process.exit(1)
完毕进程。
const puppeteer = require("puppeteer");
const pageUrl = "http://127.0.0.1:8080";
(async () => {
try {
const browser = await puppeteer.launch({
args: ["--no-sandbox", "--disable-setuid-sandbox"],
headless:'new',
});
const page = await browser.newPage();
await page.goto(pageUrl, {
// 假如页面没有恳求能够不加 waitUntil 数组中的后 2 项
waitUntil: ["domcontentloaded", "load", 'networkidle0', 'networkidle2'],
});
// 假如不是分过程判分,运用 process.exit(1) 表示查看未经过;
// ...... 在下面编写自己的测验代码 start
//...... 你的测验代码
//.... 自己的测验代码 end
browser.close();
} catch (error) {
console.error(`测验未经过,报错为${error}`)
process.exit(1);
}
})();
2. 完毕检测,提示过错信息
- 当检测失利时,运用
console.error
输出过错信息。 - 运用
process.exit(1)
完毕进程,表示检测失利。
console.error("Error:.address、.user-info 元素获取不到!");
process.exit(1); // 完毕进程,检测失利
3. 延时(用于 DOM 点击过后正确获取dom 等状况)
- 由于某些操作可能需求等待 DOM 更新或其他异步使命完结,因而需求运用延时。
- 这儿供给了一个运用 Promise 的延时函数
delay
,能够替换已废弃的page.waitForTimeout
。
let delay = (ms)=>new Promise((r) => setTimeout(r, ms)); // ms 换成自己的延迟时间就能够
await delay(300)
4. 获取元素及相关信息
- 运用
page.$$eval
获取多个匹配选择器的元素。 - 运用
page.$$eval
对获取到的元素履行函数,并回来成果。例如,获取元素的 value 属性。 - 依据获取到的信息进行判断,假如不满足条件,则输出过错信息并完毕进程。
// 获取多个元素
let optionEls = await page.$$(selector);
// 获取多个元素的相关信息
let leftSelect = await page.$$eval(selector,(el) => el);
optionValues = await page.$$eval(selector,
(optionEls) =>
optionEls.map((optionEl) => optionEl.value)
);
if (optionValues) {
if(optionValues.includes('闷油瓶')||optionValues.includes('三叔')){
console.error(
`Error:${selector == "left" ? "左" : "右"}边的多选选项并没有被移除掉!`
);
process.exit(1); // 完毕进程,检测失利
}
}
5. 依据文本内容获取元素
- 运用 XPath 表达式
//*[text()='登录']
查找文本内容为“登录”的元素。注意,这种方法对文本内容十分敏感,假如文本中存在空格或其他不可见字符,可能会导致找不到元素。 - 找到元素后,能够进行点击等操作。
// 假定按钮的文本内容为登录
let btn = await page.$x(`//*[text()='登录']`)
await btn[0].click()
6. 点击元素
- 供给了两种方法点击元素:直接经过选择器点击和运用
page.evaluate
履行 JavaScript 点击。第一种方法在某些状况下可能无效,特别是当元素是起浮定位或遭到其他因素影响时。此刻,能够尝试第二种方法。
// 方法一
const singleClick = async (page,selector) => {
let markEl = await page.$(selector);
if(!markEl){
console.error(`Error:找不到 ${selector} 元素!`);
process.exit(1); // 完毕进程,检测失利
}
await page.click(selector); // 这种方法有时候会呈现无效的状况,假如发现,请运用方法二
}
// 起浮定位的元素运用 page.click 可能会形成无法点击,运用下面方法
// 方法二
await page.evaluate((selector) => {
document.querySelector(selector) && document.querySelector(selector).click();
},selector);
7. 点击列表元素的某一个
- 能够经过
page.$$
获取元素列表,然后经过索引点击特定元素。 - 例如,
btn[0].click()
点击第一个按钮。 - 另一种方法是运用CSS选择器直接定位并点击特定元素,如
.item:nth−child(1)
表示点击第一个item
元素。
// 方法一 经过 $$获取 经过索引点击
await page.$$('.btn')
await btn[0].click() // 点击第一个 btn 元素
// 方法 2
// 以 item 为例,点击第一个 item
await page.click('.item:nth-type-of(1)')
8. 获取页面变量 (只能获取全局变量)
运用 page.evaluate
履行 JavaScrip t代码并回来成果。在这儿,能够访问并回来页面中的全局变量。但需求注意的是,page.evaluate
中的代码是在页面上下文中履行的,所以只能访问页面中的全局变量和函数。
let res = await page.evaluate(() => option); // 将 option 替换成页面中的变量
9. 清空 input 并输入示例
供给了一个函数 clearAndType
,用于清空指定选择器的 input
元素并输入文本。首要,运用 page.evaluate
清空 input
元素的值,然后运用 page.type
输入文本。这个函数在需求自动化填写表单时十分有用。
const clearAndType = async (selector, text) => {
await page.evaluate((selector) => {
const textarea = document.querySelector(selector);
textarea.value = '';
}, selector);
await page.type(selector, text);
};
// 运用示例
await clearAndType('input','小')
10. 检测 ajax 恳求是否成功
- 界说了一个函数
checkAjax
来检测页面是否发送了特定的 AJAX 恳求。 - 首要,监听页面的一切响应并记载
URL
。 - 然后,导航到指定页面并等待一切网络恳求完结。
- 最后,查看记载的
URL
列表中是否包括要检测的AJAX
恳求的URL
。假如不包括,则输出过错信息并完毕进程。 - 这个函数在需求验证页面功能是否经过
AJAX
恳求实现时十分有用。但需求注意的是,这种方法只能检测是否发送了恳求,并不能直接判断恳求是否成功或回来了希望的成果。假如需求进一步验证恳求的成果,可能需求结合其他方法或工具来实现。
/**
* 异步恳求数据检测
* url: 接口地址(域名与待检测域名相同)
**/
const checkAjax = async (page,pageUrl,jsonUrl)=>{
const urls = [];
page.on("response", (response) => {
urls.push(response.url());
});
await page.goto(pageUrl, {
waitUntil: "networkidle0", //一直等待一切网络恳求完结后再触发
});
// console.log(urls);
// 验证是否发送 ajax 恳求
if (!urls.includes(jsonUrl)) {
console.error(`没有恳求到数据!`);
process.exit(1); // 完毕进程,检测失利
}
}