Chapter 26Lesson 05~245 minutes

Checkpoint Lab — Selenium IDE, Record/Playback, and Migration to Maintainable Code

Complete the chapter by producing both a disposable Selenium IDE learning artifact and a maintainable WebDriver test, proving the migration with a controlled markup break and an auditable evidence packet.

CheckpointMigration rationaleEvidence packetCI readinessCleanup

Learning objectives

  • Record and inspect one local IDE flow without real credentials or production targets.
  • Predict and verify a controlled locator failure caused by v1→v2 markup.
  • Repair the learning artifact and migrate to maintainable Python WebDriver.
  • Compare IDE and WebDriver responsibilities using observable evidence.
  • Clean all disposable state and define what artifact is retained.

1. Checkpoint contract and preflight

Use only http://127.0.0.1:8826. Required baseline: Python 3.10+, selenium==4.47.0 for the migrated test, a supported local Chromium-family browser, Selenium Manager, and the currently installed Selenium IDE build. Grid is not required. Paid browser clouds and enterprise identity are outside the mandatory path.

Preflight checks:

  1. verify /health reports v1/v2;
  2. record the IDE build and Selenium/browser versions separately;
  3. confirm the target is loopback and contains only synthetic data;
  4. create a disposable working/evidence directory;
  5. confirm no personal browser profile is selected.

2. Predict before execution

Write at least these predictions before touching v2:

  • DOM: the Save button generated-looking ID will change between v1 and v2 while data-testid=save-profile remains;
  • recording: a copy using id=save-profile-427 will fail at the click on v2;
  • browser/session: the migrated test will create a fresh WebDriver session/profile and dispose it afterward;
  • evidence: the first failed locator and repaired selector will be preserved as different records rather than overwritten.

3. Execute: record, inspect, and retain one learning artifact

Start the fixture, record the v1 flow, stop recording immediately, and inspect all commands. Save the project only inside the disposable checkpoint workspace. Do not commit it yet.

Create a small review table with each command, target, value sensitivity, state changed/read, and whether the target is approved for migration. If your IDE picked a stable locator, create a copy of the learning test that uses id=save-profile-427 so the failure injection remains deterministic.

{
  "id": "academy-ide-migration",
  "version": "2.0",
  "name": "IDE Migration Learning Artifact",
  "url": "http://127.0.0.1:8826",
  "tests": [{
    "id": "profile-flow",
    "name": "save profile v1",
    "commands": [
      {"command": "open", "target": "/v1", "value": ""},
      {"command": "type", "target": "id=display-name", "value": "Ada"},
      {"command": "click", "target": "id=save-profile-427", "value": ""},
      {"command": "wait for element visible", "target": "css=[data-testid='status']", "value": "3000"},
      {"command": "assert text", "target": "css=[data-testid='status']", "value": "saved:Ada"}
    ]
  }],
  "suites": [],
  "urls": ["http://127.0.0.1:8826/v1"]
}

4. Break and diagnose v2

Point the copied learning flow at /v2. Capture the first failure before changing anything. Confirm the DOM contains the stable data-testid selector and does not contain the old ID. Classify this as a locator/test defect, not a browser, Grid, synchronization, or AUT business failure.

Repair the copied IDE target to css=[data-testid='save-profile'] and replay only the smallest scenario. Do not add pause commands.

5. Migrate and verify independently

Create the maintainable WebDriver test from the scenario intent—not by copying every recorded command. Use the same architecture as Lesson 2:

import unittest
from pathlib import Path
import tempfile, shutil
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

BASE_URL = "http://127.0.0.1:8826"

class ProfilePage:
    NAME = (By.CSS_SELECTOR, "[data-testid='display-name']")
    SAVE = (By.CSS_SELECTOR, "[data-testid='save-profile']")
    STATUS = (By.CSS_SELECTOR, "[data-testid='status']")

    def __init__(self, driver):
        self.driver = driver

    def open(self, variant="v2"):
        self.driver.get(f"{BASE_URL}/{variant}")
        WebDriverWait(self.driver, 3).until(
            lambda d: d.find_element(*self.STATUS).text == "idle"
        )
        return self

    def save_name(self, name):
        field = self.driver.find_element(*self.NAME)
        field.clear(); field.send_keys(name)
        self.driver.find_element(*self.SAVE).click()
        WebDriverWait(self.driver, 3).until(
            lambda d: d.find_element(*self.STATUS).text.startswith(("saved:", "error:"))
        )

    def status(self):
        return self.driver.find_element(*self.STATUS).text

class ProfileFlowTest(unittest.TestCase):
    def setUp(self):
        self.profile = Path(tempfile.mkdtemp(prefix="ide-migration-"))
        options = webdriver.ChromeOptions()
        options.add_argument("--headless=new")
        options.add_argument(f"--user-data-dir={self.profile}")
        self.driver = webdriver.Chrome(options=options)

    def tearDown(self):
        try:
            self.driver.quit()
        finally:
            shutil.rmtree(self.profile, ignore_errors=True)

    def test_save_profile(self):
        page = ProfilePage(self.driver).open("v2")
        page.save_name("Ada")
        self.assertEqual("saved:Ada", page.status())

if __name__ == "__main__":
    unittest.main()

Run it against v2. Record the Selenium version, returned browser/version, session ID, URL, final status, test-runner result, and cleanup outcome. If the run fails, capture first-failure evidence before quit().

6. Compare the two artifacts

The following table organizes the key choices and evidence for Compare the two artifacts. Use it together with the surrounding prose so the rows serve as a comparison aid rather than standalone rules.

Concern IDE learning artifact Maintainable WebDriver test
Locator Recorder-selected then curated manually. Stable selector lives near page service and is code-reviewed.
Synchronization IDE wait command depends on current command/build capability. Explicit state wait expresses the condition the assertion needs.
Fixture Interactive IDE/browser project context. Test fixture owns driver/profile and cleanup.
Assertion Recorded assertion command. Test owns business assertion and failure meaning.
Diagnostics Interactive playback/logs. Unique first-failure evidence plus session/version/URL state.
Data/config Literal synthetic learning values. Configuration/data can be parameterized and secret-injected by framework/CI.
CI readiness Not the production gate. Runnable by the project’s provider-neutral test command/headless or Grid path.

7. Evidence packet and migration rationale

Your checkpoint packet must contain:

  • IDE build/version and Selenium/browser versions;
  • sanitized command/target/value review;
  • the old generated-looking locator and new stable locator;
  • v1/v2 DOM evidence relevant to that selector;
  • first failed playback/translation evidence;
  • migrated test output, session ID, URL, final status, and optional failure screenshot;
  • cleanup result;
  • a short rationale explaining why the IDE artifact is learning material rather than the CI gate.

Do not include passwords, tokens, cookies, personal profiles, production URLs, or unrelated full page source.

8. Cleanup and retention

Stop the loopback fixture. Quit every WebDriver session. Delete temporary browser profiles, exported downloads, and scratch recordings. Retain only the sanitized learning artifact if it has educational value; otherwise retain the migration rationale and production WebDriver code. A recording must not become an unreviewed duplicate source of truth.

If a paid browser cloud or managed enterprise platform is later introduced, preserve the same boundary: IDE exploration is optional; authoritative execution, secrets, evidence, lifecycle, and gating belong to the maintained test/infrastructure stack.

9. What Chapter 26 adds to the operating model

The production browser-automation model now has a controlled intake path for recorded interactions. Teams can prototype quickly without normalizing recorder weaknesses: every recording is inspected, sensitive values are excluded, locator/wait semantics are reviewed, and durable intent migrates into the same abstraction, fixture, evidence, security, capacity, and CI disciplines built in earlier chapters.

Chapter 27 builds directly on this outcome by integrating Selenium with pytest, JUnit, TestNG, NUnit, and language bindings, making test-framework lifecycle and reporting choices explicit rather than inheriting them accidentally from an IDE exporter.

Knowledge checks

Answer from the operating model, then reveal the explanation.

Your recorder selected a stable data-testid. Must you manufacture a brittle production locator to prove the chapter?

The repaired IDE test passes v2. What still must be proved?

Which artifact should gate CI?

A recorder captured a real password accidentally. Can redaction make the project safe to keep?

Why bridge next to framework integration?

Summary and next bridge

  • Record only disposable, authorized flows and inspect the artifact before trusting it.
  • Use controlled markup change to distinguish locator brittleness from timing or product failure.
  • Migrate scenario intent into stable selectors, explicit waits, fixtures, assertions, and diagnostics.
  • Retain IDE artifacts only as sanitized learning/prototyping material.
  • Use maintained WebDriver/framework code as the CI-quality evidence source.

Chapter 27 moves from migration into explicit framework integration across pytest, JUnit, TestNG, NUnit, and Selenium language bindings.

Next chapter

Framework Integration: pytest, JUnit, TestNG, NUnit, and Language Bindings: Core Concepts and Mental Model

Continue with Framework Integration: pytest, JUnit, TestNG, NUnit, and Language Bindings: Core Concepts and Mental Model. It builds directly on the state, evidence, and operating assumptions established here, so carry those constraints forward rather than treating the next page as an isolated topic.

Primary references and version notes

Version baseline — August 2026

The WebDriver examples pin selenium==4.47.0 and Python 3.10+. Selenium Manager remains the normal local driver-resolution path. Selenium IDE is versioned separately: the SeleniumHQ repository currently marks v4.0.1-beta.14 as its latest GitHub release, published July 20, 2024. Official IDE Code Export documentation lists C# NUnit, Java JUnit, JavaScript Mocha, and Python pytest, but the mandatory course path still verifies the installed IDE build and migrates manually so recorded/exported code is never treated as authoritative architecture.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.