Fields in UI Scripts
Read and compare Test Management fields correctly in a UI Script, using internal_name for system fields and label for custom fields.
Fields in Test Management belong to two families. You compare each family differently. Mixing up the two is a common reason a working-looking rule never fires.
The rule is short:
- A system field is a built-in dropdown such as Priority. Compare it using
internal_name. - A custom field is one you added, such as Target Region. Compare it using
label.
// System field: compare using internal_name.
form.priority.internal_name === "critical";
// Custom dropdown: compare using label, addressed by display name.
form.fields["Target Region"].label === "EMEA";
System fields compare using internal_name
The built-in dropdowns arrive as objects. Priority, State, Type of Test Case, and Automation Status all share the same shape:
{ value: 42, label: "Critical", colour: "#FF3B30", internal_name: "critical" }
Compare using internal_name. It is a stable machine name that survives a rename, so a rule keeps working after someone changes Critical to P0 in the admin panel. Comparing using label breaks the moment that rename happens. Compare using value and the rule breaks between projects, because value is an internal numeric ID.
form.priority.internal_name === "critical";
form.automationStatus.internal_name === "automated";
Expand this list to look up the machine name behind a label:
internal_name values for each system field
| System field | Form label | internal_name |
|---|---|---|
| Priority | Low | low |
| Priority | Medium | medium |
| Priority | High | high |
| Priority | Critical | critical |
| State | Active | active |
| State | Draft | draft |
| State | In Review | in_review |
| State | Rejected | rejected |
| State | Outdated | outdated |
| Type of Test Case | Acceptance | acceptance |
| Type of Test Case | Accessibility | accessibility |
| Type of Test Case | Compatibility | compatibility |
| Type of Test Case | Destructive | destructive |
| Type of Test Case | Functional | functional |
| Type of Test Case | Performance | performance |
| Type of Test Case | Regression | regression |
| Type of Test Case | Security | security |
| Type of Test Case | Smoke & Sanity | smoke_sanity |
| Type of Test Case | Usability | usability |
| Type of Test Case | Other | other |
| Automation Status | Not Automated | not_automated |
| Automation Status | Automated | automated |
| Automation Status | Automation Not Required | automation_not_required |
| Automation Status | Cannot Be Automated | cannot_be_automated |
| Automation Status | Obsolete | obsolete |
| Result Status | Passed | passed |
| Result Status | Failed | failed |
| Result Status | Blocked | blocked |
| Result Status | Retest | retest |
| Result Status | Skipped | skipped |
| Result Status | Untested | untested |
| Result Status | In Progress | in_progress |
| Result Status | Unknown | unknown |
Values you add to a system field
A value you add to a system field through the admin panel also gets an internal_name. Test Management builds it by lowercasing and trimming the text you entered. So a Priority value named Super High arrives as internal_name: "super high", with the space preserved.
The value is always a string. It is never empty and never a numeric ID, so you compare it the same way you compare a built-in value.
Result Status on the result surfaces
Result Status is the one system field that does not always carry internal_name. On the Add Result and Update Result surfaces, the status contains only { id, label }. Compare using label there:
formState.status.label === "Failed";
Everywhere else, Result Status carries internal_name, and internal_name is the preferred property for comparison. For a working rule that handles this exception, see the Add Result scripts in the script library.
Custom fields compare using label
Custom fields live under form.fields, addressed by their display name in bracket notation. Bracket notation is needed because most names contain a space:
form.fields["Target Region"];
A custom dropdown value carries no internal_name. Compare using label, which contains the option text. Never compare using value, because that number is an internal ID and differs from project to project.
Read a custom field of each type
What you read back depends on the field type, and two of the types return something other than what their name suggests. Read each type as shown in this script:
var f = form.fields;
// Text and URL fields contain a string.
f['Automation Link'] === 'https://example.com/build/42';
// A Date field contains a formatted string.
f['Target Date'] === '2026-07-30';
// A Number field contains a string, so parse it before any arithmetic.
Number(f['Retry Count']) > 3;
// A Text Area field contains HTML, so strip the tags before you test for emptiness.
String(f['Review Notes'] || '').replace(/<[^>]*>/g, '').trim() === '';
// A Boolean field contains true or false.
f['Needs Sign-off'] === true;
// A Dropdown contains { value, label }, or null when unset. Compare the label.
f['Target Region'] && f['Target Region'].label === 'EMEA';
// A Multi-select contains an array of { value, label }. Compare the label on each item.
(f['Platforms'] || []).some(function (o) { return o.label === 'iOS'; });
// A Nested dropdown contains the ID of the selected option.
// Compare the ID, or the label when the option carries one.
f['Component'] === 42;
// A User field contains the user object as selected. Read the property you need off it.
f['Reviewer'];
Field names on the Test Case Form
This table lists the property that contains each built-in field on the Test Case Form:
| Built-in field |
form property |
|---|---|
| Title | form.title |
| Priority | form.priority |
| State | form.state |
| Type of Test Case | form.caseType |
| Automation Status | form.automationStatus |
| Tags | form.tags |
| Preconditions | form.preconditions |
| Description | form.description |
| Requirements | form.requirements |
| Steps | form.steps |
A field verb and TM.onFieldChange do not name a field the same way. Both take a custom field by its display name. On a built-in field they differ:
- Field verbs such as
TM.setFieldVisibletake the label shown on the form, such as"Tags". -
TM.onFieldChangetakes theformproperty name, such as"tags".
So hiding Tags is TM.setFieldVisible("Tags", false), while reacting to Tags is TM.onFieldChange("tags", callback).
Field names on the run, plan, and session forms
The Test Run Form, Test Plan Form, and Exploratory Session Form surfaces use a single name for each field. Every built-in field carries one canonical name, written in camel case, such as title or startDate. The same name works everywhere a script names a field: in a field verb, in TM.onFieldChange, as a property on form, and as the field argument of TM.blockSave.
Custom fields keep their display name, the same way they do on the Test Case Form. The Test Plan Form and the Exploratory Session Form carry the custom fields defined for them. The Test Run Form carries built-in fields only.
Two behaviors on these forms differ from the Test Case Form. Check both before you write a rule:
-
Pre-filling follows the field shape.
TM.setFieldValuewrites text and boolean fields directly, so a pre-filledtitleorautoAssignalways renders. A structured field, such asownerortags, renders a pre-filled value only when you pass it in the fieldβs own shape. A pre-filled value on a custom Text Area field might not render in the editor. -
A dropdown reports its stored value.
TM.onFieldChangeon a dropdown field receives the optionβs stored value, which is often a numeric ID, rather than the visible label. To keep the condition readable, use a text or boolean field as the trigger instead. The Test Run Form scripts in the script library show the pattern.
Test Run Form field names
| Form label | Script name |
|---|---|
| Test Run Name | title |
| Description | description |
| Assign Run | owner |
| State | state |
| Tags | tags |
| Requirements | requirements |
| Test Plan | testPlans |
| Configurations | configurations |
| Run Group | runGroup |
| Auto-assign | autoAssign |
Test Run Name is always mandatory, so a script cannot hide or lock it. Test Plan is testPlans, in the plural. Requirements renders only after an issue tracker is connected on the project. Run Group renders only when run groups are enabled. It supports only the required and hide options. Configurations and Auto-assign cannot be marked required and do not show an inline error.
Test Plan Form field names
| Form label | Script name |
|---|---|
| Title | title |
| Parent Test Plan | parentTestPlan |
| Start Date | startDate |
| End Date | endDate |
| Tags | tags |
| Owner | owner |
| Requirements | requirements |
| Description | description |
Start Date and End Date support every field verb, the inline error, and TM.onFieldChange. Parent Test Plan, Tags, and Owner contain structured values.
Exploratory Session Form field names
| Form label | Script name |
|---|---|
| Title | title |
| Timebox | timebox |
| Configurations | configurations |
| Description | description |
| Tags | tags |
| Requirements | requirements |
| Test Plan | testPlan |
| Owner | owner |
Test Plan is testPlan, in the singular, unlike testPlans on the Test Run Form. Timebox contains the session duration in minutes, as a number. Configurations, Tags, and Requirements each contain more than one value, while Test Plan and Owner each contain one. Every built-in field on this form supports required, hide, read-only, the inline error, and pre-fill options.
Fields that can show an inline error
TM.blockSave takes an optional field name. When you pass a field name that supports an inline error, the message renders under that field and the form scrolls to it. When the field does not support it, the message falls back to a message strip on the form, even though you passed a name.
This table covers the Test Case Form:
| Field | Location of the TM.blockSave message |
|---|---|
| Title | Inline, under the field |
| Tags | Inline, under the field |
| Preconditions | Inline, under the field |
| Description | Inline, under the field |
| Requirements | Inline, under the field |
| Steps | Message strip, above the form footer |
| Priority | Message strip, above the form footer |
| State | Message strip, above the form footer |
| Type of Test Case | Message strip, above the form footer |
| Automation Status | Message strip, above the form footer |
| Owner | Message strip, above the form footer |
Any custom field also supports the inline error, addressed by its display name. On the run, plan, and session forms, pass the canonical name, such as TM.blockSave('Link a Test Plan first.', 'testPlans'). On the Test Run Form, Configurations and Auto-assign do not show an inline error.
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!