You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Selenium+Chrome WebDriver中禁用错误密码时的认证弹窗?

解决Chrome非无头模式下禁用HTTP认证弹窗,获取401页面的方案

我之前也遇到过这个问题——Chrome自带的认证弹窗确实会打断Selenium的测试流程,没办法直接获取服务器返回的401页面。这里有两种可靠的解决方法,都能在非无头模式下禁用弹窗,让你顺利验证密码错误返回401、密码正确返回200的测试场景:

方法一:URL嵌入认证信息(简单直接)

HTTP基本认证支持在URL中直接嵌入用户名和密码,格式为http://username:password@target-domain.com。Chrome会自动将这些凭证添加到请求头的Authorization字段中,不会弹出认证弹窗;如果密码错误,服务器会直接返回401页面,而非重试弹窗。

注意事项

Chrome 81及以上版本默认会拦截这种带凭证的URL,所以需要添加启动参数解除限制:

// 配置ChromeOptions,允许URL中的凭证认证
ChromeOptions options = new ChromeOptions();
options.addArguments("--allow-url-auth-bypass-for-testing");
// 如果目标是HTTPS且使用自签证书,需添加以下参数避免拦截
options.addArguments("--ignore-certificate-errors");

WebDriver webDriver = new ChromeDriver(options);

修改导航代码

将用户名和密码拼接进目标URL:

String username = System.getProperty("id");
String password = System.getProperty("password");
String urlToOpen = "https://your-target-url.com"; // 替换为你的目标URL

// 拆分URL的协议和域名部分,拼接凭证
String[] urlParts = urlToOpen.split("://");
String authenticatedUrl = String.format("%s://%s:%s@%s", 
    urlParts[0], username, password, urlParts[1]);

webDriver.navigate().to(authenticatedUrl);

方法二:使用Chrome DevTools Protocol(CDP)设置请求头(更可靠)

如果URL嵌入凭证的方式被浏览器安全策略限制,推荐使用CDP直接在请求头中添加Authorization字段。这种方法不需要修改URL,兼容性更好。

代码示例

ChromeOptions options = new ChromeOptions();
WebDriver webDriver = new ChromeDriver(options);

// 初始化CDP会话
DevTools devTools = ((ChromeDriver) webDriver).getDevTools();
devTools.createSession();
devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));

// 生成Base64编码的认证信息
String username = System.getProperty("id");
String password = System.getProperty("password");
String authCredentials = username + ":" + password;
String encodedAuth = Base64.getEncoder().encodeToString(authCredentials.getBytes(StandardCharsets.UTF_8));
String authHeader = "Basic " + encodedAuth;

// 设置全局请求头,添加Authorization字段
devTools.send(Network.setExtraHTTPHeaders(new Headers(Map.of("Authorization", authHeader))));

// 导航到目标URL
webDriver.navigate().to(urlToOpen);

验证状态码和页面内容

Selenium本身没有直接获取HTTP状态码的API,需要通过CDP监听网络请求来获取:

// 监听请求完成事件,收集目标URL的状态码
List<Integer> statusCodes = new ArrayList<>();
devTools.addListener(Network.responseReceived(), response -> {
    if (response.getResponse().getUrl().equals(urlToOpen)) {
        statusCodes.add(response.getResponse().getStatus());
    }
});

// 等待请求完成后验证
Integer statusCode = statusCodes.get(0);
if (password.equals("wrongpass")) {
    // 验证密码错误场景
    assert statusCode == 401 : "密码错误时应返回401";
    assert webDriver.getPageSource().contains("401 Unauthorized") : "页面应包含401提示";
} else {
    // 验证密码正确场景
    assert statusCode == 200 : "密码正确时应返回200";
}

额外注意事项

  • 确保Chrome WebDriver版本与Chrome浏览器版本完全匹配,否则CDP功能可能失效。
  • 非无头模式下,以上两种方法均有效,不会触发浏览器的认证弹窗。
  • 如果测试环境使用HTTPS,需根据实际情况添加证书相关的启动参数。

内容的提问来源于stack exchange,提问作者Stéphane GRILLON

火山引擎 最新活动