Skip to content

Commit

Permalink
Moving docs into docs folder for ReadTheDocs
Browse files Browse the repository at this point in the history
  • Loading branch information
JakeGinnivan committed Jan 9, 2016
1 parent 10b00b1 commit e3ee19f
Show file tree
Hide file tree
Showing 50 changed files with 1,569 additions and 0 deletions.
24 changes: 24 additions & 0 deletions docs/Advanced Topics/ContinuousIntegration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
layout: layout
title: Continuous Integration
---

White drives the mouse and keyboard for it's automation, and only falls back to the automation API's when it can't use the mouse/keyboard. This simulates real world behavior more than using automation directly.
This means that White has to run on an UNLOCKED desktop.

Here is a list of my setup requirements when I create a UI test agent:

- The build agent running as a Console agent (both TFS and TeamCity support this) and set it to automatically start on boot
- Automatic logon setup (Use [SysInternals Autologon for Windows](http://technet.microsoft.com/en-us/sysinternals/bb963905.aspx) as it encrypts your password in the registry)
- Screensaver disabled
- Disable Windows Error Reporting. View on Gist: [DisableWER.reg](https://gist.github.com/JakeGinnivan/5131363)
- VNC installed and connect via VNC, *not remote desktop*
- When you connect using Remote desktop, then disconnect, the desktop will be locked, and UI Automation will fail
- Personally I use [Tight VNC](http://www.tightvnc.com/) with the [DFMirage driver](http://www.tightvnc.com/download.php)
- I also put a shortcut (cmd) which restarts the PC on the desktop `shutdown -r -t 0`. Useful for when you connect via Remote Desktop, you can then reboot, and auto login will make sure your test agent is good to go when it comes back up!

Make sure that, while running these tests you would need to make sure that there aren't applications which would show windows while test is running. e.g. new chat message window coming up in restored or maximum mode. (I am not going into this here but there are ways to do this, like get the Yahoo Messenger new message window can be made to show as minimized).

You might have issues running it in CI, if the server runs as windows service. Allowing the service to "interact with the desktop" might help. (This can be set from the service properties log-on tab)

Please choose user version of windows instead of server versions. i.e. XP/Windows7 over Windows2003/Windows2008. The automation support for UIA is generally poor in server editions of windows.
54 changes: 54 additions & 0 deletions docs/Advanced Topics/CustomUIItems.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
layout: layout
title: Custom UI Items
---
Fundamentally all UIItems are either elementary (Label, e.g. having no other item in it) or composed of other UI Items. In white there is in-built support for standard UIItems. These are called standard mainly because of their prevalent use and ready availability in development environments.
When we use "third party controls", this might not be enough. Even though these UI Items are still made up of elementary items and can be automated by finding them individually. But we might miss some abstraction while doing this. Also we need build a lot of things in these items ourselves which are already done in white for other items. This is where Custom UI Item would be useful.

Sample code of a Date control which consists of three text boxes for day, month and year. (See the inline comments)

//Specify the ControlType which corresponds to the top level of Custom UI Item.
//White needs this when finding this item inside the window.
[ControlTypeMapping(CustomUIItemType.Pane)]
public class MyDateUIItem : CustomUIItem
{
// Implement these two constructors. The order of parameters should be same.
public MyDateUIItem(AutomationElement automationElement, ActionListener actionListener)
: base(automationElement, actionListener)
{
}

//Empty constructor is mandatory with protected or public access modifier.
protected MyDateUIItem() {}

//Sample method
public virtual void EnterDate(DateTime dateTime)
{
//Base class, i.e. CustomUIItem has property called Container. Use this find the items within this.
//Can also use SearchCriteria for find items
Container.Get<TextBox>("day").Text = dateTime.Day.ToString();
Container.Get<TextBox>("month").Text = dateTime.Month.ToString();
Container.Get<TextBox>("year").Text = dateTime.Year.ToString();
}
}

This is how it can be used.
MyDateUIItem myDateUIItem = window.Get<MyDateUIItem>("dateOfBirth");
Assert.AreNotEqual(null, myDateUIItem);
myDateUIItem.EnterDate(DateTime.Today);

If you have downloaded the source code you can find all of this in CustomItemTest.cs

### What do I need to do when the CustomUIItem type is not specified is not defined in the source code already?
These are the places where you need to make the change.
1. Add your type in CustomUIItemType
1. Add the mapping to UIAutomation ControlType

mappings[CustomUIItemType.Table] = System.Windows.Automation.ControlType.Table;

### What happens to the extended controls? e.g. I extend TextBox in the code and use MyTextBox.
In such a case the it would remain as TextBox for white.

## Subclassing CustomUIItems
- Since the object has to be constructed by white. You need to define the same constructors in the subclass.
- The CustomUIItem type attribute should be redefined in the subclass.
32 changes: 32 additions & 0 deletions docs/Advanced Topics/Localisation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
layout: layout
title: Localisation
---
White uses text internally to find UIItems. These string differ based on locale. e.g. in Table(DataGrid) the header, row header etc, or scroll bars, are identified by some names given to them. These don't work in locales which are not english based. While doesn't provide all the locale values but allows you to configure these text.
In the app.config define sections as:

<sectionGroup name="White">
....
<section name="UIItemId" type="System.Configuration.NameValueSectionHandler"/>
</sectionGroup>
<White>
...
<UIItemId>
<add key="TableVerticalScrollBar" value="Vertical Scroll Bar"/>
</UIItemId>
</White>

Like other configuration these can be set programmatically as well.

UIItemIdAppXmlConfiguration.Instance. TableVerticalScrollBar = "Vertical Scroll Bar";

Configurable values are:

TableVerticalScrollBar=Vertical Scroll Bar
TableHorizontalScrollBar=Horizontal Scroll Bar
TableColumn=Row
TableTopLeftHeaderCell=Top Left Header Cell
TableCellNullValue=(null)
TableHeader=Top Row
HorizontalScrollBar=Horizontal ScrollBar
VerticalScrollBar=Vertical ScrollBar
16 changes: 16 additions & 0 deletions docs/Advanced Topics/MouseAndKeyboard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
layout: layout
title: Mouse and Keyboard
---

## Using keyboard/mouse directly
Ideally you don't need to use these directly but if you do want to use. If you do want to use it then please use window.Keyboard and window.Mouse instead on instantiating a new window. The different between these two is that the use of Keyboard.Instance gives you raw keyboard and any operation performed on it would not wait till the window is busy. You can call window.WaitForInputIdle as well.

Moving the mouse to a particular location
var point = new Point(100, 100);
mouse.Location = point;

Moving the mouse to a particular UI Item
mouse.Location = uiItem.Bounds.Center(); //Please see the class RectX to see options of different locations to which a mouse can be moved.

Sometimes you do not want to use mouse to be used for click and directly use the pattern provided by the UI Automation framework. You can use RaiseClickEvent event method on any UI Item as long as it supports InvokePattern. If it doesn't support the pattern then this would result in no-op.
29 changes: 29 additions & 0 deletions docs/Advanced Topics/PositionBasedSearch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
layout: layout
title: Position Based Search
---

### Speed up performance by Position based search

Performance of finding UIItems (based on search criteria) is proportional to the number of items on a window. A UIItem is found by enumerating over all the controls in a window (at windows messages level, everything is a window, try spy++ to understand this better). Smaller the scope of faster would be search. Position based search is based on this idea.

When finding a window from an application or another window you need to specify the identification of the window. This identification has to be unique as this is the identification for the cache. This cache is stored in the xml file. Duplicate identification would not cause any failures but you would not get benefit of position based search in such cases. This is how to do this.

Window window = application.GetWindow("Customer - Foo", InitializeOption.NoCache.AndIdentifiedBy("Customer"));

The identification is tied to the type of window and not instance of window. So even if I was doing this somewhere else in the code where my customer name is "Bar" I would do this.

Window window = application.GetWindow("Customer - Bar", InitializeOption.NoCache.AndIdentifiedBy("Customer"));

Similarly for modal windows same applies:

Window modalWindow = window.ModalWindow("Address - Home", InitializeOption.NoCache.AndIdentifiedBy("Address"));

You also need to do

application.ApplicationSession.Save();

at the end of the test (or after killing the application).

White remembers the position of UIItems on a window when you run your program for the first time and stores it on the file system as an xml file (see Configuration for setting the directory). In the next run it finds the UIItems based on the position of UIItem which is very fast because there is only one item at the point. If the item is not found at the position it would perform the normal search.
The position which is saved in xml file is relative to the window, hence change in position of window doesn’t affect position based find. Changes in layout of items in a window are taken care of by overwriting the position when it changes. You need to delete these files when you switch to new version of white. After first run they would be cached again.
16 changes: 16 additions & 0 deletions docs/Advanced Topics/SearchDepth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
layout: layout
title: Controlling Search Depth
---

- UI Automation provides two approach for querying the UIAutomation tree of an automation element.
- Search on automation element tree: In this search the API user specifies the criteria and scope of the search. The scope is of two levels children or descendant. This is simpler API as the user doesn't need to match against every element.

Search during automation element tree navigation: In this search the user is provided with tree navigation calls which the she can use to search the elements among other things. This provides complete freedom to the user at the cost of simplicity of API.
White until release 0.19 used only the first approach. With 0.20 one can configure search based on tree navigation using the RawElementBasedSearch property in Configuration file. This property is used along with MaxElementSearchDepth property which indicates the depth of navigation, white should perform when using this mode. Hence, if you have a very deep tree but you hope to find your UI Items within 4 levels then you can set RawElementBasedSearch=true and MaxElementSearchDepth=4, and this would perform much better than when RawElementBasedSearch=false. Like most other configuration this can be set programmatically using CoreAppXmlConfiguration.Instance.

CoreAppXmlConfiguration.Instance.RawElementBasedSearch = true;
CoreAppXmlConfiguration.Instance.MaxElementSearchDepth = 2;
var listView = window.Get<ListView>("listView");
// or any of other execution in white would use search depth of 2
CoreAppXmlConfiguration.Instance.RawElementBasedSearch = false; // white starts using regular search
17 changes: 17 additions & 0 deletions docs/Advanced Topics/ThirdPartyControls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
layout: layout
title: Third Party Controls
---

White provides support for all the controls which comes with standard .NET libraries. This support is partially just abstraction over UIAutomation and window messages. So, in case of third party controls like DevExpress, PureComponents etc, there are no standard UIItem implementation in white which you can use out of the box. The reason being the automation element structure beneath is unique to each of them. These Custom UI Item can be plugged in to white.
While implementing these you might face issues. Some known issues and possible resolution is provided below. Soon we would have a sample for each of them available here:

## Do not rely on UISpy
UISpy comes along with .NET SDK. Please do not trust UISpy, it doesn't tell everything even for standard controls. You can use LogStructure() method to see what is present inside the control. This method is available on all the UIItems including window. It prints out the entire UIA tree which is helpful, if you are having problem finding UIItems. The structure would be logged in log file (and console if configured) as configured in log4net Configuration.
A lot of people on the white forums have been successful with http://www.codeplex.com/UIAutomationVerify for the same.

## Silverlight
Some of the controls http://msdn.microsoft.com/en-us/library/cc645045(VS.95).aspx?ppud=4 which come with silverlight do not have built-in support for UIAutomation. Hence white cannot recognize them.

## Focusing the UIItem
...using Focus method, sometimes activates the UIAutomation to fetch the internal elements.
25 changes: 25 additions & 0 deletions docs/Advanced Topics/UIAv3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
layout: layout
title: UIA v3/COM Api
---
White will soon be running against the [UIA COM Wrapper](https://github.com/JakeGinnivan/UIAComWrapper) which means that White can support and will expose UI patterns for Virtualisation, and also add support for WinRT applications.

# Breaking Changes
Unfortunately, this will not be a perfectly clean upgrade. There are many small behavior differences, and some more fundamental changes.

For example, SWA would return a control type of `document` for a multi-line textbox in Windows forms, in the COM UIA Api the control type that is exposed is `edit`. But WPF will still have a control type of This means that with the UIA Com wrapper, a multi-line textbox in WPF you would use the MultiLineTextBox control in White, but in WinForms you would just use TextBox.
There are a number of different controls which have changed slightly, and I will do my best to document changes below.

## Behavior changes
- Combo-box items no longer are visible to UIA while closed

## Control changes
A few controls will change, for these changes, White will throw meaningful exceptions along the lines of

The MultiLineTextBox control is no longer supported in Winforms due to a change in UIA 3.0, please use the TextBox or WinFormTextBox instead.

### Conversion list

Windows Forms:
- MultiLineTextBox -> TextBox
- ListView -> ListBox
Loading

0 comments on commit e3ee19f

Please sign in to comment.