Puppeteer与无头浏览器:自动化Web页面测试

Puppeteer简介

Puppeteer是一个由Google Chrome团队开发的Node库,它提供了一套高级API来控制Chrome或Chromium浏览器。Puppeteer主要用于无头浏览器的场景,但也可以配置为运行"有头"模式(即常规的浏览器界面)。通过模拟真实用户的操作,如页面导航、表单填写、按钮点击等,Puppeteer在Web自动化测试、爬虫、页面渲染等方面展现出了巨大的潜力。在自动化测试领域,Puppeteer特别受到青睐,原因在于它的灵活性、易用性和功能强大。

Chrome无头模式

Chrome无头模式是Google Chrome浏览器的一个特性,允许在没有图形用户界面的情况下运行浏览器。这意味着你可以在后台执行Web页面渲染、执行JavaScript或进行自动化测试等操作,而无需打开浏览器窗口。对于自动化测试而言,无头模式具有以下几个优点:

  • 速度快:由于不需要渲染图形界面,测试执行的速度更快。
  • 环境兼容:可以在没有图形界面的服务器环境中运行测试,适合持续集成(CI)环境。
  • 资源占用少:相比于全模式(Full mode)浏览器,无头模式占用更少的资源。

Puppeteer自动化测试的优势

  1. 高度模拟真实用户行为:Puppeteer能够模拟键盘输入、鼠标点击、表单提交等用户操作,以及更复杂的行为如拖拽、滚动等,使测试更接近用户实际使用情况。
  2. 无头模式提高测试效率:在无头模式下运行测试,即在后台运行浏览器实例,可以显著提高测试执行的速度,非常适合集成到持续集成/持续部署(CI/CD)流程中。
  3. 页面渲染和截图:Puppeteer可以渲染并截取页面的屏幕截图或生成PDF,这对于检查页面布局问题和文档生成非常有用。
  4. 网络请求控制:能够拦截和修改浏览器的网络请求,可以用来模拟不同的网络条件,或者测试应用对失败请求的处理能力。
  5. 可访问性测试:Puppeteer可以用来检查页面的可访问性,帮助开发者改进网站的无障碍访问能力。

Puppeteer自动化测试的应用场景

  1. 端到端(E2E)测试:模拟用户在整个应用中的操作流程,从登录到执行具体任务,再到登出,确保整个过程按预期工作。
  2. 性能测试:通过模拟用户加载页面和执行操作来评估应用的性能,包括加载时间、响应时间等。
  3. 爬虫:利用Puppeteer遍历网页并提取所需信息,特别是对于JavaScript渲染的内容。
  4. 自动化截图和PDF生成:自动化生成页面的截图或PDF文档,用于文档、报告或网站内容的备份。
  5. UI测试:自动化测试用户界面元素是否按照设计显示,包括布局、颜色、字体等。

实战

这里以一个简单的登录页面为例,通过Puppeteer来实现自动化登录测试。

首先先准备一个登录页面login.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login Page</title>
</head>
<body>
    <h2>Login Page</h2>
    <form id="loginForm">
        <div>
            <label for="username">Username:</label>
            <input type="text" id="username" name="username" required>
        </div>
        <div>
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" required>
        </div>
        <button type="submit" id="loginButton">Login</button>
    </form>
    <div id="message"></div>

    <script type="text/javascript">
        document.getElementById('loginForm').addEventListener('submit', function(event) {
            event.preventDefault(); // 阻止表单默认提交行为

            var username = document.getElementById('username').value;
            var password = document.getElementById('password').value;

            if (username === 'admin' && password === '123456') {
                document.getElementById('message').textContent = 'Login successful!';
                document.getElementById('message').style.color = 'green';
                // 实际应用中,这里可以重定向到另一个页面
            } else {
                document.getElementById('message').textContent = 'Invalid username or password.';
                document.getElementById('message').style.color = 'red';
            }
        });

    </script>
</body>
</html>

页面布局如下:

页面在登录成功时,message元素会显示Login successful!,并且颜色变成绿色:

页面在登录失败时,比如账号密码不是admin123456时,message元素会显示Invalid username or password.,并且颜色变成红色:

在本地先起一个静态服务器,将login.html放入服务器目录中。

这里需要做的是通过Puppeteer模拟登录成功和登录失败的情况。 确保你已经安装了Node.js和Puppeteer。如果还没有安装Puppeteer,可以通过运行以下命令来安装:

shell 复制代码
npm install puppeteer

先贴testLogin.js代码:

javascript 复制代码
const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({ 
        headless: true 
    });
    const page = await browser.newPage();
    await page.goto('http://127.0.0.1:8081/login.html');

    // 输入用户名和密码
    await page.type('#username', 'admin');
    await page.type('#password', '123456');
    await page.click('#loginButton');

    // 验证登录成功
    const url = await page.url();
    console.log(url); // 根据实际情况判断是否登录成功

    await page.waitForSelector('#message', { visible: true });

    // 获取消息元素的文本内容
    const message = await page.evaluate(() => document.querySelector('#message').textContent);

    // 打印消息文本
    console.log('Login message:', message);
    // 保存登录结果截图到本地
    await page.screenshot({ path: 'login.png' });
    // 关闭无头浏览器
    await browser.close();
})();
  • puppeteer.launch({ headless: true })启动了一个无头模式的Chrome实例。
  • page.goto导航到登录页面,
  • page.type用于在相应的输入框中输入用户名和密码,
  • page.click点击登录按钮。
  • page.waitForSelector等待message元素的展示
  • page.evaluate用来获取message元素的文本内容,用于后面打印
  • page.screenshot将登录的结果截图下来,并保存到本地

接下来启动testLogin.js

shell 复制代码
node testLogin.js

可以看到Login successful!,说明模拟了成功登录

通过输入一个错误的用户名,比如admin1,并重新启动testLogin.js,可以看到成功模拟了失败登录

当然也可以关闭无头模式,即设置headless: false时,Puppeteer会以有界面(GUI)模式启动Chrome或Chromium浏览器。这种模式下,浏览器的窗口会被打开,用户可以看到页面的实时渲染过程,包括模拟用户交互、动画、导航等。

关闭无头模式后,重新启动testLogin.js, 会自动打开登录页面,自动填入账号和密码,并且点击Login按钮,以展示登录结果,效果如下:

到此就完成了模拟用户登录的行为,来进行自动化测试。尽管Puppeteer提供了强大的功能,但在实践中也面临一些挑战:

  • 测试脚本的维护:随着应用的迭代,测试脚本可能需要频繁更新以适应新的用户界面和功能。
  • 复杂场景的模拟:一些复杂的用户交互或边缘情况可能难以准确模拟。
  • 资源消耗:虽然无头模式较高效,但在并发执行大量测试脚本时,仍然会占用大量的系统资源。
相关推荐
Myli_ing44 分钟前
HTML的自动定义倒计时,这个配色存一下
前端·javascript·html
dr李四维1 小时前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
雯0609~1 小时前
网页F12:缓存的使用(设值、取值、删除)
前端·缓存
℘团子এ1 小时前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z2 小时前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
彭世瑜2 小时前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund4042 小时前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish2 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue
小五Five2 小时前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序2 小时前
vue3 封装request请求
java·前端·typescript·vue