Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Automate Software using WPF UI Automation

0.00/5 (No votes)
25 Feb 2010 2  
I automated installation wizard to show the power of WPF UI Automation
Automator.gif

Introduction

In that article, I will show you a funny magic tool which can install/uninstall software automatically. Actually my intension is to show the power of WPF UI Automation. I found UI automation as a replacement of basic application testing and automate anything which we need to make repeatedly.

The article is just a sample work of how can we catch a window and follow entering and changing data in it. As an example, I am using an installation wizard.

Background

My recent development task is to automate server deployment for some of the products which are actually deploying regularly and wasting lots of time of the deployment engineers. Moreover, sometimes people make mistakes which messes up the product.

Deployment automation mainly includes making build, file copy/paste, start/stop services, setup virtual directory, and backup database, modify & run dbscripts, and so on. At the time of deployment automation, I found that I need to install and uninstall MSI file and there is no silent mode available for these MSI files but the MSI file installation wizard takes input in textbox, needs to select checkbox and so on.

Many tools are available to record the installation steps and run it according to schedule but there are many problems using these tools such as error handling, predict on a tool to run it in live server, license issue and so on. So my Chief Architect suggested that I use WPF UI Automation to make a tool which will automatically invoke button, search text box, set value in text box, change radio, measure progress and so on. I found that WPF UI Automation library is a nice step to do that and I have really done it successfully within a day.

Steps To Do

By automating the installation wizard, I will show some of the automation techniques. These are as follows:

Step 1: Search the wizard window and click next button to be forwarded. (That step will show the codes of how to find a window from the desktop and proceed invoking a button.)

Step 2: Search textbox, change text, search radio button, select radio and proceed. (That step will show the codes of how to search if any textbox is available in the present windows; if any then insert new text in it and how to select/deselect a radio button.)

Step 3: Check installation status and proceed (Every installer should have stage to wait for installation complete which normally shows progress bar, automation script needs to wait until the installation is completed. Here I will show the code to wait for a new status and proceed.)

Step 4: Close the wizard. (The simplest end of the wizard will be shown in that step.)

Step 1

Search the wizard window and click next button to be forwarded.

I1.JPG

At first, we need to search for a specific window where the automation script will execute the next steps. I called the title of the window to get the window element. The code is:

AutomationElement rootElement = AutomationElement.RootElement;
if (rootElement != null)
{
	Automation.Condition condition = 
		new PropertyCondition(AutomationElement.NameProperty, 
		"My Application Installer");
	AutomationElement appElement = 
		rootElement.FindFirst(TreeScope.Children, condition);
} 

After getting the main window, we need to click on next button to proceed. I have written a method named:

Private AutomationElement GetElementByNameProperty
	(AutomationElement parentElement, string nameValue) 

Here parameter 1 takes the parent element such as parent window, parameter 2 takes the text of the element you are searching for, not only for button will that method be used to find any element containing the name in the second parameter. The code is:

private AutomationElement GetElementByNameProperty
	(AutomationElement parentElement, string nameValue)
{
	Automation.Condition condition = 
		new PropertyCondition(AutomationElement.NameProperty, nameValue);
	AutomationElement element = 
		parentElement.FindFirst(TreeScope.Descendants, condition);
	return element;
} 

Need to invoke the button to go next.

private void ClickElement(AutomationElement element) 

The above method can click on an element; if the element is a button, then click on it, if the element is radio, then select. In future, I will modify the method for other controls too. The code is as given below:

private void ClickElement(AutomationElement element)
{
	if (element != null)
	{
		if (element.Current.ControlType.Equals(ControlType.Button))
		{
			InvokePattern pattern = 
				element.GetCurrentPattern
				(InvokePattern.Pattern) as InvokePattern;
			pattern.Invoke();
			Wait(2);
		}
		else if (element.Current.ControlType.Equals(ControlType.RadioButton))
		{
			SelectionItemPattern pattern = 
				element.GetCurrentPattern
				(SelectionItemPattern.Pattern) 
				as SelectionItemPattern;
			pattern.Select();
			Wait(2);
		}
	}
} 

Step 2

Search textbox, change text, search radio button, select radio and proceed.

I2.JPG

In that stage, I will show a method which can search if any textbox is available in the present window and it inserts data as well in any textbox found.

private bool SetValueInTextBox(AutomationElement rootElement, string value)

The code is as given below:

private bool SetValueInTextBox(AutomationElement rootElement, string value)
{
	Automation.Condition textPatternAvailable = 
		new PropertyCondition
		(AutomationElement.IsTextPatternAvailableProperty, true);
	AutomationElement txtElement = 
		rootElement.FindFirst(TreeScope.Descendants, textPatternAvailable);
	if (txtElement != null)
	{
		try{
			Console.WriteLine("Setting value in textbox");
			ValuePattern valuePattern = 
				txtElement.GetCurrentPattern
				(ValuePattern.Pattern) as ValuePattern;
			valuePattern.SetValue(value);
			Wait(2);
			return true;
		}catch{
			Console.WriteLine("Error");
			return false;
		}
	}
	else
	{
		return false;
	}
}

After inserting data in the textbox, we have 2 radio buttons to select/deselect, radio button can be selected/deselected in the same way as the button which I have described in step one next button click.

Step 3

Check installation status and proceed.

I4.JPG

In my automation, I need to wait for a window before completing installation, that means I need to wait for something. I found that the progress bar is the right control to pick and wait.

private void WaitUntilInstallationComplete(AutomationElement appElement) 

This method mainly waits until the installation is completed which means the progress bar ended. The code for the method is as follows:

private void WaitUntilInstallationComplete(AutomationElement appElement)
{
	AutomationElement status = null;
	Automation.Condition statusPatternAvailable = new PropertyCondition
		(AutomationElement.IsRangeValuePatternAvailableProperty, true);
	int numWaits = 0;
	do{
		Console.WriteLine(numWaits + "Waiting for close button");
		status = appElement.FindFirst
			(TreeScope.Descendants, statusPatternAvailable);
		++numWaits;
		Wait(5);
		} while (status != null && numWaits < 50);
} 

Step 4

Close the wizard.

I5.JPG

At the end, we have a close button to invoke and complete installation, same as the next button I described in step 1. Call the close button and invoke the wizard to be closed.

Points of Interest

This is really fun to automate something like that. Software testers can use the example to automate Windows application testing.

History

  • Version 1: Feb 23, 2010

References

Some of the blog posts and articles helped and inspired me to develop such a tool using WPF. Here are some links. I apologize if I forgot some of the links:

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here