SoftwareTestPilot
300 Selenium Q&A

300 Selenium Interview Questions & Answers (1970) — Crack Your Next SDET Round

A definitive bank of 300 real Selenium WebDriver interview questions with senior-level answers and Java code samples. Covers fundamentals, locators, waits, frameworks, Selenium Grid, Selenium 4, CI/CD, and scenario-based problem solving — for freshers through SDET architects.

  • 109 min read
  • Difficulty: Mixed (Easy → Hard)
  • Freshers → 10+ yrs
  • Updated June 1970
  • Avinash Kamble

1. Selenium Fundamentals

Medium Very Common 1 min read

Q1.What is Selenium and what are its components?

Selenium is an open-source browser automation framework used for testing web applications across different browsers and platforms. Its components include: Selenium WebDriver (direct browser automation API), Selenium IDE (record-and-playback browser extension), Selenium Grid (distributed test execution across multiple machines), and the now-deprecated Selenium RC. WebDriver is the primary component used today, as it communicates directly with the browser using the browser's native automation engine rather than injecting JavaScript. Selenium supports Chrome, Firefox, Edge, Safari, and Opera, and offers bindings for Java, Python, C#, JavaScript, Ruby, and Kotlin.

Medium Very Common 1 min read

Q2.What is the difference between Selenium IDE, WebDriver, and Grid?

Selenium IDE is a Firefox/Chrome plugin for record-and-playback — useful for quick prototyping but not suitable for production test suites. Selenium WebDriver is a programmatic API that lets you write test scripts in Java, Python, C#, etc. with full control over browser interactions, waits, assertions, and frameworks like TestNG or JUnit. Selenium Grid enables parallel test execution across multiple machines and browsers simultaneously, reducing test execution time significantly. In a modern QA setup, IDE is rarely used, WebDriver is the workhorse for writing tests, and Grid is used in CI/CD pipelines for cross-browser parallel execution.

Medium Very Common 1 min read

Q3.What are the advantages of Selenium WebDriver?

Key advantages: (1) Open-source and free with no licensing costs. (2) Supports multiple browsers — Chrome, Firefox, Edge, Safari, Opera. (3) Multi-language support — Java, Python, C#, JavaScript, Ruby, Kotlin. (4) Cross-platform — Windows, macOS, Linux. (5) Parallel execution via Selenium Grid. (6) Integration with CI/CD tools (Jenkins, GitHub Actions, Azure DevOps). (7) Integration with testing frameworks (TestNG, JUnit, NUnit). (8) Large community and extensive documentation. (9) Support for mobile web testing via Appium. (10) Highly extensible through custom listeners, reporters, and third-party integrations like BrowserStack and Sauce Labs.

Hard Very Common 1 min read

Q4.What are the limitations of Selenium?

(1) Desktop application testing — Selenium only automates web browsers, not desktop or native mobile apps (use Appium for mobile). (2) No built-in API testing — needs REST Assured, HttpClient, or similar libraries. (3) No built-in reporting — requires TestNG/ExtentReports/Allure. (4) No built-in test management. (5) Slower than newer tools like Playwright — requires manual wait statements. (6) No built-in image comparison. (7) StaleElementReferenceException is common with dynamic pages. (8) No native support for handling CAPTCHA, OTP, or barcode readers. (9) Driver management can be tedious (though WebDriverManager helps). (10) No built-in network interception (Selenium 4 added CDP support but limited compared to Playwright).

Medium Very Common 1 min read

Q5.What programming languages are supported by Selenium?

Selenium WebDriver officially supports Java, Python, C#, JavaScript/Node.js, Ruby, and Kotlin. Java is the most widely adopted in enterprise settings, especially with TestNG. Python is popular among startups and data-driven teams. JavaScript/TypeScript is growing rapidly with frameworks like WebDriverIO and Nightwatch.js built on top of Selenium. The choice depends on your team's expertise and project requirements — Java offers the strongest tooling ecosystem, while Python provides the fastest test-writing experience.

Hard Very Common 1 min read

Q6.What is the Selenium WebDriver architecture?

The WebDriver architecture follows a client-server model. On the client side, your test code sends commands via the WebDriver API (in Java, Python, etc.). These commands are converted to JSON (previously JSON Wire Protocol, now W3C standard in Selenium 4) and sent over HTTP to the browser driver. The browser driver (ChromeDriver, GeckoDriver, etc.) receives these commands and executes them in the actual browser using the browser's native automation engine. The browser returns the response back through the driver to your test code. In Selenium 4, this is fully W3C-compliant, meaning no more protocol translation overhead — commands go directly from WebDriver to the browser using the W3C WebDriver spec.

Hard Very Common 1 min read

Q7.What is the difference between W3C WebDriver protocol and JSON Wire Protocol?

JSON Wire Protocol (JWP) was the original communication protocol used in Selenium 3 and earlier. It used its own proprietary JSON format for communication between WebDriver and browser drivers. W3C WebDriver Protocol is the standardized version adopted by the W3C consortium in Selenium 4. Key differences: (1) W3C is standardized across all browsers — same protocol for Chrome, Firefox, Safari, and Edge. (2) No encoding/decoding step — commands go directly to the browser without translation, making execution faster. (3) Better error handling with standardized HTTP status codes. (4) Reduced flakiness. (5) Backward compatible — JWP requests are translated automatically in Selenium 4 but with a performance penalty.

Medium Very Common 1 min read

Q8.What are the browser drivers supported by Selenium?

ChromeDriver (for Google Chrome), GeckoDriver (for Mozilla Firefox), EdgeDriver (for Microsoft Edge), SafariDriver (for Apple Safari), and OperaDriver (for Opera browser). Each browser driver is a separate executable that acts as a bridge between Selenium WebDriver and the actual browser. They handle command translation, browser launch, and session management. Using WebDriverManager or Selenium Manager (built-in in Selenium 4) automates driver binary management — detecting the installed browser version, downloading the matching driver, and setting up the system path automatically.

Hard Very Common 1 min read

Q9.How do you download and set up ChromeDriver?

(1) Check your Chrome version from chrome://settings/help. (2) Download the matching ChromeDriver from chromedriver.chromium.org. (3) Place the executable in a directory in your system PATH, or specify its path in code. (4) In Java code: System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver"); WebDriver driver = new ChromeDriver();. Modern approach: use WebDriverManager — WebDriverManager.chromedriver().setup(); WebDriver driver = new ChromeDriver(); — this handles everything automatically. Selenium 4 also includes Selenium Manager which auto-manages drivers without any setup code.

Hard Very Common 1 min read

Q10.What is WebDriverManager?

WebDriverManager (by Boni García) is a Java library that automates the management of browser drivers. It automatically detects the installed browser version, downloads the matching driver binary from the official repository, caches it locally, and sets the system property. Usage: WebDriverManager.chromedriver().setup(); WebDriver driver = new ChromeDriver();. It supports Chrome, Firefox, Edge, Opera, and PhantomJS. It also supports Docker-based browser execution and can download drivers for specific versions. Selenium 4 introduced Selenium Manager as a built-in alternative, but WebDriverManager remains popular for its additional features like driver version resolution and proxy support.

Medium Very Common 1 min read

Q11.How do you launch a browser in Selenium WebDriver?

In Java: WebDriver driver = new ChromeDriver(); launches Chrome. For Firefox: WebDriver driver = new FirefoxDriver();. For Edge: WebDriver driver = new EdgeDriver();. For Safari: WebDriver driver = new SafariDriver();. You need the corresponding browser driver set up (via System.setProperty or WebDriverManager). The browser launches with default settings. To launch with custom options, use: ChromeOptions options = new ChromeOptions(); options.addArguments("--headless"); WebDriver driver = new ChromeDriver(options);. Always quit the driver at the end: driver.quit();.

Medium Very Common 1 min read

Q12.What is the difference between driver.close() and driver.quit()?

driver.close() closes only the currently focused browser window or tab. If multiple windows/tabs are open, the rest remain. The WebDriver session is still active. driver.quit() closes ALL browser windows and tabs, terminates the browser process, and ends the WebDriver session completely. After quit(), the driver object cannot be reused — you must create a new instance. Best practice: Always use driver.quit() in your @AfterClass or finally block to ensure clean session termination. Use driver.close() only when you need to close one specific window while continuing tests in another.

Medium Very Common 1 min read

Q13.How do you maximize the browser window in Selenium?

driver.manage().window().maximize(); maximizes the window to fill the screen. For full-screen mode (like F11): driver.manage().window().fullscreen();. For a specific window size: Dimension dim = new Dimension(1920, 1080); driver.manage().window().setSize(dim);. For getting the current window position: Point position = driver.manage().window().getPosition();. Maximizing is important for consistent test behavior since element visibility and layout can vary with window size.

Medium Very Common 1 min read

Q14.How do you navigate to a URL in Selenium?

Two ways: driver.get("https://example.com"); or driver.navigate().to("https://example.com");. get() simply loads the URL and waits for the page to load. navigate().to() also loads the URL but can additionally navigate history — navigate().back(), navigate().forward(), and navigate().refresh(). Both methods are functionally identical for initial page loading. The navigate() interface is useful when you need to simulate browser back/forward/refresh behavior during testing.

Medium Very Common 1 min read

Q15.How do you refresh a page in Selenium?

Multiple ways: (1) driver.navigate().refresh(); — the standard approach. (2) Send a key: driver.findElement(By.tagName("body")).sendKeys(Keys.F5);. (3) Using JavaScript: ((JavascriptExecutor) driver).executeScript("location.reload();");. (4) Load the same URL again: driver.get(driver.getCurrentUrl());. Method 1 is the recommended approach. Refreshing is useful when testing page reload behavior, cache clearing, or dynamic content that updates on refresh.

Medium Very Common 1 min read

Q16.What is the difference between navigate() and get()?

Both load a URL. driver.get(url) is simpler — it loads the URL and waits for the page to load. It's the most commonly used method. driver.navigate().to(url) internally calls get() but returns a Navigation interface that also provides .back(), .forward(), and .refresh() methods. So if you only need to load a URL, use get(). If you need to navigate browser history afterward, use navigate().to() to access the chainable methods. Performance-wise, both are identical.

Hard Very Common 1 min read

Q17.How do you handle browser notifications/pop-ups in Selenium?

Browser notification prompts can be handled using ChromeOptions: ChromeOptions options = new ChromeOptions(); Map<String, Object> prefs = new HashMap<>(); prefs.put("profile.default_content_setting_values.notifications", 2); options.setExperimentalOption("prefs", prefs);. The value 2 means "block". For geolocation: set "profile.default_content_setting_values.geolocation" to 2. For allowing all notifications on a specific site, you can use Chrome DevTools Protocol (CDP) in Selenium 4: ((HasAuthentication) driver).register(UsernameAndPassword.of("user", "pass"));. For JavaScript alerts within the page, use the Alert interface (covered in later questions).

Medium Very Common 1 min read

Q18.What is a WebElement in Selenium?

A WebElement is an interface in Selenium representing an HTML element on a web page. It provides methods to interact with elements — click(), sendKeys(), getText(), getAttribute(), isDisplayed(), isEnabled(), isSelected(), submit(), clear(), getCssValue(), getSize(), getLocation(), getRect(), findElement(), findElements(), getScreenshotAs(), and sendKeys(Keys.ENTER). WebElements are returned by the findElement() and findElements() methods. They are reference objects that point to DOM elements — if the DOM changes, the reference may become stale (StaleElementReferenceException). Best practice is to find elements fresh each interaction rather than storing them.

Medium Very Common 1 min read

Q19.What is the difference between findElement() and findElements()?

findElement(By by) returns the first matching WebElement. It throws NoSuchElementException if no element matches the locator. findElements(By by) returns a List<WebElement> containing all matching elements. It returns an empty list if no elements match — never throws an exception. Use findElement when you expect exactly one element and its absence is a failure. Use findElements when zero matches is a valid state (e.g., checking that an error list is empty, or verifying no results after a search). Performance-wise, findElements can be more reliable for dynamic pages.

Hard Very Common 1 min read

Q20.What is a NoSuchElementException and how do you handle it?

NoSuchElementException is thrown when findElement() cannot locate an element using the given locator strategy. Common causes: wrong locator, element not yet loaded (synchronization issue), element in a different frame/window, or element dynamically removed. Handling strategies: (1) Add proper waits — explicit wait with ExpectedConditions.presenceOfElementLocated(). (2) Verify the locator — use browser DevTools to validate your XPath/CSS. (3) Check if the element is inside an iframe — switch to the frame first. (4) Check if the element is in a different window. (5) Use findElements() instead and check list size > 0. (6) Wrap in a try-catch or FluentWait with ignored exception. The most common root cause is timing — always use explicit waits.

Medium Very Common 1 min read

Q21.How do you verify if an element exists on a page in Selenium?

Use findElements() and check the list size: List<WebElement> elements = driver.findElements(By.id("element-id")); if (elements.size() > 0) { // exists }. Unlike findElement(), findElements() doesn't throw an exception when no elements are found. Alternatively, use explicit wait: WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5)); try { wait.until(ExpectedConditions.presenceOfElementLocated(By.id("element-id"))); } catch (TimeoutException e) { // doesn't exist }. The ExpectedConditions approach is preferred because it also handles timing.

Hard Very Common 1 min read

Q22.What is the difference between isDisplayed(), isEnabled(), and isSelected()?

isDisplayed() returns true if the element is visible on the page (not hidden via CSS, not having display:none or visibility:hidden, and within the viewport). isEnabled() returns true if the element is interactive (not disabled via the disabled attribute). isSelected() returns true if the element is selected/checked — applicable only to radio buttons, checkboxes, and option elements. isDisplayed() is the most commonly used for general visibility checks. Note: isDisplayed() can be slow because it queries the browser's CSS engine. These methods throw NoSuchElementException if the element doesn't exist.

Medium Very Common 1 min read

Q23.How do you get the text of an element in Selenium?

element.getText() returns the visible text content of an element, including all child elements. It ignores hidden text (display:none or visibility:hidden). For getting the full inner HTML (including hidden text and HTML tags): element.getAttribute("innerHTML") or element.getAttribute("textContent"). For getting the value of an input field: element.getAttribute("value"). The difference: getText() returns "visible text only", getAttribute("textContent") returns "all text including hidden", and getAttribute("innerHTML") returns "including HTML markup".

Medium Very Common 1 min read

Q24.How do you get an attribute value of an element?

element.getAttribute("attributeName") returns the value of the specified attribute. Common attributes: "class", "id", "href", "src", "value", "placeholder", "disabled", "style", "data-*" custom attributes. For boolean attributes like "disabled", "checked", "readonly", getAttribute() returns "true" or null. Alternatively, element.getDomAttribute("attr") (Selenium 4) returns the DOM property value. element.getDomProperty("property") returns the current runtime property. Example: String href = driver.findElement(By.linkText("Click")).getAttribute("href");.

Hard Very Common 1 min read

Q25.How do you type text in a text box using Selenium?

element.sendKeys("text to type") sends keystrokes to a text field, textarea, or any editable element. It appends to existing text by default. To clear first: element.clear(); element.sendKeys("new text");. Or use element.sendKeys(Keys.chord(Keys.CONTROL, "a"), "replacement text"); to select all and replace. For special keys: element.sendKeys(Keys.ENTER), element.sendKeys(Keys.TAB), element.sendKeys(Keys.ESCAPE). For file uploads: element.sendKeys("/path/to/file.txt"); on an input[type=file] element. To type slowly (character by character for demo purposes), you can loop with Thread.sleep between characters.

Medium Very Common 1 min read

Q26.What is the difference between clear() and sendKeys() behavior?

clear() removes any existing text from an input field or textarea. It's equivalent to selecting all and deleting. sendKeys() appends text to the existing content by default. If the field already has placeholder text (not value), sendKeys() works fine since there's no existing value. If the field has a pre-populated value, you should call clear() first before sendKeys() to avoid appending to existing data. Some modern frameworks (React controlled components) may not respond to clear() — in that case, use element.sendKeys(Keys.chord(Keys.CONTROL, "a"), Keys.DELETE, "new text");.

Hard Very Common 1 min read

Q27.How do you click on an element in Selenium?

element.click() clicks at the center of the element. The element must be visible and enabled. Selenium scrolls to the element automatically if needed. Alternative click methods: (1) JavaScript click — ((JavascriptExecutor) driver).executeScript("arguments[0].click();", element); — useful when normal click fails due to overlapping elements. (2) Actions class click — new Actions(driver).moveToElement(element).click().perform(); — for precise cursor positioning. (3) Submit — element.submit(); — works on form elements. Common click failures: element not visible, element covered by another element, element not yet loaded, or intercepted click. Use waits to ensure clickability before clicking.

Medium Very Common 1 min read

Q28.How do you submit a form in Selenium?

element.submit() submits the form containing the element. It works on any element inside a <form> tag — clicking the submit button, pressing Enter in a text field, or calling .submit() on any form input. It's equivalent to clicking the form's submit button. If the element is not inside a form, submit() throws NoSuchElementException. Alternatively, you can find and click the submit button directly: driver.findElement(By.xpath("//button[@type='submit']")).click();. The submit() method is useful when you don't have a direct reference to the submit button.

Hard Very Common 1 min read

Q29.What is the page load strategy in Selenium?

Page load strategy determines when Selenium considers a page fully loaded. Three strategies: (1) NORMAL (default) — waits for the entire page including all resources (images, CSS, JS) to load. Set via: ChromeOptions options = new ChromeOptions(); options.setPageLoadStrategy(PageLoadStrategy.NORMAL);. (2) EAGER — waits only for DOMContentLoaded event (HTML loaded, but resources like images may still load). Faster but may encounter incomplete elements. (3) NONE — doesn't wait for anything after the initial URL is loaded. Use for SPAs that load content via AJAX. Choose EAGER for faster execution when images/styles are not critical, and NONE when using explicit waits for specific elements anyway.

Hard Very Common 1 min read

Q30.How do you set page load timeout in Selenium?

driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(30)); sets the maximum time to wait for a page to load. If the page doesn't load within this time, TimeoutException is thrown. You can catch this exception and either retry or continue. Additional timeouts: implicitlyWait(Duration.ofSeconds(10)) for findElement waits, and setScriptTimeout(Duration.ofSeconds(10)) for asynchronous script execution. Setting appropriate timeouts is crucial for test stability — too short causes flaky failures, too long wastes time on genuinely slow pages. A 30-60 second page load timeout is typical for web applications.

Confidence check

If you can confidently answer the Selenium Fundamentals questions above, you're well prepared for this section of your interview. Move on, or rehearse the trickier ones aloud with our AI mock interviewer.

2. WebDriver & Browser Commands

Hard Very Common 1 min read

Q31.What is the ChromeOptions class and how do you use it?

ChromeOptions is a class for configuring Chrome browser behavior before launch. Common uses: headless mode (--headless), disable sandbox (--no-sandbox), disable GPU (--disable-gpu), set window size (--window-size=1920,1080), disable notifications, set download directory, and add browser extensions. Example: ChromeOptions options = new ChromeOptions(); options.addArguments("--headless", "--disable-gpu", "--window-size=1920,1080"); options.setExperimentalOption("prefs", prefs); WebDriver driver = new ChromeDriver(options);. ChromeOptions gives you fine-grained control over the browser for different testing scenarios.

Hard Very Common 1 min read

Q32.What is the FirefoxOptions class?

FirefoxOptions configures Firefox browser behavior. Key features: headless mode, set Firefox binary path, set profile preferences, add extensions, configure logging. Example: FirefoxOptions options = new FirefoxOptions(); options.setHeadless(true); options.addArguments("--width=1920", "--height=1080"); options.addPreference("dom.webnotifications.enabled", false); WebDriver driver = new FirefoxDriver(options);. FirefoxOptions uses about:config style preferences rather than Chrome's command-line arguments. Common preferences: disable geolocation, disable PDF viewer, set download path, disable auto-updates.

Hard Very Common 1 min read

Q33.How do you run Chrome in headless mode?

ChromeOptions options = new ChromeOptions(); options.addArguments("--headless"); WebDriver driver = new ChromeDriver(options); // Or using newer headless: options.addArguments("--headless=new");. The --headless=new` mode (Chrome 112+) is the newer headless implementation that behaves more like the real browser — supports extensions, printing to PDF, and more. Headless mode is commonly used in CI/CD environments where no display is available. Benefits: faster execution, no GUI overhead, works on servers. Limitations: some browser behaviors differ from headed mode (font rendering, screen size). Always run a subset of tests in headed mode before release.

Medium Very Common 1 min read

Q34.How do you handle SSL certificate errors in Selenium?

For Chrome: ChromeOptions options = new ChromeOptions(); options.setAcceptInsecureCerts(true);. For Firefox: FirefoxOptions options = new FirefoxOptions(); options.setAcceptInsecureCerts(true);. This tells the browser to trust self-signed or invalid SSL certificates. For older approaches: Chrome uses --ignore-certificate-errors argument, Firefox uses accept.untrusted.certs preference in FirefoxProfile. Handling SSL certificates is important when testing staging or development environments that often use self-signed certificates.

Hard Very Common 1 min read

Q35.How do you set browser download directory in Selenium?

For Chrome: Map<String, Object> prefs = new HashMap<>(); prefs.put("download.default_directory", "/path/to/downloads"); prefs.put("download.prompt_for_download", false); ChromeOptions options = new ChromeOptions(); options.setExperimentalOption("prefs", prefs);. For Firefox: FirefoxProfile profile = new FirefoxProfile(); profile.setPreference("browser.download.folderList", 2); profile.setPreference("browser.download.dir", "/path/to/downloads"); profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/pdf,text/csv"); FirefoxOptions options = new FirefoxOptions(); options.setProfile(profile);. Setting download directory is essential for testing file download functionality.

Medium Very Common 1 min read

Q36.How do you add browser extensions in Selenium?

For Chrome: ChromeOptions options = new ChromeOptions(); options.addExtensions(new File("/path/to/extension.crx"));. For Firefox: FirefoxOptions options = new FirefoxOptions(); options.addExtensions(new File("/path/to/extension.xpi"));. You can also load unpacked extensions: for Chrome, use the --load-extension argument pointing to the extension directory. Extensions are useful for testing with ad-blockers, password managers, or custom dev tools. Note: some extensions may interfere with test execution, so only add those required for your test scenario.

Medium Very Common 1 min read

Q37.What is the difference between ChromeDriver and GeckoDriver?

ChromeDriver is the browser driver for Google Chrome. It uses the Chrome DevTools Protocol (CDP) and W3C WebDriver protocol. It's maintained by the Chromium project. GeckoDriver is the browser driver for Mozilla Firefox, using the Gecko engine. It communicates via the Marionette protocol (and W3C WebDriver). ChromeDriver is generally considered more stable and faster. GeckoDriver has historically been slower but has improved significantly. Both now support the W3C WebDriver standard. The choice depends on which browsers your application needs to support.

Medium Very Common 1 min read

Q38.How do you get the current page URL in Selenium?

driver.getCurrentUrl() returns the current page URL as a String. It returns the actual URL in the browser's address bar, which may differ from the URL you navigated to if redirects occurred. Example: String currentUrl = driver.getCurrentUrl(); Assert.assertTrue(currentUrl.contains("dashboard"));. This is commonly used for URL verification after navigation, login redirects, form submissions, or clicking links. Note: getCurrentUrl() reads from the browser — it's not cached by Selenium, so it reflects any client-side URL changes (SPA routing).

Medium Very Common 1 min read

Q39.How do you get the page title in Selenium?

driver.getTitle() returns the title of the current web page as a String (the text inside the <title> tag in the HTML <head>). Example: String title = driver.getTitle(); Assert.assertEquals("Dashboard - My App", title);. This is commonly used for page validation, verifying successful navigation, and checking that the correct page is loaded. If the page has no title, it returns an empty string. If the page hasn't loaded yet, it may return the previous page's title or null.

Hard Very Common 1 min read

Q40.How do you get the current window handle in Selenium?

driver.getWindowHandle() returns a unique alphanumeric string ID for the current browser window/tab. driver.getWindowHandles() returns a Set<String> of all open window handles. These are essential for switching between multiple windows or tabs. Example: String mainWindow = driver.getWindowHandle(); // store parent window // click link that opens new window Set<String> allWindows = driver.getWindowHandles(); for (String handle : allWindows) { if (!handle.equals(mainWindow)) { driver.switchTo().window(handle); break; } }. Window handles are dynamic per session and change each time a new browser session starts.

Hard Very Common 1 min read

Q41.How do you switch between browser windows/tabs?

Use driver.switchTo().window(handle) where handle is the window handle string. Steps: (1) Store the parent window handle: String parentHandle = driver.getWindowHandle();. (2) Perform action that opens a new window. (3) Get all handles: Set<String> allHandles = driver.getWindowHandles();. (4) Switch to the new window by iterating handles and skipping the parent. (5) Perform actions in the new window. (6) Close and switch back: driver.close(); driver.switchTo().window(parentHandle);. In Selenium 4, you can also open a new tab/window without clicking a link: driver.switchTo().newWindow(WindowType.TAB); or driver.switchTo().newWindow(WindowType.WINDOW);.

Medium Very Common 1 min read

Q42.How do you handle multiple browser tabs in Selenium 4?

Selenium 4 introduced newWindow() method for native tab/window management: (1) Open new tab: driver.switchTo().newWindow(WindowType.TAB);. (2) Open new window: driver.switchTo().newWindow(WindowType.WINDOW);. This creates a new tab/window in the same browser session and automatically switches to it. Previously, you had to use JavaScript window.open() or keyboard shortcuts. Example: driver.switchTo().newWindow(WindowType.TAB); driver.get("https://example.com"); // loads in new tab. This makes multi-tab testing much cleaner.

Hard Very Common 1 min read

Q43.How do you take a screenshot in Selenium?

Cast the driver to TakesScreenshot: File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); FileUtils.copyFile(screenshot, new File("screenshot.png"));. For element-level screenshots (Selenium 4): File elementScreenshot = element.getScreenshotAs(OutputType.FILE);. For viewport-only screenshots: ((TakesScreenshot) driver).getScreenshotAs(OutputType.BASE64); returns a base64 string for embedding in HTML reports. Screenshots are critical for debugging test failures. Best practice: capture screenshots automatically in test listeners on failure, naming them with test name and timestamp.

Hard Very Common 1 min read

Q44.How do you set browser proxy settings in Selenium?

For Chrome: ChromeOptions options = new ChromeOptions(); Proxy proxy = new Proxy(); proxy.setHttpProxy("proxy-server:8080"); proxy.setSslProxy("proxy-server:8080"); options.setCapability("proxy", proxy);. For Firefox: FirefoxOptions options = new FirefoxOptions(); Proxy proxy = new Proxy(); proxy.setHttpProxy("proxy-server:8080"); options.setCapability("proxy", proxy);. Alternatively, add Chrome arguments: --proxy-server=http://proxy-server:8080. Proxy settings are essential for testing behind corporate firewalls, intercepting network traffic, or using proxy-based tools like BrowserStack Local.

Medium Very Common 1 min read

Q45.How do you delete cookies in Selenium?

driver.manage().deleteAllCookies(); deletes all cookies for the current domain. For specific cookies: driver.manage().deleteCookieNamed("sessionId");. To get all cookies: Set<Cookie> cookies = driver.manage().getCookies();. To add a cookie: Cookie cookie = new Cookie("name", "value"); driver.manage().addCookie(cookie);. Deleting cookies is useful for testing login/logout flows, clearing session state, and testing cookie consent banners. Note: cookies are domain-specific, so ensure you're on the correct domain before performing cookie operations.

Medium Very Common 1 min read

Q46.How do you handle browser zoom in Selenium?

Using keyboard shortcuts: WebElement body = driver.findElement(By.tagName("body")); body.sendKeys(Keys.chord(Keys.CONTROL, "0")); resets zoom to 100%. For zoom in/out: body.sendKeys(Keys.chord(Keys.CONTROL, Keys.ADD)); and body.sendKeys(Keys.chord(Keys.CONTROL, Keys.SUBTRACT));. On macOS: use Keys.COMMAND instead of Keys.CONTROL. Using ChromeOptions: options.addArguments("--force-device-scale-factor=1.25"); sets initial zoom. Note: browser zoom affects element positioning and may cause test failures if elements move off-screen or change size. Always reset zoom to 100% before tests.

Medium Very Common 1 min read

Q47.How do you set browser language in Selenium?

For Chrome: ChromeOptions options = new ChromeOptions(); options.addArguments("--lang=fr"); sets French. For Firefox: FirefoxOptions options = new FirefoxOptions(); options.addPreference("intl.accept_languages", "fr");. Multiple languages: "en-US,en;q=0.9,fr;q=0.8". Setting browser language is important for testing localized applications, verifying that the correct locale is loaded, and testing language-specific UI elements and date/time formats.

Medium Very Common 1 min read

Q48.How do you disable JavaScript in Selenium?

For Chrome: ChromeOptions options = new ChromeOptions(); options.addArguments("--disable-javascript");. For Firefox: FirefoxOptions options = new FirefoxOptions(); options.addPreference("javascript.enabled", false);. Disabling JavaScript is useful for testing scenarios where JavaScript is unavailable (accessibility testing, graceful degradation, noscript fallbacks). However, many modern web applications rely heavily on JavaScript and will break when it's disabled. Use this option specifically for progressive enhancement testing.

Hard Very Common 1 min read

Q49.How do you emulate mobile devices in Chrome?

Use Chrome's device emulation: Map<String, Object> deviceMetrics = new HashMap<>(); deviceMetrics.put("width", 375); deviceMetrics.put("height", 812); deviceMetrics.put("pixelRatio", 3.0); Map<String, Object> mobileEmulation = new HashMap<>(); mobileEmulation.put("deviceMetrics", deviceMetrics); mobileEmulation.put("userAgent", "Mozilla/5.0 (iPhone...)"); ChromeOptions options = new ChromeOptions(); options.setExperimentalOption("mobileEmulation", mobileEmulation);. For predefined devices: mobileEmulation.put("deviceName", "iPhone X");. This is crucial for responsive design testing and mobile-specific UI verification without actual mobile devices.

Medium Very Common 1 min read

Q50.How do you set the browser position in Selenium?

driver.manage().window().setPosition(new Point(x, y)); where x and y are screen coordinates. To get current position: Point position = driver.manage().window().getPosition();. To move to a specific monitor on a multi-monitor setup: set position beyond the primary monitor's width. Example: driver.manage().window().setPosition(new Point(2000, 100)); moves the window to a secondary monitor on the right. This is useful for multi-monitor test environments.

Medium Very Common 1 min read

Q51.How do you set window size in Selenium?

driver.manage().window().setSize(new Dimension(width, height));. Example: Dimension mobileView = new Dimension(375, 812); driver.manage().window().setSize(mobileView);. Common sizes: Desktop 1920×1080, Laptop 1366×768, Tablet 768×1024, Mobile 375×812 (iPhone X), 414×896 (iPhone 11 Pro Max), 360×780 (Pixel 4). Setting window size is essential for responsive design testing and ensuring consistent element visibility across test runs.

Medium Very Common 1 min read

Q52.How do you get the browser version in Selenium?

Capabilities caps = ((RemoteWebDriver) driver).getCapabilities(); String browserVersion = caps.getBrowserVersion(); String browserName = caps.getBrowserName();. For Chrome, you can also execute JavaScript: String version = (String) ((JavascriptExecutor) driver).executeScript("return navigator.userAgent;");. Knowing the browser version is useful for logging, debugging browser-specific issues, and ensuring your test environment matches your CI/CD pipeline configuration.

Medium Very Common 1 min read

Q53.How do you start Chrome with a custom user data directory?

ChromeOptions options = new ChromeOptions(); options.addArguments("user-data-dir=/path/to/chrome/profile");. This starts Chrome using a specific profile directory, preserving cookies, extensions, and settings. Also specify: options.addArguments("profile-directory=Profile 1"); to select a specific profile within the data directory. This is useful for testing with pre-configured profiles, persistent login sessions, or specific extension setups. Note: you should use a dedicated test profile, not your personal profile, to avoid conflicts.

Medium Very Common 1 min read

Q54.How do you handle authentication pop-ups in Selenium?

For basic HTTP authentication, embed credentials in the URL: driver.get("https://username:password@example.com");. For Selenium 4, use CDP-based authentication: ((HasAuthentication) driver).register(UsernameAndPassword.of("user", "pass")); driver.get("https://example.com");. Alternative: use the Alert interface if the auth popup is a JavaScript prompt. For Chrome, use --disable-blink-features=AutomationControlled flag to avoid detection. Another approach: use AutoIT or Robot class for OS-level popups, but this is less reliable and not recommended.

Medium Very Common 1 min read

Q55.How do you handle browser crashes in Selenium?

Wrap driver operations in try-catch and check driver state: try { driver.getTitle(); } catch (Exception e) { // Browser may have crashed // Reinitialize driver driver = new ChromeDriver(); }. Use a retry mechanism with a maximum retry count. For CI/CD, use a test listener that detects WebDriver errors and restarts the driver session. Common crash causes: memory exhaustion, infinite loops, browser version mismatches, and driver compatibility issues. Best practice: implement a driver factory that validates the driver session before each test and recreates it if needed.

Medium Very Common 1 min read

Q56.How do you use the RemoteWebDriver in Selenium?

Create a RemoteWebDriver pointing to a Selenium Grid hub: WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), new ChromeOptions());. For cloud services: WebDriver driver = new RemoteWebDriver(new URL("https://username:accesskey@hub-cloud.browserstack.com/wd/hub"), caps);. RemoteWebDriver sends commands to a remote server which manages the browser session. This is the foundation of Selenium Grid and cloud testing platforms. You can specify capabilities for different browsers, versions, and platforms.

Hard Very Common 1 min read

Q57.How do you pass capabilities to RemoteWebDriver?

Use DesiredCapabilities or browser-specific options: ChromeOptions options = new ChromeOptions(); options.addArguments("--headless"); options.setCapability("browserVersion", "120"); options.setCapability("platformName", "Windows 11"); WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);. For cloud providers: options.setCapability("browserstack.user", "username"); options.setCapability("browserstack.key", "accesskey"); options.setCapability("project", "My Project"); options.setCapability("build", "Test Build 1");. Capabilities tell the remote server what browser, version, OS, and features you need.

Medium Very Common 1 min read

Q58.What is the required capability in Selenium?

Required capabilities are minimum requirements that must be met by the browser/driver for the session to be created. If not met, the session creation fails. In Selenium 3, you used caps.setCapability("browserName", "chrome"); as required. In Selenium 4, the W3C standard uses: options.setCapability("browserName", "chrome"); options.setCapability("browserVersion", "120"); options.setCapability("platformName", "WINDOWS");. Selenium 4 deprecated DesiredCapabilities in favor of browser-specific Options classes which internally set W3C capabilities. Always use Options classes for new code.

Medium Very Common 1 min read

Q59.How do you execute JavaScript in Selenium?

JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("return document.title;"); returns the page title. js.executeScript("arguments[0].scrollIntoView(true);", element); scrolls to an element. js.executeScript("arguments[0].click();", element); performs a JavaScript click. js.executeScript("window.scrollTo(0, document.body.scrollHeight);"); scrolls to the bottom. JavaScript execution is useful when normal WebDriver actions fail — clicking hidden elements, manipulating DOM, scrolling, or getting computed styles. The return type is Object, cast appropriately.

Medium Very Common 1 min read

Q60.How do you handle async JavaScript calls in Selenium?

JavascriptExecutor js = (JavascriptExecutor) driver; js.executeAsyncScript("var callback = arguments[arguments.length - 1]; setTimeout(function() { callback('done'); }, 3000);");. executeAsyncScript() waits for a callback function to be called (the last argument automatically added by Selenium). Set the timeout: driver.manage().timeouts().setScriptTimeout(Duration.ofSeconds(10));. This is useful for waiting for async operations like AJAX calls, setTimeout, animations, or API responses before continuing test execution.

Confidence check

If you can confidently answer the WebDriver & Browser Commands questions above, you're well prepared for this section of your interview. Move on, or rehearse the trickier ones aloud with our AI mock interviewer.

3. Locators & Element Identification

Medium Very Common 1 min read

Q61.What are the different locator strategies in Selenium?

Selenium provides eight built-in locator strategies: By.id, By.className, By.name, By.tagName, By.linkText, By.partialLinkText, By.cssSelector, and By.xpath. Selenium 4 also adds relative locators: above(), below(), near(), toLeftOf(), and toRightOf(). The priority order for locator selection should be: id (fastest and most reliable) → name → className → cssSelector → xpath (most flexible but slower). Use the most specific and least likely to change locator. Avoid fragile locators like absolute XPath or dynamically generated classes/IDs.

Medium Very Common 1 min read

Q62.Which locator strategy is the fastest in Selenium?

By.id is the fastest locator because browsers internally use getElementById() which is highly optimized. By.name is next fastest. By.className and By.tagName are also fast but may return multiple elements. By.cssSelector is moderately fast. By.xpath is the slowest, especially absolute XPath (/html/body/div[1]/div[2]/...) which requires traversing the entire DOM. For performance-critical tests, prefer ID and CSS selectors over XPath. However, the difference is negligible for most test suites — reliability and maintainability matter more than micro-optimizations.

Hard Very Common 1 min read

Q63.How do you find dynamic elements in Selenium?

Dynamic elements have IDs, classes, or attributes that change on each page load. Strategies: (1) Use stable parent elements and traverse: driver.findElement(By.xpath("//div[@class='stable-container']//button[contains(@class,'submit')]"));. (2) Use contains() in XPath: //button[contains(@id,'submit')]. (3) Use starts-with(): //button[starts-with(@id,'btn_')]. (4) Use CSS selectors with partial matching: [class*='btn-submit']. (5) Use text content: //button[text()='Submit']. (6) Use relative locators (Selenium 4) to find elements near stable elements. (7) Use multiple attribute matching for unique identification.

Medium Very Common 1 min read

Q64.What is the difference between absolute and relative XPath?

Absolute XPath starts from the root node (/html/body/div[1]/div[2]/form/input[1]). It's fragile — any DOM structure change breaks the locator. Relative XPath starts from anywhere in the DOM (//input[@id='username']). It's more robust and maintainable because it relies on element attributes rather than DOM position. Always use relative XPath in test automation. A good XPath is short, descriptive, and uses attributes that are stable across builds. Example good XPath: //button[@data-testid='submit-btn'].

Medium Very Common 1 min read

Q65.How do you write an XPath for an element with multiple attributes?

Use the and operator: //input[@type='text' and @name='username' and @placeholder='Enter email']. Or use multiple predicates: //input[@type='text'][@name='username']. You can also chain attribute conditions: //button[contains(@class,'primary') and not(@disabled) and @type='submit']. Using multiple attributes makes your locators more specific and robust. Best practice: use 2-3 attributes that together uniquely identify the element without being overly complex.

Medium Very Common 1 min read

Q66.How do you use text() in XPath?

//button[text()='Submit'] matches elements whose exact text is "Submit". For partial text match: //button[contains(text(),'Sub')]. For case-insensitive: //button[translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')='submit']. For matching text across child elements: //div[contains(.,'Search')] — the dot (.) matches concatenated text of the element and all descendants. Text-based XPath is useful when elements lack reliable attributes, but it's fragile if the text changes (internationalization).

Medium Very Common 1 min read

Q67.How do you find elements by CSS selector in Selenium?

CSS selectors use different syntax than XPath. Examples: By ID: #username or By.cssSelector("#username"). By class: .btn-primary or By.cssSelector(".btn-primary"). By attribute: [type='submit']. By attribute partial match: [class*='btn'] (contains), [class^='btn'] (starts-with), [class$='btn'] (ends-with). By tag: input. Combined: input#username.required[type='text']. Parent-child: div.form-group > input. Sibling: label + input. CSS selectors are faster than XPath and preferred when the element can be uniquely identified with CSS.

Medium Very Common 1 min read

Q68.What is the difference between CSS selector and XPath?

(1) XPath can traverse the DOM both ways (parent to child and child to parent); CSS can only go parent-to-child. (2) XPath supports text matching text()='Submit'; CSS cannot match by text content. (3) XPath supports index-based selection (//div)[3]; CSS supports :nth-child(3) but differently. (4) CSS is generally faster than XPath. (5) CSS syntax is cleaner and more readable. (6) XPath is more powerful for complex DOM navigation. Best practice: use CSS by default, switch to XPath when you need text matching or reverse traversal.

Medium Very Common 1 min read

Q69.How do you find an element by its link text?

driver.findElement(By.linkText("Click Here")); finds an anchor (<a>) element with the exact link text "Click Here". For partial match: driver.findElement(By.partialLinkText("Click"));. These work only on <a> tags. They're case-sensitive. Useful for navigation testing, but fragile if link text changes. Best used for static links with stable text values. Note: if there are multiple links with the same text, findElement returns the first one in the DOM.

Medium Very Common 1 min read

Q70.How do you find elements using relative locators in Selenium 4?

Selenium 4 introduced relative locators: driver.findElement(RelativeLocator.with(By.tagName("input")).above(By.id("password"))); finds an input element above the password field. Other methods: .below(By.id("header")), .toLeftOf(By.id("menu")), .toRightOf(By.id("content")), .near(By.id("search")).within(Distance.ofPixels(50)). Relative locators are useful for finding elements based on their visual position relative to known elements, especially in responsive layouts where DOM position may vary.

Medium Very Common 1 min read

Q71.How do you locate elements in a shadow DOM?

Selenium 4 has built-in shadow DOM support: SearchContext shadowRoot = driver.findElement(By.cssSelector("my-component")).getShadowRoot(); WebElement button = shadowRoot.findElement(By.cssSelector("button.submit"));. For nested shadow DOMs, chain the lookups. Alternatively, use JavaScript: ((JavascriptExecutor) driver).executeScript("return document.querySelector('my-component').shadowRoot.querySelector('button')");. Shadow DOM testing is increasingly important as more frameworks (Angular, Salesforce, Polymer) use it.

Medium Very Common 1 min read

Q72.How do you find elements inside an iframe?

First, switch to the iframe: driver.switchTo().frame("frameId"); or driver.switchTo().frame(frameElement); or driver.switchTo().frame(0); (by index). Then find elements as usual. To return to the main content: driver.switchTo().defaultContent();. To switch to a parent frame: driver.switchTo().parentFrame();. Always switch back after interacting with iframe content. Example: WebElement iframe = driver.findElement(By.cssSelector("iframe[title='Chat']")); driver.switchTo().frame(iframe); driver.findElement(By.id("messageInput")).sendKeys("Hello"); driver.switchTo().defaultContent();.

Medium Very Common 1 min read

Q73.What is a dynamic XPath and how do you create one?

A dynamic XPath uses functions and logic to handle elements with changing attributes. Key functions: contains(@class,'btn') for partial class matching, starts-with(@id,'dynamic_') for prefix matching, not(@disabled) for negative matching, normalize-space(text())='Submit' for whitespace-insensitive text matching, //*[@data-id] for any element with a data attribute. Example dynamic XPath: //button[contains(@class,'submit-btn') and not(contains(@class,'disabled'))]. Dynamic XPaths are essential for modern single-page applications where element attributes change frequently.

Medium Very Common 1 min read

Q74.How do you locate elements using data attributes?

Data attributes (data-*) are custom attributes in HTML5. XPath: //button[@data-testid='login-btn']. CSS: button[data-testid='login-btn']. Data attributes are ideal for test automation because they're explicitly added for testing and rarely change. Best practice: work with developers to add data-testid or data-qa attributes to all interactive elements. This eliminates locator fragility entirely and decouples tests from UI implementation details. Tools like React Testing Library use data-testid natively.

Medium Very Common 1 min read

Q75.How do you find an element when there are multiple matching elements?

Use findElements() to get all matches, then filter by additional criteria: List<WebElement> buttons = driver.findElements(By.className("btn")); for (WebElement btn : buttons) { if (btn.getText().equals("Submit")) { btn.click(); break; } }. Or refine your locator to be more specific: driver.findElement(By.xpath("//button[@class='btn' and text()='Submit']")). Or use findElements() and select by index if the order is reliable. Avoid relying on index-based selection for dynamic pages where element order may change.

Medium Very Common 1 min read

Q76.How do you locate elements in a table?

driver.findElement(By.xpath("//table[@id='data-table']/tbody/tr[2]/td[3]")); gets the 3rd cell of the 2nd row. For dynamic tables: //table[@id='data-table']//tr[contains(.,'SearchTerm')]/td. To iterate: WebElement table = driver.findElement(By.id("data-table")); List<WebElement> rows = table.findElements(By.tagName("tr")); for (WebElement row : rows) { List<WebElement> cells = row.findElements(By.tagName("td")); }. Table navigation requires good understanding of the table structure and thead/tbody/tfoot elements.

Medium Very Common 1 min read

Q77.How do you locate elements using index in XPath?

In XPath, indexing is 1-based: (//button)[1] — the first button in the document. (//div[@class='item'])[last()] — the last matching div. (//div[@class='item'])[position()=3] — the third one. (//div[@class='item'])[position()<3] — first two. Note the parentheses: without them, //button[1] means "button elements that are the first child of their parent", not "the first button in the whole document". Always wrap in parentheses when indexing across the entire document.

Medium Very Common 1 min read

Q78.How do you use axes in XPath?

XPath axes navigate the DOM relative to the current node: following-sibling::div (sibling after current), preceding-sibling::div (sibling before), parent::div (parent element), ancestor::form (any ancestor), child::span (direct child), descendant::input (any descendant), following::p (all elements after in document order), preceding::p (all elements before). Example: //label[text()='Username']/following-sibling::input finds the input following the username label. Axes are powerful for navigating complex DOM structures without brittle absolute paths.

Medium Very Common 1 min read

Q79.How do you find elements by their tag name?

driver.findElement(By.tagName("h1")); finds the first h1 element. driver.findElements(By.tagName("a")); finds all links on the page. Common tag names: input, button, a, div, span, select, option, img, form, table, tr, td, h1-h6, p, ul, ol, li. Tag name locators are rarely used alone since they typically return many elements. They're most useful in combination: driver.findElement(By.cssSelector("div.content p:first-child")); or for counting elements: int linkCount = driver.findElements(By.tagName("a")).size();.

Medium Very Common 1 min read

Q80.How do you find elements by class name that have spaces?

HTML class attributes can have multiple space-separated values: <div class="btn primary large">. By.className("btn") works — it matches any element that has "btn" in its class list. But By.className("btn primary") throws an error because className expects a single class value. For multiple classes, use CSS selector: By.cssSelector(".btn.primary.large") or XPath: By.xpath("//div[contains(@class,'btn') and contains(@class,'primary') and contains(@class,'large')]").

Medium Very Common 1 min read

Q81.How do you find an element when it's outside the viewport?

Selenium automatically scrolls to elements before clicking. However, if automatic scrolling doesn't work: ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element); scrolls the element into view. For smooth scrolling: arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'});. For scrolling to bottom: window.scrollTo(0, document.body.scrollHeight);. You can also use Actions class: new Actions(driver).moveToElement(element).perform();. After scrolling, you may need a small wait before interacting.

Hard Very Common 1 min read

Q82.What is a stale element reference exception and how to avoid it?

StaleElementReferenceException occurs when the DOM changes after you locate an element but before you interact with it. Causes: page refresh, JavaScript DOM updates, React/Angular re-renders, AJAX callbacks modifying the DOM. Solutions: (1) Re-find the element every time (don't cache). (2) Use Page Object Model with lazy initialization. (3) Use a retry mechanism: for (int i = 0; i < 3; i++) { try { element.click(); break; } catch (StaleElementReferenceException e) { element = driver.findElement(locator); } }. (4) Use FluentWait with ignored exception types. (5) In Playwright-style thinking, locate fresh each time.

Medium Very Common 1 min read

Q83.How do you optimize XPath performance?

(1) Avoid leading double slash // deep in the path — use single slash / for known paths. (2) Use ID-based XPath as the starting point: //*[@id='content']//button. (3) Avoid //* wildcards — be specific with tag names: //div//span. (4) Use CSS selectors instead when possible (they're 2-5x faster). (5) Avoid XPath functions like contains(), text(), and normalize-space() in complex chains. (6) Use @class instead of contains(@class) when the full class value is known. (7) Index early and specifically: (//form[@id='login']//input)[3] instead of //input[3].

Medium Very Common 1 min read

Q84.How do you find the parent element in XPath?

//input[@id='username']/.. finds the parent of the input. //input[@id='username']/parent::div finds the parent div specifically. //input[@id='username']/ancestor::form finds the nearest form ancestor. //input[@id='username']/ancestor::*[@class='modal'] finds the ancestor with class "modal". Parent/ancestor traversal is useful when you only have a locator for a child element but need to interact with its parent container.

Medium Very Common 1 min read

Q85.How do you find the following sibling in XPath?

//h2[text()='Details']/following-sibling::div finds the div element immediately after the h2. //label[@for='email']/following-sibling::input finds the input following a label. //li[@class='active']/following-sibling::li finds all li siblings after the active one. You can add filters: //label[@for='email']/following-sibling::input[1] finds the first input sibling. This is very useful for form fields where labels are adjacent to inputs.

Medium Very Common 1 min read

Q86.How do you find an element using multiple criteria in XPath?

Combine conditions with and, or, and not: //input[@type='text' and @name='username' and not(@disabled)] or //button[@type='submit' or @data-action='save']. For complex logic, use nested predicates: //div[contains(@class,'card') and .//h2[contains(text(),'Latest')]] — finds a card div that contains an h2 with "Latest". You can also chain: //input[(@type='text' or @type='email') and @required].

Medium Very Common 1 min read

Q87.How do you handle SVG elements in Selenium?

SVG elements don't work well with standard XPath. Use CSS selectors: driver.findElement(By.cssSelector("svg path:nth-child(2)")); or target specific attributes: driver.findElement(By.cssSelector("svg path[data-name='icon']"));. For XPath, use local-name(): //*[local-name()='svg']//*[local-name()='path' and @id='icon-path']. JavaScript can also help: ((JavascriptExecutor) driver).executeScript("return document.querySelector('svg g path');");. SVG interaction is increasingly important with icon-based UI components.

Medium Very Common 1 min read

Q88.How do you handle React elements in Selenium?

React applications often use dynamic class names and deeply nested DOM structures. Strategies: (1) Use data-testid attributes that React developers add. (2) Use CSS selectors with [class*='ComponentName'] for partial class matching. (3) Query by React component structure: //div[@data-reactroot]. (4) Use text content: //button[text()='Add to Cart']. (5) For React-select components, use specific class patterns like //div[contains(@class,'css-')]. (6) Use JavaScript to access React internals if needed (fragile). Best practice: collaborate with developers to add test attributes.

Hard Very Common 1 min read

Q89.How do you handle Angular elements in Selenium?

Angular apps use dynamic attribute bindings. Strategies: (1) Use Angular-specific attributes: //button[@_ngcontent-c123]. (2) Use contains(@class, 'mat-') for Material Design components. (3) Use CSS selectors with [ng-reflect-*] attributes: [ng-reflect-name='username']. (4) For Angular Material: //mat-select for dropdowns, //mat-checkbox for checkboxes. (5) Wait for Angular stability: ((JavascriptExecutor) driver).executeScript("return window.getAllAngularTestabilities().filter(t => !t.isStable());");. Angular elements often have extra overlay layers, so use JavaScript click if normal click fails.

Hard Very Common 1 min read

Q90.What are the best practices for writing locators?

(1) Use data-testid attributes whenever possible — they're stable and decoupled from UI changes. (2) Prefer ID > name > CSS > XPath in priority order. (3) Keep locators short and readable. (4) Avoid absolute XPath paths. (5) Avoid indexing unless the order is guaranteed. (6) Use contains() and starts-with() for dynamic attributes. (7) Combine stable attributes for uniqueness. (8) Avoid XPath text() matching for internationalized apps. (9) Store locators as constants or in Page Objects, not scattered in test methods. (10) Review and refactor locators regularly as the app evolves. (11) Use code review for locator quality. (12) Prefer CSS over XPath for performance.

Confidence check

If you can confidently answer the Locators & Element Identification questions above, you're well prepared for this section of your interview. Move on, or rehearse the trickier ones aloud with our AI mock interviewer.

4. Waits & Synchronization

Medium Very Common 1 min read

Q91.What are waits in Selenium and why are they needed?

Waits are mechanisms to handle timing issues between test execution and web page loading. Modern web pages use AJAX, JavaScript, and asynchronous rendering — elements may not be immediately available when Selenium tries to interact with them. Without proper waits, tests fail with NoSuchElementException, ElementNotInteractableException, or StaleElementReferenceException. There are three types: Implicit Wait (global, simple), Explicit Wait (specific conditions, per-element), and Fluent Wait (customizable polling and error handling). Proper synchronization is essential for reliable, flakiness-free tests.

Medium Very Common 1 min read

Q92.What is Implicit Wait in Selenium?

Implicit Wait tells WebDriver to poll the DOM for a certain duration when trying to find an element if it's not immediately available. Set once: driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));. It applies globally to all findElement() and findElements() calls during the driver's lifetime. If the element is found before the timeout, execution continues immediately. If not found after the timeout, NoSuchElementException is thrown. Implicit wait only affects element location, not other conditions like element visibility or clickability.

Medium Very Common 1 min read

Q93.What is Explicit Wait in Selenium?

Explicit Wait uses WebDriverWait with ExpectedConditions to wait for a specific condition on a specific element. Example: WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit")));. Common ExpectedConditions: visibilityOfElementLocated, elementToBeClickable, presenceOfElementLocated, textToBePresentInElement, invisibilityOf, alertIsPresent, numberOfElementsToBe, etc. Explicit wait is more precise than implicit wait because it checks exactly the condition you need.

Hard Very Common 1 min read

Q94.What is Fluent Wait in Selenium?

Fluent Wait is a more flexible version of Explicit Wait. It allows you to set polling frequency, ignore specific exceptions, and customize the timeout message. Example: Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) .withTimeout(Duration.ofSeconds(30)) .pollingEvery(Duration.ofMillis(500)) .ignoring(NoSuchElementException.class) .withMessage("Element not found within timeout"); WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("element")));. FluentWait is ideal for situations where elements may be temporarily hidden, taking longer to load, or the polling interval needs adjustment.

Medium Very Common 1 min read

Q95.What is the difference between Implicit and Explicit Wait?

(1) Scope: Implicit wait applies to ALL element find operations; explicit wait applies to SPECIFIC elements/conditions. (2) Conditions: Implicit wait only waits for element presence in DOM; explicit wait can wait for visibility, clickability, text presence, etc. (3) Performance: Implicit wait can slow down tests because it's checked on every findElement call. (4) Combination: NEVER mix implicit and explicit waits together — they can compound timeout periods unpredictably. (5) Best practice: Use implicit wait (2-5 seconds) as a baseline + explicit waits for critical elements. Or use only explicit waits for complete control.

Medium Very Common 1 min read

Q96.What is the difference between presenceOfElementLocated and visibilityOfElementLocated?

presenceOfElementLocated(By) checks if the element exists in the DOM — it doesn't check if it's visible or enabled. visibilityOfElementLocated(By) checks that the element is present in DOM AND visible (has height and width greater than 0, and CSS display/visibility properties don't hide it). Use presenceOfElementLocated when you only need to confirm the element exists (e.g., checking if an error message element is in the DOM). Use visibilityOfElementLocated when you need to interact with the element (click, sendKeys, getText) and it must be visible.

Medium Very Common 1 min read

Q97.How do you wait for an element to be clickable?

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.elementToBeClickable(By.id("submit-btn")));. This waits for the element to be present, visible, and enabled (not disabled). After this wait, you can safely call element.click(). The elementToBeClickable condition checks: element exists in DOM, element is visible, element is enabled. If the element is covered by another element (like a modal overlay), this condition may pass but the click may still fail with ElementClickInterceptedException.

Medium Very Common 1 min read

Q98.How do you wait for an element to disappear?

Use invisibilityOfElementLocated: WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-spinner")));. For waiting until an element is no longer stale: wait.until(ExpectedConditions.stalenessOf(element));. For waiting until a specific number of elements exist: wait.until(ExpectedConditions.numberOfElementsToBe(By.className("item"), 0));. This is essential for waiting for loading spinners, progress bars, or modal dialogs to close before proceeding.

Medium Very Common 1 min read

Q99.How do you wait for text to appear in an element?

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("status"), "Success")); waits for the element with ID "status" to contain the text "Success". For exact text: textToBe(By.id("status"), "Success!"). For value attribute text: textToBePresentInElementValue(By.id("inputField"), "submitted"). This is useful for waiting for status messages, search results counts, or dynamic text updates.

Medium Very Common 1 min read

Q100.How do you wait for an attribute value to change?

Use a custom ExpectedCondition: WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(d -> { WebElement el = d.findElement(By.id("element")); return "ready".equals(el.getAttribute("data-state")); });. Or use JavaScript: wait.until(d -> ((JavascriptExecutor) d).executeScript("return document.getElementById('element').getAttribute('data-state') === 'ready';"));. This pattern is useful when waiting for JavaScript-driven state changes, class updates, or data attribute modifications.

Hard Very Common 1 min read

Q101.What are ExpectedConditions in Selenium? List some important ones.

ExpectedConditions is a utility class in Selenium providing common wait conditions. Important ones: alertIsPresent(), elementToBeClickable(By), elementToBeSelected(By), frameToBeAvailableAndSwitchToIt(By), invisibilityOfElementLocated(By), presenceOfAllElementsLocatedBy(By), presenceOfElementLocated(By), textToBePresentInElementLocated(By, String), titleIs(String), titleContains(String), visibilityOf(WebElement), visibilityOfAllElementsLocatedBy(By), visibilityOfElementLocated(By), numberOfWindowsToBe(int), stalenessOf(WebElement), refreshed(ExpectedCondition) — useful for stale element handling. These cover 90% of synchronization needs in test automation.

Hard Very Common 1 min read

Q102.How do you create a custom ExpectedCondition?

Implement the ExpectedCondition interface: WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(new ExpectedCondition<Boolean>() { @Override public Boolean apply(WebDriver d) { WebElement el = d.findElement(By.id("progress")); String width = el.getCssValue("width"); return "100%".equals(width) || "0px".equals(width); } });. Or use lambda: wait.until(d -> { WebElement el = d.findElement(By.id("progress")); return "100%".equals(el.getCssValue("width")); });. Custom conditions are useful for application-specific behaviors like waiting for animations to complete, progress bars to fill, or custom JavaScript states.

Medium Very Common 1 min read

Q103.How do you set a global timeout in Selenium?

Three timeouts via driver.manage().timeouts(): (1) implicitlyWait(Duration.ofSeconds(10)) — for element finding. (2) pageLoadTimeout(Duration.ofSeconds(30)) — for page loading. (3) setScriptTimeout(Duration.ofSeconds(10)) — for async JavaScript execution. Set these once after driver initialization. Example: driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5)).pageLoadTimeout(Duration.ofSeconds(30)).setScriptTimeout(Duration.ofSeconds(10));. Setting appropriate global timeouts provides a safety net against unexpectedly slow operations.

Medium Very Common 1 min read

Q104.What happens when a wait times out in Selenium?

For implicit wait: NoSuchElementException is thrown. For explicit/fluent wait: TimeoutException is thrown (subclass of WebDriverException). The TimeoutException message includes details about what condition was expected and the timeout duration. You can catch and handle these exceptions: try { wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("element"))); } catch (TimeoutException e) { // Element not found within timeout — handle gracefully System.out.println("Element not found, continuing..."); // optional: take screenshot, log, or fail gracefully }.

Hard Very Common 1 min read

Q105.How do you wait for a page to load completely?

Multiple strategies: (1) Set page load timeout: driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(30));. (2) Use document.readyState: WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); wait.until(d -> ((JavascriptExecutor) d).executeScript("return document.readyState").equals("complete"));. (3) Wait for a specific element: wait.until(ExpectedConditions.presenceOfElementLocated(By.id("page-loaded-indicator")));. (4) For SPAs, wait for network idle (Selenium 4): via CDP performance metrics. Method 2 is the most reliable for traditional web apps; method 3 works better for SPAs.

Medium Very Common 1 min read

Q106.How do you wait for AJAX calls to complete?

For jQuery-based AJAX: WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); wait.until(d -> (Boolean) ((JavascriptExecutor) d).executeScript("return jQuery.active == 0"));. For vanilla JavaScript: wait.until(d -> (Boolean) ((JavascriptExecutor) d).executeScript("return window.XMLHttpRequest ? XMLHttpRequest.DONE === 4 : true"));. Alternatively, wait for the DOM element that confirms the AJAX update: wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("data-loaded")));. The element-based approach is more reliable than JavaScript checks.

Hard Very Common 1 min read

Q107.How do you wait for an animation to complete?

Use JavaScript to check animation state: WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(d -> { List<WebElement> animated = d.findElements(By.cssSelector("*")); for (WebElement el : animated) { String transition = el.getCssValue("transition-duration"); if (transition != null && !transition.equals("0s")) return false; } return true; });. Or wait for a specific CSS property value: wait.until(d -> { WebElement el = d.findElement(By.id("animated-element")); return el.getCssValue("opacity").equals("1"); });. Or use a timeout that matches the animation duration plus a buffer.

Medium Very Common 1 min read

Q108.What is Thread.sleep() and why should you avoid it?

Thread.sleep(5000) pauses execution for a fixed 5 seconds regardless of whether the condition has been met. It's a poor practice because: (1) It wastes time — if the element appears in 0.5s, you still wait 5s. (2) It's fragile — if the app is slower than your sleep duration, the test fails. (3) It makes tests slow and brittle. Use dynamic waits instead — they wait only as long as necessary and handle both fast and slow scenarios. Exception: occasional use for very specific race conditions or debugging purposes, but never in production test code.

Medium Very Common 1 min read

Q109.What is the recommended way to handle waits in Selenium?

(1) Set a short implicit wait (2-5 seconds) as a baseline for element presence. (2) Use explicit waits (WebDriverWait) for critical elements and operations. (3) Never mix implicit and explicit waits — they interact unpredictably. (4) Use FluentWait when you need custom polling or error handling. (5) Prefer ExpectedConditions over Thread.sleep(). (6) Set pageLoadTimeout to prevent stalled tests. (7) Always wait before interaction, not after. (8) Use wait timeouts that match your application's performance. (9) Log wait failures with screenshots for debugging. (10) Centralize wait logic in utility methods for reusability.

Medium Very Common 1 min read

Q110.How do you wait for a specific number of elements to load?

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.numberOfElementsToBe(By.className("item"), 10)); waits until exactly 10 elements with class "item" exist. Other variants: numberOfElementsToBeMoreThan(By, int), numberOfElementsToBeLessThan(By, int), numberOfWindowsToBe(int). This is useful for pagination, infinite scroll, search results, or any dynamic list where the number of items is expected to change.

Medium Very Common 1 min read

Q111.How do you wait for a frame to be available?

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("content-frame")));. This waits for the frame to exist in the DOM AND switches to it in one step. After this, any element searches are within the frame context. Equivalent long form: wait.until(ExpectedConditions.presenceOfElementLocated(By.id("content-frame"))); driver.switchTo().frame("content-frame");. The frameToBeAvailableAndSwitchToIt method is preferred because it combines both steps atomically.

Medium Very Common 1 min read

Q112.How do you wait for an alert to be present?

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.alertIsPresent()); Alert alert = driver.switchTo().alert(); alert.accept();. This waits for a JavaScript alert/prompt/confirm dialog to appear. After the wait, you can switch to the alert and accept/dismiss it or get its text. If you don't wait, trying to switch to a non-existent alert throws NoAlertPresentException. This is essential for handling confirmations, error prompts, and notification dialogs.

Medium Very Common 1 min read

Q113.How do you set different wait times for different elements?

Each WebDriverWait instance can have its own timeout: WebDriverWait shortWait = new WebDriverWait(driver, Duration.ofSeconds(3)); WebDriverWait longWait = new WebDriverWait(driver, Duration.ofSeconds(30)); // Use shortWait for elements that should load quickly shortWait.until(ExpectedConditions.visibilityOfElementLocated(By.id("quick-element"))); // Use longWait for slow-loading elements longWait.until(ExpectedConditions.visibilityOfElementLocated(By.id("slow-element")));. This optimizes test speed — fast checks don't wait for the full timeout, while slow operations have sufficient time.

Hard Very Common 1 min read

Q114.How do you handle dynamic wait times based on element behavior?

Use a polling approach with FluentWait: Wait<WebDriver> wait = new FluentWait<>(driver) .withTimeout(Duration.ofSeconds(30)) .pollingEvery(Duration.ofMillis(200)) .ignoring(NoSuchElementException.class).ignoring(StaleElementReferenceException.class); // Wait until element is stable (same content for 2 consecutive polls) wait.until(d -> { WebElement el = d.findElement(By.id("dynamic-content")); String text1 = el.getText(); sleep(200); String text2 = d.findElement(By.id("dynamic-content")).getText(); return text1.equals(text2) && !text1.isEmpty(); });. This pattern waits until dynamic content stabilizes — useful for auto-refreshing dashboards, live data feeds, or multi-step AJAX updates.

Hard Very Common 1 min read

Q115.How do you handle ElementClickInterceptedException?

ElementClickInterceptedException occurs when another element covers the target element. Solutions: (1) Wait for the covering element to disappear: wait.until(ExpectedConditions.invisibilityOfElementLocated(By.className("overlay")));. (2) Use JavaScript click: ((JavascriptExecutor) driver).executeScript("arguments[0].click();", element);. (3) Scroll to element explicitly before clicking. (4) Use Actions class to move to element: new Actions(driver).moveToElement(element).click().perform();. (5) Close any modal, popup, or banner covering the element. (6) Use explicit wait for elementToBeClickable which also checks that nothing is intercepting.

Hard Very Common 1 min read

Q116.What is the best practice for combining waits in a test framework?

(1) Define a set of reusable wait utility methods in a base class or helper: public void waitForElementVisible(WebElement element, int timeout), public void waitForElementClickable(By locator, int timeout), etc. (2) Use a standard timeout constant (e.g., 10 seconds) with per-method overrides. (3) Implement retry mechanisms for flaky operations. (4) Log wait operations and failures for debugging. (5) Use ExpectedConditions.or() and ExpectedConditions.and() for complex conditions. (6) Avoid Thread.sleep completely. (7) Use a wait timeout equal to the maximum expected load time plus a buffer. (8) Take screenshots on TimeoutException for diagnostics.

Medium Very Common 1 min read

Q117.How do you wait for a URL to change?

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.urlContains("dashboard")); waits for the URL to contain "dashboard". Other variants: urlToBe(String), urlMatches(String regex). This is useful for verifying navigation after form submission, login, or link clicks — especially when page title doesn't change (SPAs) and you need to confirm URL-based routing.

Medium Very Common 1 min read

Q118.How do you wait for a page title to change?

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.titleContains("Dashboard")); waits for the page title to contain "Dashboard". titleIs("My App - Dashboard") checks for exact title match. titleMatches(".*Dashboard.*") uses regex. This is useful after navigation, login, or any action that changes the page. It's more reliable than waiting for specific URLs because the title changes synchronously with navigation.

Hard Very Common 1 min read

Q119.How do you handle timeouts in Selenium tests gracefully?

(1) Use try-catch around wait operations: try { wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("element"))); } catch (TimeoutException e) { // Log the failure, take screenshot, but don't throw // Continue with fallback or mark test as warning File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); // log attachment }. (2) Implement a soft assertion library that collects failures without stopping the test. (3) Use test retries at the framework level (TestNG IRetryAnalyzer). (4) Log detailed timing information for debugging. (5) Differentiate between critical and non-critical elements — non-critical failures can be logged without failing the test.

Hard Common 1 min read

Q120.What is the polling interval in FluentWait and when should you change it?

The polling interval is the time between each condition check. Default is 250ms for FluentWait (vs 500ms for WebDriverWait). Change it when: (1) Elements load very quickly (use 100ms for responsive UIs). (2) Elements take long to load (use 1-2 seconds to reduce CPU overhead). (3) Testing animations that run at 60fps (~16ms intervals — use 50ms for smooth animation detection). (4) Elements appear after specific intervals (match the application's polling pattern). Example: .pollingEvery(Duration.ofMillis(100)). Adjust polling interval based on your application's behavior and performance requirements.

Confidence check

If you can confidently answer the Waits & Synchronization questions above, you're well prepared for this section of your interview. Move on, or rehearse the trickier ones aloud with our AI mock interviewer.

5. Alerts, Frames & Windows

Medium Common 1 min read

Q121.What is a JavaScript alert and how do you handle it in Selenium?

A JavaScript alert is a modal dialog created using alert(), confirm(), or prompt() methods in JavaScript. Handle it by switching to the alert: Alert alert = driver.switchTo().alert(); String text = alert.getText(); // get alert message alert.accept(); // click OK / alert.dismiss(); // click Cancel. For prompt alerts with input: alert.sendKeys("input text"); alert.accept();. Always check for alert presence before switching: WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5)); wait.until(ExpectedConditions.alertIsPresent());.

Medium Common 1 min read

Q122.What is the difference between alert.accept() and alert.dismiss()?

alert.accept() clicks the OK/Yes/Confirm button on the alert dialog. alert.dismiss() clicks the Cancel/No button, or the ESC key. For simple alert() dialogs (which only have an OK button), both accept() and dismiss() close the alert, but accept() is semantically correct. For confirm() dialogs, accept() is equivalent to clicking "OK" and dismiss() is equivalent to clicking "Cancel". For prompt() dialogs, accept() submits the entered text, dismiss() cancels the prompt.

Hard Common 1 min read

Q123.How do you handle unexpected alerts in Selenium?

Use ExpectedConditions.alertIsPresent() with a short timeout to check for unexpected alerts: try { WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(2)); wait.until(ExpectedConditions.alertIsPresent()); driver.switchTo().alert().accept(); } catch (TimeoutException e) { // No alert present — continue }. For catching alerts that appear during actions, you can also set ChromeOptions to dismiss alerts automatically: options.setCapability("unexpectedAlertBehaviour", "dismiss");. Unexpected alerts often occur from JavaScript errors, form validation popups, or session timeout warnings.

Medium Common 1 min read

Q124.How do you authenticate using the Alert interface?

For basic HTTP authentication popups, Selenium's Alert interface can handle them if they're JavaScript-based: Alert authAlert = driver.switchTo().alert(); authAlert.sendKeys("username" + Keys.TAB + "password"); authAlert.accept();. However, many HTTP auth dialogs are browser-native (not JavaScript). For those, use URL-embedded credentials: driver.get("https://username:password@example.com");. Or use Selenium 4's CDP-based authentication: ((HasAuthentication) driver).register(UsernameAndPassword.of("user", "pass"));. The CDP approach is the most reliable for modern browsers.

Medium Common 1 min read

Q125.What is an iframe and how do you identify it?

An iframe (inline frame) embeds another HTML document within the current page. You can identify iframes in the DOM using: driver.findElements(By.tagName("iframe")) or driver.findElements(By.tagName("frame")) (for older nested frame sets). Inspect the page using browser DevTools — search for <iframe> tags in the Elements panel. Iframes often have id, name, title, or src attributes. Common iframe use cases: embedded videos, payment gateways, social media widgets, advertising banners, and third-party content.

Medium Common 1 min read

Q126.How do you switch to an iframe in Selenium?

Three ways: (1) By index: driver.switchTo().frame(0); — switches to the first iframe on the page. (2) By name or ID: driver.switchTo().frame("iframe-name"); or driver.switchTo().frame("iframe-id");. (3) By WebElement: WebElement iframe = driver.findElement(By.cssSelector("iframe[title='Chat']")); driver.switchTo().frame(iframe);. To return to main content: driver.switchTo().defaultContent();. To go up one level: driver.switchTo().parentFrame();. Always switch back after interacting with iframe content.

Hard Common 1 min read

Q127.How do you handle nested iframes?

Switch step by step through each level: driver.switchTo().frame("outer-frame"); // enters outer iframe driver.switchTo().frame("inner-frame"); // enters inner iframe // interact with inner iframe content driver.switchTo().parentFrame(); // back to outer iframe driver.switchTo().defaultContent(); // back to main page. You can also switch directly using the iframe's WebElement: WebElement outerFrame = driver.findElement(By.cssSelector("iframe#outer")); WebElement innerFrame = outerFrame.findElement(By.cssSelector("iframe#inner"));. Nested iframes are common in complex applications like payment gateways, document editors, and legacy enterprise portals.

Medium Common 1 min read

Q128.How do you switch to a parent frame from a child iframe?

driver.switchTo().parentFrame(); switches to the immediate parent frame (Selenium 3.4+). This is useful when you're in a nested iframe and want to go back one level without returning to the main page. For multiple levels: chain parentFrame() calls or use driver.switchTo().defaultContent(); to go to the top-level document. Example: Main → Frame1 → Frame2 → Frame2 actions → parentFrame() (back to Frame1) → Frame1 actions → defaultContent() (back to main page).

Medium Common 1 min read

Q129.How do you find elements inside an iframe without switching?

You can't directly interact with iframe elements without switching to the iframe context. However, you can use JavaScript: ((JavascriptExecutor) driver).executeScript("return document.querySelector('#outer-iframe').contentDocument.querySelector('#inner-element').innerText;");. This accesses the iframe's contentDocument. For reading values only (not interaction), this can be more efficient. But for click(), sendKeys(), and other actions, you must switch to the iframe. Selenium's WebDriver design requires switching because element interaction commands are scoped to the current browsing context.

Medium Common 1 min read

Q130.How do you handle framesets (deprecated) in Selenium?

Framesets use <frameset> and <frame> tags instead of <iframe>. They work similarly: driver.switchTo().frame("frame-name"); or driver.switchTo().frame(index);. The main difference is that framesets divide the browser window into sections, each containing a separate HTML document. They're largely deprecated in favor of iframes and CSS layouts, but you may encounter them in legacy enterprise applications. The switching mechanics are identical to iframes.

Medium Common 1 min read

Q131.How do you handle multiple browser windows in Selenium?

(1) Store the parent window handle: String parentWindow = driver.getWindowHandle();. (2) Perform action that opens a new window. (3) Get all window handles: Set<String> allWindows = driver.getWindowHandles();. (4) Switch to new window by iterating handles: for (String window : allWindows) { if (!window.equals(parentWindow)) { driver.switchTo().window(window); break; } }. (5) Perform actions in the new window. (6) Close it: driver.close();. (7) Switch back: driver.switchTo().window(parentWindow);. Always manage window handles explicitly to avoid confusion.

Medium Common 1 min read

Q132.How do you handle pop-up windows in Selenium?

Pop-up windows (new browser windows opened via window.open()) are handled using window handles. Distinguish between pop-ups and main window by title or URL: for (String handle : driver.getWindowHandles()) { driver.switchTo().window(handle); if (driver.getTitle().equals("Popup Title")) { // This is our pop-up break; } }. For browser-level pop-ups (notifications, geolocation), pre-configure ChromeOptions to disable them. For JavaScript modal dialogs, use the Alert interface. For OS-level pop-ups (file upload), send keys directly to the input element.

Medium Common 1 min read

Q133.How do you close a specific browser window without closing others?

(1) Switch to the window you want to close: driver.switchTo().window(targetHandle);. (2) Call driver.close(); — this closes only the current active window. (3) Switch back to another open window: driver.switchTo().window(parentHandle);. Example: String mainHandle = driver.getWindowHandle(); driver.findElement(By.id("open-popup")).click(); for (String handle : driver.getWindowHandles()) { if (!handle.equals(mainHandle)) { driver.switchTo().window(handle); System.out.println("Popup title: " + driver.getTitle()); driver.close(); break; } } driver.switchTo().window(mainHandle);.

Medium Common 1 min read

Q134.How do you get the number of open browser windows?

int windowCount = driver.getWindowHandles().size(); returns the total number of open windows/tabs. Use this in assertions: Assert.assertEquals(2, driver.getWindowHandles().size()); // verify a popup opened. You can also wait for a specific number of windows: WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.numberOfWindowsToBe(2));. This is useful before switching to a new window to ensure it has fully opened.

Medium Common 1 min read

Q135.How do you open a new tab (not window) in Selenium?

Selenium 4: driver.switchTo().newWindow(WindowType.TAB); opens a new tab. In older versions, use JavaScript: ((JavascriptExecutor) driver).executeScript("window.open('about:blank', '_blank');"); then switch to it using window handles. Or use keyboard shortcut: driver.findElement(By.tagName("body")).sendKeys(Keys.chord(Keys.CONTROL, "t"));. After opening the new tab, wait for it and switch: String originalHandle = driver.getWindowHandle(); for (String handle : driver.getWindowHandles()) { if (!handle.equals(originalHandle)) { driver.switchTo().window(handle); break; } }.

Medium Common 1 min read

Q136.How do you handle Chrome's "Chrome is being controlled by automated test software" notification?

To disable this banner: ChromeOptions options = new ChromeOptions(); options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"}); options.setExperimentalOption("useAutomationExtension", false);. This removes the banner but may cause some sites to detect automation. For a more stealthy approach (to avoid bot detection): add --disable-blink-features=AutomationControlled to Chrome arguments. Note: some websites specifically check for automation flags, so you may need to override navigator.webdriver property using CDP in Selenium 4.

Hard Common 1 min read

Q137.How do you handle the Windows authentication popup?

The Windows authentication popup (native OS dialog) cannot be handled by Selenium directly. Solutions: (1) Use URL-embedded credentials: driver.get("https://username:password@example.com");. (2) Use AutoIT (Windows only) to handle the native dialog. (3) Use Robot class (Java): Robot robot = new Robot(); robot.keyPress(KeyEvent.VK_U); // type username.... (4) For Selenium 4, use CDP-based authentication: ((HasAuthentication) driver).register(UsernameAndPassword.of("user", "pass"));. (5) Configure the browser to trust the site or auto-authenticate. Option 1 is simplest; option 4 is the most robust for modern setups.

Hard Common 1 min read

Q138.How do you handle browser download popups?

Pre-configure the browser to auto-download without prompting: For Chrome: Map<String, Object> prefs = new HashMap<>(); prefs.put("download.prompt_for_download", false); prefs.put("download.directory_upgrade", true); prefs.put("safebrowsing.enabled", true); ChromeOptions options = new ChromeOptions(); options.setExperimentalOption("prefs", prefs);. For Firefox: FirefoxProfile profile = new FirefoxProfile(); profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/pdf,text/csv,application/zip"); profile.setPreference("browser.download.folderList", 2); profile.setPreference("browser.download.dir", "/path/to/downloads");. This disables the "Save As" dialog and downloads files automatically to the specified directory.

Medium Common 1 min read

Q139.How do you switch between tabs in the same browser window?

Use window handles: same as switching between windows. All tabs share the same window handle collection. driver.getWindowHandles() returns handles for all tabs in all windows. To switch to a specific tab by index: ArrayList<String> tabs = new ArrayList<>(driver.getWindowHandles()); driver.switchTo().window(tabs.get(1)); // switch to second tab. For keyboard shortcuts (less reliable): body.sendKeys(Keys.chord(Keys.CONTROL, Keys.TAB)); for next tab, body.sendKeys(Keys.chord(Keys.CONTROL, Keys.SHIFT, Keys.TAB)); for previous tab.

Medium Common 1 min read

Q140.How do you handle multiple windows with dynamic window handles?

Dynamic window handles change per session, so you can't hardcode them. Best practice: (1) Store the parent handle before any action. (2) Use a Set<String> to track all current handles. (3) After action, get the new set and find the new handle: Set<String> newHandles = driver.getWindowHandles(); newHandles.removeAll(oldHandles); String newWindowHandle = newHandles.iterator().next(); driver.switchTo().window(newWindowHandle);. (4) Use ExpectedConditions.numberOfWindowsToBe(expectedCount) to wait for the new window. This pattern handles multiple consecutive window openings reliably.

Confidence check

If you can confidently answer the Alerts, Frames & Windows questions above, you're well prepared for this section of your interview. Move on, or rehearse the trickier ones aloud with our AI mock interviewer.

6. Actions Class & Advanced Interactions

Medium Common 1 min read

Q141.What is the Actions class in Selenium?

The Actions class provides advanced user interactions like mouse hover, drag-and-drop, double-click, right-click, key combinations, and complex gesture sequences. It uses the builder pattern — you chain multiple actions and call .perform() to execute them all. Example: new Actions(driver).moveToElement(element).click().sendKeys("text").perform();. The Actions class is essential for simulating realistic user interactions that go beyond simple click() and sendKeys(). It works with the browser's native input events for accurate simulation.

Medium Common 1 min read

Q142.How do you perform a mouse hover in Selenium?

new Actions(driver).moveToElement(element).perform(); moves the mouse cursor over the specified element, triggering any hover effects (CSS :hover, JavaScript mouseenter events). For hovering over a menu and clicking a submenu: Actions actions = new Actions(driver); actions.moveToElement(driver.findElement(By.id("main-menu"))).perform(); WebElement submenu = driver.findElement(By.id("submenu-item")); submenu.click();. You can also chain: actions.moveToElement(mainMenu).pause(500).click(subMenu).perform();. The pause() is sometimes needed for animations to complete.

Medium Common 1 min read

Q143.How do you perform a right-click (context click) in Selenium?

new Actions(driver).contextClick(element).perform(); performs a right-click on the specified element, typically opening a context menu. Example: WebElement fileItem = driver.findElement(By.className("file")); new Actions(driver).contextClick(fileItem).perform(); WebElement deleteOption = driver.findElement(By.xpath("//div[text()='Delete']")); deleteOption.click();. Note: after the context click, you may need to wait for the context menu to appear before clicking the menu item. The context menu is usually a regular HTML element (not a browser-native menu), so standard locators work.

Medium Common 1 min read

Q144.How do you perform a double-click in Selenium?

new Actions(driver).doubleClick(element).perform(); performs a double-click on the element. Common use cases: selecting text, opening files, editing inline text. Example: WebElement cell = driver.findElement(By.cssSelector(".editable-cell")); new Actions(driver).doubleClick(cell).perform(); WebElement input = cell.findElement(By.tagName("input")); input.clear(); input.sendKeys("Updated value"); input.sendKeys(Keys.ENTER);. Double-click is often used in data grid applications, text editors, and spreadsheet-like interfaces.

Hard Common 1 min read

Q145.How do you perform drag and drop in Selenium?

new Actions(driver).dragAndDrop(sourceElement, targetElement).perform(); drags the source element and drops it onto the target element. For pixel-based offset: new Actions(driver).dragAndDropBy(sourceElement, xOffset, yOffset).perform();. Manual approach: actions.clickAndHold(sourceElement).moveToElement(targetElement).release().perform();. Example: WebElement source = driver.findElement(By.id("draggable-item")); WebElement target = driver.findElement(By.id("drop-zone")); new Actions(driver).dragAndDrop(source, target).perform();. Note: HTML5 drag-and-drop often needs JavaScript helpers as Selenium's native drag-and-drop may not work.

Hard Common 1 min read

Q146.How do you handle HTML5 drag and drop in Selenium?

HTML5 drag-and-drop doesn't always work with Selenium's Actions class because browsers implement it differently. Workarounds: (1) Use JavaScript to simulate HTML5 drag-and-drop events. (2) Use the html5-drag-and-drop polyfill library. (3) Bypass the drag-and-drop entirely — directly manipulate the data model if possible. JavaScript approach: ((JavascriptExecutor) driver).executeScript("var src=arguments[0],tgt=arguments[1]; var dt=new DataTransfer(); src.dispatchEvent(new DragEvent('dragstart',{dataTransfer:dt})); tgt.dispatchEvent(new DragEvent('drop',{dataTransfer:dt})); src.dispatchEvent(new DragEvent('dragend',{dataTransfer:dt}));", sourceElement, targetElement);. This fires all the necessary HTML5 drag events.

Medium Common 1 min read

Q147.How do you use keyboard shortcuts in Selenium?

Use the Actions class for modifier keys: new Actions(driver).keyDown(Keys.CONTROL).sendKeys("c").keyUp(Keys.CONTROL).perform(); copies selected text (Ctrl+C). Common shortcuts: Ctrl+A (select all), Ctrl+C (copy), Ctrl+V (paste), Ctrl+Z (undo), Ctrl+S (save), Ctrl+P (print). For non-printable keys: Keys.ENTER, Keys.TAB, Keys.ESCAPE, Keys.F5, Keys.ARROW_DOWN, Keys.SPACE. Use Keys.chord() for combination keys: body.sendKeys(Keys.chord(Keys.CONTROL, Keys.SHIFT, "i")); (DevTools on Chrome). Always release modifier keys with keyUp() to avoid stuck keys.

Hard Common 1 min read

Q148.How do you handle slider elements in Selenium?

Use Actions class dragAndDropBy: WebElement slider = driver.findElement(By.id("slider-handle")); new Actions(driver).dragAndDropBy(slider, offsetX, 0).perform();. Calculate offset based on min/max values: int sliderWidth = slider.getSize().getWidth(); int offset = (desiredValue - minValue) * sliderWidth / (maxValue - minValue);. Alternatively, use JavaScript to set the value: ((JavascriptExecutor) driver).executeScript("arguments[0].value = arguments[1];", sliderInput, desiredValue);. For range sliders (two handles), handle each handle separately, adjusting the offset for the second handle relative to the first.

Medium Common 1 min read

Q149.How do you scroll to an element using Actions class?

new Actions(driver).scrollToElement(element).perform(); (Selenium 4). In older versions: new Actions(driver).moveToElement(element).perform(); — this also scrolls the element into view. For pixel-based scrolling: new Actions(driver).scrollByAmount(0, 500).perform(); scrolls down 500px. For scrolling in an element: new Actions(driver).scrollFromOrigin(element, 0, 200).perform();. The Actions class scrolling methods in Selenium 4 provide more control than JavaScript scrolling for complex scroll scenarios.

Medium Common 1 min read

Q150.How do you use the Pause method in Actions class?

new Actions(driver).moveToElement(element).pause(Duration.ofMillis(500)).click().perform(); pauses for 500ms between actions. Useful for: (1) Waiting for animations to complete. (2) Simulating human-like delays. (3) Waiting for hover menus to appear. (4) Timing-dependent interactions. Example: actions.moveToElement(mainMenu).pause(300).moveToElement(subMenu).pause(300).click(subMenuItem).perform();. Note: pause() should be used sparingly — prefer explicit waits for conditional waits. Pause is for fixed-duration delays in multi-step action sequences.

Medium Common 1 min read

Q151.How do you select text in an element using Actions class?

new Actions(driver).moveToElement(element, 0, 0).clickAndHold().moveByOffset(elementWidth, 0).release().perform(); selects all text in the element. For selecting specific text range, calculate offsets proportionally. Simpler approach: use keyboard: element.sendKeys(Keys.chord(Keys.CONTROL, "a")); selects all text in the element. For partial selection, send HOME key first, then hold SHIFT + ARROW keys. Text selection is useful for testing copy/paste functionality, rich text editors, and content management systems.

Medium Common 1 min read

Q152.How do you set slider value using keyboard in Selenium?

Click the slider first, then use arrow keys: slider.click(); slider.sendKeys(Keys.ARROW_RIGHT); // increment by one step. For multiple steps: for (int i = 0; i < steps; i++) { slider.sendKeys(Keys.ARROW_RIGHT); }. For larger jumps: use Keys.PAGE_UP / Keys.PAGE_DOWN (typically 10-step increments). Or use Keys.HOME (minimum value) / Keys.END (maximum value). This approach is more reliable than drag-and-drop for HTML5 range inputs and works across all browsers consistently.

Hard Common 1 min read

Q153.How do you interact with a rich text editor (WYSIWYG) in Selenium?

Rich text editors (TinyMCE, CKEditor, Quill) use iframes or contentEditable divs. For iframe-based editors: driver.switchTo().frame(editorIframe); driver.findElement(By.tagName("body")).sendKeys("Hello World");. For contentEditable divs: WebElement editor = driver.findElement(By.cssSelector("[contenteditable='true']")); editor.sendKeys("Hello World");. To clear: editor.clear(); or editor.sendKeys(Keys.chord(Keys.CONTROL, "a"), Keys.DELETE);. For advanced formatting (bold, italic), use keyboard shortcuts: editor.sendKeys(Keys.chord(Keys.CONTROL, "b")); then type text. For setting HTML content: use JavaScript: ((JavascriptExecutor) driver).executeScript("arguments[0].innerHTML = arguments[1];", editor, "<p>Formatted <b>text</b></p>");.

Medium Common 1 min read

Q154.How do you simulate CAPTCHA entry in Selenium?

CAPTCHAs are designed to prevent automation, and automating them is against the terms of service of most websites. Ethical approaches: (1) Ask developers to disable CAPTCHA in test environments. (2) Use a test-only CAPTCHA bypass token. (3) Use a pre-captured test account that doesn't trigger CAPTCHA. (4) Use a manual override in test environments. Do NOT attempt to solve CAPTCHAs programmatically with OCR services — this violates anti-automation policies and can get your IP banned.
Difficulty: N/A | Topic: Actions

Hard Common 1 min read

Q155.How do you upload a file in Selenium?

For file input elements: WebElement fileInput = driver.findElement(By.cssSelector("input[type='file']")); fileInput.sendKeys("/absolute/path/to/file.pdf");. This works on the native file input element even if it's hidden (use JavaScript to make it visible if needed). For drag-and-drop upload areas: simulate the file drop using JavaScript: ((JavascriptExecutor) driver).executeScript("var input = document.createElement('input'); input.type = 'file'; input.style.display = 'none'; document.body.appendChild(input);");. For custom upload widgets, you may need to interact with the library-specific API. The sendKeys approach on a file input is the most reliable method.

Hard Common 1 min read

Q156.How do you handle file download in Selenium?

(1) Click the download button/link. (2) Wait for the file to appear in the download directory: Path downloadPath = Paths.get("/path/to/downloads"); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); wait.until(d -> { File dir = downloadPath.toFile(); File[] files = dir.listFiles((f, name) -> name.startsWith("report")); return files != null && files.length > 0; });. (3) Verify the downloaded file: File downloadedFile = downloadPath.toFile().listFiles()[0]; Assert.assertTrue(downloadedFile.length() > 0);. (4) Clean up: downloadedFile.delete();. For dynamic filenames, use Files.list(downloadPath) and find files by last modified time or name pattern.

Medium Common 1 min read

Q157.How do you use the WebElement.sendKeys() for special keys?

element.sendKeys(Keys.ENTER); presses Enter. Other special keys: Keys.TAB, Keys.ESCAPE, Keys.SPACE, Keys.BACK_SPACE, Keys.DELETE, Keys.INSERT, Keys.HOME, Keys.END, Keys.PAGE_UP, Keys.PAGE_DOWN, Keys.ARROW_UP/DOWN/LEFT/RIGHT, Keys.F1-F12, Keys.ALT, Keys.CONTROL, Keys.SHIFT, Keys.COMMAND (macOS). For combinations: sendKeys(Keys.chord(Keys.CONTROL, Keys.SHIFT, "i")) opens Chrome DevTools. For copying: sendKeys(Keys.chord(Keys.CONTROL, "c")). The chord() method presses all keys simultaneously in the order given and releases them together.

Hard Common 1 min read

Q158.How do you perform multiple actions in sequence using Actions class?

Chain action methods and call perform() once: Actions actions = new Actions(driver); actions.moveToElement(userMenu) .pause(Duration.ofMillis(300)) .click() .pause(Duration.ofMillis(200)) .sendKeys("admin") .pause(Duration.ofMillis(100)) .sendKeys(Keys.TAB) .pause(Duration.ofMillis(100)) .sendKeys("password123") .sendKeys(Keys.ENTER) .perform();. This builds a composite action that executes in order. Each action is queued in the browser's event queue. You can also build and perform actions separately: actions.moveToElement(element).perform(); // execute first action actions.click().perform(); // execute second action. The builder pattern allows either chained or step-by-step execution.

Medium Common 1 min read

Q159.How do you use the Keys.chord() method?

Keys.chord(Keys.CONTROL, "a") returns a String that represents pressing Ctrl+A simultaneously. Usage: element.sendKeys(Keys.chord(Keys.CONTROL, "a")); selects all text. element.sendKeys(Keys.chord(Keys.CONTROL, "c")); copies. The chord() method is a convenience for common key combinations. It's different from Actions class — it sends the key combination as a single string rather than pressing and releasing keys individually. For complex keyboard interactions, use Actions class with keyDown()/keyUp() instead of chord().

Medium Common 1 min read

Q160.What is the difference between Actions and Keyboard/ Mouse interactions?

Actions class provides a high-level API that queues multiple actions for composite execution. It handles mouse movement, button clicks, key presses, and pauses. The underlying implementation uses the browser's native events for accurate simulation. Keyboard (sendKeys) and Mouse (low-level) interactions are more primitive. Actions is preferred for complex user interactions (drag-and-drop, hover menus, context clicks). Simple clicks and sendKeys are better done directly on WebElements for cleaner code. Actions builds a sequence; simple interactions execute immediately.

Confidence check

If you can confidently answer the Actions Class & Advanced Interactions questions above, you're well prepared for this section of your interview. Move on, or rehearse the trickier ones aloud with our AI mock interviewer.

7. TestNG & Framework Design

Medium Common 1 min read

Q161.What is TestNG and how is it used with Selenium?

TestNG (Test Next Generation) is a testing framework inspired by JUnit and NUnit, designed for test configuration, parallel execution, data-driven testing, and reporting. It uses annotations to control test flow: @Test (marks test method), @BeforeSuite/@AfterSuite, @BeforeTest/@AfterTest, @BeforeClass/@AfterClass, @BeforeMethod/@AfterMethod (setup/teardown). With Selenium, TestNG manages driver initialization in @BeforeMethod, test execution in @Test, and cleanup in @AfterMethod. It also provides assertions, data providers, groups, and parallel execution via testng.xml configuration.

Medium Common 1 min read

Q162.What are the important TestNG annotations?

@Test — marks a method as test. @BeforeSuite / @AfterSuite — runs before/after all tests in suite. @BeforeTest / @AfterTest — runs before/after <test> tag in XML. @BeforeClass / @AfterClass — runs before/after first/last test method in class. @BeforeMethod / @AfterMethod — runs before/after each @Test method. @DataProvider — supplies test data. @Parameters — passes parameters from XML. @Factory — runs test instances with different data. @Listeners — attaches custom listeners. Execution order: Suite → Test → Class → Method (Before runs first, After runs last, each corresponding level).

Medium Common 1 min read

Q163.What is the difference between @BeforeClass and @BeforeMethod?

@BeforeClass runs ONCE before any test method in the class executes. @BeforeMethod runs BEFORE EACH @Test method. @AfterClass runs ONCE after all test methods complete. @AfterMethod runs AFTER EACH @Test method. In Selenium: use @BeforeClass for one-time setup (reading config files, creating report objects). Use @BeforeMethod for per-test setup (initializing WebDriver, navigating to base URL, logging in). Use @AfterMethod for per-test cleanup (taking screenshots on failure, clearing cookies). Use @AfterClass for one-time teardown (closing reporter, generating final report).

Hard Common 1 min read

Q164.How do you run Selenium tests in parallel using TestNG?

In testng.xml: <suite name="Suite" parallel="methods" thread-count="5"> <test name="Test"> <classes> <class name="com.test.LoginTest"/> </classes> </test> </suite>. For class-level parallelism: parallel="classes". For test-level: parallel="tests". To make WebDriver thread-safe: use ThreadLocal<WebDriver>: private static ThreadLocal<WebDriver> driver = new ThreadLocal<>(); driver.set(new ChromeDriver());. Each thread gets its own driver instance. Set thread-count to match your system's CPU cores. For cross-browser parallel execution, parameterize the browser in testng.xml.

Hard Common 1 min read

Q165.What is ThreadLocal<WebDriver> and why is it used?

ThreadLocal<WebDriver> provides thread-local variables — each thread gets its own independent copy of WebDriver. This is essential for parallel test execution because WebDriver is not thread-safe. Without ThreadLocal, sharing a single driver instance across threads causes race conditions and test failures. Usage: private static ThreadLocal<WebDriver> driverThread = new ThreadLocal<>(); @BeforeMethod public void setup() { driverThread.set(new ChromeDriver()); } public static WebDriver getDriver() { return driverThread.get(); } @AfterMethod public void teardown() { getDriver().quit(); driverThread.remove(); }. This pattern is standard in all parallel Selenium frameworks.

Hard Common 1 min read

Q166.How do you use DataProvider in TestNG?

@DataProvider(name = "loginData") public Object[][] getData() { return new Object[][] { {"user1", "pass1"}, {"user2", "pass2"}, {"user3", "pass3"} }; } @Test(dataProvider = "loginData") public void testLogin(String username, String password) { // test with each data set }. DataProvider can also return Iterator<Object[]> for lazy loading. For external data (Excel, CSV, JSON), create a utility method that reads the file and returns Object[][]. DataProvider with dataProviderClass attribute allows you to define DataProvider in a separate class for reusability. This enables data-driven testing with multiple test data sets.

Hard Common 1 min read

Q167.How do you group tests in TestNG?

Add groups to @Test: @Test(groups = {"smoke", "login"}) public void testLogin() {} @Test(groups = {"regression"}) public void testProfile() {}. In testng.xml: <test name="Smoke Tests"> <groups> <run> <include name="smoke" /> </run> </groups> <classes> <class name="com.test.AllTests" /> </classes> </test>. Exclude groups: <exclude name="broken" />. Groups help categorize tests by type (smoke, regression, sanity), feature (login, search, checkout), or priority (P0, P1, P2). You can also define meta-groups using <define> with <include>/<exclude>.

Hard Common 1 min read

Q168.What is Page Object Model (POM)?

Page Object Model is a design pattern where each web page or component is represented by a class. The class encapsulates: (1) WebElements (using locator strategies). (2) Methods that operate on those elements (login(), search(), addToCart()). (3) Page validation methods. Benefits: reduced code duplication, improved maintenance (UI change → update one class), better readability, and reusability across tests. Example: public class LoginPage { By usernameInput = By.id("username"); By passwordInput = By.id("password"); By loginBtn = By.id("loginBtn"); public void login(String user, String pass) { driver.findElement(usernameInput).sendKeys(user); driver.findElement(passwordInput).sendKeys(pass); driver.findElement(loginBtn).click(); } }.

Hard Common 1 min read

Q169.What is Page Factory in Selenium?

Page Factory is an extension of Page Object Model that uses annotations to initialize WebElements. Use @FindBy annotation: public class LoginPage { @FindBy(id = "username") WebElement usernameInput; @FindBy(name = "password") WebElement passwordInput; @FindBy(css = "button[type='submit']") WebElement loginBtn; public LoginPage() { PageFactory.initElements(driver, this); } }. Page Factory lazily initializes elements using the specified locator. It also supports caching (@CacheLookup for elements that don't change), and AjaxElementLocator for smart waiting. While convenient, Page Factory has limitations with complex locators and is less popular in modern frameworks.

Medium Common 1 min read

Q170.What is the difference between Page Object Model and Page Factory?

POM is a design pattern (conceptual); Page Factory is a Selenium library that implements POM. POM can be implemented without Page Factory by writing explicit findElement() calls. Page Factory uses @FindBy annotations and automatic initialization via PageFactory.initElements(). Page Factory provides lazy initialization (elements found on first use) and caching (@CacheLookup). However, Page Factory doesn't support complex locators (like XPath with variables), and the lazy initialization can mask NullPointerExceptions. Many modern frameworks prefer explicit POM without Page Factory for better control and debugging.

Hard Common 1 min read

Q171.How do you handle driver initialization in a framework?

Create a DriverFactory class: public class DriverFactory { private static ThreadLocal<WebDriver> driver = new ThreadLocal<>(); public static WebDriver getDriver() { return driver.get(); } public static void setDriver(String browser) { switch(browser) { case "chrome": driver.set(new ChromeDriver(chromeOptions())); break; case "firefox": driver.set(new FirefoxDriver(firefoxOptions())); break; } getDriver().manage().window().maximize(); getDriver().manage().timeouts().implicitlyWait(Duration.ofSeconds(5)); } public static void quitDriver() { getDriver().quit(); driver.remove(); } }. Call DriverFactory.setDriver("chrome") in @BeforeMethod and DriverFactory.quitDriver() in @AfterMethod. This centralizes driver creation and supports easy browser switching and parallel execution.

Hard Common 1 min read

Q172.How do you read configuration from properties files?

Create a ConfigReader class: public class ConfigReader { private static Properties prop = new Properties(); static { try { FileInputStream fis = new FileInputStream("config.properties"); prop.load(fis); } catch (IOException e) { e.printStackTrace(); } } public static String get(String key) { return prop.getProperty(key); } public static String getBrowser() { return prop.getProperty("browser", "chrome"); } public static String getUrl() { return prop.getProperty("url", "https://example.com"); } public static int getTimeout() { return Integer.parseInt(prop.getProperty("timeout", "10")); } }. Config file example: browser=chrome\nurl=https://example.com\ntimeout=10. This separates configuration from code, making tests environment-agnostic.

Hard Common 1 min read

Q173.How do you implement logging in Selenium tests?

Use Log4j 2 or SLF4J: import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class BaseTest { private static final Logger log = LogManager.getLogger(BaseTest.class); @BeforeMethod public void setup() { log.info("Starting test: {}", getClass().getSimpleName()); } @AfterMethod public void teardown(ITestResult result) { if (result.getStatus() == ITestResult.FAILURE) { log.error("Test failed: {}", result.getName()); } log.info("Test completed: {}", result.getName()); } }. Configure log4j2.xml with appenders (console, file, database). Logging is essential for debugging failures in CI/CD where you can't watch the browser. Log test steps, element interactions, and failures with timestamps.

Hard Common 1 min read

Q174.How do you implement reporting in Selenium?

Use ExtentReports or Allure: ExtentReports extent = new ExtentReports(); ExtentSparkReporter spark = new ExtentSparkReporter("test-output/ExtentReport.html"); extent.attachReporter(spark); ExtentTest test = extent.createTest("Login Test"); test.log(Status.PASS, "Login successful"); // after each step test.log(Status.FAIL, "Login failed").addScreenCaptureFromPath(screenshotPath); // on failure extent.flush(); // after all tests. For Allure: add @Step annotations and use AspectJ weaving for automatic step logging. Both generate beautiful HTML reports with test history, charts, screenshots, and environment info. Integrate with TestNG listeners for automatic reporting.

Hard Common 1 min read

Q175.How do you take screenshots on test failure?

Implement ITestListener: public class TestListener implements ITestListener { @Override public void onTestFailure(ITestResult result) { Object driver = result.getTestContext().getAttribute("driver"); if (driver != null) { String screenshotPath = takeScreenshot((WebDriver) driver, result.getName()); result.setAttribute("screenshot", screenshotPath); } } private String takeScreenshot(WebDriver driver, String testName) { String path = "screenshots/" + testName + "_" + System.currentTimeMillis() + ".png"; File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); FileUtils.copyFile(src, new File(path)); return path; } }. Register in testng.xml: <listeners><listener class-name="com.test.TestListener"/></listeners>. Screenshots provide visual evidence for failure analysis.

Hard Common 1 min read

Q176.How do you retry failed tests in TestNG?

Implement IRetryAnalyzer: public class RetryAnalyzer implements IRetryAnalyzer { private int retryCount = 0; private static final int MAX_RETRY = 2; @Override public boolean retry(ITestResult result) { if (retryCount < MAX_RETRY) { retryCount++; return true; } return false; } }. Use in test: @Test(retryAnalyzer = RetryAnalyzer.class) public void flakyTest() { ... }. For global retry, implement IAnnotationTransformer to add retry analyzer to all tests. Retry flaky tests (typically 1-2 retries) to handle transient failures (network glitches, timing issues) without rerunning the entire suite.

Medium Common 1 min read

Q177.How do you pass parameters from testng.xml to tests?

In testng.xml: <parameter name="browser" value="chrome"/> <test> <parameter name="url" value="https://example.com"/> <classes> <class name="com.test.LoginTest"/> </classes> </test>. In test class: @Test @Parameters({"browser", "url"}) public void testLogin(String browser, String url) { // use parameters }. For method-level parameters: use @Optional: @Test @Parameters({"browser"}) public void testLogin(@Optional("chrome") String browser) { ... }. Parameters enable environment-specific configuration without modifying code.

Medium Common 1 min read

Q178.How do you create a hybrid Selenium framework?

A hybrid framework combines POM + Data-Driven + Keyword-Driven approaches: (1) Page Object classes for each page. (2) DataProvider for test data (Excel, JSON, CSV). (3) A utility layer for common functions (waits, screenshots, reporting). (4) Base test class for driver lifecycle. (5) TestNG for orchestration. (6) Listeners for reporting and failure handling. (7) Config files for environment settings. (8) Maven/Gradle for dependency management and build. (9) Jenkins/GitHub Actions for CI/CD. Benefits: reusable components, data-driven flexibility, easy maintenance, and CI integration.

Hard Common 1 min read

Q179.What is the difference between soft assertion and hard assertion?

Hard assertion (Assert.assertEquals()) throws an AssertionError immediately on failure — the test stops at that point. Soft assertion (TestNG's SoftAssert) accumulates failures and reports them all at the end. Example: SoftAssert softAssert = new SoftAssert(); softAssert.assertEquals(pageTitle, "Expected Title"); softAssert.assertTrue(element.isDisplayed()); softAssert.assertAll(); // throws if any assertion failed. Use hard assertions for critical checks (login must succeed). Use soft assertions for non-critical validations (verify all fields on a page without stopping on the first failure).

Hard Common 1 min read

Q180.How do you implement BDD with Selenium?

Use Cucumber + Selenium: (1) Write feature files: Feature: Login Scenario: Successful login Given I am on the login page When I enter valid credentials Then I should see the dashboard. (2) Create step definitions: @Given("I am on the login page") public void i_am_on_login_page() { driver.get("https://example.com/login"); } @When("I enter valid credentials") public void i_enter_valid_credentials() { loginPage.login("user", "pass"); }. (3) Create test runner with @RunWith(Cucumber.class). (4) Use dependency injection (PicoContainer or Spring) for sharing driver state between steps. BDD improves collaboration between QA, developers, and business stakeholders.

Hard Common 1 min read

Q181.What is the Maven build tool and how does it help with Selenium?

Maven is a build automation tool for Java projects. It manages dependencies (pom.xml), compiles code, runs tests, and generates reports. For Selenium, add dependencies in pom.xml: <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.27.0</version> </dependency>. Maven automatically downloads Selenium and its transitive dependencies (Guava, Apache Commons, etc.). Use mvn test to run all tests, mvn surefire-report:report for test reports. Maven profiles enable environment-specific configurations. It's the standard build tool for Java Selenium projects.

Medium Common 1 min read

Q182.How do you organize test classes in a Selenium project?

Package structure: src/test/java/com/company/pages/ (Page Objects), tests/ (Test classes), utils/ (utility classes like WaitHelper, ExcelReader), listeners/ (TestNG listeners), base/ (BaseTest class). src/test/resources/config/ (properties files), testdata/ (Excel, JSON, CSV files), drivers/ (browser driver executables). testng.xml at root level. This separation of concerns makes the project maintainable and scalable. Each test class corresponds to a feature or module.

Hard Common 1 min read

Q183.How do you handle test data with Excel files?

Use Apache POI library: public Object[][] getExcelData(String filePath, String sheetName) { FileInputStream fis = new FileInputStream(filePath); Workbook workbook = new XSSFWorkbook(fis); Sheet sheet = workbook.getSheet(sheetName); int rows = sheet.getPhysicalNumberOfRows(); int cols = sheet.getRow(0).getPhysicalNumberOfCells(); Object[][] data = new Object[rows-1][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(); } } return data; }. Use with DataProvider: @DataProvider(name = "excelData") public Object[][] getData() { return getExcelData("testdata/login.xlsx", "Sheet1"); }. Excel is popular for non-technical team members to maintain test data without touching code.

Medium Common 1 min read

Q184.How do you handle dynamic test data generation?

Use Java Faker library or random generators: Faker faker = new Faker(); String email = faker.internet().emailAddress(); String name = faker.name().fullName(); String phone = faker.phoneNumber().phoneNumber();. For unique data: use timestamps: String uniqueEmail = "test" + System.currentTimeMillis() + "@test.com";. For specific formats: use libraries like JavaFaker or generate UUID: UUID.randomUUID().toString(). Dynamic data is essential for registration forms, cart checkouts, and any scenario requiring unique user data to avoid test collisions.

Hard Common 1 min read

Q185.What is the BaseTest pattern in Selenium?

BaseTest is a superclass that all test classes extend. It contains: (1) ThreadLocal<WebDriver> for parallel-safe driver. (2) @BeforeClass/@BeforeTest for suite-level setup. (3) @BeforeMethod for per-test setup (initialize driver, navigate to URL). (4) @AfterMethod for per-test cleanup (screenshots on failure, logout, clear cookies). (5) @AfterClass for driver quit. (6) Common utility methods (waitForElement, takeScreenshot). (7) Logger and reporter instances. Example: public class BaseTest { protected WebDriver driver; @BeforeMethod public void setUp() { driver = new ChromeDriver(); } @AfterMethod public void tearDown() { if (driver != null) driver.quit(); } }.

Hard Common 1 min read

Q186.How do you implement Singleton pattern for WebDriver?

public class WebDriverSingleton { private static ThreadLocal<WebDriver> driver = new ThreadLocal<>(); private WebDriverSingleton() {} public static WebDriver getDriver() { if (driver.get() == null) { driver.set(new ChromeDriver()); } return driver.get(); } public static void quitDriver() { if (driver.get() != null) { driver.get().quit(); driver.remove(); } } }. Usage: WebDriverSingleton.getDriver().get("https://example.com"); WebDriverSingleton.quitDriver();. The Singleton ensures only one driver instance per thread. The ThreadLocal variant makes it thread-safe for parallel execution. This pattern is common but debateable — some prefer explicit driver management via dependency injection.

Hard Common 1 min read

Q187.How do you implement Page Object Model with Fluent Interface?

Each page method returns the page object itself (or a new page), enabling method chaining: public class LoginPage { public LoginPage enterUsername(String user) { driver.findElement(By.id("username")).sendKeys(user); return this; } public LoginPage enterPassword(String pass) { driver.findElement(By.id("password")).sendKeys(pass); return this; } public DashboardPage clickLogin() { driver.findElement(By.id("loginBtn")).click(); return new DashboardPage(driver); } }. Usage: new LoginPage(driver).enterUsername("user").enterPassword("pass").clickLogin();. The Fluent Interface pattern makes tests read like natural language and reduces code repetition.

Medium Common 1 min read

Q188.How do you handle environment-specific configurations?

Use Maven profiles or config files per environment: config-dev.properties, config-qa.properties, config-prod.properties. Load based on system property: String env = System.getProperty("env", "qa"); String url = configReader.get(env + ".url");. In Maven: mvn test -Denv=dev. For Docker: pass environment variables. Use a ConfigFactory that reads the appropriate file based on the active profile. This enables running the same tests across development, staging, and production environments without code changes.

Medium Common 1 min read

Q189.What is the best project structure for Selenium automation?

Recommended structure: project-name/src/main/java/pages/ (Page Objects), utils/ (WaitUtils, ExcelUtils, ConfigReader), base/ (BasePage, BaseTest), components/ (reusable components like Header, Footer, Navigation), enums/ (constants). src/test/java/tests/ (test classes), listeners/ (TestNG listeners), dataproviders/ (DataProvider classes). resources/config/ (properties files), testdata/ (Excel/JSON), testng.xml, log4j2.xml. pom.xml. README.md. This structure separates page objects from test logic, supports reusability, and scales well for large teams.

Hard Common 1 min read

Q190.How do you integrate Selenium with CI/CD (Jenkins)?

(1) Store test code in Git repository. (2) Configure Jenkins job: Source Code Management (Git), Build Triggers (poll SCM, cron, webhooks), Build Environment (set environment variables, add necessary plugins). (3) Build step: Invoke top-level Maven targetsclean test -Denv=staging -Dbrowser=chrome. (4) Post-build actions: Archive test reports (HTML, XML), publish JUnit test results, email notifications. (5) For Jenkins pipeline (Jenkinsfile): stage('Tests') { agent { label 'selenium' } steps { sh 'mvn clean test -Dbrowser=${BROWSER}' } post { always { junit '**/target/surefire-reports/*.xml' } } }. Use Jenkins slaves for parallel test execution.

Confidence check

If you can confidently answer the TestNG & Framework Design questions above, you're well prepared for this section of your interview. Move on, or rehearse the trickier ones aloud with our AI mock interviewer.

8. Selenium Grid & Parallel Execution

Medium Common 1 min read

Q191.What is Selenium Grid?

Selenium Grid is a tool that enables distributed test execution across multiple machines and browsers simultaneously. It consists of a Hub (central coordinator) and Nodes (execution machines). Tests connect to the Hub, which routes them to available Nodes matching the requested capabilities. Benefits: (1) Parallel execution reduces test suite time. (2) Cross-browser testing on different OS/browser combinations. (3) Centralized test management. (4) Scalable — add more Nodes as needed. Selenium Grid 4 introduced a completely redesigned architecture with better scalability, Docker support, and a new UI.

Medium Common 1 min read

Q192.What is the difference between Hub and Node in Selenium Grid?

Hub (Router in Grid 4) is the central coordinator that receives test requests, matches them to available Nodes based on capabilities (browser, version, OS), and forwards requests. It's a single point of contact — tests only know the Hub URL. Node is a machine that executes the actual browser tests. Each Node registers with the Hub, declaring its capabilities (browsers installed, version limits, parallel slots). In Grid 3, Hub handled routing + queuing. In Grid 4, these responsibilities are split into Router, Session Map, Distributor, and Node components for better scalability.

Hard Common 1 min read

Q193.How do you set up Selenium Grid 4?

(1) Download Selenium Grid 4 jar from selenium.dev. (2) Start Hub/Router: java -jar selenium-server-4.27.0.jar hub (Grid 3) or java -jar selenium-server-4.27.0.jar standalone (Grid 4 single node, simpler). (3) For multi-node: Start Hub first: java -jar selenium-server-4.27.0.jar hub. Then register Nodes: java -jar selenium-server-4.27.0.jar node --hub http://localhost:4444. (4) For Grid 4 fully distributed: java -jar selenium-server-4.27.0.jar eventbus, sessions, sessionmap, distributor, router, node — each in separate processes. (5) Access Grid console at http://localhost:4444. (6) Connect tests: WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), new ChromeOptions());.

Hard Common 1 min read

Q194.How do you configure Selenium Grid in Docker?

Use official Selenium Docker images: docker network create grid then docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:4.27.0 and docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub --shm-size=2gb selenium/node-chrome:4.27.0. For Docker Compose: version: '3' services: chrome: image: selenium/node-chrome:4.27.0 shm_size: 2gb depends_on: - selenium-hub environment: - SE_EVENT_BUS_HOST=selenium-hub - SE_EVENT_BUS_PUBLISH_PORT=4442 - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 selenium-hub: image: selenium/hub:4.27.0 ports: - "4442:4442" - "4443:4443" - "4444:4444". Docker simplifies Grid setup by eliminating manual configuration.

Medium Common 1 min read

Q195.How do you configure Grid Nodes for different browsers?

Start separate Node containers for each browser: Chrome: docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub selenium/node-chrome:4.27.0. Firefox: selenium/node-firefox:4.27.0. Edge: selenium/node-edge:4.27.0. For custom browser configurations: -e SE_NODE_MAX_SESSIONS=5 (max parallel sessions). -e SE_NODE_SESSION_TIMEOUT=300 (seconds). Specify which browser versions via Node configuration TOML files. For cloud-like setups, configure Nodes with different OS/browser combinations to match your application's test matrix.

Hard Common 1 min read

Q196.How do you run parallel tests on Selenium Grid?

In testng.xml: <suite name="Suite" parallel="methods" thread-count="5"> <test name="CrossBrowser"> <parameter name="browser" value="chrome"/> <classes> <class name="com.test.LoginTest"/> </classes> </test> </suite>. Create a RemoteWebDriver in your setup: public void setup(String browser) { ChromeOptions options = new ChromeOptions(); WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options); }. The Grid Hub distributes test methods across available Nodes. Set thread-count to match total available Node slots. Each test method gets routed to a Node matching its capabilities.

Hard Common 1 min read

Q197.How do you set up cross-browser testing with Grid?

Create a parameterized test: @Test @Parameters("browser") public void testCrossBrowser(String browser) { WebDriver driver; switch(browser) { case "chrome": driver = new RemoteWebDriver(new URL("http://localhost:4444"), new ChromeOptions()); break; case "firefox": driver = new RemoteWebDriver(new URL("http://localhost:4444"), new FirefoxOptions()); break; case "edge": driver = new RemoteWebDriver(new URL("http://localhost:4444"), new EdgeOptions()); break; } }. In testng.xml, define multiple test tags with different browser parameters. The Grid Hub routes each test to a Node with the requested browser. This enables running the same tests across Chrome, Firefox, and Edge simultaneously.

Medium Common 1 min read

Q198.What is the Selenium Grid 4 architecture?

Grid 4 introduced a fully distributed, event-driven architecture: (1) Router — entry point, forwards requests to correct component. (2) Distributor — assigns test requests to Nodes based on capabilities and load. (3) Session Map — maintains mapping of session IDs to Nodes. (4) Node — executes tests, registers with Distributor. (5) Session Queue — manages pending requests. (6) Event Bus — asynchronous communication between components. Benefits: no single point of failure, horizontal scalability, dynamic Node registration, better resource utilization. Grid 4 replaced the Hub-Node model with a microservices architecture.

Medium Common 1 min read

Q199.What is the difference between Selenium Grid 3 and Grid 4?

(1) Architecture: Grid 3 monolithic Hub-Node; Grid 4 distributed microservices. (2) Scalability: Grid 3 Hub can bottleneck; Grid 4 components scale independently. (3) Protocol: Grid 3 used custom JSON Wire Protocol; Grid 4 uses W3C WebDriver standard. (4) Configuration: Grid 3 used JSON config files; Grid 4 uses TOML. (5) Observation: Grid 4 has built-in request tracing and metrics. (6) Docker: Grid 4 includes Helm charts for Kubernetes. (7) New UI: Grid 4 has a modern web interface. (8) Session management: Grid 4 has dedicated Session Map and Session Queue.

Hard Common 1 min read

Q200.How do you use Selenium Grid with cloud providers (BrowserStack/Sauce Labs)?

Create RemoteWebDriver with cloud provider URL: ChromeOptions options = new ChromeOptions(); options.setCapability("browserstack.user", "YOUR_USERNAME"); options.setCapability("browserstack.key", "YOUR_ACCESS_KEY"); options.setCapability("project", "Selenium Tests"); options.setCapability("build", "Build 1.0"); options.setCapability("name", "Login Test"); WebDriver driver = new RemoteWebDriver(new URL("https://hub-cloud.browserstack.com/wd/hub"), options);. For Sauce Labs: URL("https://YOUR_USERNAME:YOUR_ACCESS_KEY@ondemand.us-west-1.saucelabs.com:443/wd/hub"). Cloud platforms provide instant access to hundreds of browser/OS combinations, video recording, and debugging tools without maintaining your own Grid.

Medium Common 1 min read

Q201.How do you handle test session timeouts in Grid?

Configure Node session timeout: -e SE_NODE_SESSION_TIMEOUT=300 (5 minutes in Docker). In test code, set shorter timeouts: driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(30));. Implement a test listener that detects long-running tests: // Custom annotation to set per-test timeout @Test(timeOut = 120000) // 2 minutes max per test. In Grid 4, configure SessionQueue timeout for pending requests. Session timeouts prevent tests from hanging indefinitely and blocking Grid resources.

Medium Common 1 min read

Q202.How do you manage Node registration in Grid?

Nodes auto-register with the Hub upon startup. For manual registration: java -jar selenium-server-4.27.0.jar node --hub http://hub-ip:4444. Configure registration in Node config TOML: [node] [[node.driver-configuration]] display-name = "Chrome" stereotype = '{ "browserName": "chrome", "browserVersion": "120", "platformName": "Linux" }' max-sessions = 3. Nodes send heartbeat signals to the Hub. If a Node goes offline (no heartbeat), its sessions are terminated and tests are retried on other Nodes. Dynamic registration allows adding/removing Nodes without restarting the Hub.

Medium Common 1 min read

Q203.How do you configure max sessions per Node?

In Docker: -e SE_NODE_MAX_SESSIONS=5. In Node configuration TOML: [node] max-sessions = 5. In command line: --max-sessions 5. Each session uses one browser instance. A Chrome Node with max-sessions=5 can run 5 Chrome tests simultaneously. Setting max-sessions correctly is crucial — too few underutilizes hardware, too many causes resource contention. Rule of thumb: 2-3 sessions per CPU core, with at least 2GB RAM per browser session. Monitor Node CPU/memory and adjust accordingly.

Medium Common 1 min read

Q204.How do you handle session availability in Grid?

The Distributor assigns sessions based on capability matching and Node availability. If no compatible Node is available: (1) In Grid 3, the request is queued in the Hub's thread pool. (2) In Grid 4, the Session Queue holds pending requests and retries at intervals. Configure queue: --session-request-timeout 300 (seconds to wait before failing). Implement retry in tests: for (int i = 0; i < 3; i++) { try { driver = new RemoteWebDriver(hubUrl, options); break; } catch (Exception e) { Thread.sleep(5000); } }. Properly sizing the Grid prevents session contention.

Hard Common 1 min read

Q205.How do you use Selenium Grid for mobile testing?

Grid can route Appium sessions for mobile testing. Configure Appium as a Grid Node: appium --nodeconfig /path/to/nodeconfig.json --port 4723. In nodeconfig.json, specify capabilities like platformName: "Android", deviceName: "Pixel 4", automationName: "UiAutomator2". Connect using AppiumDriver: DesiredCapabilities caps = new DesiredCapabilities(); caps.setCapability("platformName", "Android"); caps.setCapability("deviceName", "Pixel 4"); caps.setCapability("browserName", "Chrome"); WebDriver driver = new AndroidDriver(new URL("http://localhost:4444/wd/hub"), caps);. The Grid Hub routes mobile requests to the Appium Node.

Medium Common 1 min read

Q206.How do you configure Grid for load balancing?

(1) Set equal max-sessions across Nodes of similar capacity. (2) Use the Distributor's max-sessions setting to prevent overloading any Node. (3) Group Nodes by capacity using tags: [[node.driver-configuration]] stereotype = '{ "browserName": "chrome", "session-type": "heavy" }'. (4) Configure session slot matcher for better distribution. (5) Use Grid 4's observer pattern to monitor Node health. (6) Implement auto-scaling with Docker Swarm or Kubernetes to spawn Nodes based on queue depth. (7) Monitor Grid metrics and adjust Node count dynamically.

Medium Common 1 min read

Q207.How do you test with different browser versions on Grid?

Configure Nodes with specific browser versions: Chrome 120 Node, Chrome 121 Node, Firefox ESR Node, etc. In test capabilities: ChromeOptions options = new ChromeOptions(); options.setCapability("browserVersion", "120");. The Distributor matches your request to a Node with the specified version. For Docker: use tagged images, each with a specific browser version. For matrix testing, run the same test with different browser versions and OS combinations. This is essential for compatibility testing where users may have different browser versions.

Medium Common 1 min read

Q208.How do you monitor Selenium Grid?

Grid 4 provides a web UI at http://localhost:4444 showing: active sessions, Node status, queue depth, and slot utilization. For advanced monitoring: (1) Enable metrics: --enable-managed-downloads true. (2) Use Graphite/Grafana for metrics visualization. (3) Configure logging: -Dlog4j.configurationFile=log4j2.xml. (4) Grid 4 traces: OpenTelemetry integration for distributed tracing. (5) Health check endpoints: /status, /readyz. (6) Third-party tools: Selenium Grid Extras, GridMon. (7) Set up alerts for: Node crashes, high queue depth, session failures.

Medium Common 1 min read

Q209.How do you handle browser-specific configurations in Grid?

Pass browser options through RemoteWebDriver: ChromeOptions options = new ChromeOptions(); options.addArguments("--headless", "--disable-gpu", "--window-size=1920,1080"); options.setExperimentalOption("prefs", prefs); WebDriver driver = new RemoteWebDriver(hubUrl, options);. These options are forwarded to the Node, which applies them to the browser instance. For advanced Node configuration: use TOML files per Node to set driver logging, timeouts, and custom capabilities. Grid 4's Node config allows per-driver settings for Chrome, Firefox, and Edge.

Hard Common 1 min read

Q210.What are best practices for Selenium Grid?

(1) Use Grid 4 for new projects (better scalability, W3C protocol). (2) Run Grid in Docker for reproducibility. (3) Use ThreadLocal<WebDriver> for parallel test safety. (4) Set appropriate timeouts (session, page load, implicit). (5) Monitor Node health and set up auto-restart. (6) Use cloud Grid (BrowserStack, Sauce Labs) if maintaining on-premises is costly. (7) Size Nodes appropriately (max-sessions = CPU cores × 2). (8) Use capability matching precisely to avoid slot wastage. (9) Implement retry for transient Grid failures. (10) Log session details (Node, browser, duration) for debugging. (11) Keep browser/driver versions in sync across Nodes. (12) Use a separate Grid for CI/CD vs local development.

Confidence check

If you can confidently answer the Selenium Grid & Parallel Execution questions above, you're well prepared for this section of your interview. Move on, or rehearse the trickier ones aloud with our AI mock interviewer.

9. Selenium 4 New Features

Hard Common 1 min read

Q211.What are the key features introduced in Selenium 4?

Key features: (1) W3C WebDriver protocol by default — standardized communication, faster, more reliable. (2) Relative locators — above(), below(), near(), toLeftOf(), toRightOf(). (3) New Window/Tab API — driver.switchTo().newWindow(WindowType.TAB). (4) Chrome DevTools Protocol (CDP) integration — network interception, console logging, performance metrics. (5) Element screenshot — element.getScreenshotAs(). (6) Enhanced Selenium Grid — microservices architecture, Docker support, new UI. (7) Improved error messages and debugging. (8) Deprecation of JSON Wire Protocol. (9) Better support for modern browsers and protocols.

Medium Common 1 min read

Q212.What are relative locators in Selenium 4?

Relative locators find elements based on their visual position relative to other elements. Static methods: above(), below(), toLeftOf(), toRightOf(), near(). Usage: WebElement passwordField = driver.findElement(RelativeLocator.with(By.tagName("input")).below(By.id("username")));. The near() method accepts a distance parameter: .near(By.id("search"), Distance.ofPixels(50)). Relative locators are especially useful for responsive layouts where DOM order may differ from visual order. They're also great for finding labels, error messages, or validation icons near form fields.

Medium Common 1 min read

Q213.How do you use the new Window/Tab API in Selenium 4?

driver.switchTo().newWindow(WindowType.TAB); opens a new tab in the current browser window and switches to it. driver.switchTo().newWindow(WindowType.WINDOW); opens a new browser window. After switching, navigate to a URL: driver.get("https://example.com");. This eliminates the need for JavaScript window.open() or keyboard shortcuts. Example: String originalHandle = driver.getWindowHandle(); driver.switchTo().newWindow(WindowType.TAB); driver.get("https://google.com"); // do something driver.close(); driver.switchTo().window(originalHandle);.

Medium Common 1 min read

Q214.How do you take an element screenshot in Selenium 4?

WebElement element = driver.findElement(By.id("logo")); File screenshot = element.getScreenshotAs(OutputType.FILE); FileUtils.copyFile(screenshot, new File("element.png"));. This captures only the specified element, not the entire page. In Selenium 3, you had to crop the full page screenshot. Benefits: smaller file sizes, focused screenshots for reporting, easy element-level visual comparison. Use cases: capturing error messages, specific UI components, CAPTCHA images, or QR codes.

Medium Common 1 min read

Q215.How do you use Chrome DevTools Protocol (CDP) in Selenium 4?

Use the DevTools interface: DevTools devTools = ((HasDevTools) driver).getDevTools(); devTools.createSession();. Then subscribe to events: devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));. Listen to network requests: devTools.addListener(Network.requestWillBeSent(), request -> { System.out.println("Request: " + request.getRequest().getUrl()); });. Block URLs: devTools.send(Network.setBlockedURLs(ImmutableList.of("*.css", "*.png")));. CDP gives you access to Chrome's internal debugging capabilities beyond what WebDriver provides.

Hard Common 1 min read

Q216.How do you capture network traffic using CDP in Selenium 4?

DevTools devTools = ((HasDevTools) driver).getDevTools(); devTools.createSession(); devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty())); List<Network.RequestWillBeSent> requestList = new ArrayList<>(); devTools.addListener(Network.requestWillBeSent(), request -> { requestList.add(request); System.out.println("URL: " + request.getRequest().getUrl() + " Method: " + request.getRequest().getMethod()); }); // Perform actions that trigger network calls // Later, assert: Assert.assertTrue(requestList.stream().anyMatch(r -> r.getRequest().getUrl().contains("api/data")));. This enables testing API calls, analytics pings, resource loading, and network performance.

Hard Common 1 min read

Q217.How do you mock network responses using CDP?

DevTools devTools = ((HasDevTools) driver).getDevTools(); devTools.createSession(); devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty())); devTools.addListener(Network.requestWillBeSent(), request -> { if (request.getRequest().getUrl().contains("api/users")) { Map<String, Object> mockResponse = new HashMap<>(); mockResponse.put("name", "Mock User"); mockResponse.put("email", "mock@test.com"); devTools.send(Fetch.fulfillRequest(request.getRequestId(), 200, "application/json", new Gson().toJson(mockResponse))); } });. This intercepts and responds to network requests with custom data, enabling front-end testing without real backend dependencies.

Hard Common 1 min read

Q218.How do you intercept console logs using CDP?

DevTools devTools = ((HasDevTools) driver).getDevTools(); devTools.createSession(); devTools.send(Log.enable()); List<LogEntry> logEntries = new ArrayList<>(); devTools.addListener(Log.entryAdded(), logEntry -> { logEntries.add(logEntry); System.out.println("Log: " + logEntry.getText() + " Level: " + logEntry.getLevel()); }); // Perform actions // Assert log contains expected message: Assert.assertTrue(logEntries.stream().anyMatch(log -> log.getText().contains("App initialized")));. This is invaluable for debugging JavaScript errors, checking console warnings, and verifying application logging without manual DevTools inspection.

Hard Common 1 min read

Q219.How do you simulate geolocation using CDP?

DevTools devTools = ((HasDevTools) driver).getDevTools(); devTools.createSession(); Map<String, Object> geoParams = new HashMap<>(); geoParams.put("latitude", 48.8566); geoParams.put("longitude", 2.3522); geoParams.put("accuracy", 1); devTools.send(Emulation.setGeolocationOverride(Optional.of(48.8566), Optional.of(2.3522), Optional.of(1.0))); // Now navigate to a location-aware page // Page should display Paris-appropriate content. This is essential for testing location-based features, regional pricing, language detection, and store locators without physically moving to different locations.

Hard Common 1 min read

Q220.How do you use device emulation with CDP?

DevTools devTools = ((HasDevTools) driver).getDevTools(); devTools.createSession(); Map<String, Object> metrics = new HashMap<>(); metrics.put("width", 375); metrics.put("height", 812); metrics.put("deviceScaleFactor", 3); metrics.put("mobile", true); devTools.send(Emulation.setDeviceMetricsOverride(375, 812, 3.0, false, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty())); // Simulate mobile user agent String userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15"; devTools.send(Network.setUserAgentOverride(userAgent, Optional.empty(), Optional.empty(), Optional.empty()));. CDP emulation is more accurate than ChromeOptions device emulation.

Medium Common 1 min read

Q221.How do you handle basic authentication with CDP in Selenium 4?

((HasAuthentication) driver).register(UsernameAndPassword.of("username", "password")); driver.get("https://example.com");. This registers credentials before the page load, so when the HTTP auth dialog appears, the browser automatically provides the credentials. This is more reliable than URL-embedded credentials (https://user:pass@example.com), which may be blocked by browsers. The UsernameAndPassword class is part of the Selenium 4 authentication API, supporting both basic and digest authentication.

Hard Common 1 min read

Q222.How do you handle virtual authenticators in Selenium 4?

Use the VirtualAuthenticator API for WebAuthn testing: VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions(); options.setProtocol(VirtualAuthenticatorOptions.Protocol.U2F); options.setTransport(VirtualAuthenticatorOptions.Transport.USB); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); // Now perform registration/authentication flows // Remove when done: ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);. This enables testing passwordless authentication flows (FIDO2, WebAuthn) without physical security keys, essential for modern login systems.

Medium Common 1 min read

Q223.How do you print a page to PDF in Selenium 4?

Pdf pdf = ((PrintsPage) driver).print(new PrintPageOptions()); String base64Pdf = pdf.getContent(); byte[] pdfBytes = Base64.getDecoder().decode(base64Pdf); Files.write(Paths.get("page.pdf"), pdfBytes);. PrintPageOptions allows customization: page size (A4, Letter), margins, orientation (portrait/landscape), scale, background graphics, and page ranges. This is useful for generating PDF receipts, invoice verification, document testing, and saving page snapshots in PDF format for archival or comparison.

Hard Common 1 min read

Q224.How do you get browser network conditions in Selenium 4?

DevTools devTools = ((HasDevTools) driver).getDevTools(); devTools.createSession(); devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty())); // Listen for response received events List<Network.ResponseReceived> responses = new ArrayList<>(); devTools.addListener(Network.responseReceived(), response -> { responses.add(response); System.out.println("URL: " + response.getResponse().getUrl() + " Status: " + response.getResponse().getStatus() + " Time: " + response.getResponse().getTiming().getDuration()); });. This provides detailed timing information: DNS lookup, TCP connection, SSL handshake, TTFB, content download. Useful for performance testing and identifying slow API calls.

Medium Occasional 1 min read

Q225.How do you set network conditions (throttling) in Selenium 4?

DevTools devTools = ((HasDevTools) driver).getDevTools(); devTools.createSession(); devTools.send(Network.emulateNetworkConditions(true, 100, // offline? latency 50000, // download throughput (50 kbps) 20000, // upload throughput (20 kbps) Optional.of(Network.ConnectionType.CELLULAR2G))); // Reset: devTools.send(Network.emulateNetworkConditions(false, 0, -1, -1, Optional.empty()));. This simulates slow networks (2G, 3G, 4G, WiFi) to test application behavior under poor connectivity — loading states, timeouts, retry logic, and offline functionality.

Medium Occasional 1 min read

Q226.How do you block specific URLs in Selenium 4?

DevTools devTools = ((HasDevTools) driver).getDevTools(); devTools.createSession(); devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty())); devTools.send(Network.setBlockedURLs(Arrays.asList("*.google-analytics.com/*", "*.facebook.net/*", "*.doubleclick.net/*")));. This blocks specified URL patterns from loading — useful for: (1) Blocking analytics/tracking scripts in test environments. (2) Simulating resource loading failures. (3) Speeding up tests by blocking unnecessary third-party content. (4) Testing how your app behaves when CDN resources are unavailable.

Hard Occasional 1 min read

Q227.How do you capture a timeline trace in Selenium 4?

DevTools devTools = ((HasDevTools) driver).getDevTools(); devTools.createSession(); devTools.send(Performance.enable(Optional.of(Performance.EnableTimeDomain.TIME_TICKS))); // Perform actions devTools.addListener(Performance.metrics(), metrics -> { metrics.getMetrics().forEach(m -> System.out.println(m.getName() + ": " + m.getValue())); });. This collects performance metrics like first paint, DOM content loaded, time to interactive, and script execution time. Combined with Network timing, this provides a comprehensive performance profile of the application under test, helping identify bottlenecks.

Medium Occasional 1 min read

Q228.How do you handle full page screenshot in Selenium 4?

Selenium 4 doesn't have built-in full page screenshot, but you can use CDP: devTools.send(Page.captureScreenshot(Optional.of(Page.CaptureScreenshotFormat.PNG), Optional.of(100), // quality Optional.empty(), // clip Optional.of(true), // fullPage Optional.empty()));. Alternatively, stitch multiple viewport screenshots: scroll the page, take screenshots at each position, and merge them using image processing. Full page screenshots are useful for visual regression testing, documentation, and capturing entire error pages.

Medium Occasional 1 min read

Q229.What is the W3C WebDriver protocol in Selenium 4?

W3C WebDriver is the standardized protocol adopted by the World Wide Web Consortium (W3C) that defines how Selenium communicates with browsers. In Selenium 4, it's the default protocol. Benefits: (1) Standardized across all browsers — same commands work on Chrome, Firefox, Edge, Safari. (2) No protocol translation — commands go directly to the browser without encoding/decoding from JSON Wire Protocol. (3) Better error messages — standardized HTTP status codes (404, 500, etc.). (4) Reduced flakiness. (5) Better performance. (6) All major browsers implement it natively, removing the need for browser-specific driver implementations.

Medium Occasional 1 min read

Q230.How do you use the new Selenium Manager in Selenium 4?

Selenium Manager is built into Selenium 4, auto-managing driver binaries (ChromeDriver, GeckoDriver, EdgeDriver). When you create new ChromeDriver(), Selenium Manager automatically detects the installed Chrome version, downloads the matching ChromeDriver, caches it, and sets up the path. No more System.setProperty() or WebDriverManager setup. You can also use it from the command line: java -jar selenium-server-4.27.0.jar manager --driver chromedriver. Selenium Manager supports: binary resolution, version matching, caching, and cleanup. It simplifies driver management significantly.

Medium Occasional 1 min read

Q231.How do you handle browser options for different browsers using a unified approach?

Selenium 4 introduced browser-specific Options classes that implement a common Capabilities interface: MutableCapabilities options = new ChromeOptions(); // or FirefoxOptions(), EdgeOptions() options.setCapability("browserName", "chrome"); WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);. This unified approach simplifies cross-browser testing by allowing you to use the same code path for different browsers. For Selenium Grid, the Hub automatically interprets the capabilities and routes to appropriate Nodes.

Medium Occasional 1 min read

Q232.How do you manage cookies improvement in Selenium 4?

Selenium 4 added SameSite cookie support: Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build(); driver.manage().addCookie(cookie);. SameSite values: "Strict", "Lax", "None". This is important for testing modern web applications that rely on SameSite cookie policies for security. You can also get cookie details: Cookie c = driver.manage().getCookieNamed("session"); System.out.println(c.getSameSite());. This helps test cookie behavior across different browsers which have varying SameSite default policies.

Medium Occasional 1 min read

Q233.How do you get element properties vs attributes in Selenium 4?

Selenium 4 introduced getDomAttribute() and getDomProperty() to distinguish between HTML attributes and JavaScript DOM properties: String attrValue = element.getDomAttribute("href"); // returns the attribute as written in HTML String propValue = element.getDomProperty("href"); // returns the fully resolved property (e.g., full URL). This distinction is important for elements like <a href="relative/path"> where getAttribute("href") differs across browsers. Selenium 4's getDomProperty() returns consistent results matching the browser's DOM.

Medium Occasional 1 min read

Q234.How do you capture element screenshots in Selenium 4 for visual testing?

WebElement element = driver.findElement(By.id("header")); byte[] screenshotBytes = element.getScreenshotAs(OutputType.BYTES); // Compare with baseline using image comparison library boolean match = ImageComparator.compare(screenshotBytes, baselineImagePath);. For visual regression testing, integrate with libraries like Applitools Eyes, Percy, or custom pixel comparison. Element-level screenshots reduce noise from dynamic content outside the element. Best practice: capture elements with stable content for baseline comparison, and ignore animated or time-sensitive elements.

Medium Occasional 1 min read

Q235.How do you handle browser downloads in Selenium 4?

Selenium 4 enhanced download management: driver.get("https://example.com/file.pdf"); // Use CDP to monitor download events DevTools devTools = ((HasDevTools) driver).getDevTools(); devTools.createSession(); devTools.send(Browser.setDownloadBehavior(Browser.SetDownloadBehaviorBehavior.ALLOW, Optional.of("/path/to/downloads"), Optional.empty()));. The new download handling enables: setting a custom download path, monitoring download progress, and waiting for downloads to complete automatically. This is more reliable than pre-configuring browser preferences.

Medium Occasional 1 min read

Q236.How do you detect and handle browser dialogs that are not JavaScript alerts?

Selenium 4's CDP support can detect various dialog types: devTools.send(Page.enable()); devTools.addListener(Page.javascriptDialogOpening(), dialog -> { System.out.println("Dialog type: " + dialog.getType() + " Message: " + dialog.getMessage()); devTools.send(Page.handleJavaScriptDialog(true)); // Accept });. This catches file download dialogs, beforeunload events, and other dialog types that traditional Alert interface cannot handle. The CDP approach provides more details about the dialog and more control over its handling.

Medium Occasional 1 min read

Q237.How do you use enhanced error messages in Selenium 4?

Selenium 4 provides significantly improved error messages. Example: Instead of "Element is not clickable at point (x, y)", Selenium 4 now says: "element click intercepted: Element <button id='submit' class='btn'>Submit</button> is not clickable at point (100, 200) because another element <div id='modal-overlay'> obscures it. Scrolling into view first...". These detailed messages include the element HTML, coordinates, and the blocking element. This drastically reduces debugging time by telling you exactly what went wrong and why.

Medium Occasional 1 min read

Q238.What is the enhanced Selenium Grid UI in Selenium 4?

Grid 4 ships with a modern, responsive web UI at http://localhost:4444 featuring: (1) Real-time dashboard showing active sessions, Node status, and slot utilization. (2) Session details — logs, capabilities, video recordings (if configured). (3) Node management — view registered Nodes, their capabilities, and health status. (4) Queue overview — pending session requests. (5) Configuration viewer. The UI is built for both desktop and mobile, making it easy to monitor your Grid infrastructure from anywhere. It replaces Grid 3's minimal console.

Medium Occasional 1 min read

Q239.How do you handle browser context (new incognito window) in Selenium 4?

For Chrome incognito: ChromeOptions options = new ChromeOptions(); options.addArguments("--incognito"); WebDriver driver = new ChromeDriver(options);. For Firefox private: FirefoxOptions options = new FirefoxOptions(); options.addArguments("-private");. In Selenium 4, you can also use CDP: devTools.send(Page.createIsolatedWorld(optionalFrameId, optionalWorldName, optionalGrantUniveralAccess));. Incognito mode is useful for testing without cached data, cookies, or extensions that might interfere with test results.

Medium Occasional 1 min read

Q240.What are the deprecations in Selenium 4?

Deprecated in Selenium 4: (1) DesiredCapabilities — replaced by browser-specific Options classes. (2) JSON Wire Protocol — replaced by W3C WebDriver protocol. (3) FindsBy* interfaces — replaced by By locators. (4) org.openqa.selenium.security.* — replaced by CDP-based authentication. (5) ExpectedConditions methods — many now deprecated in favor of new FluentWait-based approaches (still functional but may be removed in Selenium 5). (6) Selenium RC classes — fully removed. (7) Older Grid components. Always use the latest recommended APIs to ensure future compatibility.

Confidence check

If you can confidently answer the Selenium 4 New Features questions above, you're well prepared for this section of your interview. Move on, or rehearse the trickier ones aloud with our AI mock interviewer.

10. CI/CD & Real-World Scenarios

Hard Occasional 1 min read

Q241.How do you integrate Selenium tests with Jenkins?

(1) Create a Jenkins freestyle project or pipeline. (2) Configure Git repository URL and credentials. (3) Build trigger: Poll SCM, GitHub webhook, or scheduled cron. (4) Build environment: Set environment variables (BROWSER, ENV, URL). (5) Build step: Invoke Maven (mvn clean test -Dbrowser=chrome -Denv=staging). (6) Post-build: Publish HTML reports, JUnit results, archive screenshots. (7) Configure email notifications for failures. (8) For pipelines (Jenkinsfile): stage('Selenium Tests') { steps { sh 'mvn clean test' } post { always { publishHTML([reportDir: 'target/surefire-reports', reportFiles: 'index.html']) } } }.

Hard Occasional 1 min read

Q242.How do you run Selenium tests in GitHub Actions?

Create .github/workflows/selenium-tests.yml: name: Selenium Tests on: push: branches: [main] pull_request: branches: [main] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' - name: Set up Chrome uses: browser-actions/setup-chrome@v1 - name: Run tests run: mvn clean test -Dbrowser=chrome - name: Upload screenshots if: failure() uses: actions/upload-artifact@v4 with: name: screenshots path: screenshots/. GitHub Actions provides free runners with Chrome pre-installed. Use services like BrowserStack for cross-browser testing on their servers.

Hard Occasional 1 min read

Q243.How do you run Selenium in Docker containers?

(1) Create a Dockerfile for your test project. (2) Use Selenium Docker images: FROM maven:3.9-eclipse-temurin-17 WORKDIR /tests COPY . . CMD ["mvn", "clean", "test"]. (3) Use docker-compose: version: '3' services: selenium-chrome: image: selenium/node-chrome:4.27.0 shm_size: '2gb' depends_on: selenium-hub environment: - SE_EVENT_BUS_HOST=selenium-hub selenium-hub: image: selenium/hub:4.27.0 ports: - "4444:4444" tests: build: . depends_on: - selenium-hub environment: - HUB_URL=http://selenium-hub:4444/wd/hub. (4) Run: docker-compose up --build. Docker ensures consistent test environments across all machines.

Medium Occasional 1 min read

Q244.How do you handle headless execution in CI/CD?

In CI/CD environments, browsers typically run headlessly: ChromeOptions options = new ChromeOptions(); options.addArguments("--headless=new", "--no-sandbox", "--disable-dev-shm-usage", "--disable-gpu", "--window-size=1920,1080");. For CI compatibility: --no-sandbox (required for Docker/root), --disable-dev-shm-usage (prevents shared memory issues in Docker), --disable-gpu (GPU acceleration doesn't work headless). Always run a subset of tests in headed mode locally before merging. Headless execution is typically 10-20% faster than headed but can miss some rendering-related bugs.

Medium Occasional 1 min read

Q245.How do you handle test environment configuration in CI/CD?

Use environment variables and profiles: String env = System.getProperty("env", "staging"); Config config = ConfigFactory.load(env); // Load staging.conf or prod.conf. In CI/CD, pass variables: mvn test -Denv=staging -Dbrowser=chrome -Durl=https://staging.example.com. For sensitive data (passwords, API keys), use CI/CD secrets: Jenkins Credentials Binding, GitHub Actions Secrets (${{ secrets.API_KEY }}). Never hardcode credentials in test code. Use a ConfigFactory that reads from environment variables, properties files, or CI/CD parameter store.

Medium Occasional 1 min read

Q246.How do you handle flaky tests in CI/CD?

Strategies: (1) Add retry logic (TestNG IRetryAnalyzer — retry 1-2 times). (2) Implement explicit waits (never thread sleeps). (3) Use ThreadLocal<WebDriver> for parallel safety. (4) Add detailed logging and screenshots on failure. (5) Quarantine consistently flaky tests — move them to a separate suite and investigate. (6) Use Flaky Test Tracker — track flake rate per test over time. (7) Fix root causes: bad locators, missing waits, shared state, race conditions. (8) In CI/CD, allow 1-2 retries of the entire failed job before marking as failed.

Medium Occasional 1 min read

Q247.How do you handle test data management in CI/CD?

(1) Use API calls to set up test data before test execution (faster than UI). (2) Use database queries to clean up data after tests. (3) Use Docker containers with seeded databases for consistent data. (4) Generate unique test data with Faker + timestamps to avoid collisions. (5) Use data factories for common test data scenarios. (6) For shared environments, tag test data with build ID for cleanup. (7) Use test container libraries (TestContainers) for disposable databases. (8) Avoid hardcoded test data — read from files (Excel, JSON, CSV) or generate dynamically.

Hard Occasional 1 min read

Q248.How do you handle dynamic Angular/React elements in Selenium?

(1) Wait for Angular stability: wait.until(d -> ((JavascriptExecutor)d).executeScript("return window.getAllAngularTestabilities().filter(t => !t.isStable()).length === 0"));. (2) For React, wait for component state: use data-testid attributes. (3) Handle dynamic class names with contains(@class,'component-name'). (4) Wait for animations: use ExpectedConditions with CSS property checks. (5) Use FluentWait with custom ExpectedConditions for framework-specific events. (6) Use JavaScript to check if the component is fully rendered: return document.querySelector('app-root')?.innerHTML?.length > 0. (7) Avoid fragile locators based on auto-generated class names.

Hard Occasional 1 min read

Q249.How do you test file downloads in CI/CD?

(1) Configure download directory via browser options. (2) Click download button. (3) Use FluentWait to wait for file to appear in directory: Path downloadDir = Paths.get("/path/to/downloads"); wait.until(d -> { try { return Files.list(downloadDir).anyMatch(f -> f.getFileName().toString().startsWith("report")); } catch (IOException e) { return false; } });. (4) Verify file content: String content = Files.readString(downloadedFile); Assert.assertTrue(content.contains("expected data"));. (5) Clean up: Files.delete(downloadedFile);. In Docker CI/CD, mount a volume for download directory or use tmpfs.

Medium Occasional 1 min read

Q250.How do you test file uploads in CI/CD?

(1) For native file inputs: driver.findElement(By.cssSelector("input[type='file']")).sendKeys("/path/to/file.txt");. (2) For custom upload widgets: interact with the underlying hidden file input element using JavaScript to make it visible. (3) Use relative paths with test resources: String filePath = getClass().getClassLoader().getResource("testfiles/test.pdf").getPath();. (4) In Docker CI/CD, mount test data as a volume. (5) Verify upload success by checking for success messages or the uploaded file appearing in the UI. (6) Clean up uploaded files after tests (API call to delete).

Medium Occasional 1 min read

Q251.How do you handle CAPTCHA in test environments?

(1) Disable CAPTCHA in test/staging environments. (2) Use a test-specific CAPTCHA bypass endpoint. (3) Use a universal test CAPTCHA code that works on all environments. (4) Pre-generate test accounts that skip CAPTCHA. (5) Mock the CAPTCHA verification API. (6) Never use CAPTCHA-solving services — they're unreliable, slow, and may violate terms of service. Coordinate with your development team to have a test mode that disables or simplifies CAPTCHA for automated test environments.

Medium Occasional 1 min read

Q252.How do you handle OTP/2FA in test automation?

(1) Disable 2FA in test environments. (2) Use a test-specific OTP code (e.g., "000000" or "123456"). (3) Mock the SMS/email OTP service to return a known code. (4) If using authenticator apps (Google Authenticator, Authy), generate TOTP codes programmatically using the shared secret: String totp = new TOTP(sharedSecret).now();. (5) For email-based OTP, connect to a test email inbox (via IMAP) and extract the code. (6) Use a test API to bypass OTP verification. (7) Store cookies/sessions after authentication to reuse.

Medium Occasional 1 min read

Q253.How do you test responsive web design with Selenium?

(1) Set window sizes for different viewports: setWindowSize(1920, 1080) // Desktop, setWindowSize(768, 1024) // Tablet, setWindowSize(375, 812) // Mobile. (2) Use a data provider to iterate through viewports. (3) Test navigation menu: desktop shows full menu, tablet shows hamburger, mobile shows bottom nav. (4) Test element visibility: Assert.assertTrue(element.isDisplayed()); for desktop; Assert.assertFalse(element.isDisplayed()); for mobile. (5) Test touch interactions on mobile viewport using Actions class. (6) Use CDP device emulation for more accurate mobile testing.

Hard Occasional 1 min read

Q254.How do you test infinite scrolling pages?

(1) Scroll to the bottom to trigger loading: ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);");. (2) Wait for new elements: WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5)); wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.className("item"), previousCount));. (3) Repeat scroll + wait until no new items load. (4) Set a max scroll limit to prevent infinite loops. (5) Verify total item count matches expected: int totalItems = driver.findElements(By.className("item")).size(); Assert.assertEquals(expectedCount, totalItems);.

Medium Occasional 1 min read

Q255.How do you test pagination?

(1) Click next page button: driver.findElement(By.cssSelector(".pagination .next")).click();. (2) Wait for page content to update: wait.until(ExpectedConditions.stalenessOf(currentPageElements.get(0)));. (3) Verify URL/page parameter changed: Assert.assertTrue(driver.getCurrentUrl().contains("page=2"));. (4) Verify item count per page. (5) Test edge cases: first page (previous button disabled), last page (next button disabled), empty pages, single page (no pagination shown). (6) Test page size selector (10, 25, 50 items per page). (7) Test navigating to a specific page via URL parameter.

Hard Occasional 1 min read

Q256.How do you test search functionality?

(1) Enter search term and submit. (2) Verify search results appear: wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.className("search-result")));. (3) Verify each result contains the search term: results.forEach(r -> Assert.assertTrue(r.getText().toLowerCase().contains(searchTerm)));. (4) Test special characters, empty search, long strings, numeric values. (5) Test filters (sort by relevance/date/price). (6) Test autocomplete suggestions as you type. (7) Test search with no results — verify "no results" message. (8) Test search pagination. (9) Verify search analytics calls (CDP network monitoring).

Hard Occasional 1 min read

Q257.How do you test form validation?

(1) Submit form with empty required fields — verify error messages: submitBtn.click(); String error = driver.findElement(By.cssSelector(".field-error")).getText(); Assert.assertEquals("This field is required", error);. (2) Test invalid email formats, minimum/maximum length, pattern mismatches. (3) Test valid data submission — verify success message or navigation. (4) Test form field restrictions (character limits, allowed characters). (5) Test cross-field validation (password + confirm password match). (6) Test server-side validation by manipulating HTTP requests (CDP network interception). (7) Test validation on blur vs on submit.

Hard Occasional 1 min read

Q258.How do you test drag-and-drop reordering?

(1) Identify source and target positions: List<WebElement> items = driver.findElements(By.cssSelector(".sortable-item")); WebElement source = items.get(0); WebElement target = items.get(3);. (2) Use Actions class: new Actions(driver).clickAndHold(source).moveToElement(target).release().perform();. (3) If HTML5 drag-and-drop fails, use JavaScript simulation (as described in Q146). (4) Verify new order: items = driver.findElements(By.cssSelector(".sortable-item")); Assert.assertEquals("Expected item 1", items.get(3).getText());. (5) Test edge cases: drag to same position, drag to the top/bottom, drag between multiple columns.

Hard Occasional 1 min read

Q259.How do you test date picker elements?

(1) For native HTML5 date inputs: driver.findElement(By.cssSelector("input[type='date']")).sendKeys("12/25/2026");. (2) For custom date pickers (JavaScript): click the date input to open the calendar, then select a day: driver.findElement(By.xpath("//td[text()='15']")).click();. (3) Use JavaScript to set date value directly: ((JavascriptExecutor) driver).executeScript("arguments[0].value = '2026-12-25';", dateInput);. (4) Test edge cases: past dates (birth dates), future dates (event booking), leap year dates (Feb 29), invalid dates (Feb 30). (5) Test date range pickers: select start date, then end date.

Hard Occasional 1 min read

Q260.How do you test multi-step forms (wizards)?

(1) Complete each step of the wizard sequentially: Step 1: fill fields → click "Next" → wait for Step 2 to load. Step 2: fill fields → click "Next" → wait for Step 3. (2) Verify progress indicator updates: Assert.assertTrue(driver.findElement(By.cssSelector(".step-2.active")).isDisplayed());. (3) Test navigation backward (Previous button) — verify data persistence. (4) Test validation errors per step — verify you can't proceed with invalid data. (5) Test final submission — verify success page or data saved. (6) Test session timeout during multi-step form. (7) Test browser refresh during wizard — verify state restored.

Medium Occasional 1 min read

Q261.How do you test a chat application?

(1) Navigate to chat and verify the chat widget loads. (2) Send a message: chatInput.sendKeys("Hello"); chatSendBtn.click();. (3) Verify message appears in chat history: wait.until(ExpectedConditions.textToBePresentInElementLocated(By.cssSelector(".chat-message:last-child"), "Hello"));. (4) Test typing indicators, read receipts, online status. (5) Test file/image sharing in chat. (6) Test multiple users in a conversation (open two browser instances). (7) Test reconnection after network interruption (CDP throttling). (8) Test notifications for new messages.

Hard Occasional 1 min read

Q262.How do you test video playback?

(1) Verify video element exists: WebElement video = driver.findElement(By.tagName("video"));. (2) Click play button. (3) Wait for playback: Thread.sleep(3000); double currentTime = (Double) ((JavascriptExecutor) driver).executeScript("return arguments[0].currentTime;", video); Assert.assertTrue(currentTime > 0);. (4) Test pause: click pause, verify currentTime stops increasing. (5) Test seek: js.executeScript("arguments[0].currentTime = 30;", video);. (6) Test volume control. (7) Test fullscreen mode. (8) Test video quality/speed options. (9) Test error states (invalid URL, network failure during streaming).

Hard Occasional 1 min read

Q263.How do you test payment gateway integration?

Payment gateways require special handling: (1) For sandbox/stripe test mode, use test card numbers: 4242 4242 4242 4242 (Stripe test successful payment). (2) Handle iframe-based payment forms: switch to the iframe before interacting. (3) Test successful payment — verify "Payment successful" message and order confirmation. (4) Test declined cards — verify appropriate error messages. (5) Test insufficient funds, expired cards, invalid CVV. (6) Test payment cancellation. (7) Test refund flow via API (not UI). (8) Never use real credit card numbers in test automation. Use sandbox environments exclusively.

Hard Occasional 1 min read

Q264.How do you handle session management in Selenium tests?

(1) Store session cookies after login: Set<Cookie> cookies = driver.manage().getCookies(); // store in a file. (2) Reuse cookies for subsequent tests: driver.get("https://example.com"); // first navigate to the domain for (Cookie cookie : storedCookies) { driver.manage().addCookie(cookie); } driver.navigate().refresh();. (3) Use Selenium 4's storage state: serialize cookies to JSON and reload. (4) For parallel tests, each thread gets its own session. (5) Clear cookies between test runs: driver.manage().deleteAllCookies();. (6) Handle session timeout — re-authenticate when session expires.

Medium Occasional 1 min read

Q265.How do you test Single Sign-On (SSO) with Selenium?

(1) Navigate to the application — it should redirect to the SSO login page. (2) Verify SSO provider page loads (Okta, Azure AD, Google, GitHub). (3) Enter SSO credentials and submit. (4) After SSO redirect back to the application, verify user is logged in. (5) Store the authenticated session cookies for reuse. (6) For multi-provider SSO, test each provider. (7) Test SSO logout — verify it logs out from both the app and the SSO provider. (8) Test session expiry — verify redirect to SSO login. (9) Handle MFA if enabled in the SSO configuration.

Medium Occasional 1 min read

Q266.How do you handle rate limiting in test automation?

(1) Add delays between test requests: Thread.sleep(1000);. (2) Rotate IP addresses using proxy rotation. (3) Use different test users for concurrent tests. (4) Monitor HTTP response status codes for 429 (Too Many Requests): use CDP to track responses. (5) Implement exponential backoff if rate-limited: if (responseStatus == 429) { int waitMs = (int) Math.pow(2, retryCount) * 1000; Thread.sleep(waitMs); retry(); }. (6) In test environments, request higher rate limits or have them disabled. (7) Distribute tests across multiple sessions/machines.

Hard Occasional 1 min read

Q267.How do you test WebSockets in Selenium?

(1) Use CDP to monitor WebSocket events: devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty())); devTools.addListener(Network.webSocketCreated(), ws -> { System.out.println("WebSocket created: " + ws.getUrl()); }); devTools.addListener(Network.webSocketFrameSent(), frame -> { System.out.println("Sent: " + frame.getResponse().getPayloadData()); }); devTools.addListener(Network.webSocketFrameReceived(), frame -> { System.out.println("Received: " + frame.getResponse().getPayloadData()); });. (2) Perform actions that trigger WebSocket communication. (3) Verify messages sent/received match expected data. (4) Test WebSocket reconnection by throttling network (CDP).

Hard Occasional 1 min read

Q268.How do you test Progressive Web Apps (PWA) with Selenium?

(1) Verify manifest: check for <link rel="manifest"> in page HTML. (2) Check service worker registration: js.executeScript("return navigator.serviceWorker.controller ? true : false");. (3) Test offline functionality: use CDP to throttle network to 0 bandwidth, then verify the still works. (4) Test add-to-home-screen prompt. (5) Test push notifications. (6) Test cached asset loading. (7) Background sync: verify queued operations sync when online. (8) Verify app shell loads immediately on repeat visits. PWA testing requires extensive CDP usage for network control and service worker inspection.

Hard Occasional 1 min read

Q269.How do you test performance with Selenium?

(1) Use Navigation Timing API: Map<String, Object> timing = (Map<String, Object>) js.executeScript("var t = performance.timing; return {loadTime: t.loadEventEnd - t.navigationStart, domReady: t.domComplete - t.domLoading, ttfb: t.responseStart - t.requestStart};");. (2) Use CDP Performance metrics: devTools.send(Performance.enable(Optional.empty())); devTools.addListener(Performance.metrics(), metrics -> { metrics.getMetrics().forEach(m -> System.out.println(m.getName() + ": " + m.getValue())); });. (3) Set performance budgets: Assert.assertTrue((long) timing.get("loadTime") < 3000); // page should load in < 3s. (4) Test under network throttling. (5) Test with multiple iterations for statistical significance.

Hard Occasional 1 min read

Q270.What are the top best practices for Selenium test automation?

(1) Use Page Object Model for maintainability. (2) Never use Thread.sleep() — use dynamic waits. (3) Keep tests independent — no shared state. (4) Use unique test data to avoid collisions. (5) Run tests in parallel. (6) Use atomic tests — each test verifies one thing. (7) Implement proper logging and reporting. (8) Take screenshots on failure only (saves storage). (9) Use data-driven tests for multiple scenarios. (10) Version control everything: tests, data, configs. (11) Run smoke tests on every commit, full suite nightly. (12) Retry flaky tests (max 2-3 times). (13) Use CI/CD integration. (14) Regular code reviews of test code. (15) Keep locators clean and use data-testid attributes. (16) Test on real browsers and devices (cloud platforms). (17) Monitor test stability metrics. (18) Quarantine consistently failing tests.

Confidence check

If you can confidently answer the CI/CD & Real-World Scenarios questions above, you're well prepared for this section of your interview. Move on, or rehearse the trickier ones aloud with our AI mock interviewer.

11. Performance, Logging & Best Practices

Hard Occasional 1 min read

Q271.How do you measure test execution time in Selenium?

Use TestNG listeners: public class ExecutionTimeListener implements IInvokedMethodListener { @Override public void beforeInvocation(IInvokedMethod method, ITestResult result) { result.setAttribute("startTime", System.currentTimeMillis()); } @Override public void afterInvocation(IInvokedMethod method, ITestResult result) { long start = (Long) result.getAttribute("startTime"); long duration = System.currentTimeMillis() - start; System.out.println(method.getTestMethod().getMethodName() + " took " + duration + "ms"); if (duration > 5000) { System.out.println("WARNING: Test exceeded 5 seconds!"); } } }. Register in testng.xml. Track slow tests and optimize them.

Hard Occasional 1 min read

Q272.How do you optimize Selenium test execution speed?

(1) Use explicit waits with appropriate timeouts — don't wait longer than necessary. (2) Run tests in parallel. (3) Use headless mode for CI (10-20% faster). (4) Minimize driver calls — batch operations when possible. (5) Use CSS selectors over XPath (faster). (6) Avoid unnecessary navigation — reuse page objects. (7) Use findElements() instead of try-catch for element existence checks. (8) Prefer data-testid over complex XPath. (9) Use browser session reuse for related tests. (10) Minimize screenshot capture (only on failure). (11) Disable animations in test environments. (12) Block analytics and third-party scripts.

Hard Occasional 1 min read

Q273.How do you implement logging with Log4j in Selenium?

Add log4j2 dependency to pom.xml. Create log4j2.xml in resources: <Configuration> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> <File name="File" fileName="logs/selenium-tests.log"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </File> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> <AppenderRef ref="File"/> </Root> </Loggers> </Configuration>. In test classes: private static final Logger log = LogManager.getLogger(LoginTest.class); log.info("Navigating to login page"); log.error("Login failed", exception);. Structured logging helps in debugging failures.

Hard Occasional 1 min read

Q274.How do you implement step-by-step logging in tests?

Create a logging utility: public class TestLogger { private static final Logger log = LogManager.getLogger("Test"); private static ExtentTest extentTest; public static void logStep(String step) { log.info("STEP: " + step); if (extentTest != null) extentTest.log(Status.INFO, step); } public static void logPass(String msg) { log.info("PASS: " + msg); if (extentTest != null) extentTest.log(Status.PASS, msg); } public static void logFail(String msg) { log.error("FAIL: " + msg); if (extentTest != null) extentTest.log(Status.FAIL, msg); } }. Use in tests: TestLogger.logStep("Entering username"); loginPage.enterUsername("user"); TestLogger.logPass("Username entered");. This creates a readable step-by-step report for each test.

Hard Occasional 1 min read

Q275.How do you use listener pattern in Selenium?

Implement WebDriver EventListener: public class MyListener implements WebDriverEventListener { @Override public void beforeClickOn(WebElement element, WebDriver driver) { System.out.println("Clicking on: " + element.getText()); } @Override public void afterClickOn(WebElement element, WebDriver driver) { System.out.println("Clicked successfully"); } @Override public void onException(Throwable throwable, WebDriver driver) { System.out.println("Exception: " + throwable.getMessage()); } }. Register with EventFiringWebDriver: EventFiringWebDriver eventDriver = new EventFiringWebDriver(driver); eventDriver.register(new MyListener());. This provides visibility into all WebDriver operations, useful for logging and debugging.

Hard Occasional 1 min read

Q276.How do you implement hardcoded string avoidance in Selenium?

Use constants/enums/configs: public class Locators { public static final By USERNAME_INPUT = By.id("username"); public static final By PASSWORD_INPUT = By.name("password"); public static final By LOGIN_BUTTON = By.cssSelector("button[type='submit']"); } public class Messages { public static final String LOGIN_SUCCESS = "Welcome back!"; public static final String LOGIN_FAILED = "Invalid credentials"; } public class Timeouts { public static final int STANDARD_WAIT = 10; public static final int LONG_WAIT = 30; }. This centralizes strings, making maintenance easier and avoiding magic strings scattered throughout tests.

Hard Occasional 1 min read

Q277.How do you implement the Fluent/Builder pattern in Page Objects?

public class LoginPage { private WebDriver driver; public LoginPage(WebDriver driver) { this.driver = driver; } public LoginPage withUsername(String username) { driver.findElement(By.id("username")).sendKeys(username); return this; } public LoginPage withPassword(String password) { driver.findElement(By.id("password")).sendKeys(password); return this; } public DashboardPage andLogin() { driver.findElement(By.id("loginBtn")).click(); return new DashboardPage(driver); } } // Usage: new LoginPage(driver).withUsername("admin").withPassword("pass123").andLogin();. This makes tests read like sentences and improves code readability.

Hard Occasional 1 min read

Q278.How do you implement data-driven testing with CSV files?

public class CsvDataProvider { @DataProvider(name = "csvData") public static Iterator<Object[]> fromCsv(String filePath) throws IOException { List<Object[]> data = new ArrayList<>(); try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { String line; boolean header = true; while ((line = br.readLine()) != null) { if (header) { header = false; continue; } String[] values = line.split(","); data.add(values); } } return data.iterator(); } } @Test(dataProvider = "csvData", dataProviderClass = CsvDataProvider.class) public void testLogin(String username, String password, String expectedResult) { // test implementation }. CSV files are human-readable and version-control friendly.

Hard Occasional 1 min read

Q279.How do you implement screenshot comparison for visual testing?

Use libraries like AShot, Applitools, or custom pixel comparison: Screenshot screenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(100)).takeScreenshot(driver); BufferedImage actualImage = screenshot.getImage(); // Compare with baseline BufferedImage baselineImage = ImageIO.read(new File("baseline.png")); boolean match = compareImages(actualImage, baselineImage); Assert.assertTrue(match, "Visual regression detected!");. For Applitools: Eyes eyes = new Eyes(); eyes.open(driver, "App", "Test Name"); eyes.checkWindow("Homepage"); eyes.close();. Visual testing catches layout, styling, and rendering issues that functional tests miss.

Hard Occasional 1 min read

Q280.How do you implement conditional wait logic based on element state?

Create a utility that waits differently based on context: public class WaitHelper { public static void waitForElement(WebDriver driver, By locator, WaitCondition condition) { WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); switch(condition) { case PRESENT: wait.until(ExpectedConditions.presenceOfElementLocated(locator)); break; case VISIBLE: wait.until(ExpectedConditions.visibilityOfElementLocated(locator)); break; case CLICKABLE: wait.until(ExpectedConditions.elementToBeClickable(locator)); break; case INVISIBLE: wait.until(ExpectedConditions.invisibilityOfElementLocated(locator)); break; case STALE: wait.until(ExpectedConditions.stalenessOf(driver.findElement(locator))); break; } } }. This provides a clean API for different wait conditions.

Medium Occasional 1 min read

Q281.How do you handle element interaction retries?

Implement a retry wrapper: public class ElementActions { public static void clickWithRetry(WebDriver driver, By locator, int maxRetries) { for (int i = 0; i < maxRetries; i++) { try { WebElement element = new WebDriverWait(driver, Duration.ofSeconds(5)).until(ExpectedConditions.elementToBeClickable(locator)); element.click(); return; } catch (Exception e) { if (i == maxRetries - 1) throw e; try { Thread.sleep(500); } catch (InterruptedException ignored) {} } } } }. This handles transient failures gracefully without cluttering test code.

Hard Occasional 1 min read

Q282.How do you implement test environment validation?

Before running tests, validate the environment: @BeforeSuite public void validateEnvironment() { // Check browser availability try { WebDriver driver = new ChromeDriver(); driver.quit(); } catch (Exception e) { throw new SkipException("Chrome not available: " + e.getMessage()); } // Check application availability try { URL url = new URL(config.getUrl()); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.connect(); Assert.assertEquals(200, conn.getResponseCode()); } catch (Exception e) { throw new SkipException("Application not reachable: " + e.getMessage()); } // Check required files for (String file : config.getRequiredFiles()) { Assert.assertTrue(new File(file).exists(), "Required file not found: " + file); } }. This prevents running tests against a broken environment.

Hard Occasional 1 min read

Q283.How do you implement test category tagging?

Use TestNG groups or custom annotations: @Test(groups = {"smoke", "regression", "checkout"}) public void testAddToCart() {}. Define groups in testng.xml: <test name="Smoke"> <groups> <run> <include name="smoke"/> </run> </groups> <classes> <class name="com.test.AllTests"/> </classes> </test>. Run specific groups via Maven: mvn test -Dgroups=smoke. For custom annotations: @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface SmokeTest {}. Groups help organize and selectively execute tests based on purpose.

Hard Occasional 1 min read

Q284.How do you handle dynamic content loading with AJAX?

(1) Wait for a specific element that indicates loading complete: wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-spinner")));. (2) Use JavaScript to check jQuery active state: wait.until(d -> (Boolean) ((JavascriptExecutor)d).executeScript("return jQuery.active == 0"));. (3) Poll for expected content: wait.until(d -> d.findElement(By.id("content")).getText().contains("Expected Data"));. (4) Use FluentWait with polling for AJAX-dependent content. (5) For infinite scroll, implement scroll-trigger loading detection. (6) Monitor XHR requests via CDP for precise AJAX completion detection.

Medium Occasional 1 min read

Q285.How do you implement a custom test runner?

Create a custom TestNG runner: public class CustomTestRunner { public static void main(String[] args) { TestNG testng = new TestNG(); testng.setTestClasses(new Class[] { LoginTest.class, CheckoutTest.class }); testng.setOutputDirectory("test-output/custom"); testng.addListener(new CustomReporter()); testng.setParallel(XmlSuite.ParallelMode.METHODS); testng.setThreadCount(5); testng.run(); // Generate custom report CustomReportGenerator.generate(testng.getSuites()); } }. Custom runners allow fine-grained control over test execution, reporting, and CI integration beyond what testng.xml offers.

Medium Occasional 1 min read

Q286.How do you implement dependency injection in Selenium tests?

Use Guice or Spring DI: With Guice: @Guice(moduleFactory = DriverModule.class) public class BaseTest { @Inject protected WebDriver driver; } public class DriverModule extends AbstractModule { @Override protected void configure() { bind(WebDriver.class).toProvider(DriverProvider.class).in(Singleton.class); } }. With Spring: @SpringBootTest @ContextConfiguration(classes = TestConfig.class) public class LoginTest { @Autowired private WebDriver driver; @Autowired private LoginPage loginPage; }. DI reduces boilerplate, improves test code structure, and simplifies dependency management.

Medium Occasional 1 min read

Q287.How do you implement feature toggles testing?

(1) Set feature flags via URL parameters: driver.get("https://example.com?feature=new-checkout=true");. (2) Use CDP to set localStorage/sessionStorage flags: js.executeScript("localStorage.setItem('feature_new_checkout', 'true');"); driver.navigate().refresh();. (3) Mock feature flag API responses via CDP network interception. (4) Test both enabled and disabled states. (5) Verify UI reflects correct feature state. (6) Test feature transition (enable while user is active). Feature toggles allow testing in-progress features without deploying separate environments.

Hard Occasional 1 min read

Q288.How do you handle API integration in Selenium tests?

Use REST Assured or similar for API calls within Selenium tests: // Create test data via API Response response = RestAssured.given() .header("Content-Type", "application/json") .body(newUser) .post("/api/users"); Assert.assertEquals(201, response.getStatusCode()); String userId = response.jsonPath().getString("id"); // Now use UI to verify data driver.get("/users/" + userId); Assert.assertTrue(driver.findElement(By.id("user-name")).getText().contains("New User")); // Clean up via API RestAssured.delete("/api/users/" + userId);. Mixing API + UI testing increases speed (API for data setup, UI for verification).

Hard Occasional 1 min read

Q289.How do you implement parallel execution strategy?

(1) TestNG parallel in testng.xml: <suite name="Suite" parallel="methods" thread-count="5">. (2) Thread-safe driver: ThreadLocal<WebDriver>. (3) Thread-safe test data: each thread gets unique data. (4) Isolated test environments or unique data per thread. (5) Parallel-safe reporting: ThreadLocal<ExtentTest>. (6) Shared resource management (database connections, file access). (7) Consider test dependencies — dependent tests should not be parallel. (8) Monitor resource usage: CPU, memory, network. Start with 2x CPU cores threads and adjust. (9) Use separate Grid Nodes for better isolation.

Hard Occasional 1 min read

Q290.How do you implement test data cleanup strategy?

(1) Clean up after each test: @AfterMethod public void cleanup() { // Delete test user created during test apiClient.deleteUser(testUserId); }. (2) Use @AfterSuite for suite-level cleanup. (3) Tag test data with unique identifiers for easy cleanup: String testUserId = "test-user-" + System.currentTimeMillis();. (4) Use database cleanup: jdbcTemplate.execute("DELETE FROM users WHERE email LIKE 'test-%'");. (5) For cloud environments, use API cleanup. (6) In Docker, discard containers after test suite. (7) Implement cleanup in TestNG listeners. (8) Always clean up to prevent data pollution and test interference.

Confidence check

If you can confidently answer the Performance, Logging & Best Practices questions above, you're well prepared for this section of your interview. Move on, or rehearse the trickier ones aloud with our AI mock interviewer.

12. Scenario-Based Problem Solving

Hard Occasional 1 min read

Q291.Scenario: Your test passes locally but fails on CI/CD. How do you debug?

Common causes: (1) Timing differences — CI/CD is slower; add explicit waits. (2) Screen resolution — CI may have different viewport; set explicit window size. (3) Browser version differences — ensure CI has the same browser version. (4) No display server — use headless mode with --headless=new --no-sandbox --disable-dev-shm-usage. (5) Network restrictions — CI may block external resources. Debugging steps: (a) Add detailed logging. (b) Capture screenshots and HTML source on failure. (c) Run CI build with same browser options locally (headless). (d) Check CI logs for timeouts. (e) Use video recording in CI (BrowserStack, Sauce Labs). (f) Compare locale, timezone, language settings.

Hard Occasional 1 min read

Q292.Scenario: Your test clicks a button but nothing happens. How do you solve it?

(1) Check ElementClickInterceptedException — another element may cover the button. (2) Use JavaScript click as workaround: js.executeScript("arguments[0].click();", button);. (3) Verify element is enabled: Assert.assertTrue(button.isEnabled());. (4) Wait for element to be clickable: wait.until(ExpectedConditions.elementToBeClickable(button)).click();. (5) Scroll to element first: new Actions(driver).moveToElement(button).click().perform();. (6) Check if button is inside an iframe — switch to it. (7) Check if there's a loading overlay — wait for it to disappear. (8) Verify button's JavaScript event listeners aren't blocked — use CDP to check console errors.

Hard Occasional 1 min read

Q293.Scenario: How do you automate a web page that loads content in a shadow DOM (open mode)?

Selenium 4 supports open shadow DOM natively: SearchContext shadowRoot = driver.findElement(By.cssSelector("my-component")).getShadowRoot(); WebElement button = shadowRoot.findElement(By.cssSelector(".btn")); button.click();. For nested shadow DOMs: SearchContext outerShadow = driver.findElement(By.tagName("outer-component")).getShadowRoot(); SearchContext innerShadow = outerShadow.findElement(By.cssSelector("inner-component")).getShadowRoot(); WebElement target = innerShadow.findElement(By.id("target"));. For closed shadow DOM (encapsulated), use JavaScript: return document.querySelector('my-component').shadowRoot.querySelector('.target'); — but closed mode intentionally blocks access.

Hard Occasional 1 min read

Q294.Scenario: How do you test a feature that requires email verification?

(1) Use a test email service that captures emails (Mailinator, Gmail API, Yopmail, or a custom SMTP server). (2) Register with the test email address. (3) Wait for the email to arrive: use IMAP or API polling: // Using Mailinator API String emailInbox = restClient.get("https://api.mailinator.com/v2/domains/example.com/inboxes/testuser"); String verificationLink = extractLinkFromEmail(emailInbox);. (4) Open the verification link: driver.get(verificationLink);. (5) Verify account is activated. (6) Alternative: use a test backend API to bypass email verification: restClient.post("/api/users/verify/testuser");. Always cleanup test email accounts.

Hard Occasional 1 min read

Q295.Scenario: How do you implement a framework for 5000+ test cases?

(1) Modular architecture: separate page objects, test data, utilities, and tests. (2) Data-driven: externalize test data (Excel, JSON, database). (3) Parallel execution: Grid with multiple Nodes, thread-safe drivers. (4) Tiered test suites: smoke (minutes), component (hours), full regression (overnight). (5) Test categorization: groups, tags, priorities. (6) CI/CD integration with build pipeline. (7) Dynamic test selection: run tests related to changed code. (8) Flaky test dashboard and quarantine. (9) Comprehensive reporting with historical trends. (10) Regular test audit: remove obsolete tests, merge duplicates. (11) Use BDD (Cucumber) for non-technical stakeholder readability. (12) Implement test impact analysis to run relevant tests only.

Medium Occasional 1 min read

Q296.Scenario: Your suite has 30% flaky tests. How do you stabilize it?

Systematic approach: (1) Log analysis — identify common failure patterns. (2) Fix synchronization — replace Thread.sleep with explicit waits. (3) Fix locators — use stable data attributes, avoid index-based and fragile XPath. (4) Clean test data — eliminate shared state and data collisions. (5) Environment stability — ensure consistent browser versions, network conditions. (6) Retry mechanism — max 2 retries for known transient failures. (7) Quarantine — move consistently flaky tests to a separate suite. (8) Root cause analysis — fix the underlying issue, not the symptom. (9) Review new tests for flakiness before merging. (10) Implement test stability metrics in CI/CD dashboard.

Hard Occasional 1 min read

Q297.Scenario: How do you test a single-page application with complex state management?

(1) Understand the app state lifecycle (Redux store, Vuex, or component state). (2) Use CDP/CDP to evaluate JavaScript state: Object state = js.executeScript("return window.__REDUX_STORE__.getState();");. (3) Assert specific state values: Map<String, Object> state = (Map<String, Object>) state; String userRole = (String) ((Map<String, Object>)state.get("auth")).get("role"); Assert.assertEquals("admin", userRole);. (4) Test navigation via client-side routing: verify URL changes and component updates. (5) Test browser back/forward buttons. (6) Test state persistence after page refresh. (7) Test state reset on logout. (8) Use CDP to monitor network requests triggered by state changes.

Hard Occasional 1 min read

Q298.Scenario: How do you handle a website that detects and blocks automation?

(1) Disable automation indicators: options.addArguments("--disable-blink-features=AutomationControlled"); options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"}); options.setExperimentalOption("useAutomationExtension", false);. (2) Override navigator.webdriver: js.executeScript("Object.defineProperty(navigator, 'webdriver', {get: () => undefined});");. (3) Use realistic user-agent: options.addArguments("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...");. (4) Add random delays between actions: Thread.sleep(random.nextInt(1000) + 500);. (5) Randomize mouse movements: use Actions class with varied coordinates. (6) Use residential proxies for IP rotation. (7) Add browser fingerprint randomization (Canvas, WebGL, Font). Note: Only use these for testing your own applications, not for scraping or bypassing anti-automation on third-party sites.

Hard Occasional 1 min read

Q299.Scenario: How do you structure tests for microservices-based applications?

(1) Test each microservice UI independently if possible (separate URLs/dedicated pages). (2) Use service virtualization: mock downstream microservices via CDP network interception. (3) Test API contracts: verify API responses match expected schema (contract testing). (4) Test cross-service flows: end-to-end journeys that span multiple services (login → order → payment → shipping). (5) Use test containers: spin up microservice dependencies in Docker for integration tests. (6) Implement service-level health checks before UI tests. (7) Use distributed tracing (Jaeger, Zipkin) via CDP to trace requests across services. (8) Test circuit breakers and fallback behavior (simulate a downstream service failure via CDP).

Hard Occasional 1 min read

Q300.Scenario: How do you design a complete Selenium automation framework from scratch?

Step-by-step: (1) Choose tech stack: Java/TestNG/Selenium 4, Maven/Gradle, Log4j, ExtentReports. (2) Project structure: pages/, tests/, utils/, listeners/, base/, config/, testdata/. (3) Base classes: BasePage (common page methods, waits, logger), BaseTest (driver lifecycle, reporting). (4) Driver factory: ThreadLocal<WebDriver>, multiple browser support, RemoteWebDriver for Grid. (5) Page Object Model: one class per page, with By locators and page-specific methods. (6) Utilities: WaitHelper, ElementActions, ConfigReader, ExcelReader, ScreenshotHelper, RandomDataGenerator. (7) TestNG configuration: testng.xml with parallel execution, groups, listeners. (8) Reporting: ExtentReports with screenshots on failure, logs, test categories. (9) CI/CD: Jenkinsfile/GitHub Actions with Docker execution. (10) Data: external test data (Excel/JSON/CSV), DataProvider integration. (11) Grid: Docker Compose for Selenium Grid, parallel execution. (12) Maintenance: code reviews, regular dependency updates, flaky test tracking, test impact analysis.

Confidence check

If you can confidently answer the Scenario-Based Problem Solving questions above, you're well prepared for this section of your interview. Move on, or rehearse the trickier ones aloud with our AI mock interviewer.

Quick revision

  1. Q1: What is Selenium and what are its components — Selenium is an open-source browser automation framework used for testing web applications across different browsers and platforms.
  2. Q2: What is the difference between Selenium IDE, WebDriver, and Grid — Selenium IDE is a Firefox/Chrome plugin for record-and-playback — useful for quick prototyping but not suitable for production test suites.
  3. Q3: What are the advantages of Selenium WebDriver — Key advantages: (1) Open-source and free with no licensing costs.
  4. Q4: What are the limitations of Selenium — (1) Desktop application testing — Selenium only automates web browsers, not desktop or native mobile apps (use Appium for mobile).
  5. Q5: What programming languages are supported by Selenium — Selenium WebDriver officially supports Java, Python, C#, JavaScript/Node.js, Ruby, and Kotlin.

Frequently asked questions

The 2026 short-list covers: WebDriver vs Selenium RC, explicit vs implicit waits, relative locators (above/below/near), Selenium 4 CDP access, Selenium Grid 4 architecture, Page Object Model, handling iframes and shadow DOM, file uploads/downloads, Actions API, JavaScriptExecutor, headless mode, parallel execution with TestNG, data-driven testing, reporting (Allure/ExtentReports), CI/CD integration, dynamic XPath, stale element handling, browser profile management, network interception via CDP, and flaky-test debugging. All 20 are covered in the question bank below with sample answers.

Learn Selenium first if you're targeting enterprise Java roles, BFSI/healthcare clients, or teams with existing Grid-based suites. Pick Playwright first for greenfield TypeScript/Node stacks, faster local execution, and modern auto-wait. Most senior SDETs end up knowing both — Selenium for breadth of jobs, Playwright for modern speed.

Yes — the question bank is sourced from real loops at FAANG and FAANG-adjacent companies (Amazon, Microsoft, Google, Meta, Atlassian, Salesforce, Flipkart, Swiggy). FAANG SDET rounds lean on framework design, parallelism, Grid architecture, CI/CD, and scenario debugging — all covered in sections 7–12.

Every Selenium interview question on this page ships with a senior-SDET-written sample answer, and many include Java/WebDriver code snippets. You can also rehearse the answers out loud against our AI mock interviewer for instant scoring.

Yes. Selenium remains the most-requested automation tool in QA/SDET job postings worldwide — especially in India, the US, and Europe — because of its Java ecosystem, Grid scalability, and decade-long install base in regulated industries. Playwright is growing fast, but Selenium roles still outnumber it 3:1 in 2026 listings.

Was this article helpful?

Cluster · QA Career

More from QA Interview Questions

Behavioral, framework, coding — full interview prep.

Pillar guide · 10 articles
More in this cluster
From the QA Career pillar

Key takeaways

  • Master the fundamentals before tackling advanced Selenium scenarios.
  • Always explain trade-offs — interviewers reward judgement, not memorisation.
  • Use real project examples; generic answers blend in.
  • Practice answers out loud — written prep doesn't transfer to live rounds.
  • Revise the 30-second cheat sheet the night before your interview.
  • Keep one strong scenario story ready for every section above.

These Questions Are Just the Start

Get 1000+ more with detailed model answers in our QA Interview Preparation Kit. Covers manual testing, automation, API, SQL, Selenium, Playwright, and framework concepts — everything asked in real QA interviews.

Get Interview Kit — ₹1,045

Selenium QA jobs hiring now

Live, indexable Selenium openings — updated daily in Jobs Radar.

Browse all QA jobs on Jobs Radar

Loading current openings…

Home