Automating UI Components with Selenium WebDriver

Samiksha KuteSamiksha Kute
9 min read

Web automation is a powerful skill, and mastering UI components like dropdowns and shopping carts is a must for any test automation engineer. In this blog, we’ll be focusing on automating UI components like dropdowns, alerts, and a real-world e-commerce scenario.

Using a practice site, we’ll explore practical techniques, coding standards, and solutions to common challenges. Let’s get started!

Setting Up Selenium WebDriver

Before diving into UI automation, ensure your environment is ready:

  • Selenium WebDriver: Install with a browser driver (e.g., ChromeDriver).

  • Programming Environment: Use Eclipse with Java for scripting.

  • Basic Knowledge: Familiarity with HTML, CSS, Java, and locators (ID, CSS, XPath).

Check out the complete Selenium Series to get started with Selenium WebDriver.

Automating Static Dropdowns

A static dropdown is a dropdown list that contains a fixed set of options that are predefined and hardcoded into the HTML code. They are built with the HTML <select> tag, are straightforward to automate thanks to Selenium’s Select class. Here’s how to handle them:

Steps:

  1. Identifying the Dropdown

    Check for the <select> tag using browser inspection (right-click > Inspect). If present, it’s static, meaning options don’t change dynamically.

  2. Select Class: Selenium provides the Select class to handle <select> dropdowns.

  3. Locate the Dropdown

    Find the <select> element using a locator like By.id.

     driver.get("https://rahulshettyacademy.com/dropdownsPractise/");
     WebElement staticDropDown = driver.findElement(By.id("ctl00_mainContent_DropDownListCurrency"));
    
  4. Initialize Select

     Select dropdown = new Select(staticDropDown);
    
  5. Choose an Option

    Use one of the four methods:

    • selectByIndex(int index): Selects an option by its position (0-based).

    • selectByVisibleText(String text): Selects by the visible text of the option.

    • selectByValue(String value): Selects by the value attribute of the option.

Example:

    // using index
    dropdown.selectByIndex(3); // selects USD, third index

    // using visible text
    dropdown.selectByVisibleText("AED");

    // using value attribute
    dropdown.selectByValue("INR");
  1. Verify Selection

     String selectedOption = dropdown.getFirstSelectedOption().getText();
     System.out.println("Selected: " + selectedOption); // Outputs: Selected: INR
    

Automating Custom Dropdowns

Custom dropdowns differ from standard <select> tags, often appearing as <div> or other elements styled to mimic dropdowns. Let’s explore a passenger selector on the Practice Website, where you adjust the number of adults.

Steps:

  1. Open the Dropdown

    Locate and click the element to reveal controls. The passenger field has an ID of divpaxinfo:

     driver.get("https://rahulshettyacademy.com/dropdownsPractise/");
     driver.findElement(By.id("divpaxinfo")).click();
    
  2. Interact with Controls: The dropdown uses buttons to adjust values (e.g., hrefIncAdt to increment adults). To select 5 adults, click the increment button 4 times (assuming it starts at 1):

     int i = 0;
     while (i < 4) {
         driver.findElement(By.id("hrefIncAdt")).click();
         i++;
     }
    
  3. Handle Synchronization: Custom controls may respond slowly. A brief pause ensures stability:

     Thread.sleep(1000);
    
  4. Verify Selection: Check the displayed text to confirm the selection. Use TestNG’s Assert for robust validation:

     String selectedText = driver.findElement(By.id("divpaxinfo")).getText();
     Assert.assertEquals(selectedText, "5 Adult");
     System.out.println(selectedText); // Outputs: 5 Adult
    

Pro Tip: Inspect custom dropdowns for unique IDs or classes on controls. Avoid hardcoding excessive clicks - use loops for flexibility.

Handling Dynamic Dropdowns

Dynamic dropdowns are lists of options that are generated in real-time based on user input, database queries, or other factors, and can change dynamically as the user interacts with the dropdown. They are trickier, as their options load based on user actions and often lack <select> tags.

Steps:

  1. Trigger Dropdown

     driver.findElement(By.id("ctl00_mainContent_ddl_originStation1_CTNR")).click();
    
  2. Target Specific Options

     driver.findElement(By.xpath("//a[@value='BLR']")).click();
    
  3. Handling Delays

     Thread.sleep(2000);
    
  4. Select Arrival:

     driver.findElement(By.xpath("(//a[@value='MAA'])[2]")).click(); // OR use parent-child XPath
    

Example Code (Index-Based):

driver.findElement(By.id("ctl00_mainContent_ddl_originStation1_CTNR")).click();
driver.findElement(By.xpath("//a[@value='BLR']")).click(); // Bengaluru
Thread.sleep(2000);
driver.findElement(By.xpath("(//a[@value='MAA'])[2]")).click(); // Chennai

Example Code (Parent-Child):

driver.findElement(By.id("ctl00_mainContent_ddl_originStation1_CTNR")).click();
driver.findElement(By.xpath("//a[@value='BLR']")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("//div[@id='glsctl00_mainContent_ddl_destinationStation1_CTNR'] //a[@value='MAA']")).click();

Key Concepts:

  • Dynamic Behavior: Options are absent until triggered (e.g., selecting Bengaluru loads Chennai options).

  • Multiple Nodes: XPaths may match multiple elements (e.g., //a[@value='MAA'] for Chennai matches both From and To dropdowns).

  • Index-Based Solution: Use index to select the desired node: (//a[@value='MAA'])[2].

  • Parent-Child XPath: Scope the search to a parent element to avoid indexes: //div[@id='destination-parent'] //a[@value='MAA'].

  • Synchronization: Options may take time to load, requiring waits.

  • Validation: Use browser console to validate XPaths and check node counts.

Real-Time Challenges:

  • Multiple Nodes: Without specifying an index, Selenium selects the first node (e.g., Chennai in From dropdown), causing failures.

  • Error Analysis:

    • Element Not Visible: Indicates multiple nodes or a closed dropdown. Use SelectorsHub to check node count and index.

    • No Such Element: Suggests an invalid XPath. Validate with SelectorsHub or console.

  • Index Rejection: Some teams disallow index-based XPaths due to fragility. Parent-child XPaths are more robust.

  • Pull Requests: In real projects, code undergoes review. Parent-child XPaths may be preferred to meet coding standards.

  • Troubleshooting: Read error logs carefully. “Element Not Visible” vs. “No Such Element” guides the fix (index vs. XPath correction).

Handling Auto Suggestive Dropdowns

Auto-suggestive dropdowns, also known as autocomplete or type-ahead dropdowns, are UI elements that provide a list of suggested options as the user types in a text field.

Key Concepts:

  • Dynamic Suggestions: Options appear after typing and may vary in order.

  • Generic Locator: Use findElements to capture all suggestions (e.g., By.cssSelector("li.ui-menu-item a")).

  • Iteration: Loop through options, check text, and select the desired one.

  • Break Statement: Exit the loop after selecting to avoid unnecessary iterations.

  • Synchronization: Wait for suggestions to load.

Steps:

  • Enter Input:

      driver.findElement(By.id("autosuggest")).sendKeys("ind");
    
  • Wait:

      Thread.sleep(3000);
    
  • Get Options:

      List<WebElement> options = driver.findElements(By.cssSelector("li.ui-menu-item a"));
    
  • Iterate and Select:

      for (WebElement option : options) {
          if (option.getText().equalsIgnoreCase("India")) {
              option.click();
              break;
          }
      }
    

Handling Alerts

Alerts are JavaScript popups (e.g., OK/Cancel prompts) that require Selenium’s Alert class, as they aren’t standard web elements. You cannot inspect alerts using browser dev tools. Handling alerts requires switching to the alert context immediately after triggering.

Key Concepts:

  • Alert Class: Use driver.switchTo().alert() to handle alerts.

  • Methods:

    • getText(): Retrieves the alert message.

    • accept(): Clicks “OK” or “Yes” (positive action).

    • dismiss(): Clicks “Cancel” or “No” (negative action).

  • Common Scenarios: Alerts appear for confirmations or unsaved changes.

  • Non-Web Popups: Windows authentication popups require tools like AutoIt.

Steps:

  • Trigger Alert

      driver.findElement(By.id("alertbtn")).click();
    
  • Switch to Alert

      Alert alert = driver.switchTo().alert();
    
  • Get Text

      System.out.println(alert.getText());
    
  • Accept/Dismiss: Use alert.accept() for OK, alert.dismiss() for Cancel.

      alert.accept(); // Clicks OK
      alert.dismiss(); // Clicks Cancel
    

Example Code:

driver.findElement(By.id("alertbtn")).click();
Alert alert = driver.switchTo().alert();
System.out.println(alert.getText()); 
alert.accept(); // Clicks OK
driver.findElement(By.id("confirmbtn")).click();
alert = driver.switchTo().alert();
System.out.println(alert.getText());
alert.dismiss(); // Clicks Cancel

Real-Time Tips:

  • Validation: Always verify the alert text to ensure the correct popup is handled.

  • Execution Speed: Alerts may appear quickly, so observe closely or slow down execution in debug mode.

  • Non-Web Popups: Be aware of network-related popups that require different tools.

Leveling Up: Dynamic Cart Additions

Let’s tackle a more complex scenario: dynamically adding items to a shopping cart on GreenKart.

The Scenario:

  • Target products like "Cucumber", "Broccoli", etc.

  • Handle multiple items dynamically.

  • Format product names (e.g., remove “- 1 Kg”).

  • Optimize to exit early once all items are added.

Step 1: Identify Products Dynamically

List<WebElement> products = driver.findElements(By.cssSelector("h4.product-name"));

Step 2: Iterate and Match Items

String[] itemsNeeded = {"Broccoli", "Cucumber", "Beetroot"};
List<String> itemsNeededList = Arrays.asList(itemsNeeded);
for (int i = 0; i < products.size(); i++) {
    String name = products.get(i).getText(); // "Cucumber - 1 Kg"
}

Step 3: Format Product Names

String[] splitName = name.split("-");
String formattedName = splitName[0].trim();

Step 4: Click "Add to Cart" Safely

driver.findElements(By.xpath("//div[@class='product-action']/button")).get(i).click();

Step 5: Optimize with Early Exit

int j = 0;
for (int i = 0; i < products.size(); i++) {
    String name = products.get(i).getText();
    String[] splitName = name.split("-");
    String formattedName = splitName[0].trim();
    if (itemsNeededList.contains(formattedName)) {
        driver.findElements(By.xpath("//div[@class='product-action']/button")).get(i).click();
        j++;
        if (j == itemsNeeded.length) {
            break;
        }
    }
}

Step 6: Handle Synchronization

Thread.sleep(3000);
List<WebElement> products = driver.findElements(By.cssSelector("h4.product-name"));

Complete Code Example

import java.util.Arrays;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class GreenKartTest {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();
        driver.get("https://rahulshettyacademy.com/seleniumPractise/");
        String[] itemsNeeded = { "Cucumber", "Brocolli", "Beetroot" };
        addItems(driver, itemsNeeded);
    }

    public static void addItems(WebDriver driver, String[] itemsNeeded) {
        int j = 0;
        List<WebElement> products = driver.findElements(By.cssSelector("h4.product-name"));
        for (int i = 0; i < products.size(); i++) {
            // Brocolli - 1 Kg
            // Brocolli, 1 kg

            String[] name = products.get(i).getText().split("-");
            String formattedName = name[0].trim();

            // format it to get actual vegetable name
            // convert array into array list for easy search
            // check whether name you extracted is present in arrayList or not

            List<String> itemsNeededList = Arrays.asList(itemsNeeded);
            if (itemsNeededList.contains(formattedName)) {
                j++;
                // click on Add to cart
                driver.findElements(By.xpath("//div[@class='product-action']/button")).get(i).click();
                if (j == itemsNeeded.length) {
                    break;
                }
            }
        }
    }
}

End-to-End Automation Example

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.Select;
import java.util.Arrays;
import java.util.List;

public class AutomationTest {
    public static void main(String[] args) throws InterruptedException {
        WebDriver driver = new ChromeDriver();
        // Flight Booking: Dropdowns
        driver.get("https://rahulshettyacademy.com/dropdownsPractise");
        WebElement staticDropdown = driver.findElement(By.id("ctl00_mainContent_DropDownListCurrency"));
        Select currency = new Select(staticDropdown);
        currency.selectByVisibleText("USD");
        System.out.println("Selected Currency: " + currency.getFirstSelectedOption().getText());
        driver.findElement(By.id("ctl00_mainContent_ddl_originStation1_CTXT")).click();
        driver.findElement(By.xpath("(//a[@value='BLR'])[1]")).click();
        driver.findElement(By.xpath("(//a[@value='DEL'])")).click();
        System.out.println("Selected Route: Bengaluru to Delhi");
        // GreenKart: Cart Additions
        driver.get("https://rahulshettyacademy.com/seleniumPractise");
        Thread.sleep(3000);
        String[] itemsNeeded = {
                "Broccoli",
                "Cucumber"
        };
        List<String> itemsNeededList = Arrays.asList(itemsNeeded);
        List<WebElement> products = driver.findElements(By.cssSelector("h4.product-name"));
        int j = 0;
        for (int i = 0; i < products.size(); i++) {
            String name = products.get(i).getText();
            String[] splitName = name.split("-");
            String formattedName = splitName[0].trim();
            if (itemsNeededList.contains(formattedName)) {
                driver.findElements(By.xpath("//div[@class='product-action']/button")).get(i).click();
                j++;
                if (j == itemsNeeded.length) {
                    break;
                }
            }
        }
        driver.quit();
    }
}

Real-Time Best Practices

  1. Code Optimization:

    • Use loops (for, while) for repetitive actions (e.g., passenger dropdown clicks).

    • Store inputs in arrays or external files for dynamic testing.

    • Avoid hardcoding indices or counts (e.g., use itemsNeeded.length).

  2. Robust Locators:

    • Prioritize IDs for stability, then CSS, then XPath.

    • Use parent-child XPaths over indexes for dynamic dropdowns.

    • Avoid text-based locators if text changes (e.g., “Add to Cart” to “Added”).

  3. Synchronization:

    • Thread.sleep is temporary. Use WebDriverWait (Explicit Wait) for production.

    • Upcoming sections cover Implicit, Explicit, and Fluent Waits.

  4. Debugging:

    • Use Eclipse’s debug mode to inspect variables and step through code.

    • Analyze errors:

      • “Element Not Visible”: Check for multiple nodes or synchronization.

      • “No Such Element”: Validate XPath/CSS.

    • Use SelectorsHub or console to verify locators.

  5. Code Reviews:

    • Expect feedback on indexes, repetitive code, or text locators.

    • Parent-child XPaths and loops demonstrate expertise.

    • Submit clean, generic code for pull requests.

  6. Troubleshooting:

    • Read error logs to distinguish XPath issues from visibility problems.

    • Validate node counts with SelectorsHub to resolve dynamic dropdown issues.

Check out the sample scripts below:

What’s Next?

This is just the start! Try automating carts or dropdowns on your favorite website. Got questions or want to share your automation wins? Drop a comment below!

Thank you for reading!

0
Subscribe to my newsletter

Read articles from Samiksha Kute directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Samiksha Kute
Samiksha Kute

Passionate Learner!