Automation - Q&A Set 2

Advanced automation scenarios

Q1: Critical Bug Before Release

Question

How would you handle a critical bug discovered just before release?

Handling critical bugs before release requires immediate assessment, stakeholder communication, and structured decision-making.

Decision Matrix

Critical Bug Assessment:
├── Severity Level
│   ├── Blocker: Prevents core functionality
│   ├── Critical: Major feature broken
│   └── High: Minor feature affected
│
├── Risk Assessment
│   ├── Production Impact: Customer-facing issues
│   ├── Business Impact: Revenue/reputation loss
│   └── Technical Debt: Future maintenance cost
│
└── Available Options
    ├── Hotfix: Quick targeted fix
    ├── Rollback: Revert problematic changes
    ├── Feature Toggle: Disable affected functionality
    └── Release Postponement: Full delay

Pro Tip

Always maintain a “Go/No-Go” checklist with predefined criteria for release decisions.

Q2: Java Uppercase to Lowercase Conversion

Question

Write a Java program to convert uppercase letters to lowercase.

Implementation Approaches

public class CaseConverter {

    // Method 1: Using built-in toLowerCase()
    public static String convertToLowercase(String input) {
        if (input == null) return null;
        return input.toLowerCase();
    }

    // Method 2: Manual conversion using ASCII
    public static String manualToLowercase(String input) {
        if (input == null || input.isEmpty()) return input;

        StringBuilder result = new StringBuilder();
        for (char c : input.toCharArray()) {
            if (c >= 'A' && c 'Z') {
                result.append((char) (c + 32));
            } else {
                result.append(c);
            }
        }
        return result.toString();
    }

    public static void main(String[] args) {
        String test = "HELLO World 123!";
        System.out.println("Original: " + test);
        System.out.println("Lowercase: " + convertToLowercase(test));
    }
}

Q3: Second Largest Number in Array

Question

Find the second largest number in an array using Java.

Single Pass Approach

public class SecondLargestFinder {

    // Single pass approach - Most Efficient
    public static Integer findSecondLargest(int[] array) {
        if (array == null || array.length 2) {
            return null;
        }

        int largest = Integer.MIN_VALUE;
        int secondLargest = Integer.MIN_VALUE;

        for (int num : array) {
            if (num > largest) {
                secondLargest = largest;
                largest = num;
            } else if (num > secondLargest && num != largest) {
                secondLargest = num;
            }
        }

        return secondLargest == Integer.MIN_VALUE ? null : secondLargest;
    }

    public static void main(String[] args) {
        int[] array = {3, 1, 4, 1, 5, 9, 2, 6};
        System.out.println("Second Largest: " + findSecondLargest(array));
    }
}

Q4: OOPs Concepts with Real-World Examples

Question

Explain OOPs concepts with real-world examples.

Four Pillars of OOP

// 1. ENCAPSULATION - Data Hiding
public class BankAccount {
    private double balance;

    public BankAccount(double initialBalance) {
        this.balance = initialBalance;
    }

    public boolean withdraw(double amount) {
        if (amount > 0 && amount return true;
        }
        return false;
    }

    public double getBalance() { return balance; }
}

// 2. INHERITANCE - IS-A Relationship
abstract class Vehicle {
    protected String brand;
    public abstract void start();
}

class Car extends Vehicle {
    @Override
    public void start() {
        System.out.println("Car engine started");
    }
}

// 3. POLYMORPHISM - Same Interface, Different Implementation
interface Payment {
    boolean process(double amount);
}

class CreditCard implements Payment {
    public boolean process(double amount) {
        System.out.println("Processing via Credit Card");
        return true;
    }
}

class PayPal implements Payment {
    public boolean process(double amount) {
        System.out.println("Processing via PayPal");
        return true;
    }
}

// 4. ABSTRACTION - Hiding Complexity
abstract class Database {
    public abstract void connect();
    public abstract void disconnect();
}

Q5: Test Automation Framework Components

Question

Describe your test automation framework and its components.

Framework Structure

Hybrid Test Automation Framework
═══════════════════════════════════

project-root/
├── src/main/java/
│   ├── base/
│   │   ├── BaseTest.java
│   │   └── BasePage.java
│   ├── pages/
│   │   ├── LoginPage.java
│   │   └── HomePage.java
│   ├── utils/
│   │   ├── DriverFactory.java
│   │   ├── ConfigReader.java
│   │   ├── ExcelUtils.java
│   │   └── APIUtils.java
│   └── constants/
│       └── FrameworkConstants.java
├── src/test/java/
│   └── tests/
│       ├── smoke/
│       └── regression/
├── src/test/resources/
│   ├── config.properties
│   ├── testdata.xlsx
│   └── testng.xml
└── reports/

Q6: API Payload Validation

Question

Validate a given API payload and explain your approach.

RestAssured Validation

import io.restassured.RestAssured;
import static org.hamcrest.Matchers.*;

public class APIValidator {

    public void validateUserAPI() {
        RestAssured
            .given()
                .baseUri("https://api.example.com")
                .header("Content-Type", "application/json")
            .when()
                .get("/users/1")
            .then()
                .statusCode(200)
                .body("id", notNullValue())
                .body("name", notNullValue())
                .body("email", matchesPattern("^[A-Za-z0-9+_.-]+@(.+)$"))
                .body("age", greaterThan(0))
                .body("status", oneOf("active", "inactive"));
    }
}

Q7: Git Commands and Branching Strategies

Question

Explain commonly used Git commands and branching strategies.

Essential Git Commands

# Repository Setup
git init
git clone <url>
git remote add origin <url>

# Basic Workflow
git status
git add .
git commit -m "message"
git push origin <branch>
git pull origin <branch>

# Branching
git branch
git checkout -b <branch>
git merge <branch>
git branch -d <branch>

# Advanced
git stash
git stash pop
git rebase <branch>
git cherry-pick <commit>
git reset --hard <commit>

Git Flow Strategy

main (production)
├── develop (integration)
│   ├── feature/user-auth
│   ├── feature/payment
│   └── feature/dashboard
├── release/v2.0.0
└── hotfix/security-patch

Pro Tip

Always pull latest changes before creating a new branch.

Q8: Toggle Case in Java

Question

Write a Java program to convert uppercase to lowercase and vice versa (Example: HexAwarE -> hEXaWARe).

Toggle Case Implementation

public class CaseToggler {

    public static String toggleCase(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }

        StringBuilder result = new StringBuilder();

        for (char c : input.toCharArray()) {
            if (Character.isUpperCase(c)) {
                result.append(Character.toLowerCase(c));
            } else if (Character.isLowerCase(c)) {
                result.append(Character.toUpperCase(c));
            } else {
                result.append(c); // Keep non-alphabetic
            }
        }

        return result.toString();
    }

    public static void main(String[] args) {
        String input = "HexAwarE";
        String output = toggleCase(input);

        System.out.println("Input:  " + input);
        System.out.println("Output: " + output);
        // Output: hEXaWARe
    }
}

Q9: Jenkins CI/CD Pipeline

Question

Explain how Jenkins is integrated into a CI/CD pipeline.

Jenkinsfile Pipeline

pipeline {
    agent any

    tools {
        maven 'Maven-3.8'
        jdk 'JDK-11'
    }

    stages {
        stage('Checkout') {
            steps {
                git branch: 'main',
                    url: 'https://github.com/repo/tests.git'
            }
        }

        stage('Build') {
            steps {
                sh 'mvn clean compile'
            }
        }

        stage('Run Tests') {
            steps {
                sh 'mvn test -Dbrowser=chrome'
            }
        }

        stage('Generate Reports') {
            steps {
                publishHTML([
                    reportDir: 'target/reports',
                    reportFiles: 'index.html',
                    reportName: 'Test Report'
                ])
            }
        }
    }

    post {
        always {
            junit 'target/surefire-reports/*.xml'
        }
        failure {
            emailext (
                subject: "Build Failed",
                body: "Check Jenkins console",
                to: 'team@company.com'
            )
        }
    }
}

Q10: XPath for Menu Elements

Question

Write an XPath to locate specific menu elements on a webpage.

XPath Examples

// Menu by text
//nav//a[text()='Home']
//ul[@id='menu']//li[contains(text(), 'Products')]

// Submenu elements
//li[@class='menu-item']//ul[@class='submenu']
//nav//li[text()='Services']//following-sibling::ul

// Dynamic menu
//nav[@id='main-nav']//ul[@class='level-1']//li[@class='level-2']

// Menu with icons
//li[@class='menu-item']//i[@class='fa-home']/parent::a

// Menu by position
//ul[@id='menu']//li[3]

// Active menu
//nav//a[contains(@class, 'active') and text()='Dashboard']

Java Implementation

public void clickMenuItem(String menuText) {
    String xpath = String.format(
        "//nav//a[normalize-space()='%s']", menuText);
    driver.findElement(By.xpath(xpath)).click();
}

public void navigateToSubmenu(String menu, String submenu) {
    Actions actions = new Actions(driver);
    WebElement mainMenu = driver.findElement(
        By.xpath("//nav//li[text()='" + menu + "']"));
    actions.moveToElement(mainMenu).perform();

    driver.findElement(By.xpath(
        "//ul[@class='submenu']//a[text()='" + submenu + "']")).click();
}

Best Practice

Use relative XPath and prefer text() or contains() for stability.

Q11: Switching Between Frames

Question

Describe how to switch between frames in Selenium with a practical scenario.

Frame Switching Methods

public class FrameSwitcher {

    // Switch by index
    public void switchByIndex(int index) {
        driver.switchTo().frame(index);
    }

    // Switch by name or ID
    public void switchByNameOrId(String nameOrId) {
        driver.switchTo().frame(nameOrId);
    }

    // Switch by WebElement
    public void switchByElement(By locator) {
        WebElement frameElement = driver.findElement(locator);
        driver.switchTo().frame(frameElement);
    }

    // Switch back to main content
    public void switchToDefault() {
        driver.switchTo().defaultContent();
    }

    // Practical Scenario: Payment Gateway
    public void processPayment(String cardNumber, String cvv) {
        // Main page - click pay button
        driver.findElement(By.id("proceedToPay")).click();

        // Switch to payment iframe
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(
            By.xpath("//iframe[@id='payment-frame']")));

        // Fill payment details in iframe
        driver.findElement(By.id("card-number")).sendKeys(cardNumber);
        driver.findElement(By.id("cvv")).sendKeys(cvv);
        driver.findElement(By.id("submit-payment")).click();

        // Switch back to main content
        driver.switchTo().defaultContent();

        // Verify confirmation
        WebElement confirmation = wait.until(
            ExpectedConditions.presenceOfElementLocated(
                By.id("payment-confirmation")));
        System.out.println("Status: " + confirmation.getText());
    }
}

Q12: CSS Selectors vs XPath

Question

What is the difference between CSS Selectors and XPath?

Comparison Table

Feature          | CSS Selector        | XPath
-----------------+---------------------+----------------------
Performance      | Faster              | Slower
Syntax           | Simpler             | More complex
Traversal        | Forward only        | Bidirectional
Text search      | Not supported       | Fully supported
Parent access    | Not possible        | Possible
Browser support  | All browsers        | All browsers
Learning curve   | Easy                | Moderate

Side-by-Side Examples

// By ID
CSS:   #username
XPath: //input[@id='username']

// By Class
CSS:   .error-message
XPath: //div[@class='error-message']

// By Attribute
CSS:   input[type='email']
XPath: //input[@type='email']

// Starts With
CSS:   a[href^='https']
XPath: //a[starts-with(@href, 'https')]

// Contains
CSS:   div[class*='container']
XPath: //div[contains(@class, 'container')]

// By Text (CSS - NOT POSSIBLE)
CSS:   N/A
XPath: //button[text()='Submit']

// Parent Element (CSS - NOT POSSIBLE)
CSS:   N/A
XPath: //input[@id='username']/parent::div

// nth Element
CSS:   li:nth-child(3)
XPath: //li[3]

Best Practice

Prefer CSS for better performance. Use XPath when CSS cannot achieve the desired selection.

Q13: QA Team Structure and Work Distribution

Question

How many testers are in your team, and how is work distributed?

Team Organization

QA Team Structure (Example):
═════════════════════════════

Team Size: 6 QA Engineers

Roles:
├── QA Lead (1)
│   ├── Sprint planning
│   ├── Test strategy
│   └── Stakeholder communication
│
├── Senior QA (2)
│   ├── Framework development
│   ├── Complex feature testing
│   └── Code reviews
│
└── QA Engineers (3)
    ├── Feature testing
    ├── Test execution
    └── Bug reporting

Sprint Workflow

Sprint Timeline:

Day 1: Sprint Planning
- Story estimation
- Task assignment
- Automation planning

Days 2-8: Development & Testing
- Test case creation
- Automation scripts
- Exploratory testing

Days 9-10: Regression & Release
- Full regression suite
- Smoke testing
- Release validation

Sample Response

“Our team has 6 QA engineers including 1 lead. We follow feature-based distribution where each QA owns 2-3 modules. Stories are assigned based on module ownership and workload during sprint planning.”

Q14: Page Factory and Annotations

Question

Explain Page Factory in Selenium and its annotations.

Page Factory is a built-in Page Object Model implementation in Selenium that provides annotation-based element initialization.

Page Factory Implementation

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.How;

public class LoginPage {

    private WebDriver driver;

    // @FindBy - Basic annotation
    @FindBy(id = "username")
    private WebElement usernameField;

    @FindBy(name = "password")
    private WebElement passwordField;

    // Different locator strategies
    @FindBy(xpath = "//button[@type='submit']")
    private WebElement loginButton;

    @FindBy(css = ".error-message")
    private WebElement errorMessage;

    // Using How enum
    @FindBy(how = How.LINK_TEXT, using = "Forgot Password?")
    private WebElement forgotPasswordLink;

    // @CacheLookup - Cache element reference
    @FindBy(id = "logo")
    @CacheLookup
    private WebElement logo;

    // List of elements
    @FindBy(className = "menu-item")
    private List<WebElement> menuItems;

    // @FindBys - AND condition (all must match)
    @FindBys({
        @FindBy(className = "form-input"),
        @FindBy(name = "email")
    })
    private WebElement emailInput;

    // @FindAll - OR condition (any can match)
    @FindAll({
        @FindBy(id = "submit"),
        @FindBy(name = "submit"),
        @FindBy(xpath = "//button[@type='submit']")
    })
    private WebElement submitButton;

    // Constructor
    public LoginPage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    // Methods
    public void login(String username, String password) {
        usernameField.sendKeys(username);
        passwordField.sendKeys(password);
        loginButton.click();
    }

    public String getErrorMessage() {
        return errorMessage.getText();
    }
}

Best Practice

Avoid @CacheLookup for dynamic elements. Elements are initialized lazily only when accessed.

Q15: Constructor in Page Factory

Question

What is the purpose of a constructor in Page Factory?

The constructor in Page Factory serves multiple critical purposes for proper page object initialization.

Constructor Examples

// Basic Constructor
public class LoginPage {
    private WebDriver driver;

    @FindBy(id = "username")
    private WebElement username;

    // Constructor
    public LoginPage(WebDriver driver) {
        this.driver = driver;
        // Initialize all @FindBy elements
        PageFactory.initElements(driver, this);
    }
}

// Advanced Constructor with Wait
public class BasePage {
    protected WebDriver driver;
    protected WebDriverWait wait;

    public BasePage(WebDriver driver) {
        this.driver = driver;
        this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        PageFactory.initElements(driver, this);
    }
}

// Constructor with Custom Field Decorator
public class EnhancedPage {
    private WebDriver driver;

    public EnhancedPage(WebDriver driver) {
        this.driver = driver;
        // Custom timeout for element location
        PageFactory.initElements(
            new AjaxElementLocatorFactory(driver, 15),
            this
        );
    }
}

// Usage in Tests
@Test
public void testLogin() {
    WebDriver driver = new ChromeDriver();
    driver.get("https://example.com");

    // Constructor is called here
    LoginPage loginPage = new LoginPage(driver);
    loginPage.login("user@test.com", "password");
}

Initialization Flow

Initialization Flow:

1. Test creates page object
   LoginPage page = new LoginPage(driver);

2. Constructor receives driver
   public LoginPage(WebDriver driver) {
       this.driver = driver;

3. PageFactory.initElements() called
       PageFactory.initElements(driver, this);
   }

4. Elements are wrapped in proxies
   - @FindBy elements become proxy objects
   - Actual element location happens on first access

5. Element usage triggers location
   page.usernameField.sendKeys("test");
   // Element located NOW, not during initialization