Blog We love to talk!

Nov Thu

How To Automate Cross Browser Testing

  •  11-17-2016
automation

Today I would like to show you a great way to automate and speed up most of your cross browser testing.

But before we jump right into automation lets see when it even makes sense to use automation in your cross browser testing.

When to automate?

Creating automation scripts and processes takes quite a bit of time and resources so you should make sure that it is really necessary in your case. You should make sure that…

  • you need to support a high number of browsers
  • you need to do regression tests multiple times
  • you have a suitable test execution environment
  • you have a clear plan when and how to execute the tests

Moreover you should think about which browsers you want to test in an automated fashion. The discussed method below supports all major browsers.

browsers-icons

Requirements:

To run the tests described in the post you will need a Selenium Grid (How to install one) and the cross platform image tool ImageMagick.

Otherwise no special knowledge is necessary. I have written the code examples in C# but any other Selenium supported language (Java, PHP, JavaScript …) will work the same.

Static Page Testing

The easiest possible test case would be the testing of a simple static page which does not have any user interaction. Cross browser testing a static page simply means that the layout works correctly across all targeted browsers.

How to automate this?

  • During development use a specific browser for testing. This will be our so called known-to-be-good browser.
  • After development is finished we can use Selenium to automatically take a screenshot in this known-to-be-good browser. We now have a screenshot of the page as it should be.
  • Now use Selenium to take screenshots in all other supported browsers.
  • The tool ImageMagick can be used to compare the image taken in the known-to-be-good browser with all other images and create a visual representation of differences found.
  • The tester only needs to manually review the final image file, which will look something like this:

firefox_compare

The picture tells us that there are no big differences between the Google homepage in Chrome (my known-to-be-good browser) and Firefox.

The code to run this test case looks like this:

public static void TestGoogleHomepage() 
{     
   // Create a screenshot with a known good browser first     
    IWebDriver chromeDriver = new RemoteWebDriver(TestParameter.SeleniumHubUrl, DesiredCapabilities.Chrome());     
    GetPageScreenshot(chromeDriver, Path.Combine(basePath, "chrome.png"));     

    // Create screenshots in the other browsers we need to support     
    IWebDriver firefoxDriver = new RemoteWebDriver(TestParameter.SeleniumHubUrl, DesiredCapabilities.Firefox());     
    GetPageScreenshot(firefoxDriver, Path.Combine(basePath, "firefox.png"));     

    // Create screenshot comparison     
    ScreenshotHelper.CreateComparison(Path.Combine(basePath, "chrome.png"), Path.Combine(basePath, "firefox.png"), Path.Combine(basePath, "firefox_compare.png")); 
} 

private static void GetPageScreenshot(IWebDriver driver, string screenshotPath) 
{     
   // Change to the correct resolution     
   driver.Manage().Window.Size = new System.Drawing.Size(TestParameter.Width, TestParameter.Height);     
   // Open Homepage     
   driver.Navigate().GoToUrl(TestUrl);     

   // Take Screenshot     
   ScreenshotHelper.TakeScreenshot(driver, screenshotPath);     
   driver.Quit(); 
}

Dynamic Page Testing

Testing a dynamic page where the users can interact with different functions is a little more complicated than a simple screenshot comparison. But with a few small changes to the method above we can still create an automation workflow to test these pages.

How to automate this?

  • During development use a specific browser for testing. This will be our so called known-to-be-good browser.
  • Use Selenium to automate all user interactions
  • Take screenshots between each user interaction step
  • Use ImageMagick to compare these screenshots for problems
  • The tester only needs to manually review the final image files, which will look something like this:

firefox_compare2

The red rectangle on the right shows you that the Google search results look different in Chrome and Firefox. And indeed, for Firefox a notification is added which does not appear in Chrome.

The code for this test looks slightly different than the static page test:

public static void TestGoogleHomepage()
{
    // Create a screenshot with a known good browser first
    IWebDriver chromeDriver = new RemoteWebDriver(TestParameter.SeleniumHubUrl, DesiredCapabilities.Chrome());
    GetPageScreenshots(chromeDriver, new string[] { Path.Combine(basePath, "chrome.png"), Path.Combine(basePath, "chrome2.png") });

    // Create screenshots in the other browsers we need to support
    // Firefox
    IWebDriver firefoxDriver = new RemoteWebDriver(TestParameter.SeleniumHubUrl, DesiredCapabilities.Firefox());
    GetPageScreenshots(firefoxDriver, new string[] { Path.Combine(basePath, "firefox.png"), Path.Combine(basePath, "firefox2.png") });

    // Create screenshot comparison
    ScreenshotHelper.CreateComparison(Path.Combine(basePath, "chrome.png"), Path.Combine(basePath, "firefox.png"), Path.Combine(basePath, "firefox_compare.png"));
    ScreenshotHelper.CreateComparison(Path.Combine(basePath, "chrome2.png"), Path.Combine(basePath, "firefox2.png"), Path.Combine(basePath, "firefox_compare2.png"));
}

private static void GetPageScreenshots(IWebDriver driver, string[] screenshotPath)
{
    // Change to the correct resolution
    driver.Manage().Window.Size = new System.Drawing.Size(TestParameter.Width, TestParameter.Height);

    // Open Page
    driver.Navigate().GoToUrl(TestUrl);

    ScreenshotHelper.TakeScreenshot(driver, screenshotPath[0]);

    IWebElement inputField = driver.FindElement(By.Name("q"));

    // Add some text to the input field
    inputField.SendKeys("Selenium");

    // Submit the search
    inputField.Submit();

    // Google uses JS to render the results page so we need to wait
    var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    wait.Until(o => o.Title.StartsWith("Selenium", StringComparison.OrdinalIgnoreCase));

    // Take Screenshot
    ScreenshotHelper.TakeScreenshot(driver, screenshotPath[1]);

    driver.Quit();
}

Taking Screenshots

So how can we actually take screenshots in Selenium? The below code is an example in C#:

public static void TakeScreenshot(IWebDriver driver, string path) 
{     
   IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;     
   ITakesScreenshot takesScreenshot = (ITakesScreenshot)driver;     

   // Generate Bitmap     
   Image finalScreenshot = new Bitmap(TestParameter.Width, TestParameter.Height);     

   // Scroll to top     
   jsExecutor.ExecuteScript("window.scrollTo(0,0);", new object[] { });     

   byte[] screenshot = takesScreenshot.GetScreenshot().AsByteArray;     

   using (MemoryStream stream = new MemoryStream(screenshot))     
   {         
      Bitmap originalScreenshot = (Bitmap)Bitmap.FromStream(stream);         
      Bitmap parsedScreenshot = ResizeBitmap(originalScreenshot, TestParameter.Width, TestParameter.Height);         

      parsedScreenshot.Save(path, ImageFormat.Png);         

      parsedScreenshot.Dispose();         
      originalScreenshot.Dispose();     
   } 
}

Using this method we have automated the cross browser testing of our complete website and internal dashboards. Running a full test suite (using the integrated Selenium Grid in BrowseEmAll) takes around 15 Minutes including the manual review of images.

Give it a try and let us know what you think in the comments!

No Comments

Leave a Reply

Your email address will not be published.