skip to content

What does Selenium IDE record into a .side project file as you click through a page?

level: juniorimportance: should knowfreq 52%

answer

  1. It is data, not generated source code
  2. One row per interaction you performed
  3. Three columns in the editor table
  4. Locators carry a strategy prefix
  5. The project saves as JSON

basics

~10 s

Selenium IDE writes each interaction as a row of three fields - command, target and value - into a JSON project file with a .side extension, grouped into named tests and suites.

solid answer

~40 s

Selenium IDE is a Chrome and Firefox extension that watches your clicks, typing and navigation and appends one step per interaction. Every step is a triple: a `command` such as `open`, `click`, `type`, `select` or `assertText`; a `target`, which for element commands is a locator written with a strategy prefix like `id=site-picker`, `css=.total-kwh` or `xpath=//h1`; and a `value` for commands that take an argument, such as the text `type` sends. Each command also stores a `targets` array of alternative locators the recorder computed for the same element, which the Target dropdown lets you swap in. All of it saves as one JSON document with a `.side` extension holding the project `id`, `version`, base `url`, a `tests` array of command lists and a `suites` array grouping test ids.

code

json · 33 lines
json
{
  "id": "9c1f0d3a-4b21-4d0e-9d5a-6b7c8e9f0a1b",
  "version": "2.0",
  "name": "solar-yield-report",
  "url": "https://reports.example.com",
  "tests": [
    {
      "id": "b2e4d6f8-1234-4a5b-8c9d-0e1f2a3b4c5d",
      "name": "August yield total for the north array",
      "commands": [
        { "id": "c1", "comment": "", "command": "open", "target": "/reports/yield", "targets": [], "value": "" },
        { "id": "c2", "comment": "", "command": "setWindowSize", "target": "1280x900", "targets": [], "value": "" },
        { "id": "c3", "comment": "", "command": "select", "target": "id=site-picker", "targets": [], "value": "label=North Array" },
        { "id": "c4", "comment": "", "command": "type", "target": "id=month", "targets": [], "value": "2026-08" },
        { "id": "c5", "comment": "", "command": "click", "target": "id=run-report", "targets": [["id=run-report", "id"], ["css=#run-report", "css:finder"], ["xpath=//button[@id='run-report']", "xpath:attributes"]], "value": "" },
        { "id": "c6", "comment": "", "command": "waitForElementVisible", "target": "css=.total-kwh", "targets": [], "value": "10000" },
        { "id": "c7", "comment": "", "command": "assertText", "target": "css=.total-kwh", "targets": [], "value": "1842 kWh" }
      ]
    }
  ],
  "suites": [
    {
      "id": "f0a1b2c3-5678-4d9e-8f01-2a3b4c5d6e7f",
      "name": "Default Suite",
      "persistSession": false,
      "parallel": false,
      "timeout": 300,
      "tests": ["b2e4d6f8-1234-4a5b-8c9d-0e1f2a3b4c5d"]
    }
  ],
  "urls": ["https://reports.example.com"],
  "plugins": []
}

go deeper

for a junior

Be ready to name the three columns of a recorded step and say what each holds, and to state that the project saves as JSON with a .side extension rather than as generated code.

for a middle

Explain how a locator strategy prefix such as id=, css= or xpath= is encoded in the target field, and what the targets array of alternative locators is for during playback and editing.

for a senior

Show that you know what recording leaves out - no assertions, no deliberate waits, no data abstraction - and that the JSON shape is what makes a recorded project reviewable in version control.

for a principal

Be able to argue where a recording format with a fixed command set belongs in a team's tooling at all, and what a low-code artefact costs once it has to be maintained beside real code.

## What Selenium IDE is and what it produces **Selenium IDE** is a browser extension for Chrome and Firefox that watches what you do in a page and writes it down. It is not a WebDriver client library: there is no compiler, no test framework and no source file. What it produces is a **project file** carrying a `.side` extension - plain JSON that the extension reads back and that the `selenium-side-runner` command line can execute later without the extension installed at all. You give the project a base URL - for the solar-panel yield report, the dashboard the operations team opens each morning - and press record. Every interaction appends one row to a table. ## The three columns of a recorded step Each row is a triple, and every step carries all three fields even when one is blank: - **`command`** - the verb. `open`, `click`, `type`, `select`, `sendKeys`, `mouseOver`, `setWindowSize`, `assertText`, `waitForElementVisible`, `store`, `echo`. - **`target`** - what the command acts on. For an element command this is a **locator written with a strategy prefix**: `id=site-picker`, `name=month`, `css=.total-kwh`, `xpath=//table[@id='yield']/tbody/tr[3]`, `linkText=Download CSV`. For `open` it is a path resolved against the project base URL; for `setWindowSize` it is a size such as `1280x900`. - **`value`** - the argument, when the command takes one. `type` puts the typed text there, `select` puts `label=North Array` there, `store` puts the variable name there, a `waitFor` command puts its timeout in milliseconds there, `assertText` puts the expected text there. `click` leaves it empty. | Recorded action | `command` | `target` | `value` | |---|---|---|---| | Land on the report | `open` | `/reports/yield` | | | Pick an array | `select` | `id=site-picker` | `label=North Array` | | Enter the month | `type` | `id=month` | `2026-08` | | Run the report | `click` | `id=run-report` | | | Check the total | `assertText` | `css=.total-kwh` | `1842 kWh` | ## The alternative locators the recorder keeps Beside `target`, each command object carries a **`targets`** array: every locator the recorder managed to compute for that same element, each paired with the strategy that produced it - `id`, `name`, `css:finder`, `xpath:idRelative`, `xpath:attributes` and, as a last resort, `xpath:position`. Playback uses the primary `target` only; the `targets` list is what the IDE's Target dropdown offers so you can swap one in by hand. A step whose alternatives are all `xpath:position` entries is the recorder telling you the element had nothing distinctive to grab, and that the step is anchored to where the node sits in the tree. ## What the file actually holds A `.side` document is one JSON object: ```json { "id": "0f0d6e0a-...", "version": "2.0", "name": "solar-yield-report", "url": "https://reports.example.com", "tests": [ { "id": "...", "name": "...", "commands": [ ] } ], "suites": [ { "id": "...", "name": "Default Suite", "tests": [ ] } ], "urls": [ ], "plugins": [ ] } ``` - `url` is the **base URL**, which is why an `open` target can be a relative path. - `tests` is an array of named command lists - one recording each. - `suites` groups tests **by generated id**, not by name, and carries the flags a run reads, including `persistSession`, `parallel` and `timeout`. - Every test and every command has its own generated `id`; that is how a suite, and the `run` command, point at a test. Because the whole thing is JSON, a `.side` file diffs and merges in version control like any other text file, and reordering steps in the IDE shows up as reordered array elements rather than an opaque binary change. ## What recording does not put in the file 1. **No expectations.** Clicks, typing and navigation are captured for you; `assertText`, `verifyTitle` and the rest appear only if you add them - from the right-click menu on the page while recording, or by editing rows afterwards. 2. **No deliberate waiting.** `waitForElementVisible` and `pause` are commands you insert; the recorder does not infer that you paused because a chart was still drawing. 3. **No data abstraction.** The month you typed sits as a literal in `value` until you replace it with `${month}` and set that variable with `store`. ## The vocabulary above what a recorder can see The command list stays editable, and Selenium IDE's command set is much larger than the subset a recorder can observe. `store`, `storeText` and `storeValue` create variables you then reference as `${name}`; `if`, `else if`, `else`, `end`, `while`, `times` and `forEach` give the flat list control flow; `run` calls another test in the same project; `executeScript` drops to JavaScript and can put its return value into a variable. Recording produces the starting rows. The `.side` file is where you turn those rows into something worth replaying.

  • Why does an `open` step's target often look like a relative path rather than a full URL?
    Because the project stores a base `url` at its top level, and `open` resolves its target against it. Recording against the yield report dashboard stores the host once, so a step reads `/reports/yield`. That indirection is what lets the same project run against another environment later without editing any row.
  • What is in the `targets` array beside each command's primary target?
    The alternative locators the recorder computed for the same element, each labelled with the strategy that produced it - `id`, `name`, `css:finder`, `xpath:idRelative`, `xpath:attributes`, `xpath:position`. Playback uses the primary `target`; the array is what the Target dropdown offers so you can swap a fragile positional XPath for something steadier by hand.
  • How does a suite in a .side project reference the tests it runs?
    By generated id, not by name. Every test and every command gets its own id, and a suite's `tests` member is an array of those test ids. Renaming a test therefore does not break the suite, and the same is true of the `run` command, which calls another test in the project by id.

saying these in an interview costs you the question

  • Thinks Selenium IDE generates Java source while you record
  • Believes assertions are captured automatically during recording
  • Cannot say what the value column is for
  • Calls a .side file a binary or proprietary format
  • Confuses the target locator with the command verb