Interacting with Notifications using Selenium for Java
Interacting with Notifications using Selenium for Java
Learn how to interact with browser notifications using Selenium for Java. This includes disabling notifications, enabling notifications, and verifying the text of notifications.
If your application generates desktop notifications, you may need to test them.
These are different than traditional JavaScript alerts. Unfortunately, there’s no native support for interacting with these in Selenium WebDriver.
However, in this video, I’ll show you how to still use Selenium to handle notifications.
How to Disable Notifications with Selenium
Before I do that, let me demonstrate how to disable these types of notifications. Because if you’re not explicitly testing them, then you can just prevent them from popping up all together.
To disable notifications from appearing, we’ll first create a ChromeOptions object. And then, we’ll make a call to options.setExperimentalOption(). Inside of here, we’ll tell Selenium we want to set a preference by using the abbreviation “prefs”.
Then, we need to specify the name of the preference and its value.
We can do this with a Map.of(“name”, value), which will hold the key and value. The preferences’ name is “profile.default_content_setting_values.notifications”. And the value can be either 1 or 2 — where 1 is to enable notifications, and 2 is to disable notifications. So, if you want to disable them, you simply place 2 there.
Finally, we can instantiate the driver and pass in the Chrome options object.
That’s all that’s needed to prevent push notifications from being shown.
How to Test Notifications with Selenium
If you want to test the notification, you should change this value to 1. Then within the test, we’ll need to handle this with pure JavaScript. Because remember, there’s no native support for this within Selenium WebDriver.
As we can see on the MDN Web Docs example — var notification = new Notification(“Hi there!”); — to invoke a notification, the application creates a new instance of Notification and passes the message into the constructor.
This means we somehow need to be able to get a handle of this instance to access its message.
So, within our tests, let’s write some JavaScript as a String. If you’re using Java 13 or later, you can use text blocks to make this prettier. And if not, you can use a regular String and that will work as well.
We’re going to use Selenium to make an asynchronous JavaScript call. And when it does that, the last argument it passes is a callback. When we’re done with the script, we make a call to callback to let Selenium know we’re done.
Let’s grab the callback, which again is the last arguments passed in.
Next, we want to grab a reference to the Notification and store it as the “original_notification”. This is because we’re going to need to intercept its call, and we want to be able to restore it back to its original state when we’re done.
Okay, now for the juicy part.
We are going to set window.Notification = and we’re going to assign a new function as this constructor’s behavior. So, we’ll say function. We can call this function whatever we want, let’s say, stubNotification(value) and this takes a value.
When our application calls “new_notification” (new Notification), this stubNotification function will be invoked instead. And this value is whatever was passed into the call to the constructor.
The reason for doing this is to get ahold of the instance of notification that is invoked so that we can get the title property of it.
Otherwise, we’re unable to access this particular instance of Notification, and wouldn’t be able to verify it. But no worries, once we’ve intercepted the instance of Notification, we’re simply going to re-call the constructor, but we’ll assign that instance to a variable that we can access.
Let’s do that part now — new_notification.onshow = function(){ }.
To verify the notification when it actually appears, we’ll add an event handler that says, when this notification is shown, please grab the title attribute, which is the message. Like this: const notification_text = new_notification.title .
Now that we have the title, we’re done with this Notification instance. So let’s be good stewards and return window.notification to its original implementation of “original_notification”.
And finally, we tell Selenium that we’re done by using the callback(). And we can pass in our “notification_text” into the callback so that it’s sent back to our test. Great.
Now, because we have not clicked the button yet, none of this will be invoked.
If we click the button using the Selenium API and then try to invoke this, we’ll run into a timing issue. So, we’ll need to click the button from within this JavaScript code itself.
We’ll do that outside of this function. And the ID for this button is notification button — document.getElementById(‘notification-button’).click().
Okay, now our JavaScript is done but we still need to write the Selenium code to make this call.
We can cast our driver to a JavascriptExecutor object. Now, we’ll call js.executeAsyncScript(), and we’ll pass in that getNotificationText.
This will return that notification title because of this callback, so let’s store that inside of a variable called “notification_body”.
Last, but not least, let’s assertEquals that what was returned is indeed what we are expecting.
And this, my friends, is how you verify a notification with Selenium WebDriver.
Resources
- Git Repo – NotificationsTests.java
- Applitools Kitchen – Notification Testing
- MDN Web Docs – Notifications
Schedule a free Applitools Demonstration
Request DemoHere’s the code sample from our tutorial on how to interact with browser notifications using Selenium for Java. This includes disabling notifications, enabling notifications, and verifying the text of notifications.