bewildr

Test WPF UI apps with IronRuby!

Written by Nat Ritmeyer (www.natontesting.com)

Intro

Documentation is on the way; until then, take a look at the tests or read the API overview below.

Getting started

Dependencies

  1. Install .net 3 and 4 (www.microsoft.com/downloads/details.aspx?FamilyID=10cc340b-f857-4a14-83f5-25634c3bf043&displaylang=en & msdn.microsoft.com/en-us/netframework/aa569263.aspx)

  2. Install the latest ironruby (ironruby.codeplex.com/), and for your own sanity install it in c:\\ironruby instead of the default location.

  3. You’ll need at least rubygems version 1.3.6:

gem update --system

Installation

gem install bewildr --no-rdoc --no-ri

To use bewildr:

require 'bewildr'

API Overview

Application Management

Start an app

@app = Bewildr::Application.start('notepad')
@app = Bewildr::Application.start('c:/windows/notepad.exe')

Start an app and wait for a particular window:

@app, @window = Bewildr::Application.start_app_and_wait_for_window('notepad', 'Untitled - Notepad')

or (taking a regex for the window title instead of a string - tests become more robust):

@app, @window = Bewildr::Application.start_app_and_wait_for_window('c:/windows/notepad.exe', /.* - Notepad/)

Kill an app

@app.kill
@app.running? == false
@app.should_not be_running

Window Management

Get application windows:

All windows belonging to an app:

@all_windows_for_my_app = @app.windows

Window with a particular name:

@main_window = @app.window('My App 1.0')

Window with a particular name (find window using regex instead of string):

@main_window = @app.window(/My App .*/)

Basic Element Interaction

Find an element by its automation id:

my_button = @window.get(:id => 'my_button')

Find an element by its type:

@all_buttons = @window.get(:type => :button)

Find an element by its name:

my_button = @window.get(:name => 'Click Here')

Find an element by a combination of criteria:

@main_window.get(:type => :hyperlink, :name => "Link Text")

Click a button:

@window.get(:id => 'my_button').click

Element State

Check for existence/enabled state of an element:

@window.get(:id => 'some_element').exists?
@window.get(:id => 'some_element').enabled?

…which allows for some nice idiomatic test code if you’re using rspec:

@window.get(:id => 'some_element').should_not exist
@window.get(:id => 'some_element').should be_enabled

Wait for an element to exist:

@window.wait_for_existence_of(:id => "an_object")

Wait for an element to disappear:

@window.wait_for_non_existence_of(:id => "an_object")

The wait_for_existence_of method can be called recursively:

@window.wait_for_existence_of(:id => "an_object").wait_for_existence_of(:id => "child_object")

The line above will result in waiting for ‘an_object’, and once it has appeared it’ll wait for an object below it in the object hierarchy called ‘child_object’.

Background story

I’ve recently being testing a WPF app. I wrote some classes to wrap the White automation library (white.codeplex.com/) using IronRuby to allow the WPF app tests to be written in ruby - the same language as the tests for the other systems. Due to some performance issues and a number of bugs, I ended up rewriting large chunks of the functionality of white by directly talking to the MS Automation API (msdn.microsoft.com/en-us/library/ms747327(v=VS.100).aspx). After a while it occured to me… “why not write a library from scratch that tests WPF apps, that’s fast and allows for idiomatic tests due to a clean API?”

Enter ‘Bewildr’.