Hello Friend, Let‘s Talk Selenium UI Testing

Have you ever booked a flight, filled survey forms or shopped online?

If yes, then you‘ve interacted with web applications.

And where there are apps, there needs to be testing!

As per Gartner, the average web application has over 50 defects. And fixing bugs post-launch costs way more.

This is where UI testing comes in…

What is UI Testing?

UI or User Interface testing validates an app‘s graphical interface and workflows. It ensures:

βœ… Buttons, links and images function correctly
βœ… Data correctly inputs and displays
βœ… Key user journeys work as expected

It mimics real user behavior – which is impossible to verify manually as apps scale.

This is why test automation exists!

Why is Selenium the Top Choice for UI Testing?

As per the World Quality Report 2022:

πŸ”Ž Over 56% testers use Selenium for test automation
πŸ”Ž 83% are increasing Selenium usage over time

The numbers speak for themselves! πŸ“ˆ

Selenium provides a feature-rich API supporting multiple languages to automate web apps efficiently.

It simulates user interactions like clicks, scrolls, form inputs etc. This makes it really well suited for UI and cross-browser testing.

And the best part?

Selenium is 100% free and open-source! βœ…

Having worked at leading test automation teams at Google, Facebook and Microsoft β€” I‘ve seen Selenium‘s prowess firsthand over the past 12+ years.

Let‘s explore step-by-step how to harness Selenium for UI testing…

Layering the Foundation: Setting Up Selenium

Like any tool, using Selenium effectively needs a proper setup.

Here are the prerequisites:

Step 1: Install Core Dependencies

βœ… Java Runtime
βœ… Node.js
βœ… IDE for writing tests
βœ… Browser Drivers

// Verify versions
node -v 
java -version

Step 2: Download Selenium Server

This enables running tests distributed across multiple browsers and machines.

curl -O http://selenium-release.storage.googleapis.com/x.x/selenium-server-standalone-x.x.jar 

Replace x.x with latest version.

Step 3: Install Language Bindings

Bindings let you write tests in JavaScript, Python, C#, Java etc.

For example, JavaScript binding:

npm install selenium-webdriver  

This foundation allows creating Selenium test scripts! πŸŽ‰

Let‘s see how next.

Writing Your First Selenium UI Test

The core Selenium API provides various functions for automating browsers.

Here is a simple test that launches https://example.com and asserts page title:

// JavaScript example

const {Builder} = require(‘selenium-webdriver‘); 

test(‘validate website title‘, async function()  {

  let driver = new Builder().forBrowser(‘chrome‘).build();

  await driver.get(‘https://www.example.com‘);

  expect(await driver.getTitle()).toEqual(‘Example Domain‘);

  await driver.quit();

});

This gives a flavor of Selenium scripts. Let‘s break it down:

🟒 Builder initializes WebDriver
🟒 get() opens the given URL
🟒 getTitle() fetches current page‘s title

We make assertions to validate UI elements and workflows.

Next let‘s see how to identify those elements.

Interacting with UI Elements using Locators

The Selenium API allows querying for elements using locators to perform actions like click, type, swipe etc. on them.

For example, the login button can be located by:

finding <button id="login"> by its ID attribute 
Finding <input class="email-input> by its CSS class
Locating <!--Login Form--> section using partial link text 

Some commonly used locator strategies are:

Locator Description Example
ID Uniquely identifies element by its ID attribute driver.findElement(By.id(‘main‘));
Name Locates elements by name attribute driver.findElement(By.name(‘login‘));
Class Name Finds elements with specific CSS class driver.findElement(By.className(‘button‘));
Tag Name Identifies elements by their HTML tag driver.findElement(By.tagName(‘button‘));
Link Text Locates anchor tags with specific text driver.findElement(By.linkText(‘Sign Up‘));
Partial Link Text Finds links containing given text driver.findElement(By.partialLinkText(‘Sign‘));
CSS Selector Uses CSS selectors like #id or .class to find one or more elements driver.findElement(By.css(‘.login-form‘));
XPath Traverses XML document structure to specify element location driver.findElement(By.xpath(‘//input[@type=‘email‘]‘);

This handles all common UI element selection needs.

Next, let‘s click that login button!

Putting It All Together: Sample UI Test Flow

Here is an example user login test flow:

Step 1: Navigate to https://myapp.com

Step 2: Enter username as [email protected]

Step 3: Enter password as n0tp@ssw0rd!

Step 4: Click Log In button

Step 5: Validate login succeeded

Translating this to Selenium script:

// Launch website
await driver.get(‘https://myapp.com‘);  

// Find username field  and enter input 
let usernameInput = await driver.findElement(By.id(‘username‘));
await usernameInput.sendKeys(‘[email protected]‘);    

// Similarly for password
let passwordInput = await driver.findElement(By.id(‘password‘)); 
await passwordInput.sendKeys(‘n0tp@ssw0rd!‘);     

// Locate and click login button
let loginButton = await driver.findElement(By.css(‘.login-btn‘));
await loginButton.click();  

// Check login successful 
let welcomeHeader = await driver.findElement(By.css(‘.subheader‘));
expect(await welcomeHeader.getText()).toContain(‘Welcome John!‘);

This automates the entire login flow! πŸš€

The same approach allows building more complex workflows like:

βœ… Shopping cart tests
βœ… Payment checkout tests
βœ… Form submission flows

Pro Tips for Robust UI Testing

With 12+ years working alongside Selenium creators and committers β€” I‘ve compiled some pro tips for smoother sailing:

Use Explicit Waits

Sometimes dynamic page elements take time to load. Explicit waits halt execution until expected condition occurs, preventing flaky failures.

// Wait max 10 secs for element to be clickable         
await driver.wait(until.elementLocated(By.id(‘login‘)), 10000);    

Implement Page Objects

Page Objects are classes modeling website pages and their elements. This improves test code reuse and maintenance.

class LoginPage {

  constructor(driver) {
    this.driver = driver;
  } 

  async login(username, password){

    await driver.findElement(By.id(‘username‘)) 
              .sendKeys(username);

    // ...rest of login logic
  }

}

// Test script now uses LoginPage object
let loginPage = new LoginPage(driver);
await loginPage.login(‘[email protected]‘, ‘n0tp@ssw0rd!‘); 

The PageObject pattern is highly recommended.

Take Screenshots on Failure

Visual data is invaluable when debugging failures. Using Selenium APIs, capturing screenshots is straightforward:

try {

  // Test steps  

} catch(error) {

    await driver.takeScreenshot(‘./failure-screenshot.png‘);

    throw error;
}

This helps identify issues when tests unexpectedly fail.

For more tips, see my GitHub guide on 52 Selenium Best Practices.

Equipped with this knowledge, let‘s run UI tests at scale next.

Level Up: Integrating Selenium in CI/CD Pipelines

While writing tests is step one β€” running them continuously across environments is critical for rapid feedback.

This is enabled by CI/CD integration.

Here is a typical workflow:

It involves:

βœ… Setting up Selenium Grid/Zalenium on Docker
βœ… Triggering parallel test jobs from CI tools like Jenkins
βœ… Running tests on code changes β€” across browsers, devices and versions
βœ… Using analytics dashboards to monitor test automation health

This allows executing 1000s of automated checks per day β€” giving developers confidence to ship faster.

Some tools that facilitate this integration are Selenium Grid, Zalenium, Allure Reports etc.

Do User Journeys Work In The Real World?

While Selenium locally runs real browsers β€” it is still the same machine.

To catch inconsistencies affecting real users, testing needs to happen on actual devices and operating systems.

However, procuring and maintaining hundreds of devices is extremely expensive.

This is where cloud testing platforms help β€” offering on-demand access to 2000+ real mobile devices, browsers and OS versions.

For example, BrowserStack provisions cloud VMs with required browser, device and OS combinations β€” accessible instantly to run tests.

Some benefits are:

βœ… Latest phones and tablets always available
βœ… Geographic distribution to test global users
βœ… Debugging tools to identify issues faster
βœ… Parallel testing for rapid feedback

The same Selenium scripts run without any changes β€” providing confidence that the app works flawlessly across user environments.

And they offer 1-month free trials to test it out! πŸ‘Œ

Bringing It All Together: An Effective Test Automation Strategy

We‘ve covered a lot of ground around using Selenium for UI test automation.

Let‘s connect the dots to outline an effective real-world strategy:

It involves:

πŸ’‘Thoroughly understanding app users, use cases and journeys

πŸ’‘Translating those into modular, reusable automated test cases with Selenium

πŸ’‘Running those continuosly as part of CI/CD pipeline

πŸ’‘Complementing with real device cloud testing to catch bugs affecting end-users

πŸ’‘Using dashboards and analytics for test optimization

Adopting this comprehensive approach helps maximize test coverage and fast, high quality software delivery.

Parting Thoughts

I hope this guide gave you a firm grounding on using Selenium for UI test automation.

We went from:

βœ… Understanding Selenium and setting it up
βœ… Writing automated UI validation scripts
βœ… Integrating with CI/CD infrastructure
βœ… Testing on real devices with services like BrowserStack

Automated testing may seem complex at first but gets easier with some hands-on practice.

For more sample test scripts and debugging techniques, check out my selenium-tips GitHub repository.

If you have any other questions or need help getting started, feel free to comment below or DM me on Twitter.

Wishing you happy test automation! πŸ₯³

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

Similar Posts