Automating a non-web UI in Selenium WebDriver with AutoIt

Selenium WebDriver is a pure browser automation API and works with HTML/web elements. It does not support the native UI built with C++, .NET, Java, or any other desktop technologies. It also does not support Flex, Flash, or Silverlight native controls out of the box.

While testing applications that interact with the native UI, it becomes difficult to automate the functionality involved. For example, the web application provides a file upload feature that invokes the native OS UI for selecting a file.

We can use tools such as AutoIt to handle the native UI. AutoIt is a freeware BASIC-like scripting language designed to automate the Windows GUI and general scripting. Using AutoIt, we can simulate a combination of keystrokes, mouse movement, and window/control manipulation in order to automate. It is a very small, self-contained utility. It runs on all versions of Windows operating system. AutoIt scripts can be compiled as self-contained executables.

AutoIt has certain limitations in terms of OS support as it is not supported on Linux and Mac OSX, and it will not work with RemoteWebDriver.

In this recipe, we will explore the integration of AutoIt with Selenium WebDriver to test the file upload functionality on a sample page.

Getting ready

Download and install AutoIt tools from http://www.autoitscript.com/site/autoit/downloads/.

How to do it...

To implement the file upload functionality, there are a number of libraries or plugins available that provide a number of additional features for uploading files. We will use the jQuery File Upload plugin. It offers multiple ways in which users can upload files on the server. Users can either drag-and-drop a file on the browser or can click on the Add Files button, which opens the native Open dialog box, as shown in the following screenshot:

How to do it...

We will automate a test where the user to upload a file by clicking on the Add Files button. This invokes the Open dialog box, as shown in the preceding screenshot. We will create an AutoIt script to automate interactions on this dialog box.

Creating the AutoIt script

Let's create an AutoIt script that works with the Open dialog box.

  1. Launch SciTE Script Editor from Start | AutoIt.
  2. Create a new script by selecting File | New from the SciTE Script Editor main menu.
  3. Name and save this file as OpenDialogHandler.au3 (AutoIt scripts have .au3 extension) and copy the following code to the script, then save the script:
    WinWaitActive("Open","","20")
    If WinExists("Open") Then
        ControlSetText("Open","","Edit1",$CmdLine[1])
        ControlClick("Open","","&Open")
    EndIf
  4. Launch the Compile Script to .exe utility from Start | AutoIt. Using the Compile Script to .exe utility, we will convert the AutoIt script into an executable file.
  5. On the Aut2Exe v3 - AutoIt Script to EXE Converter window, enter the path of the AutoIt script in the Source (AutoIt .au3 file) textbox, and the path of the executable in the Destination (.exe/.a3x file) textbox, and click on the Convert button, as shown in the following screenshot:
    Creating the AutoIt script

Using OpenDialogHandler in Selenium WebDriver script

  1. Now create a test that allows us to click on the Add Files button and then call OpenDialogHandler.exe and validate that the specified file is uploaded on the page.
  2. Create a new test class named FileUpload and copy the following code in it:
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.By;
    import org.openqa.selenium.support.ui.ExpectedCondition;
    import org.openqa.selenium.support.ui.WebDriverWait;
    
    import org.junit.*;
    import static org.junit.Assert.*;
    
    public class FileUpload {
        protected WebDriver driver;
    
        @Before
        public void setUp() {
            driver = new ChromeDriver();
            driver.get("http://blueimp.github.com/jQuery-File-Upload/");
        }
    
        @Test
        public void testFileUpload() throws InterruptedException {
            try {
    
                // Click on Add Files button
                driver.findElement(By.className("fileinput-button")).click();
    
                // Call the OpenDialogHandler, specify the // path of the file to be uploaded
                Runtime.getRuntime().exec(new String[] {"C:\Utils\OpenDialogHandler.exe", ""C:\Users\Admin\Desktop\Picture1.png""});
    
                //Wait until file is uploaded
                boolean result = (new WebDriverWait(driver, 30)).until(new ExpectedCondition<Boolean>() {
                    public Boolean apply(WebDriver d) {
                        return d.findElement(By.xpath("//table[@role='presentation']")).findElements(By.tagName("tr")).size() > 0;
                }});
    
                assertTrue(result);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @After
        public void tearDown() {
            driver.close();
        }
    }

How it works...

AutoIt provides an API to automate a native Windows UI control. In this example, we used the WinWaitActive() function, which waits for a window. It takes the title of the expected window, text of the window, and timeout as parameters. We supplied the title as Open and the timeout of 20 seconds. The text of the windows is passed as blank, as the title is enough to identify the window:

WinWaitActive("Open","","20")

Once the open window is activated, the ControlSetText() function is called to enter the text in the File name: textbox:

ControlSetText("Open","","Edit1",$CmdLine[1])

This function takes the title of the window, text of the window, control ID, and text that needs to be entered in the textbox. Similar to locators in Selenium, AutoIt identifies controls using control IDs. You can find control IDs using the AutoIt V3 Window Info tool installed with AutoIt. You can spy on a window or control using this tool and find out various properties. In this example, the ControlSetText() function takes the last parameter as $CmdLine[1]. Instead of hardcoding the path of the filename that we want to upload, we will pass the filename to AutoIt script using command line arguments; $CmdLine[1] will hold this value.

To click on the Open button, the ControlClick() function is called. This function takes the title of the window, text of the windows, and control ID as parameters:

ControlClick("Open","","&Open")

You can find more about AutoIt API in AutoIt help documentation.

Using the Aut2Exe v3 - AutoIt Script to EXE Converter utility, AutoIt script is compiled as an executable, that is, OpenDialogHandler.exe.

The Selenium WebDriver test calls this executable file using the exec() method of the RunTime class, which allows the Java code to interact with the environment in which the code is running. The complete path of OpenDialogHandler, as well as the path of the file to be uploaded, is passed through the exec() method. Please note that OpenDialogHandler needs quotes for arguments:

Runtime.getRuntime().exec(new String[] {"C:\Utils\OpenDialogHandler.exe", ""C:\Users\Admin\Desktop\Picture1.png""});

There's more…

You can use AutoIt scripts with other Selenium WebDriver bindings such as .NET, Ruby, or Python, as long as these languages allow you to call external processes.

AutoIt also comes with a lightweight AutoItX COM library that can be used with languages that support Component Object Model (COM). Using the COM API will save you from writing the AutoIt script and compiling it into an executable.

You will come across web applications using HTTP authentication, which requires users to authenticate before displaying the application. An HTTP authentication dialog is displayed, as shown in the following screenshot:

There's more…

This dialog box is displayed using the native UI. In addition, the layout and controls on this dialog box may change for different browsers. In the following example, AutoItX API is called directly in the Ruby script to automate the HTTP authentication dialog box displayed in Google Chrome:

require 'rubygems'
require 'selenium-webdriver'
require 'test/unit'
require 'win32ole'

class HttpAuthTest < Test::Unit::TestCase
    def setup
        @driver = Selenium::WebDriver.for :chrome
        @driver.get 'http://www.httpwatch.com/httpgallery/authentication'
        @verification_errors = []
    end

    def test_http_auth_window
        #Create instance of AutoItX3 control.
        #This will provide access to AutoItX COM API
        au3 = WIN32OLE.new("AutoItX3.Control")

        #Get the Display Image button and
        #click on it to invoke the Http Authentication dialog
        display_image_button = @driver.find_element :id => "displayImage"
        display_image_button.click

        #Wait for couple of seconds for Http Authentication
        #dialog to appear
        sleep(2)

        #Check if Http Authentication dialog exists and
        #enter login details using send method
        result = au3.WinExists("HTTP Authentication - Google Chrome")
        if result then
            au3.WinActivate("HTTP Authentication - Google Chrome","")
            au3.Send("httpwatch{TAB}")
            au3.Send("jsdhfkhkhfd{Enter}")
        end
        assert_equal 1, result
    end

    def teardown
        @driver.quit
        assert_equal [], @verification_errors
    end
end

In the previous example, Ruby's win32ole module was used to create an instance of AutoItX COM interface:

au3 = WIN32OLE.new("AutoItX3.Control")

Using this interface, the AutoIt methods are called to interact with non-web UIs.

See also

  • The Automating a non-web UI in Selenium WebDriver with Sikuli recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.255.87