如何用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没法直接操作它。这里给你两个思路:
- 优先模拟跳转URL:如果通知点击后会跳转到网页的某个特定页面,那你直接让driver访问那个URL就行,比模拟点击靠谱多了。
- 用Robot类模拟点击(不推荐):如果必须要点击通知,那只能用Java的Robot类模拟鼠标点击,但你得提前知道通知在屏幕上的位置,换个环境就可能失效,适合固定测试环境的场景。
总结一下:先提前配置浏览器权限跳过提示框,再用CDP或JS拦截的方式验证通知内容,点击通知优先用URL跳转替代。
内容的提问来源于stack exchange,提问作者user11221




