DEV Community

Valeria
Valeria

Posted on

How to automate file upload testing with Autoit and Protractor

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.

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.

Window info app

Basic information about system dialog that is needed for programming of interaction with dialog is Class, Title and Instance.

Winfow info

To get an information about a element or a window hold on Finder Tool and move mouse to an element or a window.

Finder tool

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&gt

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).

Get Window class

#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.

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.

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:

  1. Run Autoit2Exe.exe app.
  2. Import saved script and click by Convert button.

Convert to exe

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.

File uploading

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();
  }
}
Enter fullscreen mode Exit fullscreen mode

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);
  });
});
Enter fullscreen mode Exit fullscreen mode

Conclusion

From this article you have learned:

  1. What is Autoit and how to use it.
  2. How to automate interaction with Windows system dialog.
  3. How to use compiled Autoit script in E2E tests.

Thanks and enjoy automation!🌈🌈🌈
Don't forget to tap 💗

Top comments (6)

Collapse
 
paulogoncalvesr profile image
Paulo Gonçalves • Edited

Hello Valeria, you can use the protractor-helper library and use the method Upload file into input field.

Collapse
 
valeria profile image
Valeria • Edited

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:

inputHtmlElem.sendKeys(absolutePath)

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 :)

Collapse
 
paulogoncalvesr profile image
Paulo Gonçalves

Thanks to explain Valeria, nice post :D

Collapse
 
pradeepsankran1 profile image
Pradeep Sankranthi

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.

Collapse
 
valeria profile image
Valeria • Edited

Hi! Sorry for too late answer. Does your problem still actual?

Collapse
 
ashokkumarg profile image
Ashok kumar

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!