You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何用Selenium WebDriver+Java验证并操作浏览器推送通知?

搞定Selenium处理通知权限+验证推送通知的方案

嘿,这个场景我太熟了!之前帮好几个测试同学解决过类似问题,给你捋一套靠谱的步骤:

第一步:先搞定那个烦人的权限提示框

首先得说,这个"Show notifications"的提示是浏览器原生弹窗,不属于网页DOM元素,Selenium根本没法用常规的findElement去定位点击。所以最稳妥的方式是提前给浏览器配置好权限,让它自动允许,直接跳过提示框,比事后去点靠谱多了。

针对Chrome浏览器的配置代码

直接用ChromeOptions设置偏好就行,代码示例给你:

ChromeOptions options = new ChromeOptions();
// 用HashMap存浏览器偏好,1代表允许通知权限,2是拒绝
Map<String, Object> prefs = new HashMap<>();
prefs.put("profile.default_content_setting_values.notifications", 1);
options.setExperimentalOption("prefs", prefs);

// 启动带配置的浏览器
WebDriver driver = new ChromeDriver(options);

这样启动Chrome后,访问目标站点会自动允许通知权限,完全不会弹出那个提示框,省心!

要是已经弹出提示框了怎么办?(不推荐)

如果实在没法提前配置,比如遇到动态场景,那只能用AutoIt或者Java的Robot类模拟鼠标点击,但这种方法兼容性极差,换个浏览器版本或者屏幕分辨率就可能失效,所以真心不建议用,优先选上面的预配置方法。


第二步:验证+操作Web推送通知

推送通知是浏览器的桌面通知,同样不属于网页DOM,Selenium没法直接定位操作。这里给你两种靠谱的实现方式:

方法1:用Chrome DevTools Protocol(CDP)监听通知

Chrome自带的DevTools有专门的Notification API,可以监听通知的创建事件,直接拿到标题、内容这些信息,代码示例:

// 初始化带配置的ChromeDriver
ChromeDriver driver = new ChromeDriver(options);
// 获取DevTools实例
DevTools devTools = driver.getDevTools();
devTools.createSession();

// 启用Notification监听域
devTools.send(Notification.enable());

// 监听通知创建事件,拿到通知内容
devTools.addListener(Notification.notificationCreated(), notification -> {
    String notifyTitle = notification.getTitle();
    String notifyMessage = notification.getMessage();
    
    // 这里写你的验证逻辑,比如断言标题和内容是否符合预期
    Assert.assertEquals(notifyTitle, "你的预期标题");
    Assert.assertEquals(notifyMessage, "你的预期内容");
    
    // 要是需要点击通知的话,CDP没法直接触发,这时候可以考虑下面说的替代方案
});

// 点击触发通知的按钮
driver.findElement(By.id("你的按钮ID")).click();

方法2:注入JavaScript拦截通知

你可以在页面加载时注入一段JS,重写浏览器的Notification构造函数,把所有通知都存起来,之后再从JS里取出来验证,这种方法兼容性更好,代码示例:

// 注入拦截通知的JS代码
String interceptNotifyJs = "window.capturedNotifications = [];" +
            "const originalNotify = window.Notification;" +
            "window.Notification = function(title, options) {" +
            "    window.capturedNotifications.push({title: title, content: options.body});" +
            "    return new originalNotify(title, options);" +
            "};" +
            "window.Notification.prototype = originalNotify.prototype;" +
            "window.Notification.permission = originalNotify.permission;";

driver.executeScript(interceptNotifyJs);

// 点击按钮触发通知
driver.findElement(By.id("你的按钮ID")).click();

// 从JS里取出捕获的通知
List<Map<String, Object>> notifications = (List<Map<String, Object>>) driver.executeScript("return window.capturedNotifications;");
if (!notifications.isEmpty()) {
    Map<String, Object> firstNotify = notifications.get(0);
    String title = (String) firstNotify.get("title");
    String content = (String) firstNotify.get("content");
    
    // 验证内容,比如你提到的类似Facebook的通知,就断言标题和内容符合预期
    Assert.assertEquals(title, "Facebook");
    Assert.assertEquals(content, "您有一条新消息");
}

关于点击通知的小技巧

因为通知是桌面元素,Selenium没法直接操作它。这里给你两个思路:

  1. 优先模拟跳转URL:如果通知点击后会跳转到网页的某个特定页面,那你直接让driver访问那个URL就行,比模拟点击靠谱多了。
  2. 用Robot类模拟点击(不推荐):如果必须要点击通知,那只能用Java的Robot类模拟鼠标点击,但你得提前知道通知在屏幕上的位置,换个环境就可能失效,适合固定测试环境的场景。

总结一下:先提前配置浏览器权限跳过提示框,再用CDP或JS拦截的方式验证通知内容,点击通知优先用URL跳转替代。

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

火山引擎 最新活动