Introduction
The code in this article facilitates out of process UI automation with Silverlight applications. Mouse and Keyboard commands are simulated to create broad scenario based automated tests.
Background
In September 2008, I was tasked with writing automated UI tests for a Silverlight application. The client was pushing the immature technology to its limits with a complex and fully featured enterprise application. I was brought into the project late and had a slim choice in terms of existing tools to get the job done.
Microsoft’s UI Automation framework proved to be unreliable when used with the application. This was reflected by ‘UI Spy’ often not finding UIElements it had previously been able to locate or if they were located it couldn't deal with the 3rd party Telerik controls. The ‘White’ project uses the UI Automation framework and therefore had the same issues.
Art of test supports Silverlight with its excellent Internet Explorer automation tool WebAii. To date, none of the releases have worked with the application I needed to test. I'm sure in the future these problems will be solved but until then these are the techniques I used to allow automated testing to go ahead with the project in question.
Using the Code
The ultimate aim was that any automated tests written would be easy to follow for non-technical testers and completely abstract any of the underlying implementation.
AutomatedSampleApplication
This class represents the Silverlight application being tested and is the entry point for any automated interaction with the application.
AutomatedElement
Objects of this type are used to represent any UI Element and provide UI interactions that may be performed against them. The information required to perform the UI tasks is requested from the application itself via JavaScript.
For example, the Click
function requests that the application scroll to the element, retrieve its screen co-ordinates and then uses WebAii to ensure the window has focus and sends the click event to the screen position.
public void Click()
{
Parent.RunJScript(EntryPointAccessor + ".ScrollToElement
(\"" + ElementName + "\")");
var elementPoint = GetUIElementPosition();
Global.BlockInput(true);
Parent.myManager.ActiveBrowser.Window.SetActive();
Parent.myManager.ActiveBrowser.Window.SetFocus();
Thread.Sleep(100);
Parent.myManager.Desktop.Mouse.Click
(MouseClickType.LeftClick, elementPoint.X, elementPoint.Y);
Global.BlockInput(false);
}
A reference to the Silverlight plug-in is obtained for the RunJScript
function using the onLoad
event in the HTML page:
var plugin = null;
function pluginLoaded(sender, args) {
plugin = sender.getHost();
}
<param name="onLoad" value="pluginLoaded" />
ScriptEntryPoint
Within the Silverlight application, the ScriptEntryPoint
class registers entry point objects that represent the different views in an application. This serves as a bridge between AutomatedElement
and ElementAccessor
.
ElementAccessor
This class actually implements the actions that have been requested from the AutomatedElement
class.
Some of the code runs within the Silverlight application by the Click
function in AutomatedElement
:
public string GetUIElementPosition(string ElementName)
{
var point = GetUIElementPositionPoint(ElementName);
if (point.X == 0 && point.Y == 0)
return "ELEMENT NOT FOUND";
return string.Format("{0},{1}", point.X, point.Y);
}
Tests
The resulting tests make it obvious what part of the application we are sending UI actions to and are relatively easy to understand.
[Test]
public void SubmitTest()
{
SampleApp.mainPage.Submit.Click();
SampleApp.sideView.NameEdit.SetText("Hello from Automated UI Testing!!");
SampleApp.sideView.SubmitButton.Click();
Assert.AreEqual("Hello from Automated UI Testing!!",
SampleApp.sideView.TextOut.GetTextBlockString(), "Incorrect output text");
}
History
- 6th April, 2009: Initial post