Automation - Q&A Set 1

Core automation concepts and frameworks

Q1: WebDriver Architecture

Question

Explain the WebDriver architecture and how Selenium communicates with browsers.

WebDriver uses a client-server architecture where tests act as clients sending HTTP requests to the browser driver, which then controls the browser.

WebDriver Setup Example

// Setting up WebDriver with proper configuration
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");

ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
options.addArguments("--no-sandbox");
options.addArguments("--disable-dev-shm-usage");

WebDriver driver = new ChromeDriver(options);

// Communication flow
driver.get("https://example.com"); // HTTP POST to /session/{id}/url
WebElement element = driver.findElement(By.id("submit")); // POST to /session/{id}/element
element.click(); // POST to /session/{id}/element/{id}/click

Pro Tip

Understanding this architecture helps in debugging connection issues and optimizing test performance by minimizing HTTP calls.

Q2: Page Object Model with Page Factory

Question

Implement Page Object Model with Page Factory and explain its advantages.

Page Object Implementation

// Base Page class
public abstract 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);
    }
}

// Login Page implementation
public class LoginPage extends BasePage {
    @FindBy(id = "username")
    private WebElement usernameField;

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

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

    public LoginPage(WebDriver driver) {
        super(driver);
    }

    public HomePage login(String username, String password) {
        usernameField.clear();
        usernameField.sendKeys(username);
        passwordField.clear();
        passwordField.sendKeys(password);
        loginButton.click();
        return new HomePage(driver);
    }
}

Q3: Implicit, Explicit, and Fluent Waits

Question

Differentiate between Implicit, Explicit, and Fluent waits with implementation examples.

Types of Waits

// 1. Implicit Wait - Global setting
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

// 2. Explicit Wait - Specific conditions
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

// Wait for element to be clickable
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit")));

// Wait for element to be visible
wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("loading")));

// 3. Fluent Wait - Custom polling and exceptions
FluentWait<WebDriver> fluentWait = new FluentWait<>(driver)
    .withTimeout(Duration.ofSeconds(30))
    .pollingEvery(Duration.ofSeconds(2))
    .ignoring(NoSuchElementException.class)
    .ignoring(StaleElementReferenceException.class);

WebElement element = fluentWait.until(driver -> {
    WebElement el = driver.findElement(By.id("dynamic-element"));
    return el.isDisplayed() ? el : null;
});

Q4: TestNG Annotations and Parallel Execution

Question

Explain TestNG annotations, groups, and parallel execution configuration.

TestNG Annotations

public class TestClass {

    @BeforeSuite
    public void beforeSuite() {
        // Database setup, report initialization
    }

    @BeforeClass
    public void beforeClass() {
        driver = new ChromeDriver();
    }

    @BeforeMethod(groups = {"smoke", "regression"})
    public void beforeMethod() {
        // Method-level setup - login, navigate to page
    }

    @Test(groups = "smoke", priority = 1)
    public void loginTest() {
        // High priority smoke test
    }

    @Test(groups = {"regression"}, dependsOnMethods = "loginTest")
    public void userProfileTest() {
        // Depends on login test
    }

    @Test(dataProvider = "userData")
    public void dataProviderTest(String username, String password) {
        // Data-driven test
    }

    @DataProvider(name = "userData")
    public Object[][] getUserData() {
        return new Object[][] {
            {"user1", "pass1"},
            {"user2", "pass2"}
        };
    }
}

testng.xml for Parallel Execution

<suite name="ParallelSuite" parallel="methods" thread-count="3">
    <test name="RegressionTests">
        <groups>
            <run>
                <include name="regression"/>
            </run>
        </groups>
        <classes>
            <class name="com.tests.LoginTest"/>
            <class name="com.tests.CheckoutTest"/>
        </classes>
    </test>
</suite>

Q5: Handling StaleElementReferenceException

Question

How do you handle StaleElementReferenceException and implement retry logic?

Occurs when an element reference becomes invalid due to DOM changes. Common in AJAX-heavy applications.

Retry Mechanism

// Method 1: Retry mechanism with exponential backoff
public WebElement findElementWithRetry(By locator, int maxAttempts) {
    int attempts = 0;
    while (attempts < maxAttempts) {
        try {
            return driver.findElement(locator);
        } catch (StaleElementReferenceException e) {
            attempts++;
            if (attempts == maxAttempts) throw e;

            try {
                Thread.sleep(500 * attempts); // Exponential backoff
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
            }
        }
    }
    return null;
}

// Method 2: Using ExpectedConditions
public WebElement refreshElement(By locator) {
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    return wait.until(ExpectedConditions.refreshed(
        ExpectedConditions.presenceOfElementLocated(locator)
    ));
}

Q6: Advanced Actions Class Usage

Question

Demonstrate advanced Actions class usage for complex user interactions.

Actions Class Examples

Actions actions = new Actions(driver);

// Drag and Drop
WebElement source = driver.findElement(By.id("draggable"));
WebElement target = driver.findElement(By.id("droppable"));
actions.dragAndDrop(source, target).perform();

// Hover over menu and click submenu
WebElement menu = driver.findElement(By.id("menu"));
WebElement submenu = driver.findElement(By.id("submenu"));
actions.moveToElement(menu)
       .pause(Duration.ofSeconds(1))
       .moveToElement(submenu)
       .click()
       .perform();

// Right-click context menu
actions.contextClick(element).perform();

// Double click
actions.doubleClick(element).perform();

// Keyboard shortcuts (Ctrl+A, Delete)
actions.keyDown(Keys.CONTROL)
       .sendKeys("a")
       .keyUp(Keys.CONTROL)
       .sendKeys(Keys.DELETE)
       .perform();

// Slider movement
WebElement slider = driver.findElement(By.id("slider"));
actions.clickAndHold(slider)
       .moveByOffset(100, 0)
       .release()
       .perform();

Q7: Hybrid Test Automation Framework Design

Question

Design a hybrid test automation framework with proper project structure.

Project Structure

src/
├── main/
│   ├── java/
│   │   ├── base/
│   │   │   ├── BaseTest.java
│   │   │   └── BasePage.java
│   │   ├── pages/
│   │   │   ├── LoginPage.java
│   │   │   └── HomePage.java
│   │   ├── utils/
│   │   │   ├── DriverFactory.java
│   │   │   ├── ConfigReader.java
│   │   │   └── ExtentReportManager.java
│   │   └── constants/
│   │       └── FrameworkConstants.java
│   └── resources/
│       ├── config.properties
│       └── testdata.xlsx
├── test/
│   ├── java/
│   │   └── tests/
│   │       ├── LoginTests.java
│   │       └── CheckoutTests.java
│   └── resources/
│       └── testng.xml

Base Test Implementation

public class BaseTest {
    protected ThreadLocal<WebDriver> driver = new ThreadLocal<>();
    protected Properties config;

    @BeforeSuite
    public void setupSuite() {
        ExtentReportManager.initReports();
        config = ConfigReader.loadProperties();
    }

    @BeforeMethod
    @Parameters("browser")
    public void setup(@Optional("chrome") String browser) {
        WebDriver webDriver = DriverFactory.createDriver(browser);
        driver.set(webDriver);
        getDriver().manage().window().maximize();
    }

    protected WebDriver getDriver() {
        return driver.get();
    }

    @AfterMethod
    public void tearDown(ITestResult result) {
        if (result.getStatus() == ITestResult.FAILURE) {
            String screenshot = captureScreenshot(result.getName());
            ExtentReportManager.attachScreenshot(screenshot);
        }

        if (getDriver() != null) {
            getDriver().quit();
            driver.remove();
        }
    }
}

Q8: CI/CD Pipeline with Jenkins

Question

Implement CI/CD pipeline with Jenkins for automated test execution.

Jenkinsfile Pipeline

pipeline {
    agent any

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

    parameters {
        choice(name: 'BROWSER', choices: ['chrome', 'firefox', 'edge'],
               description: 'Select browser')
        choice(name: 'TEST_SUITE', choices: ['smoke', 'regression', 'all'],
               description: 'Select test suite')
    }

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

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

        stage('Run Tests') {
            steps {
                sh """
                    mvn test -Dbrowser=\${params.BROWSER} \\
                             -Dsuite=\${params.TEST_SUITE} \\
                             -Dthreads=3
                """
            }
        }
    }

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

Q20: Best Practices and Performance Optimization

Question

What are the best practices and performance optimization techniques in Selenium?

Optimized Configuration

// Optimized ChromeOptions Configuration
ChromeOptions options = new ChromeOptions();

// Performance optimizations
options.addArguments("--headless");
options.addArguments("--disable-gpu");
options.addArguments("--no-sandbox");
options.addArguments("--disable-dev-shm-usage");
options.addArguments("--blink-settings=imagesEnabled=false");

// Page load strategy
options.setPageLoadStrategy(PageLoadStrategy.EAGER);

// Disable unnecessary features
Map<String, Object> prefs = new HashMap<>();
prefs.put("profile.managed_default_content_settings.images", 2);
prefs.put("profile.default_content_setting_values.notifications", 2);
options.setExperimentalOption("prefs", prefs);

WebDriver driver = new ChromeDriver(options);