Introduction
In the most of web applications file uploading is not only web-based feature and requires system window activity like
opening of system dialog "Open" where you choose file(s) to upload them to web site. This window based activity is not handled by test automation frameworks and instruments.
Is it possible to handle Windows system dialog in my automated tests of web application?
Yes. It is possible using compiled Autoit scripts.
In the article we will try to automate interaction with Windows upload dialog and will learn:
- What is Autoit
- How to use Autoit
- How to write and compile Autoit script
- How to use compiled Autoit script in E2E tests
1. What is Autoit
Autoit is a freeware tool that can be used to automate interaction with Windows desktop applications, dialogs and processes like running, closing, deleting application. In general Autoit can be used in automating Windows GUI.
To automate Windows GUI Autoit v3 scripting language uses.
Autoit v3 is BASIC-like scripting language. So, be ready to be involved into learning BASIC-like syntax in this tutorial.
More information about Autoit and Autoit v3 you can find on Autoit official site.
2. How to use Autoit
First of all let's go to AutoIt downloads and download Autoit full installation.
Pass all installation steps, open Autoit3 folder and run Au3Info.exe.
This app is used for getting info about a window that will be used in programming.
Basic information about system dialog that is needed for programming of interaction with dialog is Class, Title and Instance.
To get an information about a element or a window hold on Finder Tool and move mouse to an element or a window.
Well, how to use Autoit tool is pretty clear. Let's go to the programming part.
3. Autoit scripting
The article is about automating testing of file uploading.
So, the goal is to automate interaction with "Open" Windows system dialog. Let's do it in a few steps.
Step 1
The first step is to open Notepad or your a code editor you prefer.
Start writing a script with importing necessary dependencies.
;Constants to be userd in an AutoIt v3 script. #include <AutoItConstants.au3>
Step 2
Define variable $hWnd
- the handle of the window you will interact with.
#include <AutoItConstants.au3> Local $hWnd
Step 3
We need to wait for the system dialog.
Use WinWait(WINDOW_CLASS, TITLE, TIMEOUT)
function.
Let's get WINDOW_CLASS
and TITLE
with use of Au3Info.exe (find it in Autoit installation folder).
#include <AutoItConstants.au3> Local $hWnd ;Wait 15sec for file dialog (Class #32770) with title 'Open' $hWnd = WinWait("[CLASS:#32770]","Open",15)
Step 4
We need a mechanism to put file path to the file path field of the system window. Let's get CLASS
and INSTANCE
of the file path field.
Set focus to the field and put a file path.
#include <AutoItConstants.au3> Local $hWnd ;Wait 15sec for file dialog (Class #32770) with title 'Open' $hWnd = WinWait("[CLASS:#32770]","Open",15) ;Second parameter can be empty string, because of you use class and instance to define the element ;More information about Autoit functions see here https://www.autoitscript.com/autoit3/docs/functions/ ControlFocus($hWnd, "", "[CLASS:Edit; INSTANCE:1]") ControlSetText($hWnd, "", "[CLASS:Edit; INSTANCE:1]", $CmdLine[1])
$CmdLine[1]
- the parameter will be passed to the function as a path of a file we want to upload to a web site.
You can hardcode this parameter by absolute file path (ex. "c:\upload_me.txt");
Step 5
Click by Open button.
First get CLASS
and INSTANCE
of Open button.
When we know CLASS
and INSTANCE
of Open button we are ready to click by it.
There are 2 ways to click by the element.
Way 1.
Just use ControlClick()
method.
ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1])
My experience has shown that ControlClick()
works unstable. From time to time a button is not clicked by unknown reason.
I have solved this problem by using mouse actions such as mouse move and mouse click. Let's programming it.
Way 2.
Describe variables for x, y coordinates and array with size 2 for storing Open button position.
Local $pos[2] Local $x Local $y
Get Open button position.
;ControlGetPosition returs x and y coordinates of high left corner of the button. $pos = ControlGetPos($hWnd, "", "[CLASS:Button; INSTANCE:1]")
Set the way coords will be used in the mouse functions, either absolute coords or coords relative to the current active window
;2 = relative coords to the client area of the active window AutoItSetOption("MouseCoordMode", 2)
Define $x
and $y
variables. To prevent some random failures move the mouse from high left corner to another button space by adding 10px to $x
and $y
. Feel free in playing with coordinate values!
$x=$pos[0] + 10 $y=$pos[1] + 10
And finally perform mouse left click action.
MouseClick($MOUSE_CLICK_LEFT, $x, $y, 1);
Nice! You have finished scripting. Let's see the whole script.
#include Local $hWnd Local $pos[2] Local $x Local $y $hWnd = WinWait("[CLASS:#32770]","Open",15) ControlFocus($hWnd, "", "[CLASS:Edit; INSTANCE:1]") ControlSetText($hWnd, "", "[CLASS:Edit; INSTANCE:1]", $CmdLine[1]) AutoItSetOption("MouseCoordMode", 2) $pos = ControlGetPos($hWnd, "", "[CLASS:Button; INSTANCE:1]") $x=$pos[0]+10 $y=$pos[1]+10 MouseClick($MOUSE_CLICK_LEFT, $x, $y, 1);
Save the script with .au3 extension.
3. Compile Autoit script
To use the script in automated E2E tests you need to compile the script to executable file:
- Run Autoit2Exe.exe app.
- Import saved script and click by Convert button.
Perfect, now you have executable file which can be used in E2E tests.
4. Test compiled Autoit script
Before using compiled script in E2E tests we should be sure that it works.
To test it, pass the following steps:
1.Trigger upload file dialog.
2. Run compiled script with a file path argument.
If you didn't mistakes during scripting the file should be uploaded.
5. Use the script in E2E tests.
You can extremely easy use compiled script in E2E tests.
Below you can see an example of Protractor tests.
Page object example
import { by, element, $ } from 'protractor';
import * as cp from 'child_process';
export class FileUploadingPage {
uploadButton = $('.mat-raised-button');
addFilesButton = element(by.xpath('//button[contains(@class, "add-files-btn")]'));
uploadFile(filePath) {
console.log('File path: ', filePath);
//UploadFile.exe - compiled Autoit script
cp.execSync('uploadFile.exe' + ' ' + filePath);
return Promise.resolve();
}
}
E2E test example
import { FileUploadingPage } from './file-uploading-page';
import { browser, ExpectedConditions, element, by } from 'protractor';
import { win32 } from 'path';
const path = win32;
const EC = ExpectedConditions;
const TIMEOUT = 30000;
let fileUploadingPage: FileUploadingPage;
fileUploadingPage = new FileUploadingPage();
describe('File uploading, () => {
before((done) =>
browser.get(browser.baseUrl)
.then(() => done())
.catch(done)
);
it('Upload file', (done) => {
browser.wait(EC.visibilityOf(fileUploadingPage.uploadButton), TIMEOUT)
.then(() => fileUploadingPage.uploadButton.click())
.then(() => browser.wait(EC.visibilityOf(fileUploadingPage.addFilesButton), TIMEOUT))
.then(() => fileUploadingPage.addFilesButton.click())
.then(() => {
const filePath = path.resolve(__dirname + '/test_file.txt');
return fileUploadingPage.uploadFile(filePath);
})
.then(() => done())
.catch(done);
});
});
Conclusion
From this article you have learned:
- What is Autoit and how to use it.
- How to automate interaction with Windows system dialog.
- How to use compiled Autoit script in E2E tests.
Thanks and enjoy automation!🌈🌈🌈
Don't forget to tap 💗
Top comments (6)
Hello Valeria, you can use the protractor-helper library and use the method Upload file into input field.
Hi Paulo! uploadFileIntoInputField will work only with "input" type html elements like ' input id="bla bla" '. In this case we can easily use sendKeys() method:
BUT, if html element is not "input", neither uploadFileIntoInputField nor inputHtmlElem.sendKeys(absolutePath) won't work.
Workaround I described in the post is a little bit complicated...But it helps in cases when you need to interact with not "input" html elements to upload smth to the web site :)
Thanks to explain Valeria, nice post :D
Hi Valeria, I tried following the steps mentioned, When I tried implement E2E file upload is not happening. When tried the below command from protractor.. the expected action the AutoIt suppose to do is not happening.
cp.execSync('C:/AutoIT/fileUpload.exe'+' '+'C:/AutoIT/Sample.txt');
test is passed.. but no action is performed. Can you pls suggest.
Hi! Sorry for too late answer. Does your problem still actual?
In .au3 file, trying to pass it as
ControlSetText($hWnd, "", "[CLASS:Edit; INSTANCE:1]", $CmdLine[1])
with the below typescript code
cp.execSync('uploadFile.exe' + ' ' + filePath);
But, the value is passed as empty and nothing is passed in the Open dialogue box.
When I try to keep it as $CmdLine[0] in .au3 file it sends the value in dialogue box as "1".
What I am missing here? Any suggestions!