Controls represent logical areas or elements within web, desktop, or mobile applications. A control could be an entire page, screen or view, it could be a logical area like a header or footer, or it could be a specific control like a button or text box.
All controls can contain child controls enabling the page object pattern encouraging maintainability.
Example
You have a HomePage and it consists of three logical areas such as the header, the footer, and the content area. Inside of the header you have
a search area. In this particular example, the search area contains a helper method to enter text and click search.
public class HomePage : WebControl //Full page control
{
//Logical area controls
public Header Header { get { return this.CreateControl<Header>(".header"); } }
public Content Content { get { return this.CreateControl<Control>(".content"); } }
public Footer Footer { get { return this.CreateControl<Footer>(".footer"); } }
}
public class Header : WebControl
{
//Logical area controls
public SearchArea SearchArea { get { return this.CreateControl<SearchArea>(".searcharea"); } }
}
public class SearchArea : WebControl
{
//Specific controls
public WebControl SearchTextbox { get { return this.CreateControl(".searchtextbox"); } }
public WebControl SearchBtn { get { return this.CreateControl(".searchbtn"); } }
/// <summary>
/// Helper to search for text.
/// 1. Enters the text.
/// 2. Clicks the search button.
/// </summary>
public void Search(string searchText)
{
this.SearchTextbox.SendKeys(searchText);
this.SearchBtn.Click();
}
}
Usage
using(var context = new WebContext(new OpenQA.Selenium.Firefox.FirefoxDriver()))
{
//Create the homepage
var homePage = new HomePage(context);
//Get a ref to the search area
var searchArea = homePage.Header.SearchArea;
//This would enter the text and click search
searchArea.Search("this is cool");
}
Creating controls across web, desktop, and mobile applications is identical. You can either create the instance yourself, or you can use our simple extension method which simplifies the process.
All controls are lazy loaded, thus when you create a control it will not search for itself straight away. This means you can create the controls you need at the top of your methods. Only when you call an action or property on the control will it perform a search.
Example
Create a control using the 'CreateControl' extension method. This method automatically attaches the context, the parent, and
adds '.sample-textbox' as a search property. Reducing the complexity of the example below.
using Aframe.Web.Controls; //Note: This is required to get the extension method!
public class Sample : WebControl
{
public WebControl SampleControl { get { return this.CreateControl<WebControl>(".sample-textbox"); } }
}
Example
Create an instance passing in a context, then set its parent and search properties explicitly.
var context = new WebContext(new OpenQA.Selenium.Firefox.FirefoxDriver());
var sampleControl = new WebControl(context);
sampleControl.SearchProperties.Add(WebControl.SearchNames.JQuerySelector, ".sample-textbox")
sampleControl.Parent = <insert parent control here> //If there is no parent, leave it as null.
By default, each control is scoped by its 'Parent'. If you use the 'CreateControl' extension method then the parent, context, and search properties are automatically mapped.
When a search is performed on a particular control, AFrame will walk up its parents all the way to the first control in the parent/child hierarchy. It will then search each of the controls 1 by 1 until it gets back to the initial control requested.
Whilst creating a control you can give it search properties. These search properties tell AFrame how and where to find the control.
You can have as many SearchProperites for a control as you like, however normally one or two will suffice.
Before we use controls we need to setup a context. Each technology (web, desktop, mobile) has a specific context which manages its own implementation.
All contexts implement IDisposable thus are supported within using statements etc. Calling .Dispose() will call the cleanup method.
A WebContext takes a 'Selenium WebDriver' as a parameter.
Example
//This uses a firefox driver, but it could be any other driver like ChromeDriver, IEDriver etc
//It can also be a RemoteWebDriver to use it with Browserstack or SauceLabs etc
using(var context = new WebContext(new OpenQA.Selenium.Firefox.FirefoxDriver()))
{
//Create the homepage
var homePage = new HomePage(context);
//Get a ref to the search area
var searchArea = homePage.Header.SearchArea;
//This would enter the text and click search
searchArea.Search("this is cool");
}
A DesktopContext doesn't take anything as a parameter, however it does store the application under test which is requried by CodedUI to work.
Example
using(var app = new DesktopContext().Launch<WinFormsApp>(<path to executable>))
{
//Click the login button inside the app.
app.LoginButton.Click();
}
Playback is a static class that has some configuration properties such as: