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);