Taking screenshots with Selenium WebDriver

Time to do something a bit more useful using Selenium WebDriver. Taking screenshots as we cycle through our web pages has obvious advantages for unit testing. Firstly we can just run an application overnight, have it visit every page on our website, and review the screenshots for obvious bugs the next morning before releasing to QA. Secondly, we can screenshot our localized websites, and have them linguistically reviewed, or hand off the English screenshots to our translators to provide context during the translation process.

Taking screenshots with WebDriver is exceptionally easy. The thing I like about it most, is that it takes a screenshot of just the area of the browser in which the content resides – no IE/FF/Chrome toolbars etc. But, it also takes the entire webpage – even content not visible on the screen at that time. This is a great feature. I’ve had the problem in the past with long web pages, ones for example that contain a EULA or other long document, where the screenshots had to be taken at intervals as the page scrolled. Obviously not the best process, and not very reusable code.

As mentioned in a previous post, I’m using the Selenium Client Driver for C#. I’ve created a library into which I’m adding useful functions like taking screenshots etc.

The code to take a screenshot is not complex:

using OpenQA.Selenium.IE;
using OpenQA.Selenium;
using System.Drawing.Imaging;

public void TakeScreenshot(IWebDriver driver, string saveLocation)
{
    ITakesScreenshot screenshotDriver = driver as ITakesScreenshot;
    Screenshot screenshot = screenshotDriver.GetScreenshot();
    screenshot.SaveAsFile(saveLocation, ImageFormat.Png);
}

The libraries referenced can be found in the Selenium Client Driver for C# package which can be downloaded from the Selenium website. These will need to be added to your C# project.

Notice in the above function we pass an ‘IWebDriver’ Object, as opposed to a specific InternetExplorerDriver, FirefoxDriver etc. This means this function can be used regardless of which browser you are dealing with.

Using the function is also a trival matter. Let’s browse to Google and take a screenshot, saving it in the root of the ‘C:\’ drive:

IWebDriver driver = new InternetExplorerDriver();
driver.Navigate().GoToUrl("http://www.google.com");
TakeScreenshot(driver, @"C:\screenshot.png");

Note that the TakeScreenshot function can be customized to use any image format – in fact it should probably be a function parameter. I chose PNG simply because of the small size of the generated image.

Refactoring horrible nested if-else statements

I wrote this at some point this week, I was looking back at it tonight and released how truly awful it looks:

if(filePath.Contains(".CSS"))
    return true;
else
    return false;
else if(filePath.Contains(".JS"))
    return true;
else
    return false;
else if(filePath.Contains("_STR"))
    return true;
else
    return false;
else if(filePath.Contains(".VBS"))
    return true;
else
    return false;
else if(filePath.Contains(".HTM"))
    return true;
else
    return false;
else if(filePath.Contains(".BMP"))
    return true;
else
    return false;
else if(filePath.Contains("GIF"))
    return true;
else
    return false;

Terrible huh? What was I thinking?

How much better does this look:


bool copyFile;

copyFile = (filePath.Contains(".CSS"))      ? true:
               (filePath.Contains(".JS"))   ? true:
               (filePath.Contains("_STR"))  ? true:
               (filePath.Contains(".VBS"))  ? true:
               (filePath.Contains(".HTM"))  ? true:
               (filePath.Contains(".BMP"))  ? true:
               (filePath.Contains("GIF"))   ? true:
                                              false;
return copyFile;

I like it, impressed with that one for a Friday.

Handling Exceptions on Windows Phone 7

In this post I’ll outline how to deal with exceptions in a Windows Phone 7 application. Ideally when an exception happens, we want to display some meaningful information to the user that can be provided to the developer to aid in the debugging of the issue. The worst thing that can happen is for the application to crash and just exit. This can lead to frustration on the users part (as I’ve experienced with the official Twitter application on iOS 4.0), or worse dissuade a user from purchasing any other applications bearing your name.

In this example, when an exception occurs, we’ll ensure that we navigate to an error page, and display the stack trace. Aside, this is obviously not the best thing to display to an end user. The best approach may be to display a generic error message with an option to report the error, which then emails the exception information to your support address. I leave that as an exercise to the reader, in this example, we’ll just display the stack trace information directly to the user:

1. Add a new Windows Phone Portrait Page to your Windows Phone 7 project in Visual Studio. For the purpose of this example, I’ve named the page ‘Error.xaml’.

2. In ‘Error.xaml’, locate the ‘LayoutRoot’ Grid element, and replace its content with the following:















3. The page you created above will act as the container for any exceptions that we need to display. Next, open up ‘Error.xaml.cs’, and add the following code:


using System.Windows.Navigation;
...
...

public static Exception Exception;

// Executes when the user navigates to this page.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
ErrorText.Text = Exception.ToString();
}

This sets up an Exception Object that is hooked up to ErrorText.Text upon navigating to the page.

4. Finally, we need to hook up an event handler that ensures that we navigate to this page whenever an unhandled exception occurs. This is done from ‘App.xaml.cs’. Open up ‘App.xaml.cs’, and replace the content of the ‘Application_UnhandledException’ function with the following code:


if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break in the debugger
System.Diagnostics.Debugger.Break();
}

// Running on a device / emulator without debugging
e.Handled = true;
Error.Exception = e.ExceptionObject;
(RootVisual as Microsoft.Phone.Controls.PhoneApplicationFrame).Source =
new Uri("/Error.xaml", UriKind.Relative);

If you have completed the above steps correctly, then whenever an unhandled exception occurs in your application, the application will navigate to this page, and display the exception stack trace.

To verify these steps, add a button to your ‘MainPage.xaml’ and have it link to a page that doesn’t exist, e.g.


NavigationService.Navigate(new Uri("/NotHere.xaml", UriKind.Relative));

Launch the application in the emulator, and click the button you just created, (You’ll need to launch without debugging). The result should be navigation to ‘Error.xaml’ with the exception details:

Windows Phone Error Example

WPF – Binding Data in an XML file to a ComboBox

Some things in WPF are very different from Windows Forms programming. Lately, I’ve been working on my first real UI in which I’ve used WPF over Windows Forms. Using XAML takes a little bit of getting used to, but I’m finding that I have a lot more control over the UI, along with the obvious advantage of seperating the UI presentation from the actual application logic.

Just the other day I needed to create a ComboBox control on a section of my UI, the items in which would need to be loaded from an XML file at runtime. The XML file was to be included as a resource.

The XML file looked something like this:






...

I wanted the ‘name’ attribute from each Language node to be bound to my ComboBox. In order to do this, first we need to define the XML file as a resource in our XAML:





...
...

Then, we just need to add the ItemsSource, SelectedValuePath, and DisplayMemberPath to the ComboBox XAML, specifying the resource we declared earlier, and the attribute that we want to bind:




Note the ‘SelectedItem’ can be set as well from the XAML, It’s set to ‘Arabic’ in the above example.

SharpSVN: A Gentle Introduction

SharpSVN is a really useful library which encapsulates the functionality of the Subversion client so we can leverage it programmatically from .NET applications. I can think of many uses for this. In the past, in some of the automation frameworks I’ve worked with, updating the source code from SVN has been a manual task ran weekly. Using SharpSVN, we could write a simple console application to accomplish this. It could also be useful to automate repetitive SVN tasks in a development environment.

In this post, I’m going to outline the basics of using SharpSVN, and in the process create a simple C# console application to check-out some source code.

For starters, we’ll need to download the SharpSVN package from here. Next, create a C# console application in Visual Studio. You’ll need to target .NET 2.0.

Unzip the SharpSVN package, and add ‘SharpSVN.dll’ as a reference to your console application. Next, add the following code. We’ll pass the location we want to check-out from as an argument to the application:


string Repository = string.Empty;

if (args.Length != 1)
{
Console.WriteLine("Usage: SharpSVN ");
}
else
{
Repository = args[0];
}

I’m assuming here that you’re already authenticated with your SVN server. Now the code to actually perform the check-out, which is really simple:


using (SvnClient client = new SvnClient())
{
try
{
SvnUriTarget target = new SvnUriTarget(Repository);

if (client.CheckOut(target, @"C:\Working"))
{
Console.WriteLine("Successfully checked out '" + Repository + @"' to 'C:\Working'");
}

}
catch(Exception e)
{
Console.WriteLine("Error occurred during check out: " + e.ToString());
}

That’s it. The above code will check-out the source code from the SVN repository you passed as an argument to ‘C:\Working’.

The only downside I’ve seen with SharpSVN, is that it only seems to work when I target .NET 2.0. Maybe I could download the source and try to compile it under .NET 4.0, but I haven’t tried that.

I see huge usage for this library in future projects, and it’s certainly better that a previous solution I had implemented using the command line interface to the TortoiseSVN client.

Happy Coding…

C# – Logging to the Windows Event Viewer

In the past for any applications I’ve written in C#, I’ve always logged any information I needed to in a .txt file in the Windows %temp% directory. This was really quite a messy approach when I consider it now.

Logging from your applications can be useful for a couple of reasons:

  • Auditing: Depending on your level of logging, you can get a step by step view of what’s happening with your application. I find this useful for testing as I write code.
  • Diagnostics: This is the more obvious use of logging from your application – capturing a stack trace or other useful information in the event of any issues.

Using the Windows Event Viewer to capture auditing or diagnostic logging is a much better approach, as you can specify when you log what type of event this is, i.e. ‘Information’ (for auditing), or ‘Warning’ and ‘Error’ (for diagnostic logging). This makes it a lot easier to find errors, and makes any logging you do highly readable.

I’ve created this class which wraps the logging to the Event Viewer functionality:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Diagnostics;

namespace EventLoggingExample
{
public class LoggingHelper
{
private string Application;
private string EventLogName;

///

/// Constructor
///

/// The application doing the logging /// The log to write to in the Event Viewer public LoggingHelper(string app, string log)
{
Application = app;
EventLogName = log;

// Create the event log if it doesn't exist
if (!EventLog.SourceExists(Application))
{
EventLog.CreateEventSource(Application, EventLogName);
}

}

///

/// Write to the event log
///

/// The message to write public void WriteToEventLog(string message, string type)
{
switch (type.ToUpper())
{
case "INFO":
EventLog.WriteEntry(Application, message, EventLogEntryType.Information);
break;
case "ERROR":
EventLog.WriteEntry(Application, message, EventLogEntryType.Error);
break;
case "WARN":
EventLog.WriteEntry(Application, message, EventLogEntryType.Warning);
break;
default:
EventLog.WriteEntry(Application, message, EventLogEntryType.Information);
break;
}
}
}
}

To use it, just create an instance and log at will:


LoggingHelper log = new LoggingHelper("MyApplication", "MyAppLog");
log.WriteToEventLog("Some application information", "info");
log.WriteToEventLog("This is your first warning!", "warn");
log.WriteToEventLog("An error has occurred...", "error");

This is definetely something I’ll be adding to my utilities library.