puppeteer 自动化检测常用 API (第一弹)

介绍几个自动化测试前端页面的时候使用到的,常用的 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); // 结束进程,检测失败
  }
}

原文链接:https://juejin.cn/post/7351300139762040886 作者:垂慕容

(0)
上一篇 2024年3月29日 上午10:06
下一篇 2024年3月29日 上午10:16

相关推荐

发表回复

登录后才能评论