trxa-tool 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/MANUAL.md +376 -368
  2. package/README.md +75 -51
  3. package/SETUP.md +401 -0
  4. package/STUDIO.md +417 -309
  5. package/dist/fixture-schema.d.ts +45 -5
  6. package/dist/fixture-schema.js +97 -13
  7. package/dist/fixture-store.d.ts +37 -0
  8. package/dist/fixture-store.js +75 -0
  9. package/dist/index.js +76 -40
  10. package/dist/mapping.js +4 -1
  11. package/dist/mcp-bridge.d.ts +52 -0
  12. package/dist/mcp-bridge.js +290 -0
  13. package/dist/planrun-schema.d.ts +14 -6
  14. package/dist/planrun-schema.js +31 -7
  15. package/dist/planrun.d.ts +1 -1
  16. package/dist/planrun.js +2 -2
  17. package/dist/report-schema.d.ts +10 -1
  18. package/dist/report-schema.js +31 -5
  19. package/dist/report.d.ts +4 -1
  20. package/dist/report.js +9 -2
  21. package/dist/suite-runner.js +8 -2
  22. package/media/studio/fixtures-test-cases.png +0 -0
  23. package/media/studio/plans-editor.png +0 -0
  24. package/media/studio/recordings-create-test-case.png +0 -0
  25. package/media/studio/run-dialog.png +0 -0
  26. package/media/studio/settings-agent-runs.png +0 -0
  27. package/media/studio/settings-working-folder.png +0 -0
  28. package/media/studio/studio-recordings.png +0 -0
  29. package/media/studio/suites-canvas.png +0 -0
  30. package/media/studio/suites-inspector.png +0 -0
  31. package/media/studio/testcases-expectations.png +0 -0
  32. package/media/studio/testcases-outputs.png +0 -0
  33. package/media/studio/testrun-details.png +0 -0
  34. package/media/studio/testruns-list.png +0 -0
  35. package/package.json +6 -2
  36. package/studio/client-dist/assets/CreatePanel-C5bb5OIs.js +6 -0
  37. package/studio/client-dist/assets/FactTile-G1pURLys.js +1 -0
  38. package/studio/client-dist/assets/FieldLabel-DPmIEQ08.js +1 -0
  39. package/studio/client-dist/assets/FixtureNamePicker-137AAgwZ.js +1 -0
  40. package/studio/client-dist/assets/Fixtures-D0t-soph.js +1 -0
  41. package/studio/client-dist/assets/GeneralSection-CWkTeSX2.js +1 -0
  42. package/studio/client-dist/assets/ListPaneHeader-DXKqX36N.js +1 -0
  43. package/studio/client-dist/assets/Plans-C70evkGc.js +1 -0
  44. package/studio/client-dist/assets/Recordings-BT0dyVLs.js +1 -0
  45. package/studio/client-dist/assets/Settings-k-J3u5lH.js +1 -0
  46. package/studio/client-dist/assets/Suites-DLioOiRN.css +1 -0
  47. package/studio/client-dist/assets/Suites-DQhhMxjT.js +7 -0
  48. package/studio/client-dist/assets/TestCases-BdiopVGI.js +1 -0
  49. package/studio/client-dist/assets/TestRuns-CylAe-3t.js +9 -0
  50. package/studio/client-dist/assets/api-DJZ703_F.js +24 -0
  51. package/studio/client-dist/assets/bucket-18-viuwGcaj.js +1 -0
  52. package/studio/client-dist/assets/fixtureName-CTZT_jKu.js +1 -0
  53. package/studio/client-dist/assets/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2 +0 -0
  54. package/studio/client-dist/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff +0 -0
  55. package/studio/client-dist/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff +0 -0
  56. package/studio/client-dist/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2 +0 -0
  57. package/studio/client-dist/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  58. package/studio/client-dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  59. package/studio/client-dist/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2 +0 -0
  60. package/studio/client-dist/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff +0 -0
  61. package/studio/client-dist/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2 +0 -0
  62. package/studio/client-dist/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff +0 -0
  63. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-300-normal-LoaTnByX.woff +0 -0
  64. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-300-normal-RhT0Ayi3.woff2 +0 -0
  65. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-400-italic-Bf1n82Tb.woff +0 -0
  66. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-400-italic-D9J6q4_O.woff2 +0 -0
  67. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-400-normal-BTotfTJu.woff +0 -0
  68. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-400-normal-DZqxrq2p.woff2 +0 -0
  69. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-600-normal-71GNu3SW.woff2 +0 -0
  70. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-600-normal-BGq0mW3O.woff +0 -0
  71. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-ext-300-normal-Bbd5v1xK.woff +0 -0
  72. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-ext-300-normal-DqmgDkIN.woff2 +0 -0
  73. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-ext-400-italic-BELOEI8R.woff2 +0 -0
  74. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-ext-400-italic-CfSXsIbO.woff +0 -0
  75. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-ext-400-normal-Dsrv2Tcn.woff +0 -0
  76. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-ext-400-normal-g30qAdWV.woff2 +0 -0
  77. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-ext-600-normal-Bz0x94Yp.woff +0 -0
  78. package/studio/client-dist/assets/ibm-plex-sans-cyrillic-ext-600-normal-DUMzJB7m.woff2 +0 -0
  79. package/studio/client-dist/assets/ibm-plex-sans-greek-300-normal-J-CBqZoJ.woff2 +0 -0
  80. package/studio/client-dist/assets/ibm-plex-sans-greek-300-normal-STc8XiDr.woff +0 -0
  81. package/studio/client-dist/assets/ibm-plex-sans-greek-400-italic-BEZwmy7D.woff2 +0 -0
  82. package/studio/client-dist/assets/ibm-plex-sans-greek-400-italic-CTYLy0lX.woff +0 -0
  83. package/studio/client-dist/assets/ibm-plex-sans-greek-400-normal-D9ESIMu3.woff +0 -0
  84. package/studio/client-dist/assets/ibm-plex-sans-greek-400-normal-_efipK4i.woff2 +0 -0
  85. package/studio/client-dist/assets/ibm-plex-sans-greek-600-normal-D-CqTdkO.woff +0 -0
  86. package/studio/client-dist/assets/ibm-plex-sans-greek-600-normal-DzTrcv_p.woff2 +0 -0
  87. package/studio/client-dist/assets/ibm-plex-sans-latin-300-normal-C9Of02-5.woff +0 -0
  88. package/studio/client-dist/assets/ibm-plex-sans-latin-300-normal-b4i7YzLG.woff2 +0 -0
  89. package/studio/client-dist/assets/ibm-plex-sans-latin-400-italic-CZTNEAuW.woff2 +0 -0
  90. package/studio/client-dist/assets/ibm-plex-sans-latin-400-italic-CsGl1sm0.woff +0 -0
  91. package/studio/client-dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  92. package/studio/client-dist/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  93. package/studio/client-dist/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  94. package/studio/client-dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  95. package/studio/client-dist/assets/ibm-plex-sans-latin-ext-300-normal-B8Zgwjh3.woff +0 -0
  96. package/studio/client-dist/assets/ibm-plex-sans-latin-ext-300-normal-BLFuR0P1.woff2 +0 -0
  97. package/studio/client-dist/assets/ibm-plex-sans-latin-ext-400-italic-Du9zzoL2.woff2 +0 -0
  98. package/studio/client-dist/assets/ibm-plex-sans-latin-ext-400-italic-V_9i1P_m.woff +0 -0
  99. package/studio/client-dist/assets/ibm-plex-sans-latin-ext-400-normal-C5H60-Va.woff2 +0 -0
  100. package/studio/client-dist/assets/ibm-plex-sans-latin-ext-400-normal-RBey6euL.woff +0 -0
  101. package/studio/client-dist/assets/ibm-plex-sans-latin-ext-600-normal-DIrixKbi.woff +0 -0
  102. package/studio/client-dist/assets/ibm-plex-sans-latin-ext-600-normal-DOrvGEcy.woff2 +0 -0
  103. package/studio/client-dist/assets/ibm-plex-sans-vietnamese-300-normal-CkYRZD2a.woff +0 -0
  104. package/studio/client-dist/assets/ibm-plex-sans-vietnamese-300-normal-SDfX6ktj.woff2 +0 -0
  105. package/studio/client-dist/assets/ibm-plex-sans-vietnamese-400-italic-78jqtfZH.woff +0 -0
  106. package/studio/client-dist/assets/ibm-plex-sans-vietnamese-400-italic-BbRnwouv.woff2 +0 -0
  107. package/studio/client-dist/assets/ibm-plex-sans-vietnamese-400-normal-DG4YqDda.woff2 +0 -0
  108. package/studio/client-dist/assets/ibm-plex-sans-vietnamese-400-normal-fK1oJ5dG.woff +0 -0
  109. package/studio/client-dist/assets/ibm-plex-sans-vietnamese-600-normal-DgdngZtN.woff +0 -0
  110. package/studio/client-dist/assets/ibm-plex-sans-vietnamese-600-normal-DpPYBSTl.woff2 +0 -0
  111. package/studio/client-dist/assets/index-cxBc2iRv.js +10 -0
  112. package/studio/client-dist/assets/index-wjWuVHXN.css +1 -0
  113. package/studio/client-dist/assets/status-DUGxC7G7.js +1 -0
  114. package/studio/client-dist/assets/testCaseTree-Cl1-bc5O.js +1 -0
  115. package/studio/client-dist/axtr-icon.svg +2 -5
  116. package/studio/client-dist/favicon.svg +2 -5
  117. package/studio/client-dist/index.html +5 -4
  118. package/studio/server/dist/index.js +1530 -292
  119. package/studio/client-dist/assets/index-CgWhGkEn.js +0 -24
  120. package/studio/client-dist/assets/index-CwAUMVCL.css +0 -1
package/STUDIO.md CHANGED
@@ -1,319 +1,427 @@
1
- # TRXA-TOOL Studio manual
1
+ # Use TRXA Studio
2
2
 
3
- Studio is a local browser UI for the same pipeline [MANUAL.md](MANUAL.md) walks through via the
4
- CLI: parsing a `.axtr` recording, drafting inputs, editing a Test Case's `outputs[]`/
5
- `expectations[]`, managing Fixtures, building Suites (including their dependency DAG and
6
- conditional-skip gates) and Plans, and reviewing Test Runs -- without hand-editing JSON. It runs
7
- the same code the CLI does, so anything Studio writes is exactly as valid as anything the CLI
8
- writes, and vice versa -- switch between them freely on the same files.
3
+ TRXA Studio is the visual workspace for TRXA-TOOL. Use it to turn Dynamics 365 Finance and Supply
4
+ Chain Management Task Recorder recordings into automated tests, organize the tests into suites and
5
+ plans, run them with an AI agent, and review the results. You don't need to edit any files by hand.
9
6
 
10
- ---
7
+ Studio is available as a Windows app and as a browser page that the npm package starts. Both work
8
+ the same way. This article applies to both, except where a section says otherwise.
11
9
 
12
- ## 1. Starting Studio
10
+ In this article, you learn how to:
13
11
 
14
- ```sh
15
- trxa studio # starts the server + client in the background, opens your browser
16
- trxa studio stop # shuts down the whole process tree (not just the top-level process)
17
- ```
12
+ - Start Studio and choose a working folder
13
+ - Create a test case from a recording
14
+ - Define what a test captures and checks
15
+ - Manage test data with fixtures
16
+ - Build suites and plans
17
+ - Run a test with an AI agent
18
+ - Review test runs
18
19
 
19
- Running `studio` again while it's already up just reopens the browser instead of starting a
20
- second instance -- PID/log tracking lives in `~/.trxa-tool/studio-run/` (a per-user location, independent of
21
- where the tool is installed).
20
+ ## Prerequisites
22
21
 
23
- **Which project does it open?** Studio's data (`recordings/`, `testcases/`, `suites/`, etc.) lives
24
- under a *working folder* -- a real, persisted setting, not just "wherever you happened to run the
25
- command from." The first time Studio ever starts on a machine, it defaults to and remembers
26
- whatever directory `trxa studio` was run from; after that, it's whatever you last set it to.
27
- Change it anytime from the **Settings** tab (gear icon, top right) -- the switch takes effect
28
- immediately, no restart needed. Install location, working folder, and "wherever you happen to be
29
- running the command from" are three different things, and only the working folder setting decides
30
- which project's files Studio reads and writes.
22
+ - TRXA-TOOL installed, either the Windows app or the npm package. For instructions, see
23
+ [Step 1: Install TRXA-TOOL](SETUP.md#step-1-install-trxa-tool).
24
+ - One or more Task Recorder recordings (`.axtr` files). Record them in Dynamics 365 with Task
25
+ recorder, or export them from a Business Process Modeler library in Lifecycle Services.
26
+ - To run tests with an AI agent: an agent and a connection to Dynamics 365. Complete every step in
27
+ [Set up TRXA Studio for agent runs](SETUP.md).
31
28
 
32
- Studio binds to `127.0.0.1` only and opens at `http://localhost:5173`. **Never expose it on a
33
- network** -- it does unauthenticated filesystem writes by design (same trust model as the CLI:
34
- whoever can run it can write anywhere under the working folder's `testcases/`, `testdata/`,
35
- `testscripts/` directories).
29
+ ## Key concepts
36
30
 
37
- ## 2. The six tabs, at a glance
31
+ Studio works with seven kinds of records. Each one builds on the one before it.
38
32
 
39
- | Tab | Purpose |
33
+ | Record | What it is | Folder |
34
+ |---|---|---|
35
+ | **Recording** | A Task Recorder file (`.axtr`) that captures the steps someone performed in Dynamics 365. | `recordings` |
36
+ | **Test script** | The recording's steps, translated into actions that an agent can perform. Studio creates it for you. | `testscripts` |
37
+ | **Test case** | One business scenario that passes or fails, such as "Create purchase order". It defines the test's inputs, the values to capture (outputs) and the checks to make (expectations). | `testcases` |
38
+ | **Fixture** | A named set of test data, such as one company or one scenario. It holds input values for many test cases. | `testdata` |
39
+ | **Suite** | Test cases that run together, in an order you define. A suite also says where each test case gets its input values. | `suites` |
40
+ | **Plan** | A group of suites that run and report together, such as every suite for Accounts payable. | `plans` |
41
+ | **Test run** | The result of running a test case, a suite or a plan. | `testruns`, `runs` |
42
+
43
+ All records are files in Studio's *working folder*, so you can keep them in source control and use
44
+ them with the `trxa` command line too. For the file formats, see the [TRXA-TOOL manual](MANUAL.md).
45
+
46
+ ## Start Studio
47
+
48
+ ### Start the Windows app
49
+
50
+ - If you used the installer, open **TRXA Studio** from the **Start** menu.
51
+ - If you use the portable version, run `TRXA Studio.exe` from the folder where you extracted it.
52
+
53
+ The app opens in its own window. The first time, its working folder is `Documents\TRXA Studio`.
54
+
55
+ ### Start Studio in your browser
56
+
57
+ 1. Open a terminal in the folder that holds, or will hold, your recordings and tests.
58
+ 1. Run:
59
+
60
+ ```powershell
61
+ trxa studio
62
+ ```
63
+
64
+ Studio starts in the background and opens `http://127.0.0.1:4321` in your browser. If Studio is
65
+ already running, the command opens the browser page again instead of starting a second copy.
66
+
67
+ 1. To stop Studio, run:
68
+
69
+ ```powershell
70
+ trxa studio stop
71
+ ```
72
+
73
+ The first time Studio starts on a computer, the folder you ran `trxa studio` from becomes the
74
+ working folder. After that, Studio opens the working folder you last chose.
75
+
76
+ > [!WARNING]
77
+ > Studio accepts connections only from your own computer, and it reads and writes files without
78
+ > asking you to sign in. Don't make it reachable from a network.
79
+
80
+ ### Choose the working folder
81
+
82
+ The working folder is where Studio reads and writes all your records. To change it:
83
+
84
+ 1. Select **Settings** (the gear icon in the upper-right corner).
85
+ 1. In **Folder path**, enter the full path of the folder you want.
86
+ 1. Select **Save**.
87
+
88
+ Studio switches to the new folder right away, without a restart.
89
+
90
+ ![The Settings page, with the Working folder and Appearance sections.](media/studio/settings-working-folder.png)
91
+
92
+ On the same page, **Appearance** sets the theme: **Dark**, **Light**, or **Match the operating
93
+ system**.
94
+
95
+ ## Find your way around Studio
96
+
97
+ The rail on the left side opens each page:
98
+
99
+ | Page | Use it to |
100
+ |---|---|
101
+ | **Recordings** | Review a recording's steps and create a test case and fixture from it. |
102
+ | **Test Cases** | Edit a test case's outputs and expectations, and see which fixtures hold its data. |
103
+ | **Fixtures** | Create and edit sets of test data. |
104
+ | **Suites** | Arrange test cases in run order and connect their data. |
105
+ | **Plans** | Group suites, and see a combined result for each run. |
106
+ | **Test Runs** | Review the results of every run. |
107
+
108
+ The buttons in the upper-right corner are, from left to right:
109
+
110
+ - **Run activity**: shows the runs in progress and the most recent runs.
111
+ - **Export library**: downloads all your records as one zip file, for a backup or to move them to
112
+ another computer.
113
+ - **Import library**: restores records from such a zip file.
114
+ - **Settings**: the working folder, the theme, and agent readiness.
115
+
116
+ Most pages share one layout: a searchable list on the left and the selected record on the right.
117
+ Each record opens with a **General** section that holds its name and description. Changes aren't
118
+ saved until you select **Save**, or press **Ctrl+S**. If you try to leave a page with unsaved
119
+ changes, Studio asks you first.
120
+
121
+ The address bar always reflects the page and record you have open. You can bookmark a record,
122
+ refresh the page, or use the browser's **Back** button, and Studio returns to the same place.
123
+
124
+ ## Create a test case from a recording
125
+
126
+ Studio creates a test case, its test script and its first fixture values from a recording in one
127
+ step.
128
+
129
+ 1. Copy your `.axtr` files into the working folder's `recordings` folder. You can use subfolders,
130
+ for example one per business area.
131
+ 1. Select **Recordings**, and then select a recording in the list.
132
+
133
+ Studio reads the recording and shows its steps. For each step, the **Tool** column shows the
134
+ action that the agent will use to replay it, and **Confidence** shows how sure Studio is about
135
+ that action.
136
+
137
+ ![The Recordings page, with the steps of a recording and the Suggest inputs button.](media/studio/studio-recordings.png)
138
+
139
+ 1. Select **Suggest inputs**. Studio finds the values that were typed or selected in the recording.
140
+ These become the test case's *inputs*, the values that can change from one run to the next.
141
+ 1. Select **Create test case & fixture**.
142
+ 1. In the panel that opens, enter or check these values:
143
+
144
+ | Field | Description |
145
+ |---|---|
146
+ | **Test case ID** | A short, unique ID, such as `create-purchase-order`. Studio uses it as the file name. |
147
+ | **Test case name** | A readable name. Studio fills it in from the recording. |
148
+ | **Description** | Optional. |
149
+ | **Fixture name** | Select an existing fixture to add this test case's values to, or enter a new name to create a fixture. |
150
+ | *One field per input* | The value to use for each input in this fixture. Studio fills them in from the recording. |
151
+
152
+ ![The Create test case and fixture panel, with the test case fields and the input values.](media/studio/recordings-create-test-case.png)
153
+
154
+ 1. Select **Create**.
155
+
156
+ Studio creates the test case and a notification links to it.
157
+
158
+ > [!WARNING]
159
+ > Input values come straight from the recording. If the recording was made with real business
160
+ > data, such as real vendor accounts or amounts, replace those values before you share or commit
161
+ > the fixture.
162
+
163
+ ## Define what a test case captures and checks
164
+
165
+ A test case passes only if its *expectations* hold. It can also capture *outputs*, values that a
166
+ later test case in a suite needs, such as the number of a new purchase order.
167
+
168
+ Select **Test Cases**, and then select a test case. The page shows how many inputs, outputs,
169
+ expectations and steps it has, and four tabs:
170
+
171
+ - **Inputs** lists the test case's inputs. To use an input's value in a filter or an expected
172
+ value, type its name in double braces, for example `{{vendorAccount}}`. Inputs come from the
173
+ recording, so you change them on the **Recordings** page.
174
+ - **Outputs** and **Expectations** are described in the following sections.
175
+ - **Fixtures** lists the fixtures that hold values for this test case.
176
+
177
+ ### Add an output
178
+
179
+ 1. Select the **Outputs** tab, and then select **Add output**.
180
+ 1. In **Output name**, enter a name. A suite refers to the output by this name.
181
+ 1. Select an **Output kind**:
182
+ - **OData** reads the value from a data entity. Enter the **Entity set**, a **Filter** that finds
183
+ the record, and the **Field** to read. Use this kind when the record has a reliable business
184
+ key to filter on.
185
+ - **Form field** reads the value from the form after a step. Select the step in **After step**.
186
+ Then select the control in **Control name**, or, if you don't know the control name, describe
187
+ the value in **Hint**, for example "The new purchase order number shown after clicking New".
188
+ During a run, the agent finds the control and fills in its name for later runs.
189
+ 1. Select **Save**.
190
+
191
+ ![The Outputs tab of a test case, with a Form field output that reads the purchase order number.](media/studio/testcases-outputs.png)
192
+
193
+ ### Add an expectation
194
+
195
+ 1. Select the **Expectations** tab, and then select **Add expectation**.
196
+ 1. In **Description**, describe the check. The description appears in the test results.
197
+ 1. Select the step in **Check after step**.
198
+ 1. Select an **Expectation kind**:
199
+ - **OData** queries a data entity and compares a field with a value. Enter the **Entity set**,
200
+ **Filter**, **Expected field**, **Comparator** and **Expected value**.
201
+ - **Message** checks the messages that Dynamics 365 showed. Select a **Severity**, and
202
+ optionally enter text in **Message contains**. Leave it empty to match any message of that
203
+ severity.
204
+ 1. Select **Save**.
205
+
206
+ ![The Expectations tab of a test case, with a check that no error message appeared.](media/studio/testcases-expectations.png)
207
+
208
+ > [!TIP]
209
+ > To check that *no* error appeared, select **Severity** > **Error** and clear **Message should
210
+ > appear**. If you select **Message should appear**, the test passes only when an error *does*
211
+ > appear.
212
+
213
+ To delete a test case, select **Delete**. Studio deletes only the test case. Its test script stays,
214
+ because other test cases can share it, and any suite or fixture that refers to the test case keeps
215
+ the reference until you remove it.
216
+
217
+ ## Manage test data with fixtures
218
+
219
+ A fixture is a named set of test data, such as one company or one scenario. It holds the input
220
+ values for every test case it covers. To run the same tests with different data, create another
221
+ fixture and choose it in the suite.
222
+
223
+ ### Create a fixture
224
+
225
+ 1. Select **Fixtures**, and then select **New fixture** (the plus icon above the list).
226
+ 1. Enter a **Name** and, optionally, a **Description**. Suites refer to the fixture by its name.
227
+ 1. Select **Create**. The new fixture opens.
228
+
229
+ ### Add test cases and values
230
+
231
+ 1. Select a fixture. The **Test cases** table lists each test case that the fixture holds values
232
+ for, with how many values are set and a status, such as **Complete**.
233
+ 1. To add test cases, select **Add test cases**, select one or more test cases, and then select
234
+ **Add**.
235
+ 1. To edit a test case's values, expand its row, and then enter the values. Required values are
236
+ checked when you leave each field.
237
+ 1. Select **Save**. Studio opens any row that still has a required value missing.
238
+
239
+ ![A fixture with two test cases, one expanded to show its input values.](media/studio/fixtures-test-cases.png)
240
+
241
+ Other actions:
242
+
243
+ - **Remove from fixture** (the minus icon on a row) removes that test case's values. Studio names
244
+ any suite that uses them.
245
+ - **Duplicate** copies the saved fixture, with all its test cases and values, under a new name.
246
+ - Renaming a fixture in **General** also updates every suite that uses it.
247
+ - **Delete** deletes the fixture. Studio names the suites that use it before you confirm.
248
+
249
+ > [!NOTE]
250
+ > Fixtures created by TRXA-TOOL 0.1 stored one test case per file. Studio shows those files as
251
+ > **(old format)** and opens them read-only. Select **Merge fixture files** to convert them. Studio
252
+ > makes no changes if two old files hold values for the same test case under the same fixture name.
253
+
254
+ ## Build a suite
255
+
256
+ A suite runs test cases in order and passes data between them. For example, a purchase order suite
257
+ can create an order, then confirm, receive and invoice that same order.
258
+
259
+ ### Create a suite
260
+
261
+ 1. Select **Suites**, and then select **New suite** (the plus icon above the list).
262
+ 1. Enter these values, and then select **Create**:
263
+
264
+ | Field | Description |
265
+ |---|---|
266
+ | **File name** | The suite's file name, such as `purchase-order-lifecycle`. |
267
+ | **Suite ID** | The ID that plans use to refer to the suite. |
268
+ | **Name** | A readable name. |
269
+ | **Description** | Optional. |
270
+
271
+ ### Arrange test cases
272
+
273
+ The suite's canvas shows each test case as a box. Arrows show the order: a test case runs only
274
+ after every test case it depends on has passed.
275
+
276
+ 1. In **Add a test case**, select a test case to add it to the canvas.
277
+ 1. To make one test case depend on another, drag from the bottom handle of the first box to the top
278
+ handle of the box that should run after it.
279
+ 1. To remove a dependency, select its arrow, and then press **Delete** or **Backspace**.
280
+ 1. Select **Save**.
281
+
282
+ You can drag the boxes to arrange them. The layout is saved only in your browser. To return to the
283
+ automatic layout, select **Reset layout**.
284
+
285
+ ![A suite canvas with four test cases connected in order.](media/studio/suites-canvas.png)
286
+
287
+ ### Set up a test case in the suite
288
+
289
+ Point to a box and select its **Edit** icon to open its settings. To remove the test case from the
290
+ suite, select the **×** icon or **Remove from suite**.
291
+
292
+ | Setting | Description |
293
+ |---|---|
294
+ | **Legal entity** | Optional. The company to open the test case in. Leave it empty to stay in the current company. |
295
+ | **Depends on** | The test cases that must pass first. Select **×** on one to remove that dependency. |
296
+ | **Run condition** | Optional. In **Only run if**, select a dependency, one of its outputs, a comparator and a value. If the condition isn't met, the test case is *skipped*, which is neither a pass nor a failure. Test cases that depend on a skipped test case are *blocked*. |
297
+ | **Input bindings** | Where each input gets its value. See the following table. |
298
+
299
+ For each input, select a **Source**:
300
+
301
+ | Source | The value comes from |
302
+ |---|---|
303
+ | **Unbound** | Nowhere yet. A required input must be bound before the suite can run. |
304
+ | **Fixture value** | A fixture that holds values for this test case. |
305
+ | **Output of an upstream test case** | An output of a test case that runs earlier in the suite, such as the new purchase order number. |
306
+ | **Literal value** | A value that you type into the suite. Use it for constants, not for business data. |
307
+ | **Autogenerated** | The agent, which invents a value during the run. Use it for values that only need to be unique, such as a new vendor account. |
308
+
309
+ ![The settings panel for a test case in a suite, with its dependency, run condition and input bindings.](media/studio/suites-inspector.png)
310
+
311
+ Select **Done** to close the panel, and then select **Save**. Studio checks the suite when you
312
+ save, for example for test cases that depend on each other in a loop.
313
+
314
+ ## Group suites into a plan
315
+
316
+ A plan groups suites that you run and report on together. The suites in a plan don't share data
317
+ or depend on each other. If two suites need to share data, combine them into one suite.
318
+
319
+ 1. Select **Plans**, and then select **New plan** (the plus icon above the list).
320
+ 1. Enter a **File name**, **Plan ID**, **Name** and, optionally, a **Description**, and then select
321
+ **Create**.
322
+ 1. Select **Add suites**, select the suites to include, and then select **Add**.
323
+ 1. Use the up and down arrows to set the run order, and the minus icon to remove a suite.
324
+ 1. Select **Save**.
325
+
326
+ Under **Rollup status**, select a run in **Run** to see each suite's status and an **Overall**
327
+ result. A suite is *missing* if it hasn't run yet in that plan run, *incomplete* while it's
328
+ running, *failed* if any test case failed or was blocked, and *passed* otherwise. The **Overall**
329
+ result shows the worst status of any suite.
330
+
331
+ ![A plan with two suites in run order, and the rollup status of a completed run.](media/studio/plans-editor.png)
332
+
333
+ ## Run a test with an AI agent
334
+
335
+ Test cases, suites and plans each have a **Run** button. It hands the item to an AI agent, which
336
+ replays it in Dynamics 365 through the MCP connection you set up.
337
+
338
+ Before you begin, complete [Set up TRXA Studio for agent runs](SETUP.md). If an item isn't ready,
339
+ the **Run** button is unavailable and an **Agent not ready** link opens **Settings**.
340
+
341
+ 1. Open the test case, suite or plan, and then select **Run**.
342
+ 1. In the dialog, enter these values:
343
+
344
+ | Field | Description |
345
+ |---|---|
346
+ | **Run name** | How you find the run later. Studio starts with the item's name. Add what makes this run different, such as the update you're testing. |
347
+ | **Agent** | **GitHub Copilot** or **Claude Code**. Only agents that are ready can run. |
348
+ | **Expected environment** | The environment you expect the agent to be connected to, such as `contoso-sandbox`. |
349
+ | **Expected company** | The company you expect, such as `USMF`. |
350
+ | **How far to run** | **Navigation only** opens forms and reads values. Nothing is saved, posted, created or deleted. **Full run** performs every step, including saving and posting. |
351
+
352
+ ![The Run suite with AI agent dialog.](media/studio/run-dialog.png)
353
+
354
+ 1. Select **Start navigation run** or **Start full run**.
355
+
356
+ Before it does anything else, the agent checks that it's connected to the environment and company
357
+ you entered. If they don't match, it stops and reports why. The agent runs unattended and never
358
+ asks questions.
359
+
360
+ > [!WARNING]
361
+ > A full run creates, saves and posts real records in the connected environment. Selecting
362
+ > **Start full run** is your confirmation. Use a test or sandbox environment.
363
+
364
+ While the run is in progress:
365
+
366
+ - Studio opens the run's page in **Test Runs**, which updates as the agent works. To cancel the run,
367
+ select **Stop run**.
368
+ - You can go to other pages. **Run activity**, in the upper-right corner, shows a progress bar for
369
+ the run.
370
+ - When the run ends, a notification shows the result, with a **View run** link.
371
+
372
+ Only one agent run can be in progress at a time. During a run, the agent can't write files outside
373
+ the working folder or run shell commands other than `trxa`. Studio saves each run's transcript in
374
+ the working folder's `agent-runs` folder. It isn't sent anywhere except to the agent you chose.
375
+
376
+ ## Review test runs
377
+
378
+ Select **Test Runs** to see every run: the test cases, suites and plans run from Studio, by an agent
379
+ in a terminal, or with the `trxa` command line.
380
+
381
+ ![The Test Runs table, with a passed and a failed plan run.](media/studio/testruns-list.png)
382
+
383
+ Each run is one row. A plan run includes its suites, and a suite run includes its test cases. Runs
384
+ in progress stay at the top. Use the search box and the **Type**, **Status**, **Started** and **Run
385
+ by** filters to find a run (an **Environment** filter appears once runs record one), and select a column heading to sort by it.
386
+
387
+ Select a run's name to open its page. The page shows the run's status, who ran it and how long it
388
+ took, a progress bar, and a summary of the results.
389
+
390
+ - For a plan run, expand a suite to see its test cases.
391
+ - Expand a test case to see its **Inputs**, captured **Outputs**, the **Assertions** that were
392
+ checked (each with the value the agent observed), and the **Infolog** messages Dynamics 365 showed.
393
+ - Turn on **Show failures only** to hide the test cases that passed.
394
+
395
+ ![A plan run's page, with one suite expanded to show its four test cases.](media/studio/testrun-details.png)
396
+
397
+ For a run started by an agent from Studio, the **Agent activity** tab shows what the agent did,
398
+ the reason if the run failed or was interrupted, and how many actions the run's permissions
399
+ blocked. Select **Full log** to download the complete transcript.
400
+
401
+ To share results:
402
+
403
+ - **Copy run summary** copies the results as formatted text that you can paste into an email, a
404
+ chat or a work item.
405
+ - **Export run** downloads the results as **Markdown (.md)**, or prints them to **PDF**.
406
+ - **Rename** changes the run's name.
407
+
408
+ A run's results are a record of what happened, so you can't edit them. To get new results, run the
409
+ test again. **Delete run** deletes a plan run's record. To delete one suite's results, use
410
+ **Delete** on that suite.
411
+
412
+ ## Troubleshoot
413
+
414
+ | Problem | Solution |
40
415
  |---|---|
41
- | **Recordings** | Parse a `.axtr` file, draft inputs from it, and create a new Test Case + Fixture pair. |
42
- | **Test Cases** | Edit an existing Test Case's `outputs[]`/`expectations[]`, or delete it. |
43
- | **Fixtures** | Full CRUD on `testdata/*.json` Fixtures -- concrete input values for a Test Case. |
44
- | **Suites** | A drag-and-drop dependency-graph canvas for `suites/*.json` -- `dependsOn`, `inputBindings`, and conditional-skip (`runIf`) gates. |
45
- | **Plans** | Compose a `plans/*.json` from existing suites, with reorderable run order and a rollup-status viewer. |
46
- | **Test Runs** | Plan-first, read-only viewer: pick a Plan's run (a real `runs/*.json` PlanRun record), see its suites' rollup, drill into one for per-test-case status, outputs, assertions, live auto-refresh while a run is in progress. |
47
-
48
- Every tab's search box, and the active tab + open record itself, round-trip through
49
- `location.hash` -- a refresh, a bookmarked link, or the browser's back/forward buttons all land
50
- back where you were instead of resetting to the Recordings tab. The header also carries **Export
51
- library**/**Import library** buttons that bundle or restore the whole `recordings/`/`testcases/`/
52
- `testdata/`/`testscripts/`/`suites/`/`plans/`/`testruns/` tree as one zip (same as the CLI's
53
- `export`/`import` commands) -- useful for backing up or moving an installation.
54
-
55
- Not here yet: creating a Test Case's `inputs[]`/`bindTo` after the fact -- that stays on the
56
- Recordings page's flow below.
57
-
58
- ## 3. Recordings: parse a `.axtr` file and draft a Test Case + Fixture
59
-
60
- The left pane lists every `.axtr` file under `recordings/`, grouped into a folder tree matching
61
- their layout on disk (search flattens it to a filtered list with full paths, since matches from
62
- different folders no longer need visual grouping once you're searching). Click one to parse it.
63
-
64
- Once parsed, you'll see the recording's name, step count, and required-privilege count, followed
65
- by a step table: sequence, description, form, node type, and the suggested replay hint for that step
66
- (the tool it'd call during replay, a confidence badge, and a note when the mapping needed one).
67
- Steps with no hint show an "unmapped" badge -- rare, but worth reporting if you see one.
68
-
69
- Click **Suggest Inputs** to draft candidate inputs from the recording (same output as
70
- `trxa suggest-inputs`). Each candidate traces back to either a recorded value
71
- (`PropertyUserAction`) or a low-confidence grid-selection step, and renders as an editable row
72
- directly under the step it came from -- required candidates are marked with a red `*`. Edit the
73
- values here before creating the Test Case; whatever you type becomes that draft input's initial
74
- value in the Fixture you create alongside it.
75
-
76
- **Caution:** candidate values are copied verbatim from the recording -- if it was made against
77
- real business data rather than demo data, review/scrub these before creating anything you intend
78
- to commit. See MANUAL.md's "Data hygiene" section.
79
-
80
- Once you've reviewed the candidates, fill in the **Create Test Case & Fixture** form:
81
-
82
- - **Test case ID** -- written to `testcases/<id>.json` and `testscripts/<id>.testscript.json`.
83
- - **Test case name** -- pre-filled from the recording's own name; edit freely.
84
- - **Description** -- optional.
85
- - **Fixture name** -- type a new one or pick from the autocomplete of existing fixture names
86
- (e.g. `basic`). Written to `testdata/<id>.<name>.json`.
87
-
88
- **Create Test Case & Fixture** stays disabled until every required candidate has a value and all
89
- four fields above are filled. On success it writes all three files in one action; if the Test
90
- Case is created but the Fixture write fails for some reason, the error banner says so explicitly
91
- -- you can still create the Fixture separately from the Fixtures tab using the same Test Case ID.
92
-
93
- ## 4. Test Cases: edit outputs and expectations
94
-
95
- The left pane groups every `testcases/*.json` file into a folder tree matching its source
96
- recording's location under `recordings/` (an entry that fails to parse/validate shows "Invalid:
97
- <error>" instead of crashing the list; one created before this grouping existed, or from a
98
- top-level recording, falls into an "Ungrouped" bucket). Click one to load it, along with its
99
- underlying `testscript.json` (used to populate the step pickers below).
100
-
101
- If the Test Case has `inputs[]`, they're shown read-only at the top with a reminder of the
102
- `{{paramName}}` substitution syntax you can use in a filter/value below (e.g.
103
- `CustomerAccount eq '{{customerAccount}}'`) -- editing inputs themselves stays on the Recordings
104
- page's flow (§3).
105
-
106
- ### Outputs
107
-
108
- Each output captures a value after some step, for a later Test Case in a suite to consume (see
109
- `{ "kind": "testCaseOutput", ... }` bindings in MANUAL.md §7). The **name** field is free text --
110
- whatever you call it here is what a downstream Test Case's binding refers back to.
111
-
112
- Pick a **kind**:
113
-
114
- - **`odata`** -- query the entity via OData: `Entity set`, `Filter` (may use
115
- `{{paramName}}`), `Field` to read. Preferred when there's a solid, unique business key to
116
- filter by -- durable, works even after the session ends.
117
- - **`uiField` (form state)** -- read a value straight off the live form. Pick the step to read it
118
- **after**; then either:
119
- - **Control name** -- the exact AOT control name. Free at replay time (no extra query, the
120
- value is already in that step's own response) and exactly reproducible. Auto-suggested from
121
- the selected step when it acts on one control; otherwise pick from the autocomplete of every
122
- control name seen anywhere in this script, or type your own.
123
- - **Hint** (only used when Control name is blank) -- a plain-English description (e.g. "the
124
- newly assigned purchase order number shown after clicking New"), for values Task Recorder
125
- never captured because nobody clicked them -- typically an auto-assigned ID. The replaying
126
- LLM resolves this against live form state during a run and is expected to write the resolved
127
- control name back into this field for you, so it stays free/exact on every run after the
128
- first.
129
-
130
- ### Expectations
131
-
132
- Each expectation checks something must (or must not) hold after a step, for the Test Case to
133
- pass. Pick the step to check **after**, then a **kind**:
134
-
135
- - **`odata`** -- query an entity and compare `Expected field` against `Expected value` with a
136
- `Comparator` (`equals`/`notEquals`/`contains`/`greaterThan`/`lessThan`).
137
- - **`uiMessage`** -- check `FormState.Messages` for an entry of the given **Severity**
138
- (`Info`/`Warning`/`Error`) whose text contains **Pattern** as a plain substring, not a regex --
139
- leave it blank to match any message of that severity regardless of text.
140
-
141
- **Watch the `Should exist` checkbox carefully** -- it's easy to get backwards. If your
142
- expectation reads "no error appeared," you want `Severity: Error` with **`Should exist`
143
- unchecked**, not checked -- checking it asserts an Error-severity message *must* appear, the
144
- opposite of what "no error" usually means. (This exact mistake has shipped in a real test case before
145
- being caught during a live replay -- worth double-checking every time.)
146
-
147
- ### Saving and deleting
148
-
149
- **Save** writes the file back (validated server-side the same way the CLI's
150
- `validate-testcase` command would reject a malformed one) and confirms with a toast. **Delete**
151
- asks for confirmation, then removes only `testcases/<id>.json` -- not the `testscript.json` it
152
- points to, since that file isn't guaranteed unique to one Test Case (a suite's test cases can
153
- share a source recording), and not any Fixture/Suite that still references this Test Case's ID
154
- (those will start failing to resolve; clean them up separately).
155
-
156
- ## 5. Fixtures: manage test data
157
-
158
- The left pane groups every `testdata/*.json` file by the Test Case it belongs to (same
159
- "Invalid: ..." handling as Test Cases), so a scenario with several data variants (e.g. three
160
- vendors × three items) stays organized instead of one long flat list. **+ New fixture** switches
161
- the detail pane to create mode.
162
-
163
- For a **new** fixture: pick a **Filename slug** (written to `testdata/<slug>.json` -- convention
164
- is `<testCaseId>.<name>`, e.g. `create-purchase-order.basic`, but nothing enforces it), a **Test
165
- case** from the dropdown, and an optional **Label** -- a short free-text description (distinct
166
- from the filename-safe slug) shown in the fixture's list entry so multiple variants for the same
167
- Test Case stay distinguishable at a glance. Once you pick a Test Case, the **Values** section
168
- below renders one field per its `inputs[]` -- label, required marker, placeholder from the
169
- input's recorded `example`, and its description as a hint underneath.
170
-
171
- **The Test case a Fixture targets can't be changed after creation** -- the field is locked on an
172
- existing Fixture; delete and recreate it against a different Test Case instead. This is
173
- deliberate: a Fixture's Values shape is entirely derived from its Test Case's `inputs[]`, so
174
- repointing it would silently invalidate every value already entered.
175
-
176
- **Save**/**Delete** work the same as Test Cases (§4) -- Save confirms via toast, Delete asks for
177
- confirmation and removes only that one `testdata/*.json` file.
178
-
179
- ## 6. Suites: the dependency graph canvas
180
-
181
- The left pane lists every `suites/*.json` file. **+ New suite** switches the detail pane to
182
- create mode, asking for a **Filename slug** (written to `suites/<slug>.json`), a **Suite id** (the
183
- stable id a Plan references it by -- independent of the filename), and a **Name**.
184
-
185
- The main panel is a top-to-bottom flow canvas (`@xyflow/react`): one node per entry, arrows
186
- showing `dependsOn`. **Drag from a node's bottom handle to another node's top handle** to add a
187
- dependency; select an edge and press **Backspace or Delete** to remove one. Drag a node itself to
188
- reposition it -- positions are presentation-only (kept in your browser's `localStorage`, not
189
- written to the suite file), and a **Reset layout** button (shown once you've moved something)
190
- clears them back to the automatic layered layout. Use the toolbar's dropdown + **Add** to add an
191
- existing Test Case as a new entry.
192
-
193
- Click a node to open its inspector:
194
-
195
- - **Legal entity** -- passed as the company on this entry's Test Case's *first* navigation call
196
- only; leave blank to stay in whatever company the run is already in.
197
- - **Depends on** -- read-only list of what you've connected via the canvas.
198
- - **Run condition** -- an optional conditional-skip gate. Pick one of this entry's own
199
- dependencies from the **Only run if** dropdown (or "Always run" to clear the condition), then
200
- an **output** that dependency declares, a **comparator** (`equals`/`notEquals`/`contains`/
201
- `greaterThan`/`lessThan`), and an **expected value**. If the condition evaluates false at replay
202
- time, this entry is recorded `"skipped"` instead of running -- not a pass, not a failure. A
203
- downstream entry that depends on a skipped one is itself reported `"blocked"`, so nothing is
204
- ever left waiting forever. Only shown for entries that have at least one dependency, since a
205
- root entry has nothing to gate on.
206
- - **Input bindings** -- one row per the Test Case's declared `inputs[]`, with a five-way picker:
207
- **Unbound**, **Fixture** (pick one of the Test Case's fixtures, then a value key from it),
208
- **Output** (pick an upstream Test Case -- any transitive dependency, not just a direct one --
209
- and one of its declared outputs), **Literal** (type a value directly into the suite file), or
210
- **Auto** (Autogenerated -- no value here at all; the orchestrating LLM invents one at replay
211
- time using the input's own description/example as guidance, typically for a business key that
212
- just needs to be unique per run).
213
-
214
- **Save**/**Delete** work the same as other tabs -- Save validates server-side (including the same
215
- DAG cycle/unknown-id check `validate-suite` runs on the CLI), Delete asks for confirmation and
216
- removes only that one `suites/*.json` file.
217
-
218
- ## 7. Plans: group suites for combined reporting
219
-
220
- The left pane lists every `plans/*.json` file. **+ New plan** switches to create mode, asking for
221
- a **Filename slug**, **Plan id**, **Name**, and **Description**.
222
-
223
- The editor is a two-pane picker: **Available suites** (with its own search) on the left, each
224
- with a **+ Add** button; **In this plan (run order)** on the right, each entry with move-earlier/
225
- move-later/remove controls -- array order is the suggested run order, there's no dependency graph
226
- between suites (if two suites need to share data, they belong in one suite instead).
227
-
228
- Below the editor, a **rollup-status viewer** shows a combined pass/fail verdict across every suite
229
- in the plan for one PlanRun. **Start new run** creates a real, persisted `runs/<id>.json` record
230
- (`{id, planId, startedAt}`) with an auto-generated id; the **Run** dropdown lists every PlanRun
231
- that belongs to this plan, newest first, by its actual start time. Run
232
- each of the plan's suites (by hand or via the replay skill) using that PlanRun's id as the
233
- `<runId>` in `testruns/<suiteId>-<runId>.json`, exactly as the CLI's `init-plan-run` +
234
- `init-run` sequence expects (see MANUAL.md §8).
235
-
236
- For the selected run, each suite gets one of four statuses: **missing** (no
237
- `testruns/<suiteId>-<runId>.json` exists at all -- that suite hasn't been run yet under this
238
- PlanRun), **incomplete** (the file exists, but some test case in it hasn't reached a terminal
239
- status yet), **failed** (every test case reached a terminal status, and at least one is
240
- `failed`/`blocked`), or **passed** (every test case terminal, none failed or blocked). The plan's
241
- own **Overall** badge then picks the worst case across all its suites, in that same order: any
242
- suite `failed` → **has-failures**; else any `incomplete` → **incomplete**; else any `missing` →
243
- **missing-runs**; else → **all-passed**. This is the same logic the CLI's
244
- `plan-status` command uses -- a pure, read-only computation over
245
- already-existing Test Run files, safe to check as often as you like while suites are still
246
- running, since nothing beyond each suite's own Test Run is ever written.
247
-
248
- **Save**/**Delete** work the same as Suites.
249
-
250
- ## 8. Test Runs: view results
251
-
252
- The left pane groups by Plan, not by suite file: each Plan you've created is a header, and under
253
- it every PlanRun that belongs to it (see §7) is a clickable row showing when it started, newest
254
- first -- a search box filters by plan name. Selecting a run shows the plan-level rollup (the same
255
- Overall badge plus per-suite status/counts §7 describes), and clicking one of its suites drills
256
- into that suite's own detail below.
257
-
258
- That suite detail shows every test case in it: its status badge (`Passed`/`Failed`/`Blocked`/
259
- `Skipped`/`Running`/`Pending`), any captured `outputs[]` values, and every `expectations[]`
260
- assertion with a Pass/Fail badge and the `actual` value that was actually observed (an OData
261
- field, or the matched/missing UI message) -- the same evidence `replay-trxa-testplan` records
262
- when it calls `record-result`. A "failures only" toggle filters the per-test-case list down to
263
- just what needs attention. **While a run is still in progress, this view auto-refreshes itself
264
- every few seconds** -- no manual re-selecting needed to watch it happen live.
265
-
266
- If any test case reports `tokensUsed` and/or `costUsd` (see MANUAL.md §7.8's "Token/cost
267
- reporting"), a **Tokens**/**Cost** tile appears alongside the Passed/Failed/Blocked/Skipped/Total
268
- summary row, showing the sum across the whole run; the same figures also show per-test-case in
269
- each result's meta line. Older runs recorded before this existed simply don't show these tiles --
270
- there's no "$0.00" placeholder for a run that never reported either.
271
-
272
- **Copy summary** (top-right of an open suite) copies that suite's results to your clipboard as
273
- both Markdown (for pasting into chat) and rich HTML (for pasting into email/Word/Docs, with status
274
- colors and Infolog severity preserved). **Export** offers the same content as a downloadable
275
- `.md` file, or **PDF** via the browser's own print dialog. **Delete** (same row) removes that
276
- suite's Test Run file entirely after a confirmation prompt -- unlike deleting a Test Case/
277
- Fixture/Suite/Plan, a Test Run has no other file that references it by id, so this can't break
278
- anything else. The plan-level rollup view has its own **Delete run**, which only removes the
279
- `runs/<id>.json` PlanRun record itself -- the underlying suite Test Run files aren't touched, so
280
- deleting a PlanRun just un-groups suites that already ran, it doesn't erase their results.
281
-
282
- This tab is otherwise **read-only** -- there's no editing a run's contents, since it's a durable
283
- record of what a replay session actually did, not something to hand-edit. To produce a new one,
284
- start it from the Plans tab's rollup viewer (§7), then run each suite live per MANUAL.md §8's
285
- "Running a plan" procedure (itself the same per-suite `resolve-next`/`record-result` loop from
286
- §7.7, once per suite); this tab picks it up on its own (the list itself also polls periodically,
287
- so a run started from another session or the CLI appears without a manual refresh).
288
-
289
- ## 9. Cross-cutting UI notes
290
-
291
- - **Toasts**: every Save on an editable tab (Recordings/Test Cases/Fixtures/Suites/Plans) confirms
292
- with a small message that fades in at the top of the screen, holds briefly, then fades out on
293
- its own -- no need to dismiss it. Test Runs has nothing to save, so it never shows one.
294
- - **Error banners**: validation failures (missing required fields, a malformed filter, a suite DAG
295
- cycle, etc.) show as a banner at the top of the detail pane, not a toast -- toasts are for
296
- success, banners are for something you need to fix.
297
- - **List/detail split pane**: every tab shares the same layout -- a searchable/scrollable list on
298
- the left, the selected item's editor (or, for Test Runs, read-only view) on the right. Nothing
299
- you do in an editable tab's editor is saved until you click Save.
300
- - **URL/refresh persistence**: the active tab and whichever record you have open are reflected in
301
- the browser's address bar (`location.hash`), so refreshing the page, following a bookmarked
302
- link, or using back/forward all restore the same screen instead of resetting to Recordings.
303
-
304
- ## 10. Troubleshooting
305
-
306
- - **Port 5173 (or 4321) already in use**: something else is already running there -- check
307
- `~/.trxa-tool/studio-run/` for a stale PID, or run `trxa studio stop` first. If neither
308
- clears it, something outside Studio's own tracking is holding the port; find and stop it
309
- manually (Task Manager on Windows, `lsof -i :5173` on macOS/Linux).
310
- - **A recording/Test Case/Fixture/Suite/Plan doesn't show up**: those lists load once, when you
311
- open the tab -- refresh if you added a file outside Studio (e.g. via the CLI or by hand) while
312
- it was open. Test Runs is the exception: both its list and an open run poll periodically on
313
- their own, so a run started elsewhere (another session, the CLI) appears without a manual
314
- refresh.
315
- - **"Invalid: ..." in a list**: that file failed schema validation -- the error message is the
316
- same one `validate-testcase`/`validate-fixture`/`validate-suite`/`validate-plan` would give you
317
- on the CLI. Fix it by hand or via the CLI; Studio can't open an invalid file for editing.
318
- - **Can't delete a dependency connection on the Suites canvas**: click the connection to select
319
- it, then press **Backspace or Delete**.
416
+ | `trxa studio` reports that the port is in use | Run `trxa studio stop`, and then start Studio again. If the port is still in use, another program is using port 4321. To use a different port, set the `STUDIO_SERVER_PORT` environment variable before you start Studio. |
417
+ | A record you added outside Studio doesn't appear | Lists load when you open a page. Refresh the page. **Test Runs** refreshes on its own every few seconds. |
418
+ | A list shows **Invalid** for a file | The file doesn't match the expected format, and Studio can't open it. The message describes the problem. Fix the file in a text editor, or check it with the matching `trxa validate-...` command. |
419
+ | The **Run** button is unavailable | An item in **Settings** > **Agent runs** isn't ready. See [Troubleshoot](SETUP.md#troubleshoot) in the setup article. |
420
+ | A run fails right away with a sign-in or connection message | Sign in to the agent again (`copilot login`, or run `claude`), and check the MCP connection. See [Step 5](SETUP.md#step-5-connect-the-agent-to-dynamics-365). |
421
+ | A run shows as failed with the reason **interrupted** | Studio was closed or restarted while the run was in progress. Run the test again. |
422
+
423
+ ## Related content
424
+
425
+ - [Set up TRXA Studio for agent runs](SETUP.md)
426
+ - [TRXA-TOOL manual](MANUAL.md): file formats and the `trxa` command line
427
+ - [Use Model Context Protocol for finance and operations apps](https://learn.microsoft.com/dynamics365/fin-ops-core/dev-itpro/copilot/copilot-mcp)