Original post By Mehdi Khalili on 9 Oct 2013 here
I just modified it to best suit my needs.
Mehdi Khalili uses Selenium webdriver to do an automated UI test. The key of the post is to see the test code as “code” and use object oriented patterns. Here is how I’m using it with xunit and Trackyon CUIT Helpers.
Basic MVC example
Complete solution for download here.
-
Create a new MVC 4 Intranet Application (Razor engine)
Project properties:- Anonymous Authentication (Disabled),
- Windows Authentication (Enabled),
- URL (notice port)
- Create a new Class Library to hold the tests
Nuget packages:- xunit,
- Trackyon.CUIT.Helpers,
- Selenium.WebDriver,
- Selenium.Support
- Download and add IEDriverServer
File properties:- Build Action (None),
- Copy to Output Directory (Copy if newer)
- Create base classes Host, Page, SeleniumApplication. For simplicity only the changes from the original post are shown below.
public class SeleniumApplication { public void Run(string websiteName, int portNumber) { IISExpress.Start(websiteName); // Trackyon.CUIT.Helpers var options = new InternetExplorerOptions() { IntroduceInstabilityByIgnoringProtectedModeSettings = true }; WebDriver = new InternetExplorerDriver(options); WebDriver.Navigate().GoToUrl( string.Format("http://localhost:{0}", portNumber)); AppDomain.CurrentDomain.DomainUnload += CurrentDomainDomainUnload; } private void CurrentDomainDomainUnload(object sender, EventArgs e) { WebDriver.Quit(); } }
- Create a class to mimic the HomeController Index page
public class HomeIndex : Page { public static HomeIndex Initiate() { var driver = Host.Instance.WebDriver; driver.Navigate().GoToUrl(driver.Url); return new HomeIndex(); } // bullets on the index page of the home controller public string[] Bullets { get { return WebDriver.FindElement(By.ClassName("round")) .FindElements(By.TagName("li")) .Select(x => x.Text).ToArray(); } } }
Create a class to hold the testdata.- Create a class to hold the coded UI tests.
The IUseFixture takes care of initializing and disposing the testdata. This is a xunit feature.public class HomeTest { [Fact] public void HomeIndexPage_Shows_gettingStarted() { var page = HomeIndex.Initiate(); Assert.True(page.Bullets.Any(bullet => bullet.ToLower().Contains("getting started"))); } [Fact] public void HomeIndexPage_Shows_nuget() { var page = HomeIndex.Initiate(); Assert.True(page.Bullets.Any(bullet => bullet.ToLower().Contains("nuget"))); } [Fact] public void HomeIndexPage_Shows_hosting() { var page = HomeIndex.Initiate(); Assert.True(page.Bullets.Any(bullet => bullet.ToLower().Contains("hosting"))); } }
The testcode checks the Index page for the text in the three bullets. Getting started, nuget and hosting.
Complete solution for download here.
More details
Because of the security I’m using (Windows Authentication) I’m using the Trackyon.CUIT.Helpers IISExpress class. The original solution started the process from the commandline with a custom port, but that needed IISExpress to be configured the same for all websites. I could’t figure out a way to use the visual studio solution from the commandline. The Trackyon solution just starts the website that is in the applicationhost.config and is adjusted by visual studio.
Xunit provides the IUseFixture for handling testdata. I’m using it to load a certain page, do all the tests on it and then close the page after all tests are done.
When the tests are run, the webdriver is still active as a process. I’m still looking into the AppDomain.CurrentDomain.DomainUnload event and why it is not firing when the xunit tests are done. I might add the WebDriver.close() to the testdata / IUseFixture.
[update]
I’m using WebDriver.Quit() to stop the process. After upgrading to xUnit.net runner 0.99.3 the event was triggered and everything is just “fine and dandy” now.
[update]
No need for IUseFixture (removed) and updated demo project.
Pingback: Run Selenium from visualstudio.com | .NET Development by Eric
I’m building “hand coded” CUITs, which I blog about over at http://burdettelamar.wordpress.com/.
Couple of posts:
— http://burdettelamar.wordpress.com/2014/03/21/keep-your-page-objects-dry/
— http://burdettelamar.wordpress.com/2014/04/19/clean-and-dry-verifiers/
— http://burdettelamar.wordpress.com/2014/03/21/getters-and-setters/
Pingback: Best Off .NET development by Eric | .NET Development by Eric