Advanced WPF automation – working with WinForms grid

Last Updated on by

Post summary: Example how to work with WinForms grid with TestStack White.

TestStack White is a really powerful framework. It works on top of Windows UI Automation framework hiding its complexity. If White is not able to locate element you have access to underlying UI Automation and you can do almost anything you need.

Reference

This post is part of Advanced WPF desktop automation with Telerik Testing Framework and TestStack White series. The sample application can be found on GitHub.

MainGrid

For single responsibility separation grid logic is in separate class MainGrid.cs. The constructor takes White.Core.UIItems.WindowItems.Window object. Inside the window, we search for an element with control type ControlType.Table. It is the only one of its kind. If there are more we should narrow down the SearchCriteria.

public class MainGrid
{
	private Table table;
	public MainGrid(Window window)
	{
		SearchCriteria search = SearchCriteria.ByControlType(ControlType.Table);
		table = window.Get<Table>(search);
	}

	public string GetCellText(int index)
	{
		TableCell cell = GetCell(index);
		string value = cell.Value as string;
		return value;
	}

	public void ClickAtRow(int row)
	{
		TableCell cell = GetCell(row);
		Point topLeft = cell.Bounds.TopLeft;
		topLeft.X += 5;
		topLeft.Y += 5;
		Mouse.instance.Click(topLeft);
	}

	private TableCell GetCell(int index)
	{
		TableRows rows = table.Rows;
		TableCells cells = rows[index - 1].Cells;
		return cells[0];
	}
}

Access the grid

MainGrid is property inside MainWindow page object. On access to the property new object is instantiated. This might lead to performance issues if grid search and instantiation is slow. So, in this case, you can use Singleton design pattern. Singleton might lead to issues with old object state which will be hard to debug. It depends what your priorities are.

public class MainWindow : XamlElementContainer
{
	public static string WINDOW_NAME = "MainWindow";
	private Application app;
	private string mainPath =
		"XamlPath=/Border[0]/AdornerDecorator[0]/ContentPresenter[0]/Grid[0]/";
	public MainWindow(VisualFind find, Application application)
		: base(find)
	{
		app = application;
	}

	private MainGrid MainGrid
	{
		get
		{
			return new MainGrid(app.GetWindowByName(WINDOW_NAME));
		}
	}

	public void ClickTableAtRow(int row)
	{
		MainGrid.ClickAtRow(row);
	}

	public Verification VerifyTableCell(int index, string text)
	{
		return BaseTest.VerifyText(text, MainGrid.GetCellText(index));
	}
}

Conclusion

TestStack White is a powerful framework. It will be perfect if you can do the job without it. If you cannot you are lucky it exists.

Related Posts

Read more...

Advanced WPF desktop automation

Last Updated on by

Post summary: In this series of posts I’ll expand the examples and ideas started in Automation of WPF applications series.

Telerik Testing Framework and TestStack White are powerful tools for desktop automation. You can automate almost everything with a combination of those frameworks. This series of posts will give more details how to automate more complex applications.

Reference

Code samples are located in GitHub SampleAppPlus repository. Telerik Testing Framework requires installation as it copies lots of assemblies in GAC.

SampleAppPlusThere is SampleAppPlus which is actually a dummy application with only one purpose to be used to demonstrate automation principles. With this application, you can upload an image file. Once uploaded image is visualized. The image path is listed in a table. The image path is also visualized as an image in a custom control in the bottom of the main window. The user is able to add more text which is added to the table as long as editing already existing text. Add and edit are reflected on custom image element.

Topics

  • Page objects inheritance of similar windows
  • Working with WinForms grid
  • Windows themes and XamlPath
  • Read dependency property
  • NTestsRunner in action
  • Extension methods
  • Memory usage

Page objects inheritance

It is common to have similar windows in an application. Each window is modeled as page object in automation code. If windows are also similar in terms of internal structure it is efficient to re-use similar part and avoid duplications. Re-use is achieved with inheritance. Given SampleAppPlus application has very similar windows for adding and editing text. Code examples show how to optimize your effort and re-use what is possible to be re-used. More details can be found in Advanced WPF automation – page objects inheritance post.

Working with WinForms grid

As mentioned before Telerik Testing Framework is not very good with WinForms elements. This is the main reason to use TestStack White. It is not very likely to have WinForms elements in WPF application but in order to complete the big picture I’ve added such grid in a SampleAppPlus application. Code examples show how to manage WinForms grid. More details can be found in Advanced WPF automation – working with WinForms grid post.

Windows themes and XamlPath

In given examples elements are located with exact XamlPath find expression. This approach has a serious problem related to Windows themes. For complex user interfaces, XamlPath could be different on a different theme. Windows Classic theme sometimes produces different XamlPath in comparison with standard Windows themes. Yes, it is no more available from Windows 8 but Server editions are working only with Windows Classic theme. So one and the same tests could have differences. I couldn’t find a way to automatically detect which is current theme. The solution is to have different XamlPath for both standard and classic themes. Once you have it you can switch them manually with some configuration or you can try to automate the switch by locating element for which you know is different and save variable based on its location result.

Read dependency property

A dependency property is a way in C# to extend the standard provided functionality. It can happen in a real application that developers use such functionality. Given SampleAppPlus application has a special element with dependency property. Code examples show how to extract property value and use it in your tests. More details can be found in Advanced WPF automation – read dependency property post.

NTestsRunner in action

I’ve introduced NTestsRunner which is a custom way for running functional automated tests. Code samples show how to use it and create good tests that are run only with this tool.

Extension methods

Extension methods are one extremely good feature of .NET framework. I personally like them very much. I assume everyone writing code in C# is aware of them. Still, in code examples show how they can be used.

Memory usage

Memory is not a problem on small projects. But when the number of tests continue to grow it actually becomes a problem. More details can be found in Advanced WPF automation – memory usage post.

Related Posts

Read more...

WPF automation – locating and structure of WinForms elements

Last Updated on by

Post summary: Guide how to locate WinForms elements with TestStack White.

References

This post is part of Automation of WPF applications with Telerik Testing Framework and TestStack White series. The sample application can be found in GitHub SampleApp repository.

WinForms elements manipulation with TestStack White

MessageBox.cs class is a representation of a MsgBox of our sample application which is WinForms.

using System.Windows.Automation;
using White.Core.UIItems;
using White.Core.UIItems.Finders;
using White.Core.UIItems.WindowItems;

namespace SampleApp.Tests.Framework.Elements
{
	public class MessageBox
	{
		private Window win;
		public MessageBox(Window window)
		{
			win = window;
		}

		private Button Button_OK
		{
			get
			{
				return win.Get<Button>(
					SearchCriteria.ByControlType(ControlType.Button).
					AndByText("OK"));
			}
		}
		private Label Label_Text
		{
			get
			{
				return win.Get<Label>(
					SearchCriteria.ByControlType(ControlType.Text));
			}
		}

		public void ClickOkButton()
		{
			Button_OK.Click();
		}

		public string GetText()
		{
			return Label_Text.Text;
		}
	}
}

MessageBox is following Page Object design pattern. Elements are private properties. Actions are public methods acting on elements. Again: one element must be defined in only one place.

Constructor receives an instance of the current window object. Elements are located by White framework method:

public virtual T Get<T>(SearchCriteria searchCriteria) where T : UIItem;

SearchCriteria

SearchCriteria is used for locating elements. Search is possible with a combination of following criteria: Text, ControlType, AutomationId, NativeProperty, Framework. And here comes the hardness of working with White in complex UIs. There may be several TextBox-es (ByControlType == Edit) AND with no text inside (AndByText == “”). You can take them all and then access by index the one which is proper for your test. And what happens when you fill text in one of them. Next find has one less window. If you think it is easy then enjoy, I would rather not do it.

UISpy

Finding of the proper SearchCriteria is done with powerful tool UISpy.exe. Unfortunately, this one is deprecated from Windows 8. MS have added a replacement called Inspect.exe. I don’t find it useful this is why I have added UISpy.exe in the GitHub repository.

UISpy

Dialog is the message box window which is a child of MainWindow. It has empty title and two elements: OK button and message text. Current example shows the location of the text element. Its MS ControlType == ControlType.Text. This is what we need to locate it since there is only one such element in the message box. Once we have it we take the text and test compares current vs. expected text. OK button is located by ControlType and text. In case of different localisations we may leave just the ControlType, but if there are more buttons text is mandatory to distinguish the correct button.

Once you have defined your page objects it is time to assemble them. Next post is WPF automation – locating and structure of WPF elements.

Related Posts

Read more...

WPF automation – projects structure

Last Updated on by

Post summary: How to structure projects in the course of WPF automation.

References

This post is part of Automation of WPF applications with Telerik Testing Framework and TestStack White series. The sample application can be found in GitHub SampleApp repository.

Overview

For better maintainability and good design, automation testing is separated into two projects. One is the so-called framework project. It has knowledge about third used party frameworks (Telerik Testing Framework, TestStack White, Selenium, Watij, etc.). It operates on elements via those third-party frameworks. Framework exposes actions that are building blocks of the tests. The other project is the tests. It doesn’t know anything about used automation frameworks. It uses methods exposed by an internal framework and builds the tests with them. The idea is that one team/person with development knowledge can be responsible for the internal framework, others can be responsible for writing well-designed tests using the internal framework only. Another benefit of two projects is the ability to completely change internal framework project without affecting test logic at all. Here is the structure of my sample projects:

Projects structure

Projects structure

SampleApp – This is the application under test. Generally, it is not in the test project, you receive it from developers or from nightly build or from some other place. For the purpose of this demo, I’ve created a very basic application that uploads an image and shows it inside. There is attached image (HappyFace.jpg) that is used in the tests.

SampleApp.Tests – Here is the most important artifact – the tests, the purpose of all this fuss. In the demo, this is made as UnitTest with MS Unit Testing Framework. You can use whatever run strategy you like – another unit testing framework (xUnit, nUnit, etc.) or you can build your own tests runner. I have built my own tests running because by definition unit tests should be independent of each other thus MS Unit Testing Framework runs them in random order. It might be possible to manage order, but this will require managing of some sort of external files. It gives too much overhead to me.

SampleApp.Tests.Framework – This is where the interesting part is. Here are the elements – main application form (WPF), message boxes shown on success or error (WinForms) and open file dialogue (WinForms). MainWindow is manipulated with Telerik Testing Framework, other two are manipulated with White. App.cs is a holder which represent application itself and elements are accessible through it. BaseTest holds an instance of App. It is extended by UnitTests and App and its elements are accessible.

Next post is WPF automation – locating and structure of WPF elements in the code.

Related Posts

Read more...

Automation of WPF applications

Last Updated on by

Post summary: Overview how to successfully automate WPF application with Telerik Testing Framework and TestStack White.

I’ve spent lots of time in automation of a WPF application. Nowadays the world is dealing with web application and desktop application are fading away. Nevertheless, desktop applications still have their own private space and I hope these series of posts will be useful to someone.

Preface

An application under test is created with WPF but has WinForms grids included on different windows presenting lots of information. Performance is the main reason to use WinForms grids inside a WPF application. WPF grid with 40 columns and 100 rows lags a lot. After research and proof of concept of commercial and open source tools and frameworks, two were chosen: Telerik Testing Framework and TestStack White. They provide flexibility and maintainability which is so vital in a fast-changing application. Both are used with C#. Every one has its own weaknesses and strengths but both made a perfect synergy to provide you the possibility to automate almost everything.

Telerik Testing Framework

Extremely powerful and free to use framework. You can purchase additional support which is at reasonable prices. Telerik also provides Test Studio, a tool and MS Visual Studio plug-in, build on top of the framework. This is also an option, but for me using a tool gives more restrictions than benefits. Their framework is the best available for testing WPF applications. It is very easy to use. Elements are easily located by XamlPath (very similar to XPath). Of course, there are other locate options. The framework provides very rich API with lots of operations over the elements. Still, its powerfulness is limited to WPF. It is not that good with WinForms elements. Telerik Testing Framework requires installation as it copies lots of assemblies in GAC.

TestStack White

Extremely powerful open source framework. Build as a wrapper of Microsoft UI Automation framework you can automate almost everything with it. But this comes at a price. It is hard to locate elements. I use it only where Telerik Testing Framework is not capable to do the work – WinForm grids, context menus, closing windows with small X in the top right corner?! Yes, those are WPF inside but are hosted in operation system window and Telerik has no access to it.

In GitHub, I have uploaded an MS Visual Studio 2013 project with very simple application taken from this example. I have added very basic tests to it to illustrate how it is done. With upcoming posts, I’ll explain in details the idea and implementation.

Below is a list of posts included in the series:

  1. Introduction (current post)
  2. WPF automation – projects structure
  3. WPF automation – locating and structure of WPF elements
  4. WPF automation – locating and structure of WinForms elements
  5. WPF automation – using the elements
  6. WPF automation – running the tests

Related Posts

Read more...