Selenium Interview Questions for Freshers (2026): Waits, Locators, and Why Your Test Is Flaky
Updated August 2026
Automation interviews for freshers have a predictable shape, and so does the failure. Candidates arrive able to write Selenium code that works on a tutorial site, and lose the round on three things: why a test that passes locally fails in the pipeline, why their locator broke when a developer changed nothing visible, and what they would do about a test that fails one run in five. Those are the professional questions in this field, and they are the ones a course rarely covers because they only show up once tests run repeatedly against a real application.
The other thing to understand is that a fresher automation interview is not mostly about Selenium. Expect a substantial block on your programming language — Java in most Indian postings, sometimes Python — covering collections, string handling, OOP and exception handling, because a framework is code and the interviewer needs to know you can write it. Expect testing fundamentals too, since automation without QA judgement produces scripts nobody trusts; our manual testing page covers that half and this page does not repeat it.
What follows is the Selenium and framework half: locators and why the ones copied from browser dev tools break, the wait mechanisms and why Thread.sleep is the wrong answer, the exceptions you will be asked to explain, Page Object Model and TestNG at the level a fresher is expected to know them, and a systematic answer to the flaky-test question. There is also an honest section for manual testers moving across, which is one of the most common routes into these roles in Hyderabad and Bengaluru.
Frequently asked questions
What does a fresher automation interview actually test?
Four blocks, usually in this order. Programming fundamentals in your chosen language — collections, strings, OOP concepts, exception handling — often with a small coding task, because a test framework is software. Selenium itself: locators, waits, the WebDriver API, common exceptions, handling frames, windows and dropdowns. Framework knowledge: Page Object Model, TestNG or JUnit, data-driven basics, reporting, and how you would structure a suite. And testing fundamentals: what you would automate, what you would not, severity versus priority, how you would test a given feature. Candidates over-prepare block two and under-prepare blocks one and four.
Java or Python for automation — which should I learn?
Look at the postings you are actually targeting. Java dominates automation and SDET roles at Indian service companies and many product firms, largely because existing frameworks and the TestNG ecosystem are built in it, so it is the safer default for maximising the number of jobs you are eligible for. Python is common in newer teams and is faster to become productive in. The honest part: Selenium concepts, locators, waits and framework design transfer almost entirely between them, so the choice affects which door opens rather than what you fundamentally know. Pick one, go deep enough to write a framework in it, and do not list both after a tutorial in each.
What happens when you call driver.get()?
Your test code calls the Selenium client binding, which sends an HTTP request following the W3C WebDriver protocol to a browser driver process — chromedriver, geckodriver and so on. That driver translates the command into browser-specific automation instructions, the browser acts on them, and the response travels back the same way. Two points worth adding: from Selenium 4 the W3C protocol is the standard and the older JSON Wire Protocol is gone, which is why version mismatches between your Selenium version, browser and driver cause confusing failures. And driver.get() blocks until the document load event fires, which is not the same as the page being ready to interact with — the reason waits exist at all.
What are the locator strategies, and which should you prefer?
Selenium offers id, name, className, tagName, linkText, partialLinkText, cssSelector and xpath. Prefer in roughly this order: a stable id, then a purpose-built test attribute such as data-testid where the team provides one, then a CSS selector on stable attributes, then XPath where you genuinely need it. The principle behind the ordering is stability rather than elegance — you want the locator least likely to change when someone restyles the page. The strongest answer here mentions asking developers to add test attributes, because that is what a mature team actually does instead of writing ever more elaborate selectors.
Why do XPaths copied from browser dev tools break?
Because "Copy XPath" usually produces an absolute or near-absolute path — something like /html/body/div[3]/div[2]/div/form/button — which encodes the entire structure of the page. Any developer inserting a wrapper div, reordering a section or changing a layout breaks it, even though nothing about the button changed. It is also unreadable, so the next person cannot tell what it was meant to target. Write locators by hand against stable attributes or text, keep them relative, and treat a copied absolute path as a temporary hack rather than something you commit. Interviewers ask this specifically to separate people who have maintained a suite from people who have written one.
CSS selector or XPath — which is better?
CSS selectors are generally faster, shorter and more readable, and they are the sensible default. XPath earns its place in three situations: when you need to traverse upward or sideways in the DOM using axes such as parent, ancestor or following-sibling, which CSS cannot do; when you need to match on visible text; and when the only stable thing about an element is its relationship to another element. So the professional answer is CSS by default, XPath deliberately where its extra capability is required — not a blanket preference in either direction.
Write an XPath for a button whose visible text is "Submit".
Use //button[normalize-space(text())='Submit'] — and be ready to explain normalize-space, because that is the point of the question. Markup frequently contains leading, trailing or repeated whitespace and line breaks around text, so a plain text()='Submit' comparison fails against text that looks identical on screen. normalize-space trims and collapses whitespace before comparing. If you need a partial match use //button[contains(normalize-space(.), 'Submit')], and note that using dot rather than text() matches the concatenated text of descendants, which matters when the label is wrapped in a span inside the button.
Implicit, explicit and fluent wait — what is the difference?
An implicit wait is a global setting that makes every element lookup poll for up to a set duration before throwing. It is convenient and blunt: it applies to finding elements only, not to conditions like clickability or text appearing, and mixing it with explicit waits produces unpredictable combined timeouts. An explicit wait — WebDriverWait with an ExpectedCondition — waits for a specific condition on a specific element, which is what you want in almost every real case: visibility, clickability, presence, staleness, text present, or a custom condition. A fluent wait is an explicit wait with configurable polling interval and ignored exception types, useful when you need finer control. The recommended practice is explicit waits, applied where they are needed, without a global implicit wait in play.
Why is Thread.sleep the wrong way to wait?
Because it makes a fixed promise about time that the application never made. Set it too short and the test fails intermittently on a slow run; set it long enough to be safe and every test pays that cost on every execution, so a suite of three hundred tests wastes hours. It also hides the real signal: an explicit wait that times out tells you which condition never became true, while a sleep followed by a failure tells you nothing about why. There is one narrow legitimate use — waiting out an animation or a third-party behaviour you cannot observe — and even then it should be isolated and commented. In an interview, say all of that; "sleep is bad practice" alone is a memorised answer.
A test fails one run in five. How do you investigate?
Work through causes in order of likelihood rather than guessing. Timing first: a missing or incorrect wait, or an element that exists in the DOM before it is interactable — the single largest cause. Then test data: does the test depend on data another test creates, mutates or deletes, or on data that expires? Then test independence and ordering: does it pass alone but fail in a suite, which means shared state, a session left logged in, or a dependency on execution order? Then the environment: parallel runs competing for the same account or record, differences between local and pipeline browsers, headless-versus-headed rendering differences. Then dynamic locators — generated ids or index-based paths that shift with data. Finish with the professional point: I would fix the cause rather than add a retry, because a retry on a genuinely flaky test hides real intermittent product bugs, and a suite people do not trust gets ignored.
What causes StaleElementReferenceException, and how do you fix it?
You are holding a reference to an element that is no longer attached to the DOM — because the page navigated, or because a framework re-rendered that part of the page, which is extremely common in React, Angular and Vue applications where a component refresh replaces nodes that look identical. The fix is not to catch and ignore it: re-locate the element at the point of use rather than caching WebElement references in fields, wait for the specific condition you actually need after an action that triggers a re-render, and where a page object caches elements, ensure they are re-resolved. Explaining that the element looks the same on screen but is a different node is what demonstrates real understanding.
What is the difference between findElement and findElements?
findElement returns the first matching element and throws NoSuchElementException when there is none. findElements returns a list, which is empty when nothing matches and throws nothing. That difference is genuinely useful: to check that something is absent, use findElements and assert the list is empty, because wrapping findElement in a try-catch to test for absence is slower and reads poorly. Also worth knowing that findElements combined with an implicit wait will wait the full duration before returning an empty list, which surprises people writing negative assertions.
How do you handle dropdowns, alerts, frames and multiple windows?
Dropdowns built with a select tag use the Select class — selectByVisibleText, selectByValue, selectByIndex, and getOptions to read them — but custom dropdowns built from divs and lists are not select elements at all and must be clicked and read like ordinary elements, which is a frequent follow-up question. Alerts need driver.switchTo().alert() and then accept, dismiss, getText or sendKeys. Frames need driver.switchTo().frame() by index, name or WebElement, and defaultContent or parentFrame to leave — elements inside a frame are invisible to Selenium until you switch. Multiple windows and tabs use getWindowHandles, iterating to the new handle and switching, then switching back. Each of these has the same underlying idea: Selenium acts on one context at a time and you must move it explicitly.
What is Page Object Model, and what makes an implementation good?
A design pattern where each page or significant component gets a class holding its locators and the actions available on it, so tests read as business steps and a UI change is fixed in one place instead of thirty. What separates a good implementation: locators are private to the page class; methods express user intent — login(user, pass) rather than typeUsername then typePassword then clickSubmit; navigation methods return the next page object so flows chain readably; and assertions live in tests rather than in page objects, because a page object describes capability while a test describes expectation. Mentioning that last distinction is a strong signal, as is knowing that Page Factory with @FindBy is one implementation and that caching elements there interacts badly with re-rendering pages.
What do you use from TestNG?
Annotations for lifecycle — BeforeSuite, BeforeClass, BeforeMethod and their after counterparts — plus @Test with priority, groups and enabled flags. Assertions, both hard and soft, where SoftAssert lets you collect multiple failures in one run. DataProvider for data-driven tests, which is the standard answer to "how would you run the same test with twenty inputs". Parallel execution and thread count configured through testng.xml, along with grouping and suite composition. Listeners, for reporting and screenshots on failure. Dependencies via dependsOnMethods, used sparingly since dependent tests undermine independence. And RetryAnalyzer — mention that it exists and that using it to paper over flakiness rather than to absorb genuine infrastructure noise is how a suite loses credibility.
How do you run tests across browsers and in parallel?
Cross-browser means driving different drivers from the same tests, with the browser chosen by configuration rather than hardcoded — a factory class reading a parameter is the usual fresher-level answer. Parallel execution comes from TestNG parallel settings with thread-safe driver management, which in practice means one WebDriver per thread, commonly via a ThreadLocal, and no shared mutable state between tests. Selenium Grid distributes tests across machines or containers, and cloud grid providers do the same as a service across many browser and OS combinations. The important caveat to state: parallelism exposes every hidden dependency in a suite, so tests sharing an account or a data record will start failing as soon as you turn it on.
What is headless mode, and when should you not use it?
Running the browser without a visible UI, which is faster and is how tests normally execute in a CI pipeline where no display exists. Avoid relying on it exclusively, because rendering differences do occur: element positions and viewport sizes can differ, some visual and layout issues are invisible headless, and file dialogs and certain media behaviours differ. The practical position is to run headless in the pipeline, run headed locally when debugging, set an explicit window size so layout is deterministic, and capture screenshots on failure so a headless failure is still diagnosable.
How do you decide what to automate and what not to?
Automate what is repetitive, stable and worth re-running: core regression flows, smoke tests around critical paths, data-driven cases with many input combinations, and anything a human would otherwise repeat every release. Do not automate exploratory testing, one-off checks, usability and visual judgement, or screens still changing every sprint — you will spend more time maintaining the test than the test saves. The answer that impresses adds the pyramid argument: much of what people automate through the UI is tested faster and more reliably at the API or unit level, so a good automation engineer pushes checks down the stack and reserves UI tests for genuine end-to-end journeys. Saying "everything should be automated" marks you as inexperienced.
I am a manual tester. How do I move into automation?
Your domain knowledge is a genuine asset — you know which flows matter and what breaks, which is exactly what people who can code but not test lack. The path that works: learn one language properly rather than learning Selenium first, because interviews test the language; then Selenium basics; then automate a slice of the regression suite you already run manually, which gives you both a portfolio and a visible contribution at work; then framework structure with Page Object Model and TestNG. Ask your lead for automation work on your current project, since internal moves are far easier than external ones. Be wary of expensive certification courses that promise placement — the deliverable that gets you hired is a framework repository you can walk someone through, and nobody needs to sell you that.
Do I need API testing and CI knowledge as a fresher?
Increasingly yes, at a basic level, and it differentiates you cheaply. For API testing, know why it is faster and more stable than UI testing, be able to use Postman, and know that REST Assured is the common Java library — plus status codes, request methods and how to assert on a JSON response. For CI, understand that tests run automatically on a pipeline triggered by commits, know Jenkins or GitHub Actions by name and roughly what a job configuration does, and understand why tests must be independent and headless to work there. You do not need depth. You need to not be blank when asked, and to be able to say where your tests would run.
What project should I build to show in an interview?
One framework repository you can walk someone through end to end, automating a public demo or practice site: a handful of real user journeys, Page Object Model structure, TestNG with a data-driven test, configuration-driven browser choice, explicit waits used properly, screenshots on failure, a report, and a README explaining the design decisions. Push it to GitHub with clean commit history. Two things matter more than scope: that you can explain why each part exists rather than that it covers many cases, and that it is not a line-for-line tutorial clone — interviewers recognise those instantly. Being able to say "I chose explicit waits here and this is what happened when I did not" is worth more than another twenty test cases.
I graduate in 2027. What order should I learn things in?
Language first — Java or Python to the point where collections, strings, OOP and exceptions are comfortable, because that is a large block of the interview and the hardest to fake. Then testing fundamentals, since automation without QA judgement produces scripts nobody trusts. Then Selenium: locators by hand, explicit waits, the common exceptions, frames and windows. Then framework: Page Object Model, TestNG, data-driven, reporting. Then the surrounding tools at basic depth — Git, Postman, and enough CI to explain where tests run. Build the framework repository while learning rather than afterwards, and start applying before it feels finished, because the interviews will tell you precisely what to strengthen next.
Don't just read Selenium & automation questions — get asked them
Phiny's AI interviews you on exactly these topics, follows up on weak answers, and tells you what a stronger answer looks like. Text interviews are free and unlimited.
Start a free AI mock interviewHow to prepare
- Never answer a wait question with Thread.sleep. Explain explicit waits with specific ExpectedConditions, say why a fixed sleep is both slower and less diagnostic, and mention the one narrow case — an unobservable animation or third-party behaviour — where it is defensible.
- Write locators by hand and prefer stable attributes. An XPath copied from dev tools encodes the whole page structure and breaks on any layout change, which is the single clearest signal to an interviewer that you have written tests but never maintained them.
- Prepare the flaky-test answer as a systematic sequence — waits, test data, test independence and ordering, environment and parallelism, dynamic locators — and finish by saying you would fix the cause rather than add a retry, because retries hide real intermittent bugs.
- Spend more preparation time on your programming language than on Selenium. Collections, strings, OOP and exception handling form a large block of these interviews, and a framework is ordinary software that you have to be able to write.
- Build one framework repository you can explain end to end — Page Object Model, TestNG, data-driven, config-driven browser, screenshots on failure, README — rather than many disconnected scripts. Interviewers recognise tutorial clones immediately.
- Know the test pyramid and use it. Saying that everything should be automated through the UI marks you as inexperienced; saying that checks belong at the API or unit level wherever possible, with UI tests reserved for genuine end-to-end journeys, marks you as someone who has thought about maintenance.
- Learn Git properly and keep the framework repository clean. Automation work is code that lives in a shared repository with branches and reviews, and a candidate who cannot handle a branch or explain a commit history is a practical problem regardless of Selenium knowledge.
Where these questions get asked
- TCS NQT guide and Infosys hiring guide — the two biggest exams these questions appear in.
- All company placement guides — pattern, syllabus and rounds for every mass recruiter.