Thursday, October 9, 2014

Automating Windows Store apps using Coded UI

Automating Windows Store apps with Coded UI is not as straight forward as automating desktop app. This is because recording actions is not allowed for Windows Store apps.
Here, we will learn how to automate Windows Store apps using Coded UI and launch and close the app programmatically using IApplicationActivationManager

Add a Windows Store Coded UI Test Project

    1.       Add a new Coded UI Test Project from Store App-> Windows Apps

 
 
 
 
 
 
 
 
 

     2.       Select Edit UI Map or add assertions

 
 
 
 
 
 
 
 
3.       Note that recording actions is not allowed for Windows Store apps





 
      4.       Launch the app
      5.       Drag to cross hair on to a control and select Add control to UI Map

 
 
 
 
 
 
 
 
 
6.       Add all controls and click Generate Code->Generate 

 
 
 
 
 
 
 
 
 
 
 
 


      7.       Close the Coded UI Test Builder
        8.       UIMap.uitest will be created with the selected controls

Launch and Close the App

Add the following code
public enum ActivateOptions
    {
        None = 0x00000000,  // No flags set

        DesignMode = 0x00000001,  // The application is being activated for design mode, and thus will not be able to

        // to create an immersive window. Window creation must be done by design tools which

        // load the necessary components by communicating with a designer-specified service on

        // the site chain established on the activation manager.  The splash screen normally

        // shown when an application is activated will also not appear.  Most activations

        // will not use this flag.

        NoErrorUI = 0x00000002,  // Do not show an error dialog if the app fails to activate.                               

        NoSplashScreen = 0x00000004,  // Do not show the splash screen when activating the app.
    } 

    [ComImport, Guid("2e941141-7f97-4756-ba1d-9decde894a3d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IApplicationActivationManager
    {
        // Activates the specified immersive application for the "Launch" contract, passing the provided arguments

        // string into the application.  Callers can obtain the process Id of the application instance fulfilling this contract.

        IntPtr ActivateApplication([In] String appUserModelId, [In] String arguments, [In] ActivateOptions options, [Out] out UInt32 processId);

        IntPtr ActivateForFile([In] String appUserModelId, [In] IntPtr /*IShellItemArray* */ itemArray, [In] String verb, [Out] out UInt32 processId);

        IntPtr ActivateForProtocol([In] String appUserModelId, [In] IntPtr /* IShellItemArray* */itemArray, [Out] out UInt32 processId);
    }

    [ComImport, Guid("45BA127D-10A8-46EA-8AB7-56EA9078943C")]//Application Activation Manager
    class ApplicationActivationManager : IApplicationActivationManager
    {
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)/*, PreserveSig*/]

        public extern IntPtr ActivateApplication([In] String appUserModelId, [In] String arguments, [In] ActivateOptions options, [Out] out UInt32 processId);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]

        public extern IntPtr ActivateForFile([In] String appUserModelId, [In] IntPtr /*IShellItemArray* */ itemArray, [In] String verb, [Out] out UInt32 processId);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]

        public extern IntPtr ActivateForProtocol([In] String appUserModelId, [In] IntPtr /* IShellItemArray* */itemArray, [Out] out UInt32 processId);
    }
Then create the following variables which can be accessed in TestInitialize and TestCleanup
ApplicationActivationManager appActiveManager = new ApplicationActivationManager();

uint pid;
Add the following code in TestInitialize and TestCleanup
[TestInitialize()]
        public void MyTestInitialize()
        {
            appActiveManager.ActivateApplication(appUserModelId, null, ActivateOptions.None, out pid);
        } 
[TestCleanup()]
        public void MyTestCleanup()
        {
            Process.GetProcessById((int)pid).Kill();
        }
The appUserModelId in TestInitialize can be obtained using the following steps:
1.       If you own the source code of the app, find the package name in package.appxmanifest
2.       Run regedit from command prompt
3.       On the device where the app is installed, find the package name at HKEY_CURRENT_USER\Software\Classes\ActivatableClasses\Package
4.       Find the AppUserModelId value in key in \Server\App.App...
5.       For example, the appUserModelId for Calculator app on my device is Microsoft.WindowsCalculator_8wekyb3d8bbwe!App  as shown below

 
 
 
 
 
 
 
  

Automate the App

 Now instantiate the UIMap and automate the app in a test method like below
[TestMethod]
        public void CodedUITestMethod1()
        {
            UIMap uiMap = new UIMap();

            Keyboard.SendKeys(uiMap.UICalculatorWindow.UICalculatorResultsText, "1");

            Mouse.Click(uiMap.UICalculatorWindow.UIPlusButton, new Point(50, 50));

            Keyboard.SendKeys(uiMap.UICalculatorWindow.UICalculatorResultsText, "1");

            Mouse.Click(uiMap.UICalculatorWindow.UIEqualsButton, new Point(50, 50));

            Assert.AreEqual("Display is  2 ", uiMap.UICalculatorWindow.UICalculatorResultsText.DisplayText);
        }

Tuesday, September 30, 2014

The service on Local Computer started and then stopped

I was seeing the below error on a windows service that I had created.

---------------------------
Services
---------------------------
The xxx service on Local Computer started and then stopped. Some services stop automatically if they are not in use by other services or programs.
---------------------------
OK  
---------------------------

The easiest way to debug this error was to launch the debugger from the service in the OnStart method like below:

protected override void OnStart(string[] args)
{
     System.Diagnostics.Debugger.Launch();
     // Rest of your code
}

Tuesday, August 5, 2014

Fiddler - Replay altered requests multiple times


If you want to replay a certain request in Fiddler, you can select it and press R
If you want to replay a request multiple number of times , you can select the request, press Shift + R and specify the count.
However, if you want to alter the request every time you replay it, you can do that by adding a custom rule in fiddler.

Go to Rules->Customize Rules. In the method OnBeforeRequest(oSession: Session), add the below:

 if(oSession.uriContains("yourUrl"))
 {
  oSession.utilReplaceInRequest('searchText',Guid.NewGuid());
 }

Now press Shift + R on your request and replay the altered request multiple times. Sweet!

Saturday, July 12, 2014

Android - SSL errors even after installing custom CA certificate

I followed these steps to install my custom CA cert on an Android device

  1. adb push mycert.cer /sdcard/
  2. Go to Settings->Security->Credential storage->Install from device storage
  3. Select the certificate and install
  4. Confirm that the certificate is installed in Settings->Security->Trusted credentials->User

However, the certificate was still not trusted and I was seeing SSL errors on trying to reach an SSL endpoint using the CA cert.

The issue turned out to be that the Date and time was not set correctly on the device. I fixed the Date and time and the SSL errors went away. Yay!

Tuesday, June 10, 2014

Selenium WebDriver Practical Guide

Reviewed a book on Selenium WebDriver Practical Guide. You can find it here http://www.packtpub.com/selenium-webdriver-practical-guide/book

 

 


 

Microsoft UI Automation Framework

Microsoft UI Automation is the new accessibility framework for Microsoft Windows used to provide programmatic access to UI elements on the desktop. It can be used to automate Windows applications, Web applications and Windows Store apps

To inspect the automation element properties, you can use the accessibility tools that ship with Windows SDK http://blogs.msdn.com/b/seealso/archive/2010/07/22/where-did-the-accessibility-tools-go.aspx
 

 
Pre-Requisite
Add a reference to UIAutomationClient.dll and UIAutomationTypes.dll and include the namespace
using System.Windows.Automation;

Desktop or Root element
The root element is desktop which can be obtained by
AutomationElement desktop = AutomationElement.RootElement;

 Finding the Application under Test

The application under test can be found by looking for the children of desktop
AutomationElement applicationUnderTest = desktop.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "ApplicationName"));

Finding Child elements of Application under Test

AutomationElement child = applicationUnderTest.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "ChildName"));

Finding Descendants of Application under Test

AutomationElement child = applicationUnderTest.FindFirst(TreeScope. Descendants, new PropertyCondition(AutomationElement.NameProperty, "DescendentName"));

Various ways of finding an Element

AutomationElement.NameProperty
AutomationElement.AutomationIdProperty
AutomationElement.ClassNameProperty
AutomationElement.FromHandle(IntPtr hwnd)
AutomationElement.ControlTypeProperty
Etc.

Entering Text in an Element

AutomationElement textbox = applicationUnderTest.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "TextboxName"));
object textboxValuePattern = null;
if (textbox.TryGetCurrentPattern(ValuePattern.Pattern, out textboxValuePattern))
{
   ((ValuePattern) textboxValuePattern.SetValue("Desired text");
}

Clicking a button

AutomationElement button = applicationUnderTest.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "ButtonName"));
object t buttonPattern = null;
if (button.TryGetCurrentPattern(InvokePattern.Pattern, out buttonPattern))
{
   ((InvokePattern) buttonPattern.Invoke();
}

Finding the Application under Test using Pointer to a Handle

Sometimes it’s difficult to find an application just by looking at the children of desktop. In these case, it can be found using pointer to its handle

First, create a class which uses Windows USER (User32.dll) component of Windows Operating System
public static class Win32
    {
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(String sClassName, String sAppName);
    }

Then get a handle of the application window. You will have to include the namespace
using interop.UIAutomationCore;
IntPtr handle = Win32.FindWindow("Windows.UI.Core.CoreWindow", " ApplicationName ");

Now, you can find the application under test
AutomationElement applicationUnderTest = AutomationElement.FromHandle(handle);