Skip to content

Course: Authoring with AI — 3. Version history

Fourteen hands-on exercises on the History tab: every version of a test says who made it, why, and, for a self-healing fix, which run found it (Versions, Version provenance):

  • Module 1: one person’s saves, and the label each kind of save gets;
  • Module 2: two people on one Draft, and a member who changes their name;
  • Module 3: self-healing fixes, from a person and from a rule, and the run behind each;
  • Module 4: component versions and AI-written steps;
  • Module 5: the same history through the API.

Each exercise has:

  • Goal: what you will see;
  • Before you start: the preparation it needs;
  • Steps: Action, Expected result, and a box to tick;
  • What happened: the explanation;
  • Check yourself: a question to answer before moving on. The answers are at the end.

Allow about 1 hour, or 40 minutes without Module 5 and Exercise 12. Do the exercises in order: each one starts from what the one before left.

Open a test, then the History tab above the steps. Each version is one row:

v2 DRAFT [chip] Bob Builder Edited (time) found by a run of v1 audit trail
the version's note
▸ 3 changes by 2 authors
Part Says
The chip Who last wrote the version: a person icon for a member, a key for an API token, a purple wand for a self-healing rule (click it to open the rule)
The label What that write was: Imported, Edited, Tags changed, Status changed, New revision, Restored, Duplicated, Fix approved, Fixed automatically, Fix reverted…
The links Where it came from: the run that found a fix, the self-healing audit trail, the version it started from
N changes by M authors The version was written more than once. Click it for every write, oldest first

You need two accounts in the same project, each in its own browser window (one of them a private window):

Who Role Window
You Admin or Test Manager (to mark tests Ready and create rules) Window A
A colleague, called Bob below Test Developer Window B
  1. Test Cases → Import examples/test-provenance/login.json (or save this as a file and import it):

    { "dslVersion": "1.10.0", "name": "Login", "engine": "web",
    "defaults": { "timeoutMs": 8000, "retry": 0, "onError": "abort" },
    "steps": [{ "id": "open", "type": "browser.open", "params": { "url": "https://example.com" } }] }
  2. Test Cases → Import test-plans/heal-conflict-toolbar.json: a test called Toolbar that opens a small toolbar built into the test (no network needed) and clicks Save and Cancel. The toolbar comes in three releases, picked by the Open step’s URL: {{release1}}, {{release2}} or {{release3}}. Changing it is how the exercises “deploy” a new release whose buttons have changed.

The first edit you make in the editor takes the test’s edit lock, and saving does not let go of it: it lasts until you leave the editor, or 15 minutes after your last edit. While you hold it, your colleague is asked before saving, and a self-healing rule will not fix the test (Exercise 9 shows this). So when a step says “go back to Test Cases”, do.


Goal: a new test’s history says who brought it in, and how.

Before you start: P1, P2.

# Action Expected result ✓
1 Window A: open Login → History One row: v1, DRAFT, a chip with your name, Imported, the time
2 Look below the row No “changes by” line: the version has been written once

What happened: the import was recorded as the version’s first write. You did not type any of it: the server takes it from your session.

Check yourself: a colleague sends you an exported test made in another workspace. After you import it, whose name is on v1?

Goal: many saves in a row are one change, not a long list.

# Action Expected result ✓
1 Test steps → click the test name in the toolbar, rename it Login page, Ctrl+S Saved · v1
2 Rename it back to Login, Ctrl+S Saved · v1
3 History Still one row, v1, now Edited, and ▸ 2 changes by 1 author
4 Click 2 changes by 1 author Imported, then one Edited

What happened: a Draft is saved over the same version, so the version keeps a list of its writes. Saves in a row by the same person are kept as one change; its time moves to the latest save.

Check yourself: you save a Draft ten times over an afternoon. How many Edited lines does its list show?

Goal: writes that are not edits keep their own label.

# Action Expected result ✓
1 Open the right-hand Test panel. In Tags, type smoke, press Enter The chip @smoke
2 History v1: Tags changed, ▸ 3 changes by 1 author
3 Set Status to Ready, Save. History v1 is READY, Status changed, 4 changes by 1 author
4 Open the list Imported, Edited, Tags changed, Status changed

What happened: only editor saves are merged. A tag change and marking the test Ready are each a change of their own, even straight after an edit by the same person.

Check yourself: why is it useful that Status changed is never merged into Edited?

Goal: a version says what it started from.

# Action Expected result ✓
1 Click New revision. History A new top row: v2, DRAFT, New revision, and from v1
2 Click Duplicate in the toolbar, then open Login (copy) (it opens by itself, or find it in Test Cases) → History v1, Duplicated, and a link from another test’s v2
3 Click that link Login opens: the test it was copied from. Go back to Test Cases

What happened: a new revision and a copy both record the version they came from. A copy links back to the other test, so you can always find the original.

Check yourself: what does from v1 on v2 tell you that the version number alone does not?


Goal: the version keeps everyone who wrote it, and who started it.

# Action Expected result ✓
1 Window B (Bob): open Login (v2, Draft), rename it Login - Bob, Ctrl+S, go back to Test Cases Saved · v2
2 Window A: open Login - Bob → History v2: Bob’s chip, Edited, ▸ 2 changes by 2 authors
3 Open the list You — New revision — from v1, then Bob — Edited

What happened: the row shows the latest write (Bob’s), and the list keeps who opened the version first. A Draft several people worked on shows all of them.

Check yourself: the row says Bob. Who started v2, and how do you find out?

Goal: a save in between keeps two people’s work apart.

# Action Expected result ✓
1 Window A: rename it Login - me, Ctrl+S, go back to Test Cases Saved
2 Window B: open it, rename it Login, Ctrl+S, go back to Test Cases Saved
3 Window A: open Login → History → open the list 4 changes by 2 authors: New revision (you), Edited (Bob), Edited (you), Edited (Bob)

What happened: Bob’s two saves were not merged, because yours came in between. The list reads as the story of the Draft.

Check yourself: when would two saves by Bob be one change?

Goal: history shows people as they are called today.

# Action Expected result ✓
1 Window B: click Bob’s name at the bottom of the sidebar → User profile. Change the name to Robert Builder, Save profile The sidebar shows Robert Builder
2 Window A: reload Login → History Every write Bob made now shows Robert Builder
3 Window B: change the name back

What happened: a version stores who wrote it by their account, not by their name, and shows the name the account has now. Someone who has left the organization keeps the name they had, marked (removed).

Check yourself: why would storing only the name have been a problem?


Goal: a fix names the run that found it, and the run names what it led to.

# Action Expected result ✓
1 Window A: open Toolbar, Run test with No environment Passes: three green steps. The run records each button as last known good
2 Click the Open step, change its URL from {{release1}} to {{release2}}, Ctrl+S, Run test Passes, Click Save marked Healed; a purple banner 1 self-healing suggestion is waiting for review
3 Review → Approve on the Click Save card Toast Approved - saved as Test v1.
4 Open Toolbar → History v1: Fix approved, and the links found by a run of v1 and audit trail
5 Click found by a run of v1 The run report of step 2, with a purple line under the header: Led to Toolbar v1
6 Runs → open the run of step 1 No Led to line: that run changed nothing

What happened: the fix keeps a link to the run that found it, and the version that run executed. From the run, Led to goes the other way.

Check yourself: a test started failing after Tuesday. How do you find out whether a self-healing fix changed it, and from which run?

Exercise 9: A rule’s fix, and a rule that waits

Section titled “Exercise 9: A rule’s fix, and a rule that waits”

Goal: a rule’s fix is signed by the rule. A rule never fixes a test someone is editing.

# Action Expected result ✓
1 Self-healing → Rules → new rule Toolbar fixes. Applies to: Tests → Toolbar. When: tier Fallbacks and element matches (tier ≤ 1), minimum confidence 78, risk low and medium, Seen in at least (runs) 1. Action: Apply automatically. Mode: Active. Save The rule is listed, enabled
2 Open Toolbar, Run test (still release 2) Passes. The new Save button is now last known good
3 Change the Open step’s URL to {{release3}}, Ctrl+S, and Run test straight away Passes with Click Save and Click Cancel Healed. History shows no new version
4 Self-healing → Pending Both cards wait: Local User is editing this test, so the fix waits for review (your own name)
5 Go back to Test Cases. Open Toolbar again without editing anything, Run test Passes, both steps Healed
6 Reload → History A new v2, DRAFT: a purple wand chip Toolbar fixes v1, Fixed automatically, found by a run of v1, audit trail; ▸ 2 changes by 1 author
7 Click the wand chip The Rules page

What happened: in step 3 your Ctrl+S took the edit lock, and you were still in the editor when the run ended. A rule only vouches for the test as the run saw it, so it does not change a test under someone’s open editor. Once nobody was editing, the next run’s fixes went in. The rule’s fixes did not touch your Draft v1: a rule opens a version of its own, which you review and mark Ready.

The rule asks for 78% because a click is a medium-risk step: below that the run itself would not act on a healed element, so a rule may not either. With 70, the form refuses to save.

Check yourself: a rule leaves a fix Pending every night, saying someone is editing. What is the likely cause?

Goal: undoing a fix is recorded too, and no run is named for it.

# Action Expected result ✓
1 Self-healing → Approved → Revert on a Click Save card, confirm The card moves to Reverted
2 Toolbar → History A new version: your name, Fix reverted, audit trail, and no found by a run link

What happened: a revert is a person’s decision, not something a run found. It always saves a new version, so the fix and its undoing stay visible side by side.

Check yourself: why does a revert never rewrite the version the fix went into?


Exercise 11: Who published a component version

Section titled “Exercise 11: Who published a component version”

Goal: component versions say who published them.

# Action Expected result ✓
1 Components → New component: source test Login (copy), name Open example, Create component The component page. v1: 1 steps · [your chip] Published · (time)
2 Publish new version → Publish v2 v2: the same

What happened: a component version records its author like a test version does. A version a self-healing fix published inside a component says Component fix, with the rule or person who let it in.

Check yourself: a component’s v5 changed a locator nobody remembers changing. What does its line tell you?

Goal: a save that brings in AI-written steps says so.

Before you start: the server needs an Anthropic API key (see the AI step writer).

# Action Expected result ✓
1 Open Login (copy) → Write with AI: Open the application and check that the heading is "Example Domain". → Generate steps → add them → Ctrl+S Saved
2 History Edited · with AI-written steps
3 Rename the test Login (copy, AI), Ctrl+S, History → open the list The last change still says with AI-written steps

What happened: the save that first keeps AI-written steps is marked. Your save straight after is part of the same change, and the change keeps the mark.

Check yourself: can you tell, a month later, which versions were saved with AI-written steps before this feature existed?


Module 5: The same history through the API

Section titled “Module 5: The same history through the API”

Before you start: Window A, press F12 → Console, paste this once, and press Enter:

const P = localStorage.getItem('atx.project');
const api = (path, init = {}) => fetch('/api' + path, { ...init, headers: { 'content-type': 'application/json', 'x-project-id': P } })
.then(async (r) => ({ status: r.status, body: await r.json() }));

Take a test’s id from the address bar (#/tests/tc_…). Below, TOOLBAR stands for it.

Goal: filter versions by why they were written.

# Action Expected result ✓
1 (await api('/tests/TOOLBAR/versions?trigger=heal-auto')).body.map((v) => v.version) [2]: the version the rule wrote
2 (await api('/tests/TOOLBAR/versions?trigger=heal-approve,heal-auto')).body.map((v) => v.version) [2, 1]
3 await api('/tests/TOOLBAR/versions?trigger=saved') status: 422, listing the real triggers

What happened: each version’s writes carry a trigger. Every trigger, and the label the History tab shows for it, is in Version provenance.

Check yourself: which filter finds every version a self-healing rule wrote?

Goal: a run lists the versions its fixes went into.

# Action Expected result ✓
1 Open the run report from Exercise 8 step 5; copy the run id from under the test name
2 (await api('/runs/RUN_ID')).body.produced One entry: of: "test", name: "Toolbar", version: 1, trigger: "heal-approve"

What happened: this is the Led to line as data, for a pipeline or a report.

Check yourself: the run fixed a step inside a component. What would produced list?


  1. Yours: provenance is never imported. The version starts with your Imported write.
  2. One, if nobody else wrote the Draft in between.
  3. Marking a test Ready is an approval. You can always see who approved it and when, even after more edits.
  4. That v2 is a copy of v1’s content, not a fresh start, and which version it copied.
  5. You did: the first entry in the list is who opened the version.
  6. If nobody else saved in between, and both came the same way (both from the browser, say).
  7. A renamed person would appear as a stranger in old versions, and two people with the same name could not be told apart.
  8. History: a Fix approved or Fixed automatically version, its found by a run link and its time.
  9. Someone has the test open in the editor (or edited it in the last 15 minutes) when the runs end. They should leave the editor.
  10. History is never rewritten. You can see the fix and its undoing as two steps.
  11. Who published it, and whether it was a person’s publish or a self-healing fix.
  12. No. The mark is only written at the moment of saving; earlier saves cannot be told apart.
  13. ?trigger=heal-auto.
  14. The component’s new version (of: "component") and the source test the fix was carried into.