What interviewers actually check in a Selenium interview
Selenium interviews are not a memory test on API names. Interviewers are checking whether you understand the WebDriver architecture, can write stable locators, and can design a framework that runs reliably in CI. The six areas below come up again and again.
Selenium fundamentals
WebDriver, Grid and IDE; W3C protocol; Selenium Manager; how a command travels from your Java code to the browser.
Locators and waits
Locator strategies and priority, XPath and CSS selectors, findElement vs findElements, implicit vs explicit vs fluent waits.
Handling real-world UI
Dropdowns, alerts, iframes, multiple windows, dynamic elements, JavaScriptExecutor, file uploads and screenshots.
TestNG and assertions
Annotations, priority, groups, dependsOnMethods, listeners, DataProvider, hard vs soft assertions, parallel execution.
Framework design
Page Object Model, Page Factory, data-driven and hybrid frameworks, Maven, Jenkins, Git and reporting with Extent or Allure.
Selenium 4 and modern practice
Relative locators, new window and tab APIs, CDP access, Selenium Manager and how Selenium compares to Playwright.
Selenium interview questions for freshers
These are the questions that come up first in Selenium fresher interviews. They test whether your WebDriver fundamentals are solid — answer with a short definition, then one line of why it matters.
Q01 What is Selenium, and what are its main components? +
Selenium is a set of open-source tools for browser automation. It has three main components:
- Selenium WebDriver — the API that drives a real browser. This is what you use for automation.
- Selenium Grid — runs tests on multiple machines and browsers in parallel.
- Selenium IDE — a record-and-playback browser extension, mainly for quick prototypes.
WebDriver is the only component you need for coding-based automation. Grid is for scale, IDE is for exploration.
Q02 How does Selenium WebDriver work internally? +
Your Java code calls the WebDriver API. That call is converted into a W3C WebDriver protocol HTTP request and sent to a browser driver (chromedriver, geckodriver, msedgedriver). The driver translates the request into the browser's native automation commands and returns the response back up the same chain.
This is why you need the correct driver version for your browser. Selenium 4 uses the W3C protocol end to end, which made the JSON Wire Protocol obsolete and improved cross-browser consistency.
Q03 What is Selenium Manager? +
Selenium Manager is a built-in tool that automatically downloads and configures the correct browser driver for your installed browser. In Selenium 4, you no longer need WebDriverManager or manual driver setup.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
WebDriver driver = new ChromeDriver();
driver.get("https://example.com");
Selenium Manager finds the right driver, caches it, and passes it to the browser. This removed one of the most common setup failures.
Q04 What are the different locator strategies in Selenium, and which one should you prefer? +
| Locator | Finds | Example |
|---|---|---|
| id | Element by unique id | By.id("email") |
| name | Element by name attribute | By.name("username") |
| cssSelector | Element by CSS selector | By.cssSelector("button.submit") |
| xpath | Element by XPath expression | By.xpath("//button[@type='submit']") |
| className | Element by class name | By.className("btn-primary") |
| linkText | Anchor by full link text | By.linkText("Forgot password?") |
| partialLinkText | Anchor by partial link text | By.partialLinkText("Forgot") |
| tagName | Element by tag | By.tagName("input") |
Priority in practice: id first, then name, then cssSelector, then xpath as a last resort. IDs are fastest and most stable. XPath is powerful but slower and breaks easily when the DOM structure changes.
Q05 What is the difference between findElement and findElements? +
| Method | Returns | If not found |
|---|---|---|
findElement |
A single WebElement | Throws NoSuchElementException |
findElements |
A List of WebElements | Returns an empty list |
Use findElements when you expect
zero or more matches — for example, checking
that a list is empty, or looping through rows in
a table. Use findElement when the
element must exist for the test to proceed.
Q06 What is the difference between absolute and relative XPath? +
Absolute XPath starts from the root node
with a single slash: /html/body/div[1]/form/input[2].
It breaks the moment the DOM structure changes.
Relative XPath starts with a double
slash and searches anywhere in the document:
//input[@id='email']. It is shorter,
more readable and far more resilient.
// absolute — brittle
driver.findElement(By.xpath("/html/body/div[1]/form/input[2]"));
// relative — resilient
driver.findElement(By.xpath("//input[@id='email']"));
Q07 What are the common XPath functions used in Selenium? +
contains()— partial match.//a[contains(@href, 'login')]text()— exact text.//button[text()='Submit']starts-with()— prefix match.//input[starts-with(@id, 'user_')]normalize-space()— trims whitespace before comparing.//label[normalize-space()='Email']last()— the last matching node.(//tr)[last()]position()— positional index.(//tr)[position()=2]
" Submit ", normalize-space handles it.
Q08 What is the difference between implicit, explicit and fluent wait? +
| Wait | Applies to | Behaviour |
|---|---|---|
| Implicit | Every findElement call | Polls the DOM for up to the timeout; set once per driver |
| Explicit | One specific condition | Waits for a named condition like visibilityOfElementLocated |
| Fluent | One specific condition | Like explicit, but you control the polling interval and can ignore exceptions |
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions
.elementToBeClickable(By.id("submit")))
.click();
Do not mix implicit and explicit waits — it makes the timeout behaviour unpredictable. Pick explicit waits and use them consistently.
Q09 Why is Thread.sleep() a bad practice in Selenium? +
Thread.sleep() pauses the test for
a fixed amount of time regardless of whether the
element is ready. If the element appears in 100
ms, you still waited 5 seconds. If it takes 6
seconds, the test fails anyway.
It makes the suite slower and still flaky. Use explicit waits with a condition instead — they return as soon as the condition is true, and fail clearly when it never becomes true.
Q10 What are the different ways to handle a dropdown in Selenium? +
For a native <select>
element, use the Select class:
import org.openqa.selenium.support.ui.Select;
WebElement dropdown = driver.findElement(By.id("country"));
Select select = new Select(dropdown);
select.selectByVisibleText("India");
select.selectByValue("IN");
select.selectByIndex(1);
For a custom dropdown built with divs and spans (common in React), the Select class does not work. Click the dropdown to open it, then click the option by text or value.
Q11 How do you handle an alert popup in Selenium? +
Use driver.switchTo().alert(). It
gives you the alert text and the accept, dismiss
and sendKeys methods.
Alert alert = driver.switchTo().alert();
System.out.println(alert.getText());
alert.sendKeys("Ravi"); // for prompt alerts
alert.accept(); // click OK
// alert.dismiss(); // click Cancel
Alerts are not DOM elements — you cannot find them with findElement. You must switch to them with the Alert API.
Q12 How do you switch between windows or tabs in Selenium? +
Use driver.getWindowHandles() to
get all open window handles, then
driver.switchTo().window(handle) to
move between them.
String original = driver.getWindowHandle();
driver.findElement(By.linkText("Open new tab")).click();
for (String handle : driver.getWindowHandles()) {
if (!handle.equals(original)) {
driver.switchTo().window(handle);
break;
}
}
System.out.println(driver.getTitle());
driver.switchTo().window(original); // back to first tab
Q13 How do you take a screenshot in Selenium? +
Cast the driver to
TakesScreenshot and call
getScreenshotAs(). You can capture
the whole page or just one element.
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.OutputType;
import org.apache.commons.io.FileUtils;
import java.io.File;
File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(src, new File("screenshots/login.png"));
In a framework, screenshots are captured automatically from a TestNG listener on failure and attached to the Extent or Allure report.
Q14 What are the different ways to click a button in Selenium? +
Three common approaches:
- element.click() — the normal way. Fails if the element is covered or not actionable.
- Actions.click(element).perform() — simulates a real mouse move plus click. Useful when the plain click is intercepted by an overlay.
- JavaScriptExecutor — bypasses actionability checks entirely. Use only as a last resort, because it hides real bugs.
// normal
driver.findElement(By.id("submit")).click();
// Actions
new Actions(driver)
.moveToElement(element)
.click()
.perform();
// JavaScript (last resort)
((JavascriptExecutor) driver).executeScript("arguments[0].click();", element);
Q15 What is the difference between driver.close() and driver.quit()? +
driver.close() closes only the current window or tab. If it was the last window, the browser process may still be running.
driver.quit() closes all windows and
ends the WebDriver session, killing the browser
process and releasing the driver. Always call
quit() at the end of a test to
avoid orphaned browser processes.
@AfterMethod
or @AfterClass block, or in a finally block, so it runs even if the
test fails.
Intermediate Selenium interview questions
These questions come up for candidates with 2–4 years of experience. They test whether you understand the why behind the framework and can handle real-world UI problems.
Q16 What are relative locators in Selenium 4? +
Relative locators find an element based on its position relative to another element — above, below, toLeftOf, toRightOf and near.
import static org.openqa.selenium.support.locators.RelativeLocator.with;
WebElement password = driver.findElement(
with(By.tagName("input"))
.below(By.id("email"))
);
password.sendKeys("secret");
Use them when the target element has no stable attribute of its own but is always positioned next to one that does. Do not use them as the primary strategy — they can break if the layout reorders.
Q17 What is StaleElementReferenceException, and how do you fix it? +
StaleElementReferenceException means the element you are holding is no longer attached to the DOM. This happens when the page or a section of it re-renders after you found the element.
Fixes, in order of preference:
- Re-find the element immediately before using it, instead of storing it in a variable across actions.
- Use an explicit wait with
refreshed()—ExpectedConditions.refreshed(ExpectedConditions.visibilityOf(element)). - Locate by a stable parent that does not re-render, then find the child from it.
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions
.refreshed(ExpectedConditions.elementToBeClickable(By.id("save"))))
.click();
Q18 What is JavaScriptExecutor, and when do you use it? +
JavaScriptExecutor lets you run JavaScript in the browser from your Selenium test. It is used when the normal WebDriver API cannot do what you need.
JavascriptExecutor js = (JavascriptExecutor) driver;
// scroll to an element
js.executeScript("arguments[0].scrollIntoView(true);", element);
// click when normal click is intercepted
js.executeScript("arguments[0].click();", element);
// set a value directly
js.executeScript("arguments[0].value='text';", element);
// get page title and scroll position
String title = (String) js.executeScript("return document.title;");
Long pos = (Long) js.executeScript("return window.scrollY;");
Use it sparingly. Every JavaScriptExecutor call bypasses Selenium's actionability checks, which means you may be hiding a real problem that a user would face.
Q19 How do you handle iframes in Selenium? +
You must switch into the iframe before
interacting with its contents, then switch back
out. Use index, name, WebElement or a
By locator.
// switch in by WebElement
WebElement frame = driver.findElement(By.id("payment-iframe"));
driver.switchTo().frame(frame);
driver.findElement(By.id("card-number")).sendKeys("4242424242424242");
// switch back to the main document
driver.switchTo().defaultContent();
// nested iframe — switch to parent first
driver.switchTo().frame("outer-frame");
driver.switchTo().frame("inner-frame");
driver.findElements(By.tagName("iframe")).size().
Q20 What are TestNG annotations and their order of execution? +
| Annotation | Runs |
|---|---|
| @BeforeSuite | Once before all tests in the suite |
| @BeforeTest | Before each <test> tag in testng.xml |
| @BeforeClass | Once before the first method in a class |
| @BeforeMethod | Before each @Test method |
| @Test | The test method itself |
| @AfterMethod | After each @Test method |
| @AfterClass | Once after all methods in a class |
| @AfterTest | After each <test> tag |
| @AfterSuite | Once after all tests in the suite |
In a framework, browser setup usually goes in
@BeforeMethod and teardown in
@AfterMethod so each test starts
from a clean browser session.
Q21 What is the difference between hard and soft assertions in TestNG? +
A hard assertion stops the test immediately if it fails. Use it when the rest of the test cannot continue — for example, if login fails, there is no point checking the dashboard.
A soft assertion records the failure and lets the test continue. Use it when you want to check many independent things in one test and see all failures at once.
import org.testng.asserts.SoftAssert;
SoftAssert soft = new SoftAssert();
soft.assertEquals(driver.getTitle(), "Dashboard");
soft.assertTrue(driver.findElement(By.id("welcome")).isDisplayed());
soft.assertAll(); // must be called to report failures
Note: If you forget assertAll(), soft assertion
failures are silently ignored.
Q22 What is DataProvider in TestNG, and how do you use it for data-driven testing? +
DataProvider feeds multiple sets of data into the same test method. The test runs once per data row, which is how you build a data-driven test.
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class LoginDataTest {
@DataProvider(name = "loginData")
public Object[][] loginData() {
return new Object[][] {
{ "ravi@example.com", "secret", true },
{ "ravi@example.com", "wrong", false },
{ "unknown@example.com", "secret", false },
};
}
@Test(dataProvider = "loginData")
public void loginTest(String email, String password, boolean shouldPass) {
// use the parameters in the test
}
}
You can also read the data from an Excel sheet or CSV file inside the DataProvider method, which keeps test data out of the code.
Q23 How do you run tests in parallel with TestNG? +
Two ways: through testng.xml or
through Maven Surefire configuration. In
testng.xml, set
parallel and
thread-count.
<suite name="Smoke" parallel="methods" thread-count="4">
<test name="LoginTests">
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
</suite>
Each parallel thread must have its own
WebDriver instance. Do not share a driver
across threads — it will cause race conditions
and stale element errors. Use
ThreadLocal<WebDriver> to
keep one driver per thread.
Q24 What is the Page Object Model, and why is it used? +
The Page Object Model puts all locators and page actions into a separate class per page. Tests then call readable methods instead of raw locators.
Benefits:
- Maintainability — when the UI changes, you fix one file, not fifty tests.
- Readability —
loginPage.login(email, password)is clearer than five lines of findElement. - Reusability — the same page object is used across many tests.
public class LoginPage {
private final WebDriver driver;
private final By email = By.id("email");
private final By password = By.id("password");
private final By submit = By.cssSelector("button[type='submit']");
public LoginPage(WebDriver driver) { this.driver = driver; }
public void login(String user, String pass) {
driver.findElement(email).sendKeys(user);
driver.findElement(password).sendKeys(pass);
driver.findElement(submit).click();
}
}
Q25 What is Page Factory, and how does it differ from Page Object Model? +
Page Factory is a Selenium support class
that works with the Page Object Model. You
declare fields with @FindBy and
call PageFactory.initElements().
Selenium then initialises the locators for you.
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class LoginPage {
@FindBy(id = "email") private WebElement email;
@FindBy(id = "password") private WebElement password;
@FindBy(css = "button[type='submit']") private WebElement submit;
public LoginPage(WebDriver driver) {
PageFactory.initElements(driver, this);
}
public void login(String user, String pass) {
email.sendKeys(user);
password.sendKeys(pass);
submit.click();
}
}
@FindBy also supports
@FindBys (AND) and
@FindAll (OR) for chained
conditions. Some teams now prefer plain
By locators over Page Factory
because they give better error messages when a
locator fails.
Q26 How do you handle a dynamic element whose ID changes on every page load? +
Several approaches, from most to least preferred:
- Use a stable attribute — look for data-testid, name, aria-label or any attribute that does not change.
- Use partial matching —
By.xpath("//input[starts-with(@id, 'user_')]")orBy.cssSelector("input[id^='user_']"). - Use text or label — anchor on the label next to the input and navigate from it.
- Use a stable parent — find the container by a stable attribute, then find the input inside it.
- Ask the developer to add a data-testid — this is the correct long-term fix.
Q27 How do you perform a mouse hover and drag-and-drop in Selenium? +
Use the Actions class. It builds
a sequence of low-level user gestures and
executes them when you call
perform().
Actions actions = new Actions(driver);
// hover
actions.moveToElement(driver.findElement(By.id("menu"))).perform();
// drag and drop
WebElement source = driver.findElement(By.id("source"));
WebElement target = driver.findElement(By.id("target"));
actions.dragAndDrop(source, target).perform();
// click and hold, then move
actions.clickAndHold(source)
.moveToElement(target)
.release()
.perform();
Q28 What is Selenium Grid, and how does it work? +
Selenium Grid distributes tests across multiple machines and browsers in parallel. It has two roles:
- Hub — receives test requests and routes them to a matching node. The test code talks only to the hub.
- Node — a machine with a browser and driver registered with the hub. The actual test runs here.
In Selenium 4, the standalone Grid runs both hub and node in one process. Docker Compose or Kubernetes is the common way to scale it.
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.net.URL;
DesiredCapabilities caps = new DesiredCapabilities();
caps.setBrowserName("chrome");
WebDriver driver = new RemoteWebDriver(
new URL("http://grid-hub:4444"), caps);
Q29 How do you read test data from an Excel file in Selenium? +
Use Apache POI to read .xlsx files. Wrap the read in a helper class and call it from a DataProvider.
import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;
public Object[][] readExcel(String path) throws Exception {
FileInputStream fis = new FileInputStream(path);
Workbook workbook = WorkbookFactory.create(fis);
Sheet sheet = workbook.getSheetAt(0);
int rows = sheet.getLastRowNum();
int cols = sheet.getRow(0).getLastCellNum();
Object[][] data = new Object[rows][cols];
for (int i = 1; i <= rows; i++) {
for (int j = 0; j < cols; j++) {
data[i - 1][j] = sheet.getRow(i).getCell(j).toString();
}
}
workbook.close();
return data;
}
Note: For CSV, use OpenCSV or a simple BufferedReader. CSV is lighter and easier to version-control than Excel.
Q30 How do you upload a file in Selenium? +
For a standard <input type="file">
element, use sendKeys() with the
absolute file path. Do not click the input — it
opens the OS file dialog, which Selenium cannot
control.
WebElement upload = driver.findElement(By.id("resume"));
upload.sendKeys("/Users/ravi/Documents/resume.pdf");
// verify the upload succeeded
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.visibilityOfElementLocated(
By.xpath("//div[text()='Upload complete']")));
If the upload uses a custom drag-drop widget,
use AutoIt or Robot class on Windows, or
setInputFiles-style alternatives
on the framework side.
Q31 What is headless mode, and when do you use it? +
Headless mode runs the browser without a visible window. It is faster, uses less memory, and works on CI servers without a display.
import org.openqa.selenium.chrome.ChromeOptions;
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new");
options.addArguments("--window-size=1920,1080");
WebDriver driver = new ChromeDriver(options);
Use headless for CI runs. Use headed mode locally when debugging, because you can see what the browser is doing. Some visual differences exist — always do a headed run before signing off on a UI change.
Q32 What is cross-browser testing, and how do you implement it in Selenium? +
Cross-browser testing means running the same tests against Chrome, Firefox, Edge and Safari to catch browser-specific issues.
Implementation approaches:
- Parameterise the browser — read the browser name from a config file or a TestNG parameter and create the right driver in a factory class.
- Use Selenium Grid — send tests to nodes running the browsers you need.
- Use a cloud provider — BrowserStack, LambdaTest or Sauce Labs give you a large browser matrix without local setup.
public static WebDriver createDriver(String browser) {
switch (browser.toLowerCase()) {
case "firefox": return new FirefoxDriver();
case "edge": return new EdgeDriver();
default: return new ChromeDriver();
}
}
Q33 What are the common exceptions in Selenium, and how do you handle them? +
| Exception | Cause | Fix |
|---|---|---|
| NoSuchElementException | Locator did not match any element | Verify the locator; add an explicit wait |
| StaleElementReferenceException | Element was removed from the DOM | Re-find the element; use refreshed() |
| ElementNotInteractableException | Element exists but cannot receive input | Scroll into view; wait for visibility |
| ElementClickInterceptedException | Another element covers the target | Wait for the overlay to disappear; use Actions |
| TimeoutException | Expected condition never became true | Increase timeout only after verifying the locator is correct |
| NoSuchFrameException | Frame not found | Wait for the frame; verify the index/name |
| NoAlertPresentException | No alert to switch to | Add a wait for the alert; verify the alert actually appears |
| WebDriverException | Driver or browser session issue | Check driver version; restart browser |
Catch exceptions at the utility layer, not
inside every test. A retry wrapper around
click() that handles
StaleElementReferenceException
keeps tests clean.
Selenium interview questions for experienced professionals
These questions come up for candidates with 5+ years of experience or for anyone interviewing at a product company. They expect you to reason about framework design and reliability, not just write a single test.
Q34 How would you design a Selenium automation framework from scratch? +
Layer 1 — Base setup: a base test class with @BeforeMethod and
@AfterMethod that creates and quits the driver. A driver factory
handles browser selection.
Layer 2 — Configuration: a config.properties file for URL,
browser, timeouts and credentials. Read it through a ConfigReader utility.
Layer 3 — Page Objects: one class per page, containing locators and page actions. No assertions inside page objects — they return data or navigate, and tests assert.
Layer 4 — Utilities: explicit wait helpers, screenshot helpers, Excel/CSV readers, JavaScript helpers.
Layer 5 — Test data: externalised to Excel or JSON, fed through DataProvider.
Layer 6 — Listeners: TestNG listeners for retry on failure, screenshots on failure, and Extent or Allure reporting.
Layer 7 — Tests: organised by feature, using page objects and data providers. No raw locators in tests.
Layer 8 — Build and CI: Maven for dependencies, Jenkins or GitHub Actions for running the suite on every commit and publishing the report.
Q35 How do you handle flaky tests in Selenium? +
Flakiness almost always comes from one of five causes. Diagnose before you add retries.
- Bad locators — CSS or XPath that matches multiple elements. Switch to id or a stable attribute.
- Missing waits — the test acts before the app is ready. Replace Thread.sleep with explicit waits on a specific condition.
- Shared state — tests depend on data created by other tests. Make each test create and clean up its own data.
- Parallelism problems — a shared WebDriver across threads. Use
ThreadLocal<WebDriver>. - Environment issues — slow CI machines, third-party APIs. Add retries at the network layer, not at the test layer.
Retry listeners are a safety net, not a fix. If a test needs two retries to pass, treat it as a bug and investigate.
Q36 How do you run Selenium tests in Jenkins? +
Jenkins runs your Maven or Gradle build on a schedule or on every commit.
- Install prerequisites — JDK, Maven and a browser (headless Chrome is common) on the Jenkins agent.
- Create a job — a freestyle or pipeline job that checks out the repo and
runs
mvn clean test. - Pass parameters — browser, environment and suite name as job parameters
or as
-Dsystem properties. - Publish reports — use the JUnit plugin for TestNG results and archive the Extent or Allure report folder as a build artifact.
- Trigger — poll SCM, use a webhook, or run nightly as a regression suite.
mvn clean test -Dbrowser=chrome -Denv=staging -Dsuite=smoke.xml
Q37 How do you report test results with Extent Reports or Allure? +
Both produce an HTML dashboard. Extent Reports is a Java library you call directly from a TestNG listener. Allure is a framework that collects results from many tools and generates a report with history and categories.
public class TestListener implements ITestListener {
ExtentReports extent = new ExtentReports();
ExtentTest test;
public void onTestStart(ITestResult result) {
test = extent.createTest(result.getMethod().getMethodName());
}
public void onTestSuccess(ITestResult result) {
test.pass("Test passed");
}
public void onTestFailure(ITestResult result) {
test.fail(result.getThrowable());
// attach a screenshot here
}
public void onFinish(ITestContext context) {
extent.flush(); // writes the report
}
}
Register the listener in
testng.xml or with
@Listeners. Reports should include
the failure stack trace, the screenshot and
the test data used.
Q38 How do you implement a retry mechanism for failed tests in TestNG? +
Implement IRetryAnalyzer and
attach it to tests via a listener or on each
@Test.
public class RetryAnalyzer implements IRetryAnalyzer {
private int count = 0;
private static final int MAX = 2;
public boolean retry(ITestResult result) {
if (count < MAX) {
count++;
return true;
}
return false;
}
}
public class RetryTransformer implements IAnnotationTransformer {
public void transform(ITestAnnotation annotation, Class testClass,
Constructor testConstructor, Method testMethod) {
annotation.setRetryAnalyzer(RetryAnalyzer.class);
}
}
This applies retry to every test without touching each one. Track retry counts and report them — a test that passes only on retry is still a signal that something is flaky.
Q39 How do you handle multiple environments (dev, staging, prod) in a Selenium framework? +
Externalise everything environment-specific. Use one properties file per environment and select it at run time.
baseUrl=https://staging.example.com
browser=chrome
timeout=20
adminUser=staging_admin
adminPass=${STAGING_ADMIN_PASSWORD}
String env = System.getProperty("env", "staging");
String path = "src/test/resources/" + env + ".properties";
Properties props = new Properties();
props.load(new FileInputStream(path));
driver.get(props.getProperty("baseUrl"));
Never commit passwords. Read them from environment variables or a secret manager, and keep production runs limited to read-only smoke tests.
Q40 How do you test a page that requires a file download? +
Set the browser's download directory and disable the download prompt through options, then verify the file on disk.
ChromeOptions options = new ChromeOptions();
Map<String, Object> prefs = new HashMap<>();
prefs.put("download.default_directory", "/tmp/downloads");
prefs.put("download.prompt_for_download", false);
options.setExperimentalOption("prefs", prefs);
WebDriver driver = new ChromeDriver(options);
driver.findElement(By.linkText("Export CSV")).click();
// wait for the file to appear, then assert
File file = new File("/tmp/downloads/report.csv");
Assert.assertTrue(file.exists());
Always add a wait for the file to appear — downloads are asynchronous and the test will otherwise check before the file is written.
Q41 How do you test a page with a CAPTCHA? +
Do not try to defeat CAPTCHA. Design around it.
- Disable in test env — ask the team to turn off CAPTCHA for test accounts. This is the cleanest approach.
- Use a test-friendly reCAPTCHA key — Google provides test keys that always pass. Use them in staging.
- Seed the session — log in once manually, save cookies, and inject them into the driver so the login flow is skipped.
- Bypass via API — if the app supports it, create the session through the API and set the token in the browser's local storage.
Never hard-code production credentials or automate a third-party CAPTCHA service that forbids it.
Q42 How do you measure and improve Selenium test execution time? +
Practical levers, roughly in order of impact:
- Run in parallel — TestNG parallel methods or classes with a per-thread driver. The single biggest win.
- Use headless mode — 20–30% faster in most cases.
- Replace fixed sleeps with explicit waits — tests complete as soon as the condition is met.
- Reduce redundant navigation — reuse a logged-in session instead of logging in through the UI in every test.
- Trim the smoke suite — the full regression belongs in nightly runs, not on every commit.
- Disable images and CSS where possible for non-visual tests.
- Set page load strategy to eager or none when the test does not need every resource.
Q43 What are the limitations of Selenium? +
- No built-in reporting — you need TestNG, Extent or Allure.
- No built-in auto-waiting — you must write explicit waits; Playwright handles this automatically.
- No network interception in older versions — Selenium 4 added CDP access, but Playwright's route API is simpler.
- No built-in parallelisation — you rely on TestNG or Grid.
- Web only — no desktop or mobile testing without Appium.
- Slower than API or unit tests — UI tests are the slowest layer of the test pyramid.
- Flaky by default — without good waits and locators, tests break on timing.
None of these are blockers. They just mean you build more of the framework yourself than you would with Playwright.
Q44 What is the difference between Selenium and Playwright? +
| Feature | Selenium | Playwright |
|---|---|---|
| Communication | W3C WebDriver over HTTP | Bi-directional WebSocket-style protocol |
| Auto-waiting | Manual explicit waits | Built-in actionability checks |
| Languages | Java, Python, C#, Ruby, JS, Kotlin | TypeScript, JS, Python, Java, C# |
| Browsers | Chrome, Firefox, Edge, Safari, IE (legacy) | Chromium, Firefox, WebKit |
| Parallelism | TestNG, Grid, or cloud | Workers built in |
| Tooling | Third-party or IDE plugins | Codegen, trace viewer, UI mode bundled |
| Ecosystem | Very large, many years of community content | Growing fast, modern |
Selenium still has broader language and browser support and a large existing job market. Playwright is faster to set up and has stronger debugging tools. Many testers learn both.
Q45 How do you keep locators stable when the UI changes? +
Locator maintenance is the biggest cost in Selenium automation. Practical habits:
- Centralise locators — keep them in Page Objects, not scattered across tests.
- Prefer stable attributes — id, name, data-testid. Avoid auto-generated
classes like
css-1a2b3c. - Avoid absolute XPath — a single div added at the top breaks the whole path.
- Use relative XPath with a stable anchor — anchor on a label, a section id, or a nearby heading.
- Agree on test IDs with developers — a data-testid attribute that only tests use is the single biggest reliability win.
- Run smoke tests on every commit — locator breaks show up within minutes, not days.
Q46 How do you handle a dropdown that is not a native <select> element? +
Custom dropdowns (common in React, Angular and
Vue) are built with divs and spans. The
Select class will not work.
- Click the dropdown trigger to open it.
- Wait for the option list to be visible.
- Click the option by its visible text, or by a data-value attribute if the text is dynamic.
driver.findElement(By.cssSelector(".dropdown-trigger")).click();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".dropdown-menu")));
driver.findElement(By.xpath("//li[text()='India']")).click();
Q47 What is CDP in Selenium 4, and when do you use it? +
CDP (Chrome DevTools Protocol) gives Selenium 4 direct access to Chrome's DevTools. It is used for tasks that the normal WebDriver API cannot handle.
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v120.network.Network;
ChromeDriver driver = new ChromeDriver();
DevTools devTools = driver.getDevTools();
devTools.createSession();
devTools.send(Network.enable());
devTools.addListener(Network.requestWillBeSent(),
request -> System.out.println(request.getRequest().getUrl()));
Use CDP for network throttling, geolocation spoofing, capturing console logs and intercepting requests. Chrome and Edge only — Firefox and Safari use different protocols.
Q48 How do you decide what to automate and what to leave manual? +
Automate:
- Regression tests that run on every release.
- Smoke tests for critical paths — login, checkout, payment.
- Data-driven tests where the same flow runs with many inputs.
- Tests that are tedious, repetitive, or error-prone for humans.
- API tests — fast, stable and cheap to run.
Leave manual:
- Exploratory testing where the value is human insight.
- Visual and UX evaluation that needs judgement.
- One-off tests that will never run again.
- Features that change every week — automation would be rewritten constantly.
Aim for a healthy test pyramid: many unit tests, a solid layer of API tests, and a focused set of UI tests for the critical journeys.
Scenario-based Selenium interview questions
These are the questions an interviewer asks when they want to see how you think under a realistic problem, not just how well you recall definitions. Answer with a step-by-step approach.
S01 A Selenium test passes locally but fails in CI with NoSuchElementException. How do you debug it? +
Step 1 — Capture a screenshot from the CI failure. If the page is blank or shows a different screen, the issue is navigation or environment, not the locator.
Step 2 — Check the CI logs for the URL at the moment of failure. If it is a login page, the session was not seeded correctly.
Step 3 — Check for timing. CI machines are slower. If the element appears after a network call, add an explicit wait on a specific condition.
Step 4 — Check for viewport size. CI headless browsers default to a smaller viewport, which can change the DOM — some elements may not render.
Step 5 — If the failure is intermittent, look for parallel execution problems. Multiple tests sharing a driver or a data set will cause exactly this.
S02 A dropdown is not selectable by the Select class. What do you do? +
Step 1 — Inspect the element in DevTools. If it is not a
<select>, the Select class will not work — this is expected, not
a bug.
Step 2 — Identify the actual structure — usually a div with a click handler and a list of options that appears on click.
Step 3 — Click the trigger, wait for the option list to be visible, then click the option by its text.
Step 4 — If the option text is dynamic, look for a data-value, data-key or aria attribute and match on that.
Step 5 — If the dropdown is inside an iframe, switch into the iframe first.
S03 A test passes in Chrome but fails in Firefox. What do you check first? +
Step 1 — Look at the failure message. If it is NoSuchElement, the locator may be browser-specific — XPath handling differs slightly between engines.
Step 2 — Check CSS layout. Firefox may render spacing and overflow differently, which can push elements off-screen or trigger a scroll.
Step 3 — Check for browser-specific features. Some JavaScript or CSS APIs are not supported in every engine.
Step 4 — Check for default behaviour differences. Date inputs, file uploads and number spinners behave differently across browsers.
Step 5 — If the bug is real, report it. If the test is over-specified, loosen the assertion to focus on behaviour rather than exact rendering.
S04 An element is visible in the browser but Selenium says it is not displayed. How do you investigate? +
Step 1 — Check the element's CSS. isDisplayed() returns false if
the element has zero size, is hidden by display: none or
visibility: hidden, or is off-screen.
Step 2 — Check for an overlay. A modal or cookie banner may be covering the element without hiding it.
Step 3 — Scroll the element into view with JavaScriptExecutor and check again.
Step 4 — Check for opacity: 0 or a parent with zero height. Selenium considers these hidden.
Step 5 — If the app intentionally hides the element and you still need to interact, use JavaScriptExecutor. But document why — you may be testing something the user cannot actually do.
S05 Your test suite takes 2 hours to run. How do you bring it under 30 minutes? +
Step 1 — Measure first. Sort tests by duration and optimise the top ten.
Step 2 — Run tests in parallel with TestNG. This is usually the biggest single win — 2 to 4x reduction on a suitable machine.
Step 3 — Replace UI logins with a saved cookie or session token. Every test that logs in through the UI costs 5–10 seconds.
Step 4 — Split the suite: run a smoke subset on every commit and the full regression nightly.
Step 5 — Remove redundant tests. Overlapping tests add time without adding coverage.
Step 6 — Use Selenium Grid or a cloud provider to distribute the load across machines.
S06 A test needs to verify data across two tabs. How do you do it in Selenium? +
Step 1 — Save the current window handle before opening the new tab.
Step 2 — Trigger the action that opens the new tab.
Step 3 — Loop through getWindowHandles() and switch to the one
that is not the original handle.
Step 4 — Perform the verification on the new tab.
Step 5 — Switch back to the original handle with
driver.switchTo().window(originalHandle) before continuing.
Step 6 — If you need to close the new tab, call driver.close()
and switch back to the remaining handle.
S07 Your team wants to add 200 new UI tests. How do you keep the suite maintainable? +
Step 1 — Enforce the Page Object Model. No locators in test classes. Every page interaction goes through a page method.
Step 2 — Centralise test data. Unique users, orders and IDs generated per run so parallel tests do not collide.
Step 3 — Establish naming conventions for tests and page objects. Future maintainers will thank you.
Step 4 — Set up a listener for automatic screenshots and trace capture on failure.
Step 5 — Add a retry listener for genuinely flaky third-party interactions, but report retry counts so you can fix the root cause.
Step 6 — Split the suite into smoke and regression. Run smoke on every commit and regression nightly.
Step 7 — Review the suite quarterly. Delete tests that no longer add value.
S08 A developer changes the ID of a critical input field. How do you handle it? +
Step 1 — If the locator is in a Page Object, update it in one place. That is the whole point of the Page Object Model.
Step 2 — Ask the developer why the ID changed. If it was arbitrary, request that stable IDs are treated as part of the contract.
Step 3 — Agree on a convention with the team: use data-testid for
elements that tests rely on, and do not change them without notice.
Step 4 — Add a smoke test that runs on every commit and covers this element. The break will be caught in minutes.
Step 5 — If the change was intentional, update the page object and move on.
S09 A page has a table with 500 rows and you need to verify the last row. How do you do it efficiently? +
Step 1 — Do not load and assert 500 rows in the UI. That is slow and fragile.
Step 2 — Use pagination or filtering if the app supports it. Navigate to the last page and verify the row there.
Step 3 — If the table loads all rows at once, use XPath
(//tr)[last()] or CSS tr:last-child to get the last row
directly.
Step 4 — Verify the data through the API if possible. It is faster and more reliable than parsing HTML.
Step 5 — If you must verify all rows, read them in a single findElements call and loop over the list rather than issuing 500 separate findElement calls.
S10 Your test needs to wait for a background process that finishes in 30 seconds. How do you handle it? +
Step 1 — Do not use a 30-second fixed sleep. It is slow when the process finishes quickly and still fails when it takes longer.
Step 2 — Identify a UI signal that the process has finished — a success message, a status changing to "Complete", a spinner disappearing.
Step 3 — Use an explicit wait on that signal with a timeout that is generous but not unlimited — 45 or 60 seconds is reasonable.
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(60));
wait.until(ExpectedConditions.textToBePresentInElementLocated(
By.id("status"), "Complete"));
Step 4 — If there is no UI signal, poll a status API instead of the DOM. It is faster and does not depend on rendering.
Step 5 — Log how long the wait actually took. If it is consistently near the timeout, the underlying process may need attention.
Selenium coding round — Selenium 4 + TestNG Java snippets
These are the ten snippets that come up most often in Selenium coding rounds. Write each one by hand at least once before your interview — reading Java is not the same as writing it.
C01 Launch a browser with Selenium Manager and open a page +
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class LaunchTest {
public static void main(String[] args) {
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new");
options.addArguments("--window-size=1920,1080");
WebDriver driver = new ChromeDriver(options);
driver.get("https://example.com");
System.out.println("Title: " + driver.getTitle());
System.out.println("URL: " + driver.getCurrentUrl());
driver.quit();
}
}
Title: Example Domain URL: https://example.com/
Note: Selenium 4 downloads and configures the correct driver automatically — no WebDriverManager or manual chromedriver setup needed.
C02 Explicit wait for an element to be clickable +
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.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
public class ExplicitWaitTest {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("https://example.com/login");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement submit = wait.until(
ExpectedConditions.elementToBeClickable(By.id("submit")));
submit.click();
driver.quit();
}
}
Wait completes as soon as the button is clickable — no fixed sleep
C03 Handle a native dropdown using the Select class +
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;
public class DropdownTest {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("https://example.com/signup");
WebElement country = driver.findElement(By.id("country"));
Select select = new Select(country);
select.selectByVisibleText("India");
System.out.println("Selected: " + select.getFirstSelectedOption().getText());
driver.quit();
}
}
Selected: India
C04 Switch to a new window and back +
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.Set;
public class WindowSwitchTest {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("https://example.com");
String original = driver.getWindowHandle();
driver.findElement(By.linkText("Open new tab")).click();
Set<String> handles = driver.getWindowHandles();
for (String handle : handles) {
if (!handle.equals(original)) {
driver.switchTo().window(handle);
break;
}
}
System.out.println("New tab title: " + driver.getTitle());
driver.switchTo().window(original);
driver.quit();
}
}
New tab title: Example Domain
C05 Switch into an iframe and back to the main document +
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class IframeTest {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("https://example.com/checkout");
WebElement frame = driver.findElement(By.id("payment-iframe"));
driver.switchTo().frame(frame);
driver.findElement(By.id("card-number"))
.sendKeys("4242424242424242");
driver.switchTo().defaultContent();
System.out.println("Back on main page: " + driver.getTitle());
driver.quit();
}
}
Back on main page: Checkout
C06 Handle a JavaScript alert +
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
public class AlertTest {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("https://example.com");
driver.findElement(By.id("delete-btn")).click();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
Alert alert = wait.until(ExpectedConditions.alertIsPresent());
System.out.println("Alert text: " + alert.getText());
alert.accept();
driver.quit();
}
}
Alert text: Are you sure you want to delete this record?
C07 Take a screenshot and save it to disk +
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
public class ScreenshotTest {
public static void main(String[] args) throws IOException {
WebDriver driver = new ChromeDriver();
driver.get("https://example.com");
File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
File dest = new File("screenshots/home.png");
FileUtils.copyFile(src, dest);
System.out.println("Screenshot saved to " + dest.getAbsolutePath());
driver.quit();
}
}
Screenshot saved to /project/screenshots/home.png
C08 Mouse hover and drag-and-drop with Actions +
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.interactions.Actions;
public class ActionsTest {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("https://example.com");
Actions actions = new Actions(driver);
// hover over a menu
WebElement menu = driver.findElement(By.id("user-menu"));
actions.moveToElement(menu).perform();
// drag and drop
WebElement source = driver.findElement(By.id("draggable"));
WebElement target = driver.findElement(By.id("droppable"));
actions.dragAndDrop(source, target).perform();
System.out.println("Hover and drag complete");
driver.quit();
}
}
Hover and drag complete
C09 Upload a file using sendKeys +
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class UploadTest {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("https://example.com/upload");
WebElement fileInput = driver.findElement(By.id("resume"));
fileInput.sendKeys("/Users/ravi/Documents/resume.pdf");
driver.findElement(By.id("upload-btn")).click();
System.out.println("File uploaded");
driver.quit();
}
}
File uploaded
Note: Use the absolute path to the file. Never click the file input — that opens the OS dialog which Selenium cannot control.
C10 Read test data from Excel with a TestNG DataProvider +
import org.apache.poi.ss.usermodel.*;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.io.FileInputStream;
public class ExcelDataTest {
@DataProvider(name = "excelData")
public Object[][] readData() throws Exception {
FileInputStream fis = new FileInputStream("src/test/resources/login.xlsx");
Workbook wb = WorkbookFactory.create(fis);
Sheet sheet = wb.getSheetAt(0);
int rows = sheet.getLastRowNum();
int cols = sheet.getRow(0).getLastCellNum();
Object[][] data = new Object[rows][cols];
for (int i = 1; i <= rows; i++) {
for (int j = 0; j < cols; j++) {
data[i - 1][j] = sheet.getRow(i).getCell(j).toString();
}
}
wb.close();
return data;
}
@Test(dataProvider = "excelData")
public void loginTest(String email, String password) {
System.out.println("Testing: " + email + " / " + password);
}
}
Testing: ravi@example.com / secret Testing: anita@example.com / pass123 Testing: sam@example.com / test456
Explain a Page Object Model + TestNG + Maven + Jenkins framework
This is a common system design question for automation engineer interviews. The interviewer wants to see that you know how the pieces fit together, not just that you can write a test.
selenium-framework/
├── pom.xml
├── testng.xml
├── src/
│ ├── main/
│ │ └── java/
│ │ ├── pages/
│ │ │ ├── LoginPage.java
│ │ │ ├── DashboardPage.java
│ │ │ └── CheckoutPage.java
│ │ ├── utils/
│ │ │ ├── DriverFactory.java
│ │ │ ├── ConfigReader.java
│ │ │ ├── WaitHelper.java
│ │ │ ├── ScreenshotUtil.java
│ │ │ └── ExcelReader.java
│ │ └── listeners/
│ │ ├── TestListener.java
│ │ └── RetryAnalyzer.java
│ └── test/
│ ├── java/
│ │ └── tests/
│ │ ├── BaseTest.java
│ │ ├── LoginTest.java
│ │ └── CheckoutTest.java
│ └── resources/
│ ├── config.properties
│ ├── staging.properties
│ ├── prod.properties
│ └── testdata/
│ └── login.xlsx
└── reports/
├── extent-report.html
└── screenshots/
| Part | Role | Key detail |
|---|---|---|
| pom.xml | Maven dependencies and build config | Pulls in Selenium 4, TestNG, Apache POI, Extent Reports and Commons IO. Profiles for dev/staging/prod. |
| testng.xml | Suite definition | Groups tests, sets parallel mode and thread count, registers listeners. |
| DriverFactory | Creates the right driver | Reads the browser name from config, returns ChromeDriver, FirefoxDriver or EdgeDriver. Uses ThreadLocal for parallel safety. |
| BaseTest | Shared setup and teardown | @BeforeMethod creates the driver and navigates to the base URL. @AfterMethod quits the driver. |
| Page Objects | Locators and page actions | No assertions inside page objects — they return data or navigate. Tests assert. |
| TestListener | Reporting and failure handling | Implements ITestListener. Captures screenshots on failure, logs steps to Extent Reports. |
| RetryAnalyzer | Retry on failure | Implements IRetryAnalyzer. Retries a failed test a fixed number of times. Attached via IAnnotationTransformer. |
| ExcelReader / DataProvider | Data-driven tests | Reads test data from .xlsx or .csv and feeds it to @Test methods through a DataProvider. |
| config.properties | Environment config | Base URL, browser, timeouts and credentials. Selected by an env system property. |
| Extent Reports | HTML report | One HTML file per run, with pass/fail status, stack traces and attached screenshots. |
| Jenkins pipeline | CI execution | Runs mvn clean test on every commit. Publishes the TestNG JUnit report and
archives the Extent report. |
Quick-revision cheat table
Fifteen one-line definitions and syntax reminders to skim on the morning of your interview.
| Topic | One-line reminder |
|---|---|
| Selenium components | WebDriver for automation, Grid for parallel, IDE for record-playback. |
| W3C protocol | Selenium 4 uses the W3C WebDriver protocol end to end — no more JSON Wire Protocol. |
| Selenium Manager | Downloads and configures the right browser driver automatically. |
| Locator priority | id > name > cssSelector > xpath. Prefer stable attributes over structure. |
| findElement vs findElements | findElement returns one element or throws; findElements returns a list or empty. |
| Absolute vs relative XPath | Absolute starts with / and breaks easily; relative starts with // and is resilient. |
| Implicit vs explicit wait | Implicit applies to every findElement; explicit waits for a specific condition. |
| Thread.sleep | Never use it. Always wait for a condition with an explicit wait. |
| StaleElementReferenceException | Element was removed from the DOM. Re-find it or use refreshed(). |
| Select class | Works only on native <select> elements. Custom dropdowns need
click-based handling. |
| Switch frame | switchTo().frame() to enter; switchTo().defaultContent() to exit. |
| Switch window | getWindowHandles() returns all handles; switchTo().window(handle) changes focus. |
| TestNG annotations | @BeforeSuite → @BeforeTest → @BeforeClass → @BeforeMethod → @Test → @AfterMethod → @AfterClass → @AfterTest → @AfterSuite. |
| Hard vs soft assertion | Hard stops the test; soft records failures and continues until assertAll(). |
| DataProvider | Feeds multiple data sets into one @Test; the test runs once per row. |
| Page Object Model | One class per page with locators and actions. No assertions inside page objects. |
| Page Factory | Uses @FindBy and PageFactory.initElements() to initialise locators. |
| Relative locators | Selenium 4 — above, below, toLeftOf, toRightOf, near. |
| CDP | Chrome DevTools Protocol access in Selenium 4 — network throttling, console logs, geolocation. |
| Retry mechanism | Implement IRetryAnalyzer and attach via IAnnotationTransformer. |
How to prepare for a Selenium interview in 7 days
If your interview is next week, follow this plan. Each day has a single focus and a practice task — do not just read, write code.
| Day | Focus | Practice task |
|---|---|---|
| Day 1 | WebDriver fundamentals | Answer Q1–Q8 out loud. Write a script that launches Chrome, navigates to a page, and prints the title. Run it. |
| Day 2 | Locators and XPath | Answer Q4, Q6, Q7, Q26. Write five locators for the same element using id, name, CSS, relative XPath and contains(). |
| Day 3 | Waits and exceptions | Answer Q8, Q9, Q17, Q33. Write an explicit wait that clicks a button. Handle a StaleElementReferenceException with refreshed(). |
| Day 4 | Handling UI elements | Answer Q10–Q14, Q19, Q27, Q30. Write snippets for dropdown, alert, iframe, window switch, hover, drag-drop and file upload. |
| Day 5 | TestNG | Answer Q20–Q23. Create a TestNG class with @BeforeMethod, @AfterMethod, a DataProvider and a parallel testng.xml. |
| Day 6 | Framework and reporting | Answer Q24, Q25, Q34, Q37. Draw the POM folder structure from memory. Add an Extent listener that captures screenshots on failure. |
| Day 7 | Mock interview | Answer one scenario question per level out loud. Re-run all 10 coding snippets without looking. Revise the cheat table. |
Common mistakes candidates make
Using Thread.sleep()
Fixed sleeps make tests slow and still flaky. Use explicit waits with a specific condition. A test that needs a fixed sleep is hiding a timing bug.
Fragile XPath
Absolute XPath and long index-based paths break on every DOM change. Use id, name or a relative XPath anchored to a stable attribute.
No Page Object Model
Locators scattered across test classes are the single biggest maintenance cost. Centralise them in Page Objects and tests become readable and maintainable.
Sharing WebDriver across parallel threads
A single driver shared across threads causes stale element errors and random failures. Use ThreadLocal<WebDriver> for parallel execution.
Ignoring reports and screenshots
A failing test with no screenshot or trace is almost impossible to debug in CI. Capture a screenshot and the page source on every failure through a listener.
Reading code instead of writing it
You will not remember how to switch windows or write a DataProvider by reading it three times. Write each snippet once by hand, then again without looking.
Practise these topics with Uncodemy
Selenium with Java, TestNG, Maven, Jenkins and POM/hybrid frameworks are taught inside Uncodemy's Software Testing program (automation track) and the Automation Testing course.
| Program | What it covers | Duration / fee |
|---|---|---|
| Software Testing | Manual testing, SQL, API testing (Postman, REST Assured), Selenium with Java, TestNG, Maven, Jenkins, JIRA. This is the direct track for the topics on this page. | ₹17,500 + GST · 4–5 months |
| Automation Testing | 90+ hours, 45+ live sessions. Selenium WebDriver with Java, TestNG, Maven, Jenkins, POM/hybrid frameworks, Cucumber. | Ask a counsellor for current batch details. |
| Professional Certificate Program in Playwright Automation | JavaScript, Playwright, Mocha, API testing, Jenkins, GitHub, Allure, GitHub Copilot. 5 domain projects. | 2.5–3 months. Fee not published; ask a counsellor. |
Placement assistance (as published by Uncodemy): resume building, LinkedIn optimisation, portfolio review, interview preparation, mock interviews and opportunity sharing through a network of 850+ companies. Uncodemy does not guarantee employment, as hiring decisions rest with employers. See placement support.
Also useful: AI career guidance for picking a path, and the 2-class free trial to see how a live batch runs before you commit.