Cross-Browser Testing Made Easy with Selenium
Published: 2023-08-31 11:25:21

In Today’s world technology is changing at a very fast pace, every day a new application, a new web browser is getting launched. To perform well in this competitive market, software engineers need to come up with an application that is very stable in all web browsers.

As an end user can use any browser of his/her choice, and they expect normal behavior from the application. To make sure this happens Cross browser testing comes into the picture.

## Cross Browser Testing with Selenium?

Cross browser testing or browser compatibility testing is a process that consists of testing and verifying websites or applications whether behave as per expectations or not. It’s a Non-Functional testing process.

Cross browser testing is done to make sure the compatibility of web applications on different OS, devices, and browsers. This way, developers ensure that the end users should get the best results without coping with any technical issues.

## Types of Cross Browser Testing using Selenium:
 A Developer/Tester can perform Cross browser testing in two ways:

**1. Manual Cross Browser testing:**
 Using this method users can install multiple browsers on their machine, try accessing the web application in all of them, and make a list of issues that they are observing in those browsers (Opera, Firefox, Safari, Chrome, Edge, IE).

They can perform negative testing as well, by putting the wrong address or by making a change through inspect view. We will be creating test cases that will be covering all scopes of cross browser testing for performing manually.

**2. Automated Cross Browser testing**
 When CBT is performed using Automation or without manual intervention using tools like Selenium, Cypress, Playwright, UFT, and many more.

While doing cross browser testing through automation, test developers need to write scripts with the help of automation tools, to open multiple browsers and access the URL/web application and assert multiple checks and validation. Post automation run we will get the end report where we can see how all browsers behaved in the expected way.

## How to do Cross Browser Testing using Selenium?
 The first question that comes to mind while talking about Selenium is “What exactly is selenium ?”

So the answer is very simple, Selenium is an open-source suite of tools primarily used for automating web applications for testing purposes. It provides APIs to interact with web elements and simulate user interactions, such as clicking buttons, filling out forms, and validating results. Selenium WebDriver is one of its key components, enabling cross-browser testing by automating browsers for various platforms.

 We can perform Scripting in Selenium using multiple languages such as Ruby, Python, Java, C#, and many more. 

Before jumping into Cross browser testing using Selenium, first, we need to understand what is WebDriver.

So, Selenium WebDriver is a web framework that helps us in invoking multiple browsers and performing cross browser testing. Using this tool we can automate web-based applications and validate whether they perform in the expected way or not. We get the option to choose a programming language and create test scripts.

Setting up Selenium WebDriver using Java
In Java, we need the Selenium WebDriver Java bindings. And we can use a build tool like Maven or Gradle to manage dependencies, or manually download the JAR file from the Selenium website.

```
// System Property for Chrome Driver   
    System.setProperty(“webdriver.chrome.driver”,”D:\\ChromeDriver\\chromedriver.exe”);  
      
       // Instantiate a ChromeDriver class.
WebDriver driver=new ChromeDriver();
```
Let’s Understand Cross Browser testing using Selenium with JAVA in detail:

In our Java Framework we need a pom.xml, Testng.xml and a test case for Cross browser test.

Pom.xml:

POM.xml stands for Project Object Model XML. It is a file used in Apache Maven, a popular build automation and project management tool in the Java ecosystem. The POM.xml file is an essential part of a Maven project and is used to define various project-related information, dependencies, and build configurations.

## Overview of what the POM.xml file contains:

**Project Information**: The POM.xml file defines basic information about the project, such as the project’s name, version, description, and other metadata.
**Project Dependencies**: It lists the external dependencies required by the project to compile and run. Maven uses these declarations to automatically download the required libraries from repositories.
**Build Settings:** The POM.xml file includes configurations related to the build process, such as the source directory, test directory, build output directory, and various plugins to be used during the build.
**Plugins:** Maven plugins are used to perform various tasks during the build process. The POM.xml file specifies which plugins should be used and their configurations.
**Profiles:** Profiles allow you to define different sets of configurations that can be activated based on certain conditions, such as the build environment or specific requirements.
**Parent POM:** A POM.xml file can also inherit from a parent POM, which helps in maintaining consistency and reusability across multiple projects.

```
<project xmlns=”http://maven.apache.org/POM/4.0.0″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>
<modelVersion>4.0.0</modelVersion>
<groupId>testframework</groupId>
<artifactId>web-driver-3-cross-browser-framework</artifactId>
<version>0.0.1-SNAPSHOT</version>

<dependencies>

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.13.0</version>
<scope>test</scope>
</dependency>

<!– https://github.com/bonigarcia/webdrivermanager –>
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>2.2.4</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.13</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>

<!– https://mvnrepository.com/artifact/com.codeborne/phantomjsdriver –>
<dependency>
<groupId>com.codeborne</groupId>
<artifactId>phantomjsdriver</artifactId>
<version>1.4.4</version>
<scope>test</scope>
</dependency>


</dependencies>
</project>

```

## TestNG xml:
TestNG XML is a configuration file used with the TestNG testing framework in Java. It is an XML file that allows you to define the test suite, test cases, test groups, test parameters, and various other configurations for your test execution. TestNG is an open-source testing framework inspired by JUnit and offers more features and flexibility for testing Java applications.

The TestNG XML file allows you to specify how your tests should be executed, which classes or methods to include or exclude, how to handle dependencies between tests, and how to generate test reports, among other things. It provides a powerful and flexible way to organise and execute your tests.

Below are some common elements that we can use in a TestNG XML file:

1. `<suite>`: The root element representing the test suite. It can contain more than one  `<test>` element.

2. `<test>`: Represents an individual test in the suite. You can define the test’s name, parallel execution settings, and list the test classes to be executed in the `<classes>` element.

3. `<classes>`: Contains a list of test classes that should be executed as part of the test.

4. `<groups>`: Allows you to specify which test groups to include or exclude from the test execution.

5. `<parameters>`: Enables you to set parameters that can be accessed from the test classes.

6. `<listeners>`: Allows you to configure test listeners, which can perform actions at various stages of the test execution.

7. `<reporters>`: Enables you to define test report output configurations.

```
<!DOCTYPE suite SYSTEM “http://testng.org/testng-1.0.dtd” >
<suite name=”First Suite” verbose=”1″>
<test name=”FirefoxTests”>
<parameter name=”browser” value=”firefox”/>
<packages>
<package name=”com.Testframework.selenium.crossbrowser.framework.*”/>
</packages>
</test>
<test name=”ChromeTests”>
<parameter name=”browser” value=”chrome”/>
<packages>
<package name=”com.Testframework.selenium.crossbrowser.framework.*”/>
</packages>
</test>
</suite>
```

## Chrome Browser basic test.java:
```
package com.testframework.selenium.crossbrowser;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.safari.SafariDriver;
import org.testng.annotations.Ignore;
import org.testng.annotations.Test;
import io.WebDriverManager;
public class CrossBrowserBasicsTest {
@Test
public void chromeBrowser() {
// Chrome

// Chrome Web Driver EXE
WebDriverManager.chromedriver().setup();

// WebDriver Interface – Create an instance of the web driver of the browser
WebDriver driver = new ChromeDriver();

// Launch a web page
driver.get(“http://localhost:8080/pages/tables.html”);

sleep(5);

driver.quit();
}
@Test
public void firefoxBrowser() {
// Firefox

// Firefox Web Driver EXE
WebDriverManager.firefoxdriver().setup();

// WebDriver Interface – Create an instance of the web driver of the browser
WebDriver driver = new FirefoxDriver();

// Launch a web page
driver.get(“http://localhost:8080/pages/tables.html”);

sleep(5);

driver.quit();
}
@Test
public void safariBrowser() {
// Safari
// Make sure you set Develop | Allow Remote Automation option from Safari’s main
// menu

// Couldn’t create a session: You can enable the ‘Allow Remote Automation’
// option in Safari’s Develop menu to control Safari via WebDriver.

// Safari Web Driver EXE
WebDriverManager.safaridriver().setup();

// WebDriver Interface – Create an instance of the web driver of the browser
WebDriver driver = new SafariDriver();

// Launch a web page
driver.get(“http://localhost:8080/pages/tables.html”);
sleep(5);
driver.quit();
}
@Test
@Ignore
public void ieBrowser() {

WebDriverManager.iedriver().setup();

// WebDriver Interface – Create an instance of the web driver of the browser
WebDriver driver = new InternetExplorerDriver();

// Launch a web page
driver.get(“http://localhost:8080/pages/tables.html”);
sleep(5);
driver.quit();
}
@Test
@Ignore
public void edgeBrowser() {
WebDriverManager.edgedriver().setup();
// WebDriver Interface – Create an instance of the web driver of the browser
WebDriver driver = new EdgeDriver();
// Launch a web page
driver.get(“http://localhost:8080/pages/tables.html”);

sleep(5);

driver.quit();
}
private void sleep(int i) {
try {
Thread.sleep(i * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

```

## Headless Chrome Browser basic test.java:

```

package com.testframework.selenium.crossbrowser;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.testng.annotations.Test;
import io.WebDriverManager;

public class HeadlessBrowserBasicsTest {

@Test
public void chromeBrowser() {
// Chrome

// Chrome Web Driver EXE
WebDriverManager.chromedriver().setup();

// WebDriver Interface – Create an instance of the web driver of the browser
WebDriver driver = new ChromeDriver();

// Launch a web page
driver.get(“http://localhost:8080/pages/tables.html”);

sleep(5);
driver.quit();
}

@Test
public void chromeBrowserHeadlessBrowsing() {
// Chrome

// Chrome Web Driver EXE
WebDriverManager.chromedriver().setup();

ChromeOptions options = new ChromeOptions();
options.setHeadless(true);

// WebDriver Interface – Create an instance of the web driver of the browser
WebDriver driver = new ChromeDriver(options);

// Launch a web page
driver.get(“http://localhost:8080/pages/tables.html”);

sleep(5);
driver.quit();
}

@Test
public void firefoxBrowser() {
// Firefox

// Firefox Web Driver EXE
WebDriverManager.firefoxdriver().setup();

// WebDriver Interface – Create an instance of the web driver of the browser
WebDriver driver = new FirefoxDriver();

// Launch a web page
driver.get(“http://localhost:8080/pages/tables.html”);

sleep(5);

driver.quit();
}
@Test
public void firefoxBrowserHeadlessBrowsing() {
// Firefox

// Firefox Web Driver EXE
WebDriverManager.firefoxdriver().setup();

FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);

// WebDriver Interface – Create an instance of the web driver of the browser
WebDriver driver = new FirefoxDriver(options);

// Launch a web page
driver.get(“http://localhost:8080/pages/tables.html”);

sleep(5);

driver.quit();
}

@Test
public void phanthomJS() {
WebDriverManager.phantomjs().setup();

WebDriver driver = new PhantomJSDriver();

// Launch a web page
driver.get(“http://localhost:8080/pages/tables.html”);

sleep(5);

driver.quit();
}
private void sleep(int i) {

try {
Thread.sleep(i * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

```

Now we will understand how to perform automation using selenium for performing cross browser testing using other most common scripting languages ( Ruby, Python and C#)

## Setting up Selenium WebDriver using Ruby:
 Most importantly ruby is installed in the system, then we will install gem for selenium WebDriver.

```
ruby
gem install selenium-webdriver

 ```

**  Implementation in Ruby:**

```
require ‘selenium-webdriver’

# Define the desired browser (e.g., :chrome, :firefox, :safari)
browser = :chrome
 # Create a WebDriver instance
driver = Selenium::WebDriver.for browser
 # Navigate to a website
driver.navigate.to ‘https://example.com’
 # Perform tests or interactions
# …
 # Close the browser
driver.quit
```

**Setting up Selenium WebDriver using Python:**
 First we need to make sure Python is installed in the system and post that we will perform the installation using PIP command

```

bash
pip install selenium

```
## Implementation in  Python:

```
from selenium import webdriver
 
# Define the desired browser (e.g., ‘chrome’, ‘firefox’, ‘safari’, ‘opera’)
browser = ‘chrome’
 
# Create a WebDriver instance for testcase
driver = webdriver.Chrome() if browser == ‘chrome’ else webdriver.Firefox()
 
# Navigate to a website
driver.get(‘https://example.com’)
 
# Perform tests
# …
 
# Close browser
driver.quit()
```
## Setting up Selenium WebDriver using C#:
Search for Selenium Webdriver and add the package. In the Package Explorer window:– Click on Browse,

Step1. In the Search box type Selenium
Step2. Choose Selenium.Webdriver by Selenium
Step3. On the window to the right, select the checkbox which shows Project Name
Step 4. Click on Install

**Implementation in C#:**


```
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Chrome;
namespace MultipleBrowserTesting
{
[TestFixture(typeof(FirefoxDriver))]
[TestFixture(typeof(ChromeDriver))]
[TestFixture(typeof(InternetExplorerDriver))]
public class BlogTest<TWebDriver> where TWebDriver : IWebDriver, new()
{
private IWebDriver _driver;

[Test]
public void Can_Visit_Google()
{
     _driver = new TWebDriver();
 
     // Navigate
     _driver.Manage().Window.Maximize();
     _driver.Navigate().GoToUrl(“http://www.google.com/”);
}

[TestFixtureTearDown]
public void FixtureTearDown()
{
     if (_driver != null)
         _driver.Close();
}
}
}


```

**Points to consider for Cross Browser Testing for Selenium:**
**Use Browser-specific Drivers**: For each browser, you need to download and set up the appropriate WebDriver (e.g., ChromeDriver for Chrome, GeckoDriver for Firefox). Ensure you have the correct version of the driver that matches your browser version and update it whenever required.
**Handle Synchronization**: Different browsers may have varying rendering speeds, which can lead to synchronization issues in your tests. Use explicit waits to ensure elements are present before interacting with them.
**Verify Layouts and CSS**: Cross-browser testing should not only validate functionality but also ensure consistent layouts and CSS rendering across browsers.
**Execute Tests on Multiple Browsers**: It’s crucial to run your tests on various browsers, such as Chrome, Firefox, Safari, Edge, and others, to cover a wide range of user devices and preferences.
**Cloud-Based Testing Platforms**: Consider using cloud-based testing platforms like BrowserStack or Sauce Labs to easily scale your cross-browser testing across different OS and browser combinations.

**Conclusion**
Cross Browser Testing using Selenium is an important step in ensuring a seamless user experience of web applications across various browsers and platforms. Selenium WebDriver, with its support for multiple programming languages, provides a great way to automate this testing process. In this article, we explored how to perform cross-browser testing using Selenium with code snippets in Ruby, Python, C#, and Java. By following these best practices, you can catch browser-specific issues early in the development cycle and deliver a high-quality web application to your users. Happy testing!