skip to content

In Selenium, what does a WebElement object hold, and why is it not a copy of the DOM node?

level: juniorimportance: should knowfreq 60%

answer

  1. A reference, not the element
  2. Nothing about the node travels back
  3. An id plus the session that made it
  4. Each read is a separate command
  5. The browser is asked every time

basics

~20 s

A WebElement holds an opaque id the driver assigned to a node plus the session that issued it. No markup, text or attributes come with it, so every method call asks the browser again over the wire.

solid answer

~40 s

A `WebElement` is a remote reference, not the element. The Java client's `RemoteWebElement` stores two things: the opaque id the driver returned under the `element-6066-11e4-a52e-4f735466cecf` key, and the driver session that issued it. Nothing about the node travels with it - no HTML, no text, no attributes, no locator. That is why every call on it is another command: reading a label, checking whether the approve button is enabled and clicking it are three separate round trips to the driver, which resolves the id against its own node map each time. The upside is that every read is genuinely fresh; the cost is that element access is network access, not memory access.

code

java · 17 lines
java
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class ApprovalButtonReads {
    public static void main(String[] args) {
        ChromeDriver driver = new ChromeDriver();
        try {
            driver.get("https://payroll.internal/approvals");
            WebElement approve = driver.findElement(By.id("approve-timesheet-4821"));
            System.out.println(approve.getText());
            System.out.println(approve.isEnabled());
        } finally {
            driver.quit();
        }
    }
}

go deeper

for a junior

Be ready to say a WebElement is a handle to something the browser holds, not the element itself, and that using it always means talking to the browser.

for a middle

Explain the contents precisely - an opaque driver-issued id plus its session - and why that forces one command per method call.

for a senior

Show the operational consequence: element access is network cost, so a loop over a large queue is measured in commands, and reads are always fresh rather than snapshots.

for a principal

Own the guidance that keeps a suite fast and honest here, deciding where per-element chatter is acceptable and where a page's state should be gathered differently.

## What findElement actually gives you Calling `driver.findElement(By.id("approve-timesheet-4821"))` on a payroll approval queue returns a `WebElement`. It is natural to picture that object as the button itself, pulled out of the page and into your test process. It is not. A `WebElement` is a **remote reference**: the Java client's `RemoteWebElement` holds an **opaque id string** that the driver assigned to that DOM node, plus a pointer to the driver session that issued it. That is the whole contents. The id arrives from the driver under one fixed protocol key, `element-6066-11e4-a52e-4f735466cecf`, and it means something only to the driver that minted it. ## What the object does not hold - **No markup.** The element's HTML never crossed the wire when the find returned. - **No text snapshot.** The label on the approve button is not stored anywhere in the object. - **No attributes.** Nothing about `class`, `disabled` or `data-timesheet` came back with the reference. - **No live pointer.** The object cannot observe the page; it is a value in a different process from the browser. - **No locator.** The reference does not remember the `By` that found it, so nothing in it can be re-run. ## Every call is another round trip Because the object holds only an id, each method on it is a fresh command sent to the driver, which asks the browser again. A three-line block that reads a label, checks whether the button is enabled and clicks it is three separate commands, on top of the one that found the element in the first place. 1. `findElement` sends a find command; the driver answers with a reference. 2. Each subsequent call sends the stored id back and waits for the driver's answer. 3. The driver resolves the id to a node and performs the operation in the live page. 4. The result - text, a boolean, or just success - travels back to the test. | The `WebElement` in your test | The node in the browser | |---|---| | an id string plus its session | a real DOM node in a live document | | never changes on its own | changes whenever the page changes | | costs a network call to consult | is what the driver acts on | | meaningless outside its session | exists independently of any test | ## Why the round trips are the mental model that matters Two consequences fall straight out of this, and both come up in interviews as the follow-up to "what is a `WebElement`". The first is **freshness**. Reading the same element twice gives you two genuinely fresh answers, because both reads went to the browser. Nothing is cached for you, so a value that changed between the two calls will differ - which is usually what you want, and occasionally a surprise if you assumed the object froze the state at find time. The second is **cost**. A loop that walks every row of a large payroll approval queue and reads three values from each is issuing three commands per row. On a local driver that is cheap; against a remote driver it is three network hops per row. This is the reason experienced authors read what they need in as few commands as they can, rather than treating element access as free memory access. ## Where beginners go wrong on the payroll queue - Storing the approve button in a field at the top of the test, approving a timesheet, and expecting the same reference to still work after the queue re-renders. The reference is an id, and the node it named may be gone. - Assuming a reference obtained on one page will be usable after loading a different payroll page in the same tab. Nothing about the object carries over. - Believing that two `WebElement` variables holding different ids must be different buttons, or that a reference can be built by hand from an element's HTML `id` attribute. The protocol id and the page's `id` attribute are unrelated. - Serialising a `WebElement` to reuse in the next run. The id is meaningful only inside the session that produced it, and that session is gone. The one-sentence version to have ready: a `WebElement` is a claim ticket for a node the browser is holding, not the node itself, and every use of the ticket is a question asked over the wire.

  • How many commands does finding an element and reading two of its values cost?
    Three. The find is one command that returns the reference, and each read is another command carrying that id back to the driver. Nothing is batched or cached client-side, so the count scales linearly with how many times the test touches the element.
  • Does holding a WebElement in a variable for longer save the browser any work?
    No. The object stores only an id, so every use still costs a command regardless of how long you have held it. Holding it longer only widens the window in which the node behind the id can leave the document and make the reference unusable.
  • If the button's label changes, does an already-held WebElement see the new text?
    Yes, because the read goes to the browser at the moment you call it rather than replaying something captured at find time. The reference points at a node, and the node's current state is what the driver reports - provided that node is still attached to the active document.

saying these in an interview costs you the question

  • Thinks WebElement caches the node's text
  • Expects the object to update itself live
  • Assumes reading twice costs one round trip
  • Believes the object contains the element's HTML
  • Thinks the object works without its session