A4Q Selenium Tester Mock Exam #3 — Questions & Answers
Every question in this mock exam, with the correct answer marked and a written rationale behind each option below — for reading and review, not a timed run.
Which statement correctly describes the relationship between the WebDriver interface and the ChromeDriver class in the Selenium Java bindings?
ChromeDriver implements the WebDriver interface, so you can declare the variable as the WebDriver type
Correct — programming to the interface keeps the test browser-agnostic.
WebDriver extends ChromeDriver, so ChromeDriver is the parent type
Reversed — the interface is the abstraction, the class implements it, not the other way round.
They are unrelated classes and must be cast at runtime
Wrong — they are directly related by the implements relationship, no cast needed.
WebDriver is an interface; ChromeDriver is a browser-specific implementation of it, so the recommended declaration is WebDriver driver = new ChromeDriver();
During a test run several browser windows have been opened. What is the difference between calling driver.close() and driver.quit()?
close() closes the current window only; quit() closes all windows and ends the session
Correct — this is the defined behaviour of the two commands.
close() ends the session; quit() only closes the current window
Reversed — quit() is the one that ends the whole session.
They are aliases and behave identically
Wrong — they differ when more than one window is open.
close() clears cookies; quit() clears the browser cache
Wrong — neither command is about clearing cookies or cache.
close() closes only the current window/tab; quit() closes all windows and ends the WebDriver session.
How do the methods findElement() and findElements() differ when no element matches the locator?
findElement() throws NoSuchElementException, while findElements() returns an empty list
Correct — findElements never throws for a no-match, it returns size 0.
Both throw NoSuchElementException
Wrong — findElements returns an empty list rather than throwing.
Both return null
Wrong — findElement throws, it does not return null.
findElement() returns an empty list; findElements() throws
Reversed — it is the other way round.
findElement() throws NoSuchElementException; findElements() returns an empty list.
Which of the following are legitimate browser-specific implementations of the WebDriver interface? (Choose two.)
ChromeDriver
Correct — the driver implementation for Google Chrome.
FirefoxDriver
Correct — the driver implementation for Mozilla Firefox (backed by GeckoDriver).
SeleniumIDEDriver
Wrong — no such class exists; Selenium IDE is a record-and-playback tool, not a driver.
RemoteBrowserManager
Wrong — not a real Selenium class; remote runs use RemoteWebDriver.
ChromeDriver and FirefoxDriver are real WebDriver implementations. SeleniumIDEDriver and RemoteBrowserManager are not classes in the bindings.
A tester writes the following Java code against a login form: driver.get("https://shop.example/login"); WebElement user = driver.findElement(By.id("username")); user.sendKeys("alice"); WebElement pass = driver.findElement(By.id("password")); pass.sendKeys("secret"); driver.findElement(By.id("login-btn")).click(); The field with id 'username' already contains the value 'guest' left over from a previous step. After this code runs, what value does the username field hold?
guestalice
Correct — sendKeys appends; without clear() the pre-existing 'guest' stays and 'alice' is added.
alice
Wrong — this would require calling clear() before sendKeys, which the code does not.
guest
Wrong — sendKeys does add 'alice', so the value changes.
An exception is thrown because the field is not empty
Wrong — sendKeys does not require an empty field and throws nothing here.
sendKeys() appends text to whatever is already in the field; it does not clear it. So 'guest' + 'alice' = 'guestalice'. To replace, call user.clear() first.
You need to read the current value shown inside an <input> text box. Which approach is correct?
element.getAttribute("value")
Correct — the input's content is exposed via its value attribute/property.
element.getText()
Wrong — getText() returns visible inner text, which for an <input> is typically empty.
element.getTagName()
Wrong — that returns the element's tag ('input'), not its value.
element.getCssValue("value")
Wrong — getCssValue reads CSS properties, not the field's value.
For form controls the visible value lives in the 'value' attribute/property, so getAttribute("value") is used. getText() returns the visible text of non-input elements and is usually empty for inputs.
Which Selenium API is designed for complex user gestures such as hovering over a menu, drag-and-drop, or pressing a key combination?
The Actions class
Correct — it models composite input gestures via a builder and perform().
The Select class
Wrong — Select handles <select> dropdown options only.
The Alert interface
Wrong — Alert handles JavaScript alert/confirm/prompt dialogs.
The Navigation interface
Wrong — Navigation handles back/forward/refresh/to, not gestures.
The Actions class builds sequences of low-level interactions (moveToElement, dragAndDrop, keyDown, etc.) and executes them with perform().
A <select id='country'> dropdown lets the user choose one country. Which Selenium helper is the cleanest way to choose the option labelled 'Germany'?
new Select(element).selectByVisibleText("Germany")
Correct — the Select class is the intended API for dropdowns.
element.sendKeys("Germany")
Partially works on some browsers but is not the reliable, intended approach for <select>.
element.click() then type the text
Wrong — a native <select> does not accept free-typed text this way.
new Dropdown(element).choose("Germany")
Wrong — there is no Dropdown class in the Selenium bindings.
Wrap the element in the Select class and call selectByVisibleText("Germany"). Select provides purpose-built methods for <select> elements.
According to Selenium good practice, which locator strategy should be preferred when a unique, stable id attribute is available on the target element?
By.id
Correct — preferred first choice when a unique, stable id exists.
An absolute XPath from the <html> root
Wrong — absolute XPath is the most brittle strategy and breaks on any structural change.
By.linkText on a nearby link
Wrong — targets a different element and depends on visible text.
By.tagName
Wrong — tag name usually matches many elements and is not unique.
By.id is the fastest and most robust locator because ids are meant to be unique and are rarely affected by layout changes.
Consider this HTML fragment: <div class="cart"> <ul> <li class="item" data-sku="A100">Keyboard</li> <li class="item" data-sku="B200">Mouse</li> <li class="item" data-sku="C300">Monitor</li> </ul> </div> Which single locator selects exactly the <li> for the Mouse and nothing else?
By.cssSelector("li.item[data-sku='B200']")
Correct — the unique data-sku value isolates exactly the Mouse row.
By.className("item")
Wrong — matches all three <li> elements.
By.tagName("li")
Wrong — also matches all three list items.
By.cssSelector(".cart ul li")
Wrong — selects every <li> descendant, not just the Mouse.
The data-sku attribute is unique per item, so the CSS selector li.item[data-sku='B200'] pinpoints the Mouse. Selecting by index or class alone matches multiple items.
You must locate a Submit button that has no id and no stable class, but always contains the visible text 'Place order'. Which XPath reliably matches it regardless of surrounding markup?
//button[normalize-space()='Place order']
Correct — matches by trimmed text and tolerates surrounding whitespace.
/html/body/div[2]/form/div[3]/button
Wrong — an absolute path breaks whenever the surrounding structure changes.
//button[1]
Wrong — index-based and matches whatever button happens to be first.
//button[@id='place-order']
Wrong — the element has no id, so this matches nothing.
//button[normalize-space()='Place order'] matches by trimmed visible text and is resilient to whitespace and position. An absolute path or index-based path is brittle.
What is the key difference between the CSS selectors 'div p' (with a space) and 'div > p'?
The space selects any descendant <p>; '>' selects only a direct child <p>
Correct — descendant combinator vs child combinator.
They are equivalent; the '>' is only cosmetic
Wrong — they select different sets of elements.
The space selects direct children; '>' selects any descendant
Reversed — it is the opposite.
'>' only works in XPath, not CSS
Wrong — '>' is a valid CSS child combinator.
'div p' matches any <p> that is a descendant of a <div> at any depth; 'div > p' matches only <p> that is a direct child of a <div>.
Given the element <a href="/help" class="nav-link active">Help Center</a>, which of the following locators would successfully match it? (Choose two.)
By.linkText("Help Center")
Correct — exact visible text of the anchor matches.
By.cssSelector("a.nav-link.active")
Correct — chaining both class names in CSS is valid and matches this anchor.
By.className("nav-link active")
Wrong — By.className accepts a single class name, not a space-separated compound.
By.linkText("Help")
Wrong — linkText requires the full text; use partialLinkText for a substring.
By.linkText("Help Center") matches the full visible link text; By.cssSelector("a.nav-link.active") matches both classes. By.className cannot take two classes as one string, and the partial link text given does not match.
Which statement about By.name and By.id is correct?
id is meant to be unique per page, whereas name may be shared by several elements
Correct — e.g. a radio-button group shares one name.
name must always be unique, id may repeat
Reversed — it is id that should be unique.
Neither can be used with findElement
Wrong — both By.id and By.name work with findElement.
By.name only works on <a> anchor elements
Wrong — name applies to form controls and others, not just anchors.
Both are attribute-based locators, but only id is intended to be unique per document; name may be shared by several elements (e.g. radio buttons of one group).
A results table has rows like: <tr><td class="name">Order 42</td><td class="status">Shipped</td></tr> You need the status cell that sits in the same row as the name cell containing 'Order 42'. Which XPath expresses this relationship?
//td[@class='name'][normalize-space()='Order 42']/following-sibling::td[@class='status']
Correct — anchors on the known text then hops to the sibling status cell.
//td[@class='status']
Wrong — matches every status cell in the table, not the one tied to Order 42.
//td[@class='name']/td[@class='status']
Wrong — the status cell is a sibling, not a child of the name cell.
//tr[normalize-space()='Order 42']
Wrong — selects the row, not the specific status cell requested.
Start from the name cell by text, walk up to the row (parent::tr) and down to the status cell: //td[@class='name'][normalize-space()='Order 42']/following-sibling::td[@class='status'].
Which CSS selector matches an <input> whose id attribute begins with the prefix 'user_'?
input[id^='user_']
Correct — ^= means 'attribute value starts with'.
input[id$='user_']
Wrong — $= means 'ends with', not 'starts with'.
input[id*='user_']
Partly close but *= means 'contains anywhere', not specifically a prefix.
input[id~='user_']
Wrong — ~= matches a whitespace-separated word, used for class-like lists.
The attribute-starts-with operator is ^=, so input[id^='user_'] matches ids like user_name, user_email, etc.
What is the primary purpose of the Page Object Model (POM) design pattern in Selenium test automation?
To encapsulate a page's locators and actions in one class, improving maintainability and reuse
Correct — that is exactly the maintainability goal of POM.
To make tests run faster by caching HTTP responses
Wrong — POM is a structural pattern, not a performance/caching mechanism.
To replace the need for a WebDriver instance
Wrong — page objects still use a WebDriver under the hood.
To automatically generate test data
Wrong — POM does not deal with test-data generation.
POM encapsulates the locators and interactions of a page in a dedicated class, so UI changes are fixed in one place and tests stay readable and maintainable.
In a well-designed Page Object, where should test assertions (e.g. checking that an error message equals an expected string) normally live?
In the test methods, not inside the page object
Correct — keeps page objects reusable and free of test-specific logic.
Inside each locator definition
Wrong — locators only identify elements; they hold no assertions.
In the WebDriver constructor
Wrong — the driver setup has nothing to do with assertions.
In the browser's developer console
Wrong — that is not part of the automated test structure.
Assertions belong in the test/step methods, not in the page object. The page object exposes state (getters, action methods); the test decides what is correct.
A tester writes this page-object method for a login page: public HomePage login(String u, String p) { driver.findElement(By.id("user")).sendKeys(u); driver.findElement(By.id("pass")).sendKeys(p); driver.findElement(By.id("submit")).click(); return new HomePage(driver); } Why is returning a new HomePage object considered good POM practice here?
It models the resulting page navigation and lets tests chain to HomePage actions fluently
Correct — returning the destination page object mirrors the real navigation flow.
Because it asserts that login succeeded
Wrong — the method contains no assertion; verification stays in the test.
Because it closes the WebDriver session
Wrong — nothing here quits the driver.
Because it avoids using locators
Wrong — the method clearly still uses By.id locators.
A successful login navigates to the home page, so returning the next page object lets the test chain calls fluently and models the real page flow. It does not perform any assertion by itself.
What advantage does POM give when a developer renames the id of the login button from 'login' to 'signin'?
The locator is fixed in one place, so no test scripts need editing
Correct — centralised locators are POM's core maintainability benefit.
Selenium detects the rename automatically
Wrong — Selenium cannot guess a renamed id; a human must update the locator.
The test data is regenerated
Wrong — renaming a locator has nothing to do with test data.
The browser no longer needs a driver
Wrong — unrelated; a driver is always required.
Only the single locator inside the page object must change; every test that calls the page object's method keeps working unchanged.
Which of the following are recommended characteristics of a well-designed page object class? (Choose two.)
It exposes readable action methods (e.g. login, search) rather than raw locators
Correct — tests should speak in business actions, not element internals.
It keeps its locators private/encapsulated within the class
Correct — encapsulation is what makes maintenance local to the page object.
It contains the test assertions for each scenario
Wrong — assertions belong in the tests, keeping page objects reusable.
It uses Thread.sleep() before every action for stability
Wrong — hard-coded sleeps are an anti-pattern; use explicit waits.
A page object should expose meaningful action/getter methods and keep locators private inside the class. It should not embed assertions or hard-coded sleeps.
How does the PageFactory support the Page Object Model in the Selenium Java bindings?
It initialises @FindBy-annotated fields so element lookups are wired up automatically
Correct — that is the role of PageFactory.initElements.
It launches the browser automatically
Wrong — the driver, not PageFactory, launches the browser.
It writes the assertions for you
Wrong — PageFactory has nothing to do with assertions.
It converts XPath into CSS automatically
Wrong — no such conversion is performed by PageFactory.
PageFactory initialises fields annotated with @FindBy via PageFactory.initElements(driver, this), providing lazily-located WebElements and reducing boilerplate.
What is the essential difference between an implicit wait and an explicit wait in Selenium WebDriver?
Implicit wait applies globally to all element lookups; explicit wait targets a specific condition
Correct — that is the defining distinction.
Implicit wait is for a specific element; explicit wait is global
Reversed — it is the other way round.
Both pause the thread for a fixed number of seconds regardless of state
Wrong — that describes Thread.sleep, not implicit/explicit waits, which are conditional.
There is no difference; the terms are interchangeable
Wrong — they behave quite differently.
An implicit wait sets one global polling timeout for element lookups; an explicit wait (WebDriverWait + ExpectedConditions) waits for a specific condition on a specific element.
Why is using Thread.sleep(5000) to wait for an element generally discouraged in Selenium tests?
It wastes time when the element is ready early yet can still be too short on slow loads, causing both slowness and flakiness
Correct — fixed sleeps are both slow and unreliable.
Because Thread.sleep is not supported in Java
Wrong — it is valid Java; the issue is that it is a poor synchronisation strategy.
Because it clears cookies as a side effect
Wrong — sleeping has no effect on cookies.
Because it only works in headless mode
Wrong — Thread.sleep works regardless of headless mode.
A fixed sleep always waits the full time even if the element appears sooner (slow) and may still be too short on a slow load (flaky). Explicit waits poll and continue as soon as the condition is met.
A tester wants to click a button only once it is clickable, waiting up to 10 seconds. Which snippet is correct? A) new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.elementToBeClickable(By.id("go"))).click(); B) driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); driver.findElement(By.id("go")).click(); Which is the appropriate explicit-wait solution for the clickable condition?
Option A
Correct — elementToBeClickable is the condition that matches the requirement.
Option B
Wrong — implicit wait only ensures presence, not that the element is clickable.
Both are equally correct
Wrong — only A waits for clickability; B waits merely for presence.
Neither will compile
Wrong — both are valid Java; the point is which meets the clickable requirement.
Option A uses WebDriverWait with the elementToBeClickable ExpectedCondition — exactly the explicit wait needed. Option B is an implicit wait that only waits for presence, not clickability.
A test suite sets an implicit wait of 10 seconds and, in one test, also uses an explicit WebDriverWait of 15 seconds on the same element. The team notices unpredictable, sometimes very long waits. What is the most likely cause?
Mixing implicit and explicit waits, whose timeouts can compound unpredictably
Correct — the official guidance is not to combine the two wait mechanisms.
The explicit wait always overrides the implicit wait, so there can be no conflict
Wrong — they do not cleanly override; this is precisely why mixing is discouraged.
Implicit waits are ignored once WebDriverWait is imported
Wrong — importing a class does not disable the implicit wait setting.
The browser driver is too old
Wrong — the symptom points to wait mixing, not driver version.
Mixing implicit and explicit waits can cause their timeouts to compound unpredictably. The recommended practice is to use explicit waits only and not set an implicit wait.
Which ExpectedCondition should you use to wait until an element is present in the DOM and visible on the page before reading its text?
ExpectedConditions.visibilityOfElementLocated(locator)
Correct — ensures both presence and visibility.
ExpectedConditions.invisibilityOfElementLocated(locator)
Wrong — that waits for the element to disappear, the opposite of what is needed.
ExpectedConditions.numberOfWindowsToBe(1)
Wrong — that checks the window count, unrelated to element visibility.
ExpectedConditions.titleIs("Home")
Wrong — that checks the page title, not element presence/visibility.
visibilityOfElementLocated waits for the element to be both present in the DOM and displayed (non-zero size, visible), which is what you need before reading text.
What distinguishes a FluentWait from a basic WebDriverWait?
FluentWait lets you set a custom polling frequency and ignore specific exceptions
Correct — those are the extra knobs FluentWait exposes.
FluentWait runs without any WebDriver instance
Wrong — it still operates on a driver/element.
FluentWait can only wait for page titles
Wrong — it can wait for any condition via a Function/ExpectedCondition.
FluentWait disables all timeouts
Wrong — it still has a total timeout; it just adds polling/ignore control.
FluentWait lets you configure the polling interval and which exception types to ignore, giving finer control than a default WebDriverWait (which is itself a specialised FluentWait).
Which pair of commands both load a given URL in the current browser window?
driver.get(url) and driver.navigate().to(url)
Correct — both load the URL; get is shorthand for navigate().to.
driver.open(url) and driver.load(url)
Wrong — neither open() nor load() exists in the WebDriver API.
driver.goTo(url) and driver.browse(url)
Wrong — these are not real WebDriver methods.
driver.get(url) and driver.click(url)
Wrong — click() acts on an element, it does not load a URL.
driver.get(url) and driver.navigate().to(url) both open the given URL; get() is essentially shorthand for navigate().to().
A tester runs this sequence: driver.navigate().to("https://site/a"); driver.navigate().to("https://site/b"); driver.navigate().back(); driver.navigate().forward(); Which page is displayed at the end?
https://site/b
Correct — back to /a then forward returns to /b.
https://site/a
Wrong — back() lands on /a, but forward() then moves to /b.
A blank page
Wrong — the history still contains both pages; nothing is blanked.
An error, because forward() has no history
Wrong — back() created forward history, so forward() succeeds.
After loading a then b, back() returns to a, and forward() moves again to b. So the final page is /b.
After a link opens a second browser tab, why must you call driver.switchTo().window(handle) before interacting with the new tab?
WebDriver's focus stays on the original tab until you explicitly switch to the new window handle
Correct — the driver does not auto-follow newly opened tabs.
Because the new tab has a different WebDriver instance
Wrong — all tabs of one session share the same driver; only the focus differs.
Because cookies are not shared between tabs
Wrong — focus, not cookies, is the reason a switch is required.
Because the implicit wait resets on the new tab
Wrong — the switch requirement is about command focus, not wait state.
WebDriver keeps its command focus on the original window until you explicitly switch. Commands sent before switching still target the old tab.
A JavaScript confirm() dialog appears asking 'Delete this item?'. Which Selenium API is used to accept it?
driver.switchTo().alert().accept()
Correct — the Alert interface accept() confirms the dialog.
driver.findElement(By.id("ok")).click()
Wrong — a native browser dialog is not part of the DOM, so it cannot be located as an element.
driver.navigate().refresh()
Wrong — refreshing does not confirm the dialog.
driver.quit()
Wrong — quitting ends the session instead of handling the dialog.
Switch to the alert and accept it: driver.switchTo().alert().accept(). The Alert interface handles alert/confirm/prompt dialogs.
Which of the following are provided by the driver.navigate() interface? (Choose two.)
back()
Correct — navigate().back() goes to the previous history entry.
refresh()
Correct — navigate().refresh() reloads the current page.
maximize()
Wrong — maximize() belongs to driver.manage().window(), not navigate().
accept()
Wrong — accept() is on the Alert interface, not navigate().
navigate() offers to(url), back(), forward() and refresh(). It does not offer maximize() (that is on Window) or an alert() method.
To interact with elements inside an <iframe>, what must a test do first?
Switch into the frame using driver.switchTo().frame(...)
Correct — iframe contents are only reachable after switching into the frame.
Refresh the page to merge the iframe into the DOM
Wrong — refreshing does not merge frame contexts.
Set an implicit wait of at least 30 seconds
Wrong — waiting does not change the need to switch frame context.
Delete the iframe with JavaScript
Wrong — removing the frame destroys the very elements you want to use.
You must switch context into the frame with driver.switchTo().frame(...) before its elements are reachable, and switchTo().defaultContent() to return.
A test finds a list of rows, stores the first WebElement in a variable, then triggers an AJAX call that re-renders the whole table. When it later calls .click() on the stored element, Selenium throws StaleElementReferenceException. What is the correct explanation and fix?
The old reference points to a removed DOM node; re-locate the element after the re-render
Correct — that is exactly what a stale element means and how to resolve it.
The element was never found; catch NoSuchElementException instead
Wrong — the element was found originally; it became stale after re-render.
Add Thread.sleep(1000) before the click and reuse the same reference
Wrong — sleeping does not revive a stale reference; the node is gone.
Switch to the parent frame before clicking
Wrong — there is no frame involved; the issue is the stale node reference.
The stored reference points to a DOM node that was removed and re-created by the re-render, so it is stale. The fix is to re-locate the element after the DOM changes (ideally after an explicit wait), not to reuse the old reference.
Which practice most directly reduces flaky Selenium tests caused by timing issues?
Replacing fixed sleeps with explicit waits on precise conditions
Correct — condition-based waiting is the standard cure for timing flakiness.
Increasing every Thread.sleep to 30 seconds
Wrong — that makes tests slow and still fragile, not stable.
Running the whole suite only in headless mode
Wrong — headless mode does not address timing synchronisation.
Catching and ignoring all exceptions in the test
Wrong — swallowing exceptions hides failures rather than stabilising the test.
Replacing fixed sleeps with explicit waits on precise conditions synchronises the test with the application state, cutting timing-related flakiness.
Why is depending on hard-coded, environment-specific test data (e.g. a user that exists only on one server) a threat to test stability?
The test can fail in other environments where that data is absent or changed, unrelated to any real defect
Correct — environment-coupled data makes results non-portable and flaky.
Because Selenium cannot read test data at all
Wrong — Selenium tests can and do use data; the issue is coupling to one environment.
Because hard-coded data speeds up the tests too much
Wrong — speed is not the stability concern here.
Because it forces the use of XPath locators
Wrong — test data has no bearing on which locator strategy is used.
If the data is missing or changed in another environment, the test fails for reasons unrelated to the code under test. Stable tests set up or isolate their own data.
Selenium reports ElementClickInterceptedException when clicking a button. What does this typically indicate?
Another element is overlaying the target at the click point
Correct — that is the meaning of a click interception.
The element does not exist in the DOM
Wrong — that would be NoSuchElementException; here the element exists but is covered.
The browser driver version is incompatible
Wrong — driver mismatch produces different session errors, not click interception.
The page title is wrong
Wrong — the title is unrelated to click interception.
Another element (an overlay, sticky header, cookie banner, or spinner) is covering the target at the click point, so the click would land on the covering element. Wait for the overlay to disappear or scroll the target into a clear area.
Which of the following help make a Selenium test suite more independent and stable? (Choose two.)
Each test sets up and cleans up its own preconditions
Correct — self-contained tests do not inherit broken state from others.
Tests do not rely on being executed in a particular order
Correct — order-independence allows safe parallel and partial runs.
All tests share a single browser session that is never reset
Wrong — shared, un-reset state leaks between tests and causes flakiness.
Later tests depend on data created by earlier tests
Wrong — chained data dependencies make one failure cascade into many.
Making each test set up and tidy its own state, and avoiding order dependencies between tests, are core stability practices. Sharing one browser session across all tests and relying on execution order harm independence.
Why is an absolute XPath such as /html/body/div[3]/div[2]/form/button considered a stability risk?
Any change to the surrounding DOM structure breaks it, even if the target element is unchanged
Correct — absolute paths are brittle against layout changes.
Absolute XPath is not supported by modern browsers
Wrong — it is fully supported; the problem is fragility, not support.
It always matches multiple elements
Wrong — an absolute path usually matches one node; the issue is brittleness.
It cannot be used with findElement
Wrong — By.xpath works with findElement; the concern is maintainability.
Absolute XPaths encode the entire DOM path, so any structural change (an added wrapper div, reordered sections) breaks the locator even though the target element still exists. Prefer stable attribute-based locators.