In my previous post, Selenium + AutoIT: How to Automate Non-Browser Based Functionality, I showed you how to programmatically use Java to automate the Calculator found in Windows.
Today I want to show you an example of how the same approach can be used to automate pop-up windows that you might encounter when using Selenium. There are usually three types of alerts or pop-ups you will face when creating an automated Selenium tests
- Windows authentication popup
- Windows security popup
- Web-based popup alerts
Remember, Selenium only works for browser automation.
Any time you encounter a non-browser window — like an authentication pop-window — Selenium will not be able to recognize it since it is an OS-level dialog.
How to automate OS-level dialogs with Selenium?
So what do you do in these situations? Here is one example that I've found to be an awesome workaround when developing Selenium test automation scripts in Java utilizing the AutoITX3 DLL.
For this example, I'm going to automate the browser print dialog as an example of a non-browser type window you might encounter in some of your web-based Selenium automation test flows.
To see the issue, let's first manually inspect it before automating it:
- Navigate to my Selenium Test Page example: https://testguild.com/SeleniumTestPage.html
- Click on the Print – Windows Dialog Example button.
- A Windows-based Print pop-up should appear.
- We're going to automate:
- Selecting the Pages radio button
- Enter the value of 50 in the to field
- Click on the Cancel button
- Selecting the Pages radio button
How to Spy on a Windows Dialog using Selenium?
Cool! But before we can automate this we need to be able to spy on the dialogs fields in order to know what properties we can used to identify them in our Selenium script.
The first issue you'll notice is that Firebug will not work against this window since it's not CSS, HTML or JavaScript based. In order to get the identification properties we need, we'll use the Windows UISPY tool. (You can get the UISpy.zip from my site's downloads section.)
- Start up the UI SPY
- Locate the “Dialog” “Print” section under the window Selenium WebDriver Validation section.
- Expanding the “Dialog” “Print” section will display all the elements and their properties.
- Click on the “radio Button” “pages” under the control view.
- You should then be able to see all the properties for that element.
- We will use the AutomationId for each element as the identification property in our automation test example.
- So, for this demo we will be using the following ID's:
Element Name | AutomationID |
radio button Pages | 1058 |
edit to: | 1153 |
button Cancel | 2 |
Putting it all together
Now that we have the automation ID's that we'll be using to open up the Java IDE of your choice, add the following code (I'll assume you've already followed the setup steps I've outlined in my previous post on Selenium and AutoIt):
File file = new File("lib", jacobDllVersionToUse); System.setProperty(LibraryLoader.JACOB_DLL_PATH, file.getAbsolutePath()); WebDriver driver = new FirefoxDriver(); driver.get("https://testguild.com/SeleniumTestPage.html"); WebElement printButton = driver.findElement(By.id("printButton")); printButton.click(); AutoItX x = new AutoItX(); x.winActivate("Print"); x.winWaitActive("Print"); x.controlClick("Print", "", "1058"); x.ControlSetText("Print", "", "1153", "50"); Thread.sleep(3000); //This was added just so you could see that the values did change. x.controlClick("Print", "", "2");
- Run the tests.
If all goes well, you should see that your script opened the example web page, clicked on the print dialog, changed some value, and then clicked on the Cancel button. (Note: you should never use Thread.Sleep in your real-world test cases – I just added it here so you could see what was happening.)
In this example, we made use of the existing AutoIt functions programmatically in Java. For detailed information on the methods used in this example, and to see all the other functions available in AutoIt, check out the online AutoIt function library reference.
Awesome Awesomeness in action – -Right?!? So what are some other tools you could use to test more complicated window based dialog or thick client application that your web app might integrate with?
Sikuli
Another popular method to get around other types of windows objects when using Selenium is using a tool like Sikuli. What’s cool about SikuliX is that it allows you to automate anything you see on your screen using image-based testing. Find out more in my Getting Started with Sikuli post and video.
LeanFT
Essentially, Lean Functional Testing (LeanFT) combines the best of both the vendor-based and open-source worlds by morphing Selenium with some key functionality currently found in UFT. Find out more in my A sneak peek at Lean Functional Testing (LeanFT) post.
I followed all the steps.But for the pop up window with Ok and cancel buttons,automation id is nill.what to do with this issue?
Hi,
Thanks for good information, could you please share me UISPY tool? I am not able to download from ur site? facing error as permission denied..
Thanks & Regards
Srinath K
Hi – the link should now be fixed https://testguild.com/downloads/UISpy.zip let me know if you still have issues. Thanks
Thanks for posting this article on handling windows based dialogs and pops ..
Thanks!
Hi Joe ,,,
Nice posting on windows Pop-Ups, can we have any other methods for windows Pop-ups like you said ” AutoIt ”, we find only this method for automating window Pop-Ups , can you share any other methods for windows
Pop-Ups.( where selenium webdriver can handle )
thanks
Reddy
Hi,
Thanks for the info. I appreciate your efforts for sharing this useful info. I have implemented the code in the same fashion & I was able to interact with the dialog. But my test case also needs to interact with a .ini file. On trying to use iniWrite or iniRead to read & write into the .ini file an exception is thrown. I googled but I didn’t get any solution. Am stuck now & am unable to proceed further without getting a solution for this issue. Please help me. Your help would be highly appreciated.
AutoItX x = new AutoItX();
x.iniRead(“F:\\Simulator\\DeviceSimulatorV0.8\\DefaultSimulator.ini”, “DefaultSimulator”, “Addr”, “”);
//String fileName = “\\DefaultSimulator.ini”;
//x.iniWrite(fileName, “UDP ADDRESS”, “Addr”, “54.244.118.62”);
Trying to use iniWrite, this is the exception:
FAILED: calc
com.jacob.com.ComFailException: Can’t map name to dispid: IniWrite
at com.jacob.com.Dispatch.invokev(Native Method)
at com.jacob.com.Dispatch.invokev(Dispatch.java:625)
at com.jacob.com.Dispatch.callN(Dispatch.java:453)
at com.jacob.activeX.ActiveXComponent.invoke(ActiveXComponent.java:476)
at autoitx4java.AutoItX.iniWrite(AutoItX.java:349)
at autoIt.CalcTest.calc(CalcTest.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:648)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:834)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1142)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:124)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
at org.testng.TestRunner.privateRun(TestRunner.java:771)
at org.testng.TestRunner.run(TestRunner.java:621)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:357)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:352)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:310)
at org.testng.SuiteRunner.run(SuiteRunner.java:259)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1176)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1101)
at org.testng.TestNG.run(TestNG.java:1009)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
Trying to use iniRead, this is the exception:
FAILED: calc
com.jacob.com.ComFailException: Can’t map name to dispid: IniRead
at com.jacob.com.Dispatch.invokev(Native Method)
at com.jacob.com.Dispatch.invokev(Dispatch.java:625)
at com.jacob.com.Dispatch.callN(Dispatch.java:453)
at com.jacob.activeX.ActiveXComponent.invoke(ActiveXComponent.java:476)
at autoitx4java.AutoItX.iniRead(AutoItX.java:331)
at autoIt.CalcTest.calc(CalcTest.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:648)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:834)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1142)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:124)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
at org.testng.TestRunner.privateRun(TestRunner.java:771)
at org.testng.TestRunner.run(TestRunner.java:621)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:357)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:352)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:310)
at org.testng.SuiteRunner.run(SuiteRunner.java:259)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1176)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1101)
at org.testng.TestNG.run(TestNG.java:1009)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
After clicking “Cancel” button to close my Windows popup, i try to find an element on the browser page and get an error “Unable to find element on closed window”. Any recommendations?
Thanks a lot Joe for all of your knowledge sharing.
Hmm not sure – are there multiple browser windows open for your tests? Do using driver.switchTo() help?
Any tool that can be used on OS X (Mac) ?
You could probably use SikuliX which works on Windows, Linux and Macs
Thanks for this, it was very useful. Can you provide any insight into utilizing AutoIt on a Selenium GRID set up?