You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHPUnit+Selenium测试平台获取AJAX请求状态码与响应数据

在PHPUnit+Selenium中捕获AJAX请求的状态码与响应数据

Selenium WebDriver本身并没有提供直接监听网络请求的API,不过好在Chrome浏览器支持Chrome DevTools Protocol (CDP),我们可以通过它来捕获AJAX请求的状态码、响应头和响应体。结合你给出的代码片段,我整理了完整的实现方案:

核心思路

我们需要借助CDP的网络监控能力:

  1. 启用网络监听,捕获所有HTTP/HTTPS响应
  2. 筛选出目标AJAX请求(比如登录接口)
  3. 提取状态码、响应数据并用于测试断言

完整代码示例

use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\WebDriverCapabilityType;
use Facebook\WebDriver\WebDriverBy;

class LoginAJAXTest extends \PHPUnit\Framework\TestCase
{
    protected $webDriver;
    protected $ajaxResponses = [];

    protected function setUp(): void
    {
        // 配置Chrome驱动能力,兼容新版ChromeDriver的跨域限制
        $capabilities = [
            WebDriverCapabilityType::BROWSER_NAME => 'chrome',
            'goog:chromeOptions' => ['args' => ['--remote-allow-origins=*']]
        ];
        
        // 初始化远程WebDriver
        $this->webDriver = RemoteWebDriver::create('http://localhost:4444/wd/hub', $capabilities);

        // 启用CDP网络监控
        $this->webDriver->executeCdpCommand('Network.enable', []);

        // 注册响应监听事件,捕获目标AJAX请求
        $this->webDriver->executeCdpCommand('Network.responseReceived', [], function ($response) {
            $responseDetails = $response['params']['response'];
            // 这里根据你的AJAX接口URL进行筛选,比如/login接口
            if (strpos($responseDetails['url'], '/api/login') !== false) {
                // 获取响应体内容
                $responseBody = $this->webDriver->executeCdpCommand(
                    'Network.getResponseBody',
                    ['requestId' => $response['params']['requestId']]
                )['body'];

                $this->ajaxResponses[] = [
                    'url' => $responseDetails['url'],
                    'status_code' => $responseDetails['status'],
                    'headers' => $responseDetails['headers'],
                    'response_body' => $responseBody
                ];
            }
        });
    }

    public function testLoginAJAXResponse()
    {
        // 打开登录页面(你的原有代码)
        $this->webDriver->get('http://www.test.com/login');
        
        // 输入用户名
        $username = $this->webDriver->findElement(WebDriverBy::id('name'));
        $username->clear();
        $username->sendKeys('admin');
        
        // 输入密码(补全你的代码片段)
        $password = $this->webDriver->findElement(WebDriverBy::id('password'));
        $password->clear();
        $password->sendKeys('test123');
        
        // 触发登录操作(假设登录按钮ID为login-submit)
        $loginBtn = $this->webDriver->findElement(WebDriverBy::id('login-submit'));
        $loginBtn->click();

        // 显式等待,直到捕获到AJAX响应(最多等待10秒)
        $this->webDriver->wait(10)->until(function () {
            return !empty($this->ajaxResponses);
        });

        // 提取第一个匹配的AJAX响应
        $loginResponse = reset($this->ajaxResponses);

        // 断言状态码为200
        $this->assertEquals(200, $loginResponse['status_code'], '登录AJAX请求未返回成功状态码');
        
        // 解析响应体(假设是JSON格式)并验证内容
        $responseData = json_decode($loginResponse['response_body'], true);
        $this->assertArrayHasKey('success', $responseData, '响应体缺少success字段');
        $this->assertTrue($responseData['success'], '登录AJAX请求返回失败');
    }

    protected function tearDown(): void
    {
        // 关闭网络监控并退出浏览器
        $this->webDriver->executeCdpCommand('Network.disable', []);
        $this->webDriver->quit();
    }
}

关键细节说明

  • CDP命令调用:通过executeCdpCommand方法调用CDP的API,Network.enable开启网络监听,Network.responseReceived监听每个响应的到达事件,Network.getResponseBody用于获取响应体的内容。
  • 请求筛选:通过strpos匹配URL来筛选目标AJAX请求,你可以根据实际需求调整筛选条件(比如请求方法、请求头)。
  • 显式等待:触发登录操作后,必须等待AJAX请求完成并被捕获,否则断言会因为数据未准备好而失败。
  • 版本兼容:如果使用较新的ChromeDriver,需要在chromeOptions中添加--remote-allow-origins=*参数解决跨域限制问题。

注意事项

  • 确保ChromeDriver与Chrome浏览器版本匹配,CDP的API可能会随版本更新略有变化。
  • 如果使用Selenium Grid,需要确保Grid节点上的Chrome浏览器支持CDP(大部分现代版本都支持)。
  • 对于HTTPS请求,若测试环境使用自签名证书,可能需要添加--ignore-certificate-errors到Chrome启动参数中。

内容的提问来源于stack exchange,提问作者hhniao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:09:44