avatarDmitry Yarygin

Summary

This text provides a tutorial on how to use WinAppDriver and Java for Windows App Automation.

Abstract

The tutorial begins by introducing the concept of Windows App Automation using WinAppDriver and Java. It explains the basics of WinAppDriver, a tool that allows for UI Automation similar to Selenium. The tutorial then guides the reader through the process of preparing their environment for Windows Automation, including installing necessary components and configuring settings. The tutorial also covers writing Windows Automation tests, locating elements for Windows Desktop Tests, and using assertions. The tutorial concludes with resources for further learning and exploration in the field of Test Automation.

Bullet points

  • WinAppDriver is a tool for Windows App Automation that functions similarly to Selenium.
  • To prepare for Windows Automation, one must install necessary components and configure settings.
  • Writing Windows Automation tests involves locating elements and using assertions.
  • Elements for Windows Desktop Tests can be located using tools such as Appium Desktop, WinAppDriver UI Recorder Tool, and Inspect tool from Windows SDK.
  • Assertions are a powerful tool used primarily in Unit Testing to check that certain conditions are met.
  • Further resources for learning about Windows App Automation and Test Automation are available.

Tutorial: Windows App Automation using WinAppDriver and Java

Photo by Caspar Camille Rubin on Unsplash

When we talk about Test Automation, the first thing that comes to mind is usually Mobile and Web Automation. However, as testers we should be aware of the latest technologies in Desktop Automation as well.

I was always curious about automating Desktop applications, but there seems to be less data online about Desktop Automation.

Let’s fill this knowledge gap by trying an interesting tool for Windows Automation — WinAppDriver. You could also follow along with a video tutorial here.

Also, if you are interested in Web Testing, consider watching my video tutorial about TestCafe and WebDriver + POM.

WinAppDriver: The Basics

WinAppDriver while executing the Automation Test script

Essentially, this is a Selenium-like UI Automation tool. It’s an Appium — compatible WebDriver server for Windows applications. It supports testing Universal Windows Platform (UWP) and Classic Windows (Win 32) applications.

What’s great about it is that it’s a standalone tool and there is no need to install Appium on your machine to run automation scripts. You just need to install WinAppDriver through the installer and use it with your favorite programming language and IDE.

Of course, you can also install Appium directly and it will include the WinAppDriver, but for our tutorial we will be installing WinAppDriver separately.

Since it has Selenium-like language, we can use syntax like this for our tests:

driver.findElementByName(“File").click();

Preparing our environment

Here is the list of components that we need for our Tests to function:

Windows 10: I use Windows 10 x64. You might be running a 32-bit version of Windows, but the only difference might be the location of some components. 
Test Application: For our tests, we will be using a default "Notepad" app available on any Windows computer. 
Location: C:\Windows\System32\notepad.exe
Windows Application Driver: The main component that we need for Windows Automation
Windows 10 SDK: To be able to inspect elements inside the application. We will use the “inspect.exe” tool for that purpose
IntelliJ IDEA: IDE that we will use for writing our tests
Java JDK: Since we are writing our tests in Java we would need this component for our tests to function.
 
Note: Java JDK could be installed automatically by using the IntelliJ IDEA.

Please download all the components using the links above (except Java JDK if you want IntelliJ IDEA to install it automatically during the project configuration) and install those. There should be nothing complicated about installing those, just follow the installation wizards.

Once we have those installed, there are a couple of things that we need to configure.

Enabling “Developer mode” in Windows 10
  1. Open the “Settings” app and look for “Developer mode”. Enable this option.
  2. Open IntelliJ IDEA and create a new project. Pick any name for the project (e.g “WindowsTest”) that you like and select “Maven” as a build automation tool from the left side. Select Java version 1.8 from the list (it will give you an option to download it).
Configuring Java version and Maven as a build automation tool

3. Start WinAppDriver. This is our key component that will be used for automating our tests.

WinAppDriver running in Command line

By default, the WinAppDriver is located here:

C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe

Also, notice that like any other Selenium — like tool it also runs as a server on a specific IP address and port. By default, it’s http://127.0.0.1:4723, and that’s what we will use in our tests.

Start the WinAppDriver session and minimize it. It’s ready to accept our test requests.

Preparing the Java project for Windows Automation

We are ready to write our Windows Tests. After creating the project, let’s configure the pom.xml located in the root of our test project and make it look similar to this:

<?xml version=”1.0" encoding=”UTF-8"?>
<project xmlns=”http://maven.apache.org/POM/4.0.0"
 xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
<groupId>org.nomadicdmitry</groupId>
 <artifactId>WindowsTest</artifactId>
 <version>1.0-SNAPSHOT</version>
 <dependencies>
 <! — https://mvnrepository.com/artifact/io.appium/java-client →
 <dependency>
 <groupId>io.appium</groupId>
 <artifactId>java-client</artifactId>
 <version>7.3.0</version>
 </dependency>
 <! — https://mvnrepository.com/artifact/org.testng/testng →
  <dependency>
 <groupId>org.testng</groupId>
 <artifactId>testng</artifactId>
 <version>7.1.0</version>
 <scope>test</scope>
 </dependency>
 <! — https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java →
 <dependency>
 <groupId>org.seleniumhq.selenium</groupId>
 <artifactId>selenium-java</artifactId>
 <version>3.141.59</version>
 </dependency>
 </dependencies>
 <properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 <maven.compiler.source>1.8</maven.compiler.source>
 <maven.compiler.target>1.8</maven.compiler.target>
 </properties>
</project>

After adding those lines, press the Maven “sync” button on the right side. We are making our test configuration similar to what we have done in this article (except adding Maven SureFire).

We are adding those three libraries to our project:

io.appium
org.testng
org.seleniumhq.selenium

Also, we are specifying that we use Java 1.8 by specifying “compiler.source” and “compile.target” values. Better to have everything explicitly specified.

We are ready to write our tests. In this case, things will be simple and we are not going to use the PageObject model. We need to create a class that will be our automation script.

Go ahead and create the “NotepadTest” class in “[project name]\src\test\java\”.

Structure of the Test Project

Writing Windows Automation Test

Here is where the fun part comes. We have discussed what application we are going to automate. Now let’s decide what Test Cases are going to look like:

Test Case #1:
1. Open “Notepad”
2. OpenHelp” menu item
3. Press “About Notepad”
4. Press “OK” button
Test Case #2:
1. Open “Notepad”
2. Type current date
3. Clear the results
Test Case #3
1. Open “Notepad”
2. OpenEdit” menu item
3. Press “Time/Date” in dropdown menu
4. Confirm that the test is displayed in "Notepad"
5. Clear the results

It’s always a good idea to write and execute those test cases manually first to understand the test flow. Here is how our code will look like for “NotepadTest” class:

public class NotepadTest {
private static WindowsDriver notepadSession = null;
public static String getDate(){
 LocalDate date = LocalDate.now();
 return date.toString();
 }
@BeforeClass
 public static void setUp() {
 try {
 DesiredCapabilities capabilities = new DesiredCapabilities();
 capabilities.setCapability(“app”, “C:\\Windows\\System32\\notepad.exe”);
 capabilities.setCapability(“platformName”,”Windows”);
 capabilities.setCapability(“deviceName”, “WindowsPC”);
 notepadSession = new WindowsDriver(new URL(“http://127.0.0.1:4723”), capabilities);
 notepadSession.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
} catch (Exception e) {
 e.printStackTrace();
  }
 }
@AfterMethod
 public void cleanApp(){
 notepadSession.quit();
 setUp();
 }
@AfterSuite
 public void tearDown(){
 notepadSession.quit();
 }
@Test
 public void checkAboutWindow() {
 notepadSession.findElementByName(“Help”).click();
 notepadSession.findElementByName(“About Notepad”).click();
 notepadSession.findElementByName(“OK”).click();
 }
@Test
 public void sendTestText(){
 notepadSession.findElementByClassName(“Edit”).sendKeys(getDate());
 notepadSession.findElementByClassName(“Edit”).clear();
 }
@Test()
 public void pressTimeAndDateButton(){
 notepadSession.findElementByName(“Edit”).click();
 notepadSession.findElementByAccessibilityId(“26”).click();
Assert.assertNotNull(notepadSession.findElementByClassName(“Edit”));
 notepadSession.findElementByClassName(“Edit”).clear();
  }
 }

Alright, what’s happening here? Let’s review the code starting from the beginning:

LocalDate date = LocalDate.now();
 return date.toString();

This function is easy to understand. We are using it to generate a current local date. Then we are converting it to a String. We will use this function further to enter this text into our Notepad window.

DesiredCapabilities capabilities = new DesiredCapabilities();
 capabilities.setCapability(“app”, “C:\\Windows\\System32\\notepad.exe”);
 capabilities.setCapability(“platformName”,”Windows”);
 capabilities.setCapability(“deviceName”, “WindowsPC”);
 notepadSession = new WindowsDriver(new URL(“http://127.0.0.1:4723”), capabilities);
Note: Highlighted "platformName" and "deviceName" properties are not necessary if you are performing tests using WinAppDriver. Those are only needed if you use Appium to clarify which platform we are using for tests.

Next, we are setting our environment for executing our tests. We are setting our executable file and specifying the IP Address and Port to run our tests on.

Those are the default parameters, but please make sure that it matches the address of the already running session of WinAppDriver that we started earlier. Those lines perform the start of the Notepad application.

There is also a 2 second timeout that we are performing before executing our tests:

notepadSession.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);

Afterwards, all that’s left to perform is pressing the buttons and typing the values. Here is the example of the button click action:

notepadSession.findElementByName(“Help”).click();
notepadSession.findElementByName(“About Notepad”).click();
notepadSession.findElementByName(“OK”).click();

Similarly, this how the text is sent to a specific element. We are taking the output of getDate() function and sending the output to a Notepad:

notepadSession.findElementByClassName(“Edit”).sendKeys(getDate());

If you are ready to execute the tests right-click and press the “Run NotepadTest” button:

Running Windows Tests

Is this everything that we need to understand how to perform tests? Almost, but not exactly. Here is the question that you probably still have in mind: “How to locate those elements in the application?”.

Locating elements for Windows Desktop Tests

To be able to click buttons and type text into the fields we need to be able to locate those elements first. We need to find “locators” for each element that we use in our tests. There are multiple ways of locating elements for our Windows Tests:

Appium Desktop: Using an Inspect session
WinAppDriver UI Recorder Tool: You can “record” and “play” all the button actions easily. Then you can pull those element locators from the source.
Inspect tool from Windows SDK: A popular tool that is used for locating elements in Windows Desktop applications

As discussed above in the article, we will be using the last tool from this list. Since we have already installed the Windows 10 SDK we should have this tool ready for use. Feel free to try other tools as well, if you wish.

The “inspect.exe” tool is located in this directory on my system:

C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\

It might a bit different in your case (if you run a 32-bit Windows system), but by default it should be in your Program Files\Windows Kits\10\bin directory.

Let’s launch the inspect.exe application and see how it could assist us.

Inspecting “Notepad” to identify the strategy for locating elements

The idea is simple. You open an application (such as “Notepad” in our case) and you point to an element that you would like to use in your tests. The Inspect app shows the corresponding information about the selected object.

How do we use it in our tests? Let’s take the example above. The use has pointed to “Time/Date” element and the app shows two locator strategies available to us:

Name: Time/Date
AutomationId: 26

Both of the locators point to the same object (“Time/Date” menu item), but if you try accessing it by “Name”:

notepadSession.findElementByName(“Time/Date”);

It won’t work in such a scenario. That’s why we are using an “AutomationId”:

notepadSession.findElementByAccessibilityId(“26”);

As you can see, the corresponding name of “AutomationId” in WinAppDriver is “AccessibilityId”. One thing to note is that the best locators are the ones that have a unique ID that is unlikely to change in the future.

There are more options available. For example, when we are typing the information inside the Notepad we are using the “ClassName” element locator:

notepadSession.findElementByClassName(“Edit”);

Assert or not Assert?

There is one case in the code that we haven’t examined yet:

Assert.assertNotNull(notepadSession.findElementByClassName(“Edit”));

An assertion is a powerful tool that is used primarily in Unit Testing. As you can see in this specific example, we are checking that the text is not empty in our Notepad.

Since we have text typed in our Notepad session, this test is going to pass. If you are curious, you could try changing the “assertNotNull” to “assertNull” and see how the test is going to perform afterward.

Conclusion

Results of Test Execution

I hope that this tutorial was useful and allowed you to jump-start into Windows Application Testing. We have not touched the PageObject/PageFactory concept in this tutorial, but if you are willing to learn more about Web Automation feel free to learn more about it in this tutorial. You can apply many concepts from that tutorial and improve our tests.

If you are looking for more Java-samples of how to use the WinAppDriver you can see samples from Microsoft. If you are a Mac user there is also an Appium Mac Driver available.

There is so much more to explore in the exciting world of Test Automation!

Test Automation
Programming
Java
Testing
Software Development
Recommended from ReadMedium