skip to content

Record and Replay Scripts

The record-and-playback browser extension, its .side project files, the command-line runner and code export - plus the honest case that a recording is a starting point, not a suite.

on this pageshow

explore

questions

4

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
open as a page

A Selenium IDE recording replays green against a solar-panel yield report - what must be added before it is a regression test?

level: middleimportance: should knowfreq 58%

basics

~20 s

Assertions, because a recording only replays actions and never checks results. Then conditional waitFor commands in place of pause, steadier locators than the recorder's positional XPath fallbacks, variables in place of recorded literals, and a defined starting state.

open as a page

When you export a Selenium IDE recording to JUnit code and then edit it, what have you given up?

level: seniorimportance: should knowfreq 42%

basics

~10 s

The recording, in practice. Export is one-way with no import back into the .side project, so the first hand edit makes the two artefacts diverge and re-recording silently overwrites your work.

open as a page

What does the selenium-side-runner command line let you do with a .side project that Selenium IDE cannot?

level: middleimportance: nice to knowfreq 34%

basics

~20 s

It runs a recorded .side project without the browser extension, from a script or pipeline, choosing the browser and target environment by flag, running tests in parallel or on a remote Grid, and exiting non-zero when one fails.

open as a page