Selenium WebDriver β 30 Interview Questions (Answers & Examples)¶
A Selenium 4 (W3C) interview cheat-sheet: crisp definitions, runnable Java snippets, and one gotcha per question.
Q1. What is Selenium and what are its components?¶
Selenium is an open-source suite for automating web browsers, made up of Selenium WebDriver, Selenium IDE, and Selenium Grid (RC is now legacy/removed).
In plain words: WebDriver drives the browser programmatically, IDE is a record-and-playback plugin for quick scripts, and Grid distributes tests across multiple machines/browsers in parallel.
WebDriver driver = new ChromeDriver(); // WebDriver: the core automation API
driver.get("https://example.com");
System.out.println(driver.getTitle());
driver.quit();
Gotcha: Selenium automates only web browsers β not desktop apps, mobile native apps (use Appium), or APIs (use RestAssured).
Q2. What is the difference between Selenium WebDriver and Selenium RC?¶
WebDriver talks to the browser directly through native drivers using the W3C protocol, while RC (deprecated) injected JavaScript through a middleman Selenium Server.
| Aspect | Selenium RC (legacy) | Selenium WebDriver |
|---|---|---|
| Architecture | Needs a running RC server as middleman | Talks to browser directly via native driver |
| Mechanism | JavaScript injection (Selenium Core) | Native browser automation / W3C protocol |
| Speed | Slower (extra hop) | Faster (direct communication) |
| API | Complex, verbose | Clean, object-oriented |
| Status | Deprecated / removed | Current standard |
Remember: RC = server + JS injection; WebDriver = direct native driver, no server needed.
Q3. What are the limitations of Selenium WebDriver?¶
Selenium can only automate web browsers and cannot handle desktop apps, CAPTCHAs, barcodes/images, or provide built-in reporting.
In plain words: it's a browser-driving library, not a full test framework β you bolt on TestNG/JUnit, ExtentReports/Allure, and third-party tools for the gaps.
- No desktop app support (use WinAppDriver/AutoIt).
- No CAPTCHA/OTP solving (by design β disable in test env or use OCR/3rd party).
- No native image comparison (use Applitools/OpenCV).
- No built-in reporting or test runner.
Gotcha: For OS-level dialogs (Windows file upload, print) Selenium can't act β use sendKeys on the input or AutoIt/Robot.
Q4. What programming languages are supported by Selenium WebDriver?¶
Selenium provides official language bindings for Java, Python, C#, Ruby, and JavaScript, plus community bindings like Kotlin.
In plain words: the same WebDriver commands are exposed as libraries in each language, so you pick whatever your team/stack uses.
// Java binding example
WebDriver driver = new ChromeDriver();
driver.findElement(By.id("user")).sendKeys("qa");
Gotcha: Java and Python are the most common in job postings; the API concepts are identical across bindings.
Q5. How do you launch a browser using Selenium WebDriver?¶
You instantiate the corresponding driver class (e.g., ChromeDriver) which starts the browser; in Selenium 4.6+ the driver binary is auto-resolved by Selenium Manager.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
WebDriver driver = new ChromeDriver(); // Selenium Manager auto-handles driver
driver.manage().window().maximize();
driver.get("https://example.com");
driver.quit();
Gotcha: Use driver.quit() (closes all windows + ends session), not just driver.close() (only the current window).
Q6. What is the difference between findElement() and findElements()?¶
findElement() returns the first matching WebElement (throwing NoSuchElementException if none), while findElements() returns a List<WebElement> (an empty list if none).
| Aspect | findElement() |
findElements() |
|---|---|---|
| Returns | Single WebElement |
List<WebElement> |
| No match | Throws NoSuchElementException |
Returns empty list (no exception) |
| Use case | One specific element | Count/iterate matches, existence check |
List<WebElement> links = driver.findElements(By.tagName("a"));
if (links.isEmpty()) System.out.println("No links found"); // safe existence check
Remember: findElements never throws for "not found" β it gives an empty list; findElement throws NoSuchElementException.
Q7. What are different types of waits in Selenium WebDriver?¶
Selenium offers Implicit wait (global polling for element presence), Explicit wait (WebDriverWait + ExpectedConditions for a specific condition), and Fluent wait (explicit with custom polling + ignored exceptions).
In plain words: implicit is a blanket "wait up to N seconds for any element"; explicit waits for a precise condition; fluent adds polling frequency control.
import java.time.Duration;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement el = wait.until(
ExpectedConditions.elementToBeClickable(By.id("submit")));
el.click();
Remember: Prefer Explicit over Implicit, and never mix them β combining the two can cause unpredictable, cumulative wait times.
Q8. How do you handle dynamic web elements in Selenium?¶
Handle dynamic elements by writing robust locators (stable attributes, contains()/starts-with() XPath) combined with explicit waits instead of hardcoded sleeps.
In plain words: if IDs change per session, anchor on text or partial attributes and wait for the element to appear.
WebElement dynamic = new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.presenceOfElementLocated(
By.xpath("//button[contains(@id,'save_')]"))); // partial match
dynamic.click();
Gotcha: Avoid absolute XPath and Thread.sleep() for dynamic content β they're brittle and slow.
Q9. What is the difference between get() and navigate().to() methods?¶
Both open a URL and wait for page load, but navigate() also exposes browser history controls (back(), forward(), refresh()), which get() does not.
| Aspect | driver.get(url) |
driver.navigate().to(url) |
|---|---|---|
| Loads URL | Yes | Yes |
| History methods | No | Yes β back(), forward(), refresh() |
| Typical use | Initial page load | When you also need navigation control |
Remember: Functionally get() == navigate().to() for loading; navigate() is the fuller interface with history.
Q10. How do you handle dropdowns in Selenium?¶
For native <select> dropdowns use the Select class; for custom (div/ul-based) dropdowns use ordinary click-based interactions.
import org.openqa.selenium.support.ui.Select;
Select country = new Select(driver.findElement(By.id("country")));
country.selectByVisibleText("India");
country.selectByValue("IN");
country.selectByIndex(2);
Gotcha: The Select class ONLY works on <select> tags β for Bootstrap/React custom dropdowns, click to open then click the option.
Q11. How do you handle alerts and pop-ups in Selenium WebDriver?¶
JavaScript alerts are handled by switching to them via driver.switchTo().alert() and calling accept(), dismiss(), getText(), or sendKeys().
import org.openqa.selenium.Alert;
Alert alert = driver.switchTo().alert();
System.out.println(alert.getText());
alert.sendKeys("some text"); // for prompt alerts
alert.accept(); // click OK
Gotcha: This works only for browser-native JS alerts β HTML/modal "pop-ups" (divs) are regular elements, and OS-level auth dialogs need embedded credentials or AutoIt.
Q12. How do you perform mouse hover or right-click actions?¶
Use the Actions class for advanced input: moveToElement() for hover and contextClick() for right-click, chained and finalized with perform().
import org.openqa.selenium.interactions.Actions;
Actions actions = new Actions(driver);
actions.moveToElement(driver.findElement(By.id("menu"))).perform(); // hover
actions.contextClick(driver.findElement(By.id("item"))).perform(); // right-click
Gotcha: Forgetting .perform() (or .build().perform()) means the action queue never executes.
Q13. How can you perform drag-and-drop in Selenium WebDriver?¶
Use the Actions class dragAndDrop(source, target) method, or clickAndHold().moveToElement().release() for finer control.
WebElement src = driver.findElement(By.id("draggable"));
WebElement tgt = driver.findElement(By.id("droppable"));
new Actions(driver).dragAndDrop(src, tgt).perform();
// or: new Actions(driver).clickAndHold(src).moveToElement(tgt).release().perform();
Gotcha: HTML5 drag-and-drop often fails with native Actions β fall back to a JavaScript-based HTML5 DnD helper if it doesn't work.
Q14. How do you handle multiple browser windows or tabs?¶
Capture window handles with getWindowHandle()/getWindowHandles() and switch context using switchTo().window(handle).
String parent = driver.getWindowHandle();
for (String handle : driver.getWindowHandles()) {
if (!handle.equals(parent)) {
driver.switchTo().window(handle); // switch to child window
break;
}
}
// ... do work ...
driver.close(); // close child
driver.switchTo().window(parent); // return to parent
Gotcha: Handles are unordered Set<String> values, not indices β never assume the "last" one; identify by title/URL if needed.
Q15. How do you take a screenshot using Selenium WebDriver?¶
Cast the driver to TakesScreenshot, call getScreenshotAs(OutputType.FILE), and copy the temp file to a destination.
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.OutputType;
import java.io.File;
import org.apache.commons.io.FileUtils;
File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(src, new File("screenshots/failure.png"));
Gotcha: The captured file is a temp file that's deleted when the session ends β copy it immediately. In Selenium 4 you can also screenshot a single WebElement.
Q16. How do you upload or download a file using Selenium?¶
Upload by sending the absolute file path via sendKeys() to the <input type="file"> element; downloads are typically handled by pre-configuring the browser's download preferences.
// Upload
driver.findElement(By.id("file")).sendKeys("/Users/qa/data/report.pdf");
// Download (Chrome prefs)
ChromeOptions opts = new ChromeOptions();
java.util.Map<String,Object> prefs = new java.util.HashMap<>();
prefs.put("download.default_directory", "/Users/qa/downloads");
opts.setExperimentalOption("prefs", prefs);
WebDriver driver = new ChromeDriver(opts);
Gotcha: sendKeys upload only works when the element is a native file input β for custom widgets or OS dialogs use AutoIt/Robot.
Q17. How do you handle frames and iframes in Selenium?¶
Switch into a frame with driver.switchTo().frame(...) (by index, name/id, or WebElement) before interacting, then return with switchTo().defaultContent().
driver.switchTo().frame("frameName"); // by name or id
// or: driver.switchTo().frame(0); // by index
// or: driver.switchTo().frame(driver.findElement(By.cssSelector("iframe")));
driver.findElement(By.id("insideFrame")).click();
driver.switchTo().defaultContent(); // back to main page
Gotcha: Elements inside a frame are invisible to the driver until you switch into it β a common cause of NoSuchElementException.
Q18. How do you scroll down to an element using WebDriver?¶
Use JavascriptExecutor with scrollIntoView(), or the Actions class scrollToElement() (Selenium 4).
import org.openqa.selenium.JavascriptExecutor;
WebElement el = driver.findElement(By.id("footer"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", el);
// Or scroll by pixels:
((JavascriptExecutor) driver).executeScript("window.scrollBy(0,1000);");
Gotcha: Selenium doesn't scroll automatically for JS-interactable elements; scroll first if a click reports element-not-interactable.
Q19. What are XPath and CSS Selectors? Which one is better and why?¶
Both are locator strategies to find elements; CSS selectors are generally faster and cleaner, while XPath is more powerful (bidirectional traversal, text matching).
| Aspect | CSS Selector | XPath |
|---|---|---|
| Speed | Faster (native engine) | Slightly slower |
| Direction | Forward only (parentβchild) | Both (can go to parent/ancestor) |
| Text matching | Not by inner text | Yes β text(), contains() |
| Readability | Concise | Verbose but expressive |
driver.findElement(By.cssSelector("input#username")); // CSS
driver.findElement(By.xpath("//button[text()='Login']")); // XPath by text
Remember: Prefer CSS for speed/simplicity; reach for XPath when you need text() or ancestor/parent traversal.
Q20. What is the difference between absolute and relative XPath?¶
Absolute XPath traces the full path from the root (/html/...), while relative XPath starts anywhere in the DOM (//) using attributes or text.
| Aspect | Absolute XPath | Relative XPath |
|---|---|---|
| Starts with | /html/body/... |
// (anywhere) |
| Fragility | Very brittle (breaks on DOM change) | Robust |
| Length | Long | Short |
| Recommended | No | Yes |
// Absolute (avoid): /html/body/div[2]/form/input
// Relative (prefer):
driver.findElement(By.xpath("//input[@name='email']"));
Remember: Always use relative XPath β absolute paths shatter with the smallest layout change.
Q21. What is StaleElementReferenceException and how do you handle it?¶
It's thrown when a previously located WebElement is no longer attached to the DOM (page reloaded/re-rendered); handle it by re-locating the element, ideally inside a wait/retry.
In plain words: the element you grabbed earlier got destroyed and recreated, so your old reference points to nothing.
try {
driver.findElement(By.id("save")).click();
} catch (org.openqa.selenium.StaleElementReferenceException e) {
driver.findElement(By.id("save")).click(); // re-find fresh reference
}
// Better: WebDriverWait + ExpectedConditions.refreshed(elementToBeClickable(...))
Gotcha: Don't cache WebElements across page transitions/AJAX updates β re-locate them when the DOM may have changed.
Q22. What is Page Object Model (POM)?¶
POM is a design pattern where each page is represented by a class that holds its locators and actions, separating test logic from UI details.
In plain words: one class per page keeps locators in a single place, so a UI change means editing one file, not every test.
public class LoginPage {
private final WebDriver driver;
private final By username = By.id("user");
private final By password = By.id("pass");
LoginPage(WebDriver driver) { this.driver = driver; }
public void login(String u, String p) {
driver.findElement(username).sendKeys(u);
driver.findElement(password).sendKeys(p);
}
}
Gotcha: POM improves maintainability and reuse but only if page classes hold behavior, not assertions (keep assertions in tests).
Q23. What is PageFactory in Selenium?¶
PageFactory is a built-in POM helper that initializes @FindBy-annotated WebElement fields via PageFactory.initElements(driver, this), using lazy proxies.
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class LoginPage {
@FindBy(id = "user") WebElement username;
@FindBy(id = "pass") WebElement password;
public LoginPage(WebDriver driver) {
PageFactory.initElements(driver, this);
}
}
Gotcha: PageFactory proxies re-locate on each use but can still hit StaleElementReferenceException on heavy AJAX; many teams now prefer plain By locators.
Q24. What is TestNG and how is it used with Selenium?¶
TestNG is a testing framework providing annotations, assertions, grouping, parameterization, parallelism, and reporting to structure Selenium tests.
In plain words: Selenium drives the browser; TestNG organizes the tests (setup/teardown, ordering, parallel runs, reports).
import org.testng.annotations.*;
import org.testng.Assert;
public class LoginTest {
@BeforeMethod public void setUp() { /* launch driver */ }
@Test
public void validLogin() {
Assert.assertEquals(driver.getTitle(), "Dashboard");
}
@AfterMethod public void tearDown() { /* driver.quit() */ }
}
Gotcha: Use TestNG Assert (or SoftAssert) for verifications β plain Selenium has no assertion API.
Q25. How do you prioritize test cases in TestNG?¶
Use the priority attribute on @Test; lower numbers run first, and unprioritized methods (default priority 0) run before higher-priority ones.
@Test(priority = 1)
public void openApp() { }
@Test(priority = 2)
public void login() { }
@Test(priority = 3, dependsOnMethods = "login")
public void dashboard() { }
Gotcha: Priority alone doesn't guarantee dependency β use dependsOnMethods when one test must succeed before another runs.
Q26. How do you run tests in parallel using TestNG?¶
Configure the parallel attribute in testng.xml (tests, classes, or methods) with a thread-count, and ensure the driver is thread-safe (e.g., ThreadLocal<WebDriver>).
<suite name="Suite" parallel="tests" thread-count="3">
<test name="Chrome"><classes><class name="LoginTest"/></classes></test>
<test name="Firefox"><classes><class name="SearchTest"/></classes></test>
</suite>
Gotcha: A single shared WebDriver breaks in parallel β store it in ThreadLocal so each thread gets its own browser session.
Q27. How do you manage browser drivers like ChromeDriver or GeckoDriver?¶
In Selenium 4.6+ the built-in Selenium Manager auto-downloads and configures the correct driver, so no manual path or WebDriverManager is required.
In plain words: older code set System.setProperty("webdriver.chrome.driver", ...) or used Bonigarcia's WebDriverManager; now you can usually just new ChromeDriver().
// Selenium 4.6+ β Selenium Manager resolves the driver automatically
WebDriver driver = new ChromeDriver();
// Legacy alternative:
// WebDriverManager.chromedriver().setup(); // Bonigarcia library
// System.setProperty("webdriver.chrome.driver", "/path/chromedriver");
Gotcha: Selenium Manager needs network access on first resolve; in locked-down CI, cache/pin the driver or point to a local binary.
Q28. What is headless browser testing and how is it configured?¶
Headless testing runs the browser without a visible UI (faster, ideal for CI); configure it via ChromeOptions/FirefoxOptions with the headless argument.
import org.openqa.selenium.chrome.ChromeOptions;
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new"); // new headless mode (Chrome 109+)
options.addArguments("--window-size=1920,1080");
WebDriver driver = new ChromeDriver(options);
Gotcha: Headless can behave differently (no real viewport) β set an explicit window size, and don't use headless as your only visual-regression check.
Q29. What are the best practices you follow in Selenium Automation?¶
Key practices: use the Page Object Model, prefer explicit waits over sleeps, write stable/relative locators, keep tests independent and idempotent, and add reporting plus screenshots on failure.
- Use POM +
ThreadLocaldriver for maintainability and parallelism. - Explicit waits (
WebDriverWait), neverThread.sleep(). - Stable locators (id/CSS, relative XPath) β no absolute XPath.
- Independent atomic tests; clean up state in teardown.
- Capture screenshots on failure; integrate ExtentReports/Allure.
- Data-driven via
@DataProvider/external files; run in CI.
// Explicit wait over sleep β the single most impactful practice
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.visibilityOfElementLocated(By.id("result")));
Gotcha: Flaky tests usually trace back to bad waits or shared state β fix those before blaming Selenium.
Q30. How do you generate reports in Selenium (ExtentReports/Allure)?¶
Selenium has no native reporting, so you integrate libraries like ExtentReports (rich HTML dashboards) or Allure (annotation/results-based) via TestNG listeners.
// ExtentReports (core idea)
ExtentReports extent = new ExtentReports();
extent.attachReporter(new ExtentSparkReporter("report.html"));
ExtentTest test = extent.createTest("Login Test");
test.pass("Login succeeded");
extent.flush(); // writes the HTML report
// Allure: annotate tests with @Step/@Description, run `allure serve` on results
Gotcha: Reports become far more useful when you attach a failure screenshot in an ITestListener.onTestFailure hook.