Total Pageviews

Monday 12 January 2015

ChromeDriver: Mobile Emulation

ChromeDriver is a standalone server which implements WebDriver's wire protocol.

[C#]

    var mobileEmulation = new Dictionary
    {
        { "deviceName", "Apple iPhone 5" }
    };
    var options = new ChromeOptions();
    options.AddAdditionalCapability("mobileEmulation", mobileEmulation);
    driver = new ChromeDriver(options);
  
Tips:
  • The “mobileEmulation” dictionary must use a valid device name from the DevTools Emulation panel.  
    
 
Reference:
 
ChromeDriver
Provides a mechanism to write tests against Chrome 

ChromeOptions
Class to manage options specific to ChromeDriver

AddAdditionalCapability
Provides a means to add additional capabilities not yet added as type safe options for the Chrome driver. 

Monday 11 August 2014

Git Extensions: syntax error near unexpected token `('

Git Extensions is a graphical user interface for Git that allows you to control Git without using the command line.

The Problem

After installing Git Extensions you may come across the following error when cloning a repository;
 

\"C:/Program Files (x86)/GitExtensions/GitCredentialWinStore/git-credential-winstore.exe\" get: -c: line 0: syntax error near unexpected token `('

\"C:/Program Files (x86)/GitExtensions/GitCredentialWinStore/git-credential-winstore.exe\" get: -c: line 0: `\"C:/Program Files (x86)/GitExtensions/GitCredentialWinStore/git-credential-winstore.exe\" get'

This happens when there is a syntax error in the git config file, the git config file can be found here;

C:\Users\<username>\.gitconfig

The Solution

In the credential section of the config file, you will notice that there are extra backslashes.

helper = !\\\"C:/Program Files (x86)/GitExtensions/GitCredentialWinStore/git-credential-winstore.exe\\\"

Remove the extra backslashes so that the helper key's value looks like below.

helper = !\"C:/Program Files (x86)/GitExtensions/GitCredentialWinStore/git-credential-winstore.exe\"

You should now be able to successfully clone your repository.

Summary

Hopefully this tip will save you some time so that you can focus your efforts on testing.

If you have found this or any of my other blog posts helpful, please feel free to leave a comment.

Happy Testing!

Friday 27 June 2014

Selenium WebDriver: org.openqa.selenium.firefox.NotConnectedException

The Problem

org.openqa.selenium.firefox.NotConnectedException: Unable to connect to host 127.0.0.1 on port 7055 after 45000 ms

Solution 1

Download the latest version of Selenium

Tips:

Remember to add it to your build path

Solution 2

Alternatively, downgrade Firefox

Tips:
Mozilla's archive containing old versions of Firefox are for testing purposes, it is not recommended that you use anything but the latest version. Old versions of Firefox may pose a significant security risk.

Friday 30 May 2014

Fiddler: Intercepting HTTP(S) traffic in Java Applications

To change the Java Virtual Machine's proxy settings, add the following lines at the beginning of your code.

System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("https.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "8888");
System.setProperty("https.proxyPort", "8888");

Tuesday 22 April 2014

Writing and verifying reliable locators

The problem
Selecting your locators are a core part of writing automated WebDriver tests. However, I have seen this part of automation get overlooked so many times.

If you do not craft you locators carefully you can end up wasting a lot of time debugging brittle test cases.

I have seen development teams lose faith in the tests because they consistently give incorrect results, which can sometimes be a direct result of using poorly written locators.

Iterating on the design off web apps or fixing bugs can cause the dynamics of a page to change. Dependent on the change you may want your test to fail. However, sometimes your test should be resilient to the change (for example, styling changes), and having solid locators plays a big part in this.
Writing solid locators reduce the cost of maintenance, for the reason that reliable locators make the tests less brittle. In turn, you do not need to amend them as often.

Crafting reliable locators
When selecting locators the first thing to look for is an ID, after inspecting the element if it has an ID go for that first. If the element does not have an ID, then look to see if it's parent has an ID that can be used as a starting point to provide support followed by the descendant.

The next option should be CSS class names, but only the class names that are determined by functionality. Choose these locators over CSS class names that are used for styling, because the look and feel of the page can change but the functionality may remain the same.
Another option would be to use "data-" attributes, although the "data-" attributes can only be used in HTML 5 compliant browsers.
When constructing locators try to avoid chaining direct descendants. The reason behind this is that a change to one element in the chain will cause the locator to fail. There will be occasions when you need to use a descendant, don't be afraid to use it. Use it with careful consideration and try not to use more than one or two if possible.

Another thing to avoid is using indexes, web apps change frequently and elements may get moved around (for example, a menu item in a list). In this particular scenario you wouldn't want the test to beak if your test is verifying the functionality of a menu item. Indexes should only be used in scenarios like when you want to select the first item from a list regardless of what the list item is.

Example
Fruits
  • Orange
  • Apple
If asked to select the Apple from the list above. Copying the XPath straight from Firebug will give you a locator similar to '/html/body/some/more/direct/descendants/div/ul/li[2]'. Now imagine if the list was wrapped inside an additional div... Will the Apple still be located? No!

I have also seen people create locators like this '//li[2]' or '//li[position()=2]'. Now imagine if another fruit was add to the top of the list... Will the Apple still be located? No!

To overcome a problem like this you can carefully construct your XPath as follows: '//*[@id='Shopping']//li[contains(text(), 'Apple')]'. Here you can see the Xpath uses the id of its parent as an anchor then drills into the list. When selecting the Apple, the contains function is used to ensure that the element that contains the text Apple is retrieved. This Xpath locator will work wherever the Apple is in the list.

The solution
The next time you are about to write a test, give FirePath a try. https://addons.mozilla.org/en-US/firefox/addon/firepath/
FirePath is a Firebug extension that adds a development tool to edit, inspect and generate XPath 1.0 expressions, CSS 3 selectors and JQuery selectors (Sizzle selector engine).
For FirePath to work properly you will need to install the Firebug addon.https://addons.mozilla.org/en-US/firefox/addon/firebug/
Before you;
  • right click on an element in FireBug and select Copy XPath or Copy CSS Path
  • traverse a page for a complex locator
  • repeatedly try out various locators in your tests in hope that you get what your looking for
Spend a minute or so of your time and carefully construct the locator and then try it out in FirePath.

Wednesday 26 March 2014

Selenium WebDriver: Say cheese

Taking screenshots of a test failures using Selenium WebDriver can come in handy, especially when investigating failed test cases from previous test executions. For example, a test that may have ran overnight.
 
Screenshots coupled with the stack trace and logging allows you to diagnose why a test failed without the need to rerun the test.

In the solution below I will detail how to take a screenshot using Selenium WebDriver, with the following caveats;
  • I am not sure what test may fail, so I cannot explicitly set what tests should take a screenshot.
  • I do not want to capture a screenshot of successful test runs.
 
To get around this problem I will be taking advantage of NUnit's TestContext which contains a wealth of useful information. For example, the full name and status of a test.

Tips:


Ensure you edit the location for the screenshot file as you see fit.

[C#]
using System;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using System.Diagnostics;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;

namespace TestAutomationEngineer
{
    [TestFixture]
    public class Screenshots
    {
        private IWebDriver driver;
        private string baseURL;
        private string filename;
        private string saveLocation;
        
        [SetUp]
        public void SetupTest()
        {
            driver = new FirefoxDriver();
            baseURL = "http://testautomationengineer.blogspot.co.uk/";
        }
        
        [TearDown]
        public void TeardownTest()
        {
         if (TestContext.CurrentContext.Result.Status == TestStatus.Failed)
         {
          Snap(driver);
          Console.WriteLine("Check out why the test failed, look here: " + filename);
         }
         
         if(driver != null)
         {
          driver.Quit();
         }
        }
        
        [Test]
        public void TakeScreenshotTestThatPasses()
        {
         driver.Navigate().GoToUrl(baseURL);
         Assert.IsTrue(true);
        }
        
        [Test]
        public void TakeScreenshotTestThatFails()
        {
         driver.Navigate().GoToUrl(baseURL);
         Assert.IsTrue(false);
        }
        
        public void Snap(IWebDriver driver)
        {
         try{
          createTempDirectory();
          createFilename();
    ((ITakesScreenshot) driver).GetScreenshot().SaveAsFile(filename, ImageFormat.Png);
         }
         catch(Exception){}
        }
        
        public void createTempDirectory(){
         try{
          saveLocation = "c:\\temp\\";
    bool dirExists = System.IO.Directory.Exists(saveLocation);
    if(!dirExists)
        System.IO.Directory.CreateDirectory(saveLocation);
         }
         catch(Exception){}
        }
        
        public void createFilename(){
      try{
    var timeStamp = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
    filename = TestContext.CurrentContext.Test.FullName;
    string ext = ".png";
    filename = filename + timeStamp;
    filename = saveLocation + filename + ext;
         }
         catch(Exception){}
        }
        
    }
}

Reference:

ITakesScreenshot
Defines the interface used to take screen shot images of the screen.

GetScreenshot
Gets a Screenshot object representing the image of the page on the screen.

TestContext (NUnit)
The TestContext class allows tests to access certain information about the execution context.


Tuesday 25 February 2014

Fiddler: Faking server responses using AutoResponder

Fiddler is a free web debugging proxy tool that records all HTTP(S) traffic between your computer and the internet.

Fiddler is great for capturing and manipulating HTTP(S) traffic.

I regularly use Fiddler to reproduce specific scenario’s by returning a response from my local disk instead of hitting the server.

Steps:

1. Install Fiddler.

2. Clear your cache by selecting Tools -> Clear WinNET Cache from the main menu or use the keyboard shortcut Ctrl + Shift + X.

3. Select the AutoResponder tab in the right hand side pane.

4. Check Enable automatic responses, to activate AutoResponder.

5. Check Unmatched requests passthrough, so that requests that do not match are sent to the server. If this option is not checked, Fiddler will respond to all HTTP(S) request that do not match the rule with a 404 Not Found.

6. Drag and drop traffic items from the web session list on the left into the AutoResponder pane on the right hand side.

7. Select the rule, and then compose a pattern and response using the rule editor at the bottom of the AutoResponder pane.

8. Remember to click the Save button.

9. From the main menu select File -> Capture Traffic or use the keyboard shortcut F12.