TM toolkit reference
Every event, action, dialog option, and UI component the TM toolkit gives a UI Script, with the identifier each surface takes in code.
TM is the one global object a UI Script talks to. Every function on this page is a method on it, and the autocomplete in the Script Content editor mirrors this reference. A script never touches React or Test Management internals. It registers callbacks with TM, and Test Management calls them at the right moment.
Functions fall into two groups. Events tell you that something happened. Actions change the form, open a dialog, or open a URL.
Surface identifiers
Every event that takes a surface takes it as a string. Use the exact identifier, not the label shown in settings:
| Surface in settings | Code identifier |
|---|---|
| Add Result | add_result |
| Update Result | Not documented |
| Test Case Results Section | test_case_results_toolbar |
| Test Case Form | test_case_form |
| Test Run Form | test_run_form |
| Test Plan Form | test_plan_form |
| Exploratory Session Form | exploratory_session_form |
Events
Register an event handler at the top level of your script. Test Management calls it when the matching event fires:
| Function | Trigger | Callback arguments |
|---|---|---|
TM.onFormLoad(surface, callback) |
A form on that surface opens | (formState, context) |
TM.onBeforeSave(surface, callback) |
A save on that surface is about to run | (formState, context) |
TM.onFieldChange(name, callback) |
The named field changes | (value, previousValue) |
TM.onButtonClick(label, callback) |
A button added with TM.addButton is clicked |
(context) |
TM.onAction(name, callback) |
A TM.ui.Button with a matching action is clicked |
(data, context) |
This reference names the first callback argument formState. Your callback can name it anything, and the snippets on these pages call it form.
TM.onBeforeSave is the only event that can stop a save. Return the result of TM.blockSave from its callback to block the save. Return nothing and the save proceeds. Calling TM.blockSave without return does nothing, and the save goes through silently. This is the most common mistake in a save rule, and the TM.blockSave section shows the right pattern.
TM.onFieldChange receives the new value first and the previous value second. Both arrive in the same shape the field uses on form, so a system dropdown arrives as an object and a text field arrives as a string. For the name to pass as the first argument, see Fields in UI Scripts.
Actions
Call an action from inside an event handler. Each one changes the form, opens a dialog, or opens a URL:
| Function | Effect |
|---|---|
TM.blockSave(message, fieldName) |
Stops the save and shows message. The optional fieldName puts the message under that field. |
TM.setFieldRequired(name, required) |
Marks a field required, or clears the requirement when required is false. |
TM.setFieldVisible(name, visible) |
Shows a field, or removes it from the form when visible is false. |
TM.setFieldReadOnly(name, readOnly) |
Locks a field against editing, or unlocks it when readOnly is false. |
TM.setFieldValue(name, value) |
Sets the value of a field. Pass the value in that fieldβs own shape. |
TM.constrainOptions(name, options) |
Restricts an option field to the labels listed in the options array. |
TM.addButton(surface, config) |
Adds a button to a surface. The label on config is both the visible text and the name you match in TM.onButtonClick. |
TM.openDialog(config) |
Opens a pop-up and returns a dialog ID. |
TM.closeDialog(data) |
Closes the open pop-up. |
TM.openUrl(url) |
Opens an http or https address in a new tab. |
Three constraints apply across the field actions:
- A field you mark required can no longer be hidden or made read-only.
-
TM.setFieldValuetakes the value in the fieldβs own shape. A custom dropdown takes an option object shaped as{ value, label }. On the run, plan, and session forms, a text or boolean field takes its value directly, and a structured field renders the value only when the shape matches. -
TM.openUrlopenshttpandhttpsaddresses only. It ignores every other scheme, includingjavascript:.
TM.blockSave and where its message appears
TM.blockSave(message, fieldName) stops a save and shows message. It works only as a return value from a TM.onBeforeSave callback:
The second argument is optional, and it decides where the message lands:
- Pass a field name that supports an inline error, and the message renders under that field. The form scrolls to the field and focuses it, the same way built-in validation behaves.
- Pass nothing, and the message renders in a message strip on the form.
- Pass a field that does not support an inline error, and the message falls back to the message strip anyway.
Prefer the inline form whenever the rule concerns one field, because the form scrolls to the field that needs fixing. Keep the field-less form for a rule that spans the whole form. For the list of fields that support the inline error, see Fields in UI Scripts.
TM.openDialog
TM.openDialog(config) opens a pop-up and returns a dialog ID. You build the body from TM.ui components rather than HTML, so the dialog matches the rest of Test Management.
Two rules govern dialogs:
- A dialog built from a
contenttree renders no footer. You put your ownTM.ui.Buttonnodes in the tree. - A dialog built from a
fieldslist instead of acontenttree does render a Submit and Cancel footer, labeled bysubmitLabelandcancelLabel.
Dialog options
Each key on the config object is optional unless the table says otherwise:
| Key | Effect | Default |
|---|---|---|
title |
The header text of the dialog | Defaults to Dialog
|
size |
The dialog width, as small, medium, default, large, xlarge, or full
|
Not documented |
content |
A tree of TM.ui components that becomes the dialog body |
No default |
fields |
A list of inputs that renders a Submit and Cancel footer instead of a content tree |
No default |
submitLabel |
The submit button text on a fields dialog |
Not documented |
cancelLabel |
The cancel button text on a fields dialog |
Not documented |
onSubmit |
A callback that receives (formData, context) when a submit action runs |
No default |
Named inputs arrive in onSubmit on the formData object, keyed by the name you gave each input.
Layout and display components
These components arrange the dialog and show static content:
| Component | Output | Props |
|---|---|---|
TM.ui.Stack(props, children) |
A vertical layout |
gap, as 1, 2, 3, 4, 6, or 8
|
TM.ui.Row(props, children) |
A horizontal layout |
gap, plus justify as start, center, end, or between, plus align as start, center, or end
|
TM.ui.Text(props, text) |
A line of text |
size as sm, md, or lg, plus weight as bold or medium, plus color as weaker or danger
|
TM.ui.Divider() |
A horizontal separator | None |
Inside a TM.ui.Row, each child can set its own width to full, half, third, or quarter.
Input components
Each input needs a name, because that name becomes the key in formData:
| Component | Output | Props |
|---|---|---|
TM.ui.TextField(props) |
A single-line input |
name, label, placeholder, required, defaultValue
|
TM.ui.TextArea(props) |
A multi-line input |
name, label, placeholder, required, defaultValue, plus rows, which defaults to 4
|
TM.ui.Select(props) |
A dropdown |
name, label, placeholder, required, plus options, where each option is a string or an object shaped as { value, label }. formData stores the optionβs value. |
TM.ui.Checkbox(props) |
A checkbox |
name, label
|
A TM.ui.Checkbox stores a boolean and ignores required.
Button action semantics
TM.ui.Button(props, label) takes a variant and an action. Set variant to "primary" for the brand-colored button. Any other value renders a white button. The action value decides what the click does. Only cancel closes the dialog on its own.
Value of action
|
Handler the click runs | Dialog closes |
|---|---|---|
submit |
The onSubmit callback on the dialog config |
No. Call TM.closeDialog inside onSubmit. |
cancel |
Nothing | Yes |
| Any other name | The matching TM.onAction(name, callback) handler |
No. Call TM.closeDialog inside the handler. |
A button whose action has no matching TM.onAction handler does nothing. The dialog stays open.
Next steps
We're sorry to hear that. Please share your feedback so we can do better
Contact our Support team for immediate help while we work on improving our docs.
We're continuously improving our docs. We'd love to know what you liked
We're sorry to hear that. Please share your feedback so we can do better
Contact our Support team for immediate help while we work on improving our docs.
We're continuously improving our docs. We'd love to know what you liked
Thank you for your valuable feedback!