About Me

Thursday, January 20, 2011

WatiN UI testing of autocomplete textbox created with jquery.autocomplete

While writing UI tests for one web project, I were faced with the trouble.
There is a textbox on the page where user can type first letters and the system shows all possible values that can be selected by the user.
On the client side it was created with jquery.autocomplete:


I'm using WatiN library for writing UI tests and the regular approach, that I tried to use was not working.
Below is the code that emulates inserting of character 'a' then waits for autocomplete textbox appears and select first item:

IE _ie = new IE("URL-of-the-page-with-autocompleter");

//Typing letter 'a' and emulates keyboard
_ie.TextField("VendorName").TypeText("a");
_ie.TextField("VendorName").KeyDown();

//Wait while autocomplete making AJAX call
//and open the results
_ie.Div(f => !string.IsNullOrEmpty(f.ClassName) 
    && f.ClassName == "ac_results").WaitUntilExists(6);

//Selecting first item
_ie.Div(f => !string.IsNullOrEmpty(f.ClassName) 
    && f.ClassName == "ac_results")
    .ElementsWithTag("ul")
    .FirstOrDefault()
    .Click();

_ie.WaitForComplete();
The second line of code is important. KeyDown method for the textfield should be called to make autocompleter show search results.

Tuesday, January 11, 2011

How to create a single-instance windows application in .NET

Today I found really good and simple way how to create single-instance windows application in .NET.
By meaning single-instance i mean the application that can't be launched twice at the same time.

The way is using Mutex object that is in System.Threading namespace:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows.Forms;

namespace SingleToneApplication
{
 static class Program
 {
  private const string APP_ID = "f87f4871-fc32-4032-82f6-ba3b3026faa4";
  /// 
  /// The main entry point for the application.
  /// 
  [STAThread]
  static void Main()
  {
            bool isItFirstInstance;
   
   using (Mutex m = new Mutex(true, APP_ID, out isItFirstInstance)) 
   {
    if (!isItFirstInstance) {
     MessageBox.Show("There is already an instance running!");
     return;
    }

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new MainForm());

   }

  }
 }
}

As you may see, the code creating new Mutex object and pass APP_ID parameter.
The APP_ID is just a string that may contain any text. The main rule is that the text must be unique. I decided to use GUID for it.

As said on Microsoft site : "Mutex is a synchronization primitive that grants exclusive access to the shared resource to only one thread. If a thread acquires a mutex, the second thread that wants to acquire that mutex is suspended until the first thread releases the mutex." Since each application is using separate thread, we may use this way.

isItFirstInstance property is initializing by the constructor. Returned value indicates that the Mutex with specified unique name was created or not. So, if the returned value is false, then the mutex was already created in another application.
Then we may use this flag to decide, do we need to run the application or exit.