Introduction
Xenon is a framework which helps to write stable (non flakey) acceptance tests with a fluent API. We currently only support Selenium browser automation, but we will implement more if required.
The advantage of using this framework is that you don't have to worry about your page taking time to load, or your elements being dynamically added to the page. All this is handled internally using pre and post waits. These waits do not slow down because as soon as the element appears on the page it will interact with. If you want to wait upon something out of the ordinary, you can do this using custom pre and post waits.
Background
We wrote this framework as there was one issue that kept annoying us on our build server. Our tests passed and failed whenever they felt like it. We would spend ages trying to fixing the tests only to find a few days later they were failing again.
We then came up with Xenon to make our tests consistently pass with great success. Now all our tests pass all the time (unless we broke something) and we hope that it can do the same for you.
Using the Code
Setting up Xenon
Installing
You can either download the source code from our GitHub repo here and compile it yourself. You also install it from nuget:
As currently selenium is the only supported browser automation framework, we recommend that you use Xenon.Selenium
as Xenon only contains the core code and would require you to manually implement the browser automation side.
Configuring
To use selenium, you must setup a couple of things (only needs to be done once):
Setting up the options
XenonTestOptions.Options = new XenonTestOptions
{
Assert.Method = (passed, message) => Assert.IsTrue(passed, message),
WaitForSeconds = 10
}
Testing
Writing a Test (Basic)
To write a simple but reliable test is easy using our fluent API. As demonstrated below (we will use selenium in this example and search for something on Google):
void TestMethod(){
var browser = new SeleniumXenonBrowser( new ChromeDriver() );
new XenonTest( browser )
.GoToUrl( "http://www.google.co.uk" )
.EnterText( "[name='q']", "Xenon is amazing" )
.Click( "[name='btnG']" )
.Assert( a => a.PageContains( "results") );
}
This test will now reliably pass even if going to the results page takes a while as Xenon will give the browser a chance to go to that page before failing.
Writing this test is fine for simple tests but when tests get more complicated, we created Screens which are explained below.
Writing a test (Using Screens)
To write more complex tests, you can use screens. These allow you to reuse common code throughout all of your tests. To create a screen, you write a class that inherits from XenonScreen
as demonstrated below:
public class GoogleHomeScreen : XenonScreen<GoogleHomeScreen>{
public GoogleHomeScreen( IXenonBrowser browser ) : base( browser ){
GoToUrl( "http://www.google.co.uk" );
}
public GoogleSearchResultsScreen Search( string text ){
return EnterText( "input[name='q']" )
.Click( "[name='btnK']" )
.Switch<GoogleSearchResultsScreen>();
}
}
public class GoogleSearchResultsScreen : XenonScreen<GoogleSearchResultsScreen>{
public GoogleSearchResultsScreen( IXenonBrowser browser ) : base( browser ){}
}
You can the write your test as follows:
void TestMethod(){
new GoogleHomeScreen( new SeleniumXenonBrowser( new ChromeDriver() )
.Search( "Xenon is the best" )
.Assert( a => a.PageContains( "results" ) );
}
Using Assertion API
The assertion API is one of the core parts of Xenon it can be used in multiple places throughout the framework. It allows you to assert on multiple things using fluent syntax. When ever this is used Xenon always gives your Assert method time to pass in case the browser is taking its time for some reason.
It can be for a customPreWait and customPostWait in all XenonTest/XenonScreen methods which makes it extremely usefull if say clicking a button should wait for a Ajax call to complete and output data to the page before continuing.
new XenonTest( .Click( "#loadData", customPostWait: a => a.PageContains( "Data Loaded" ) );
It can also be using in the Assert method of Xenon test method to make sure the current page state matches what is expected. A big advantage of the Assert method is that it can be used at multiple points throught your test, so that you can make sure that it is progressing as expected.
new XenonTest( .GoToUrl( "http://www.google.co.uk" )
.Assert( a => a.PageContains( "Google" ) )
.EnterText( "[name='q']", "Xenon is amazing" )
.Click( "[name='btnG']" )
.Assert( a => a.PageContains( "results") );
If the assertion api does not contain the type of assertion you are looking for all is not lost. As there is a CustomAssertion method which allow you write your own assertion using the browser directly. Using this does not affect the reliabilty of your test.
Assert( a => a.CustomAssertion( b => b.Url == "www.google.co.uk", "Custom message on failure" ) );
Notes
If you would like to view our source code, you can access it at our GitHub repo here.
If you have any recommendations or questions, please leave a comment below or an issue on GitHub.