How to deal with browser alerts that require a confirmation with Ruby/Cucumber/LapisLazuli

Recently our website application changed and with that change there was also a check for input fields that were not saved yet (dirtyflag). When you want to close the page while there is an unsaved change on the page, the browser will show you an alert with the options to Leave the page (and loose all changes) or Cancel (and stay on the page). This seems like a small thing to solve. But it seems like it's a bit more difficult to do something with this alert then I initially thought so I'll show you my case and why I needed a small workaround to make sure it was not breaking all my tests.


My case

I'm testing a one page application, which means I don't deal with a lot of url's. Actually I only have to deal with two url's. The application page https://application.domain.com and the login page https://application.domain.com/login. The disadvantage of a one page application is that you cannot use a url to go to a certain page within the application. You need to use the menu/website elements to get to the page/part you need to be to do the actual test. Which means, the bigger the application, the more steps you need in the Gherkin Given statement which can be time consuming. So I tried to take a couple of shortcuts and one is to close the browser after each feature ran so I need less checks in the Gherkin 'Given' step.

The issue

I'm using the lapis_lazuli gem and when you have created a project you see there is a config.yml file in that folder. One of the configurations in there is : `close_browser_after`
The value of this configuration can be `scenario`, `feature`, `never` or `end`. Previously I had set this to `feature` to start clean for each feature file as I mentioned above. However if your website throws an `unsaved changes` alert when the browser is changing url or closing the tab or browser itself. You will notice you'll get stuck and get the error Net::ReadTimeout (Net::ReadTimeout) can't modify frozen String (RuntimeError), but only on Firefox (Chrome seemed to just close the browser anyway, Edge and Safari I have not tested yet)

Normal solution

Normally window.onbeforeunload should do the trick like this

My solution

This took be a bit of time to figure out. There was some information available how one could deal with this: http://watir.com/guides/alerts/ (also see 'Normal solution'). But this did not do the trick for our website. So I asked around, thought I had to monkey patch browser.close and/or browser.quit to deal with this, until I realized I had not tried browser.refresh and found this question: https://stackoverflow.com/questions/30253210/how-to-handle-browser-javascript-confirm-navigation-alert-with-ruby-watir-script
This made me wonder, if I could trigger a browser.refresh with cucumber hooks: 
https://github.com/cucumber/cucumber/wiki/Hooks
Below is my solution for my project. In the `config.yml` file, I set: 
close_browser_after: end # Can be `scenario`, `feature` or `end`

This will close the browser at the end of all tests. 
And in `hooks.rb` I now have this small workaround:
After('@refresh') do browser.refresh p "browser.alert.exists? >> #{browser.alert.exists?}" if browser.alert.exists? browser.alert.ok p 'alert accepted' end sleep 1 end
And in the feature files I added the @refresh tag after every scenario tag where I needed the refresh to be sure I start clean in the scenario after.
@desk10.1.1 @desk10.1 @refresh Scenario: 10.1.1 Breadcrumb - Add event dirty flag check

This way I can perform a refresh of the page after each scenario that might contain a dirty flag to make sure this alert is gone after each scenario, which makes it possible to close the browser at the end of the test as well. The sleep was needed because of a timing issue between really closing the alert and the next browser command in the next feature file. I would prefer to have a function that will only run after each full feature. But that does not seem possible at the moment. 

Let me know what you think of this solution or if you have another way of solving this issue. In case you have any question about this topic, feel free to contact me.

Comments

Popular posts from this blog

PowerShell - How to overcome Azure VM's fixed resolution limitation

TA Basics: Website Test Automation on mobile devices via Appium server

TA: Who doesn't like proxies? Me!