Monday, July 21, 2014

Interact with Windows modal dialog from your Selenium scripts

While testing web applications sometimes we encounter Windows popup dialogs (modal windows) that block operation until the dialog is cleared. Below is how I solved this issue. Please note that there are other options out there (e.g. AutoIt), however, I decided against calling an external exe and opted for integrating the tried and true Win32::GuiTest module for this task; mainly because it is written in the same language as the bindings and so there is no need to call external executables as well as learning a new "language", simply call a method.

NOTE: The workhorse of this solution is the SendKeys call.

In your test script:
1:  my $win_id = 0;  
2:  my $win_title = 'Test window title';  
3:  my $win_class = 'Class name';  
4:    
5:  $driver->key_press_native( $win_id, $win_title, $win_class, 'ENTER' );  

In the Driver.pm OR in your page object:
1:  sub key_press_native {  
2:    
3:    my ( $self, $win_id, $win_title, $win_class, $keycode ) = @_;  
4:    
5:    use Win32::GuiTest qw(FindWindowLike GetWindowText SetForegroundWindow SendKeys);  
6:     
7:    $Win32::GuiTest::debug = 0; # Set to "1" to enable verbose mode  
8:    # First find the window of interest.  
9:    my @windows = FindWindowLike( $win_id, "^$win_title", "^$win_class\$" );  
10:    
11:    # Then we iterate through that list and send the "keys" to any matching window.  
12:    for (@windows) {  
13:      SetForegroundWindow($_);  
14:      SendKeys("{$keycode}");  
15:      Custom::TagSubs::wait_for(2);  
16:    }  
17:    return;  
18:  }  

As you can see from the above, the solution requires the test developer to know the pertinent details of the window we will be interacting with (i.e. window id, window title, window class) as well as the key(s) you would like to press (i.e. keycode). Luckily Win32::GuiTest comes with a tool found in Recoder\Win32GuiTest.exe which you can use to get "Window Hints" (i.e. WinClass, WinTitle, etc).
Some caveats:
  • The solution uses the SetForegroundWindow call which means that it does require the window being interacted with to be able to be brought to the foreground.
Information on Win32::GuiTest can be found here: http://search.cpan.org/~karasik/Win32-GuiTest-1.60/lib/Win32/GuiTest.pm you can also find key codes in the module documentation.

Feel free to drop a line or comment.
Creative Commons License
VGP-Miami Web and Mobile Automation Blog by Alfred Vega is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.