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.
Download and install AutoIt tools from http://www.autoitscript.com/site/autoit/downloads/.
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:
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.
Let's create an AutoIt script that works with the Open dialog box.
.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
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.OpenDialogHandler.exe
and validate that the specified file is uploaded on the page.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(); } }
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""});
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:
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.
3.144.255.87