UI Test Script examples

reference brazil Updated Jun 25, 2026 3 min read r_run_ui_test_script_examples.md
Raw file servicenow.com

Reference example scripts to use in a Run UI Test Script step.

These examples include:

  • Element verification,
  • filling and saving records,
  • waiting for async conditions,
  • impersonation,
  • file uploads,
  • step outputs,
  • parameter values,
  • and scoped queries.

Assert that a heading is visible on the current page

JavaScript
const heading = screen.getByRole('heading', { name: 'My Application' });expect(heading).toBeVisible();
JavaScript
await sn_atf.navigate('/incident.do?sys_id=-1');
// Update Callerconst caller = screen.getByRole('searchbox', { name: 'Caller' });await user.click(caller);await user.type(caller, 'Abel Tuter');await user.tab();
// Update Short descriptionconst short_desc = screen.getByRole('textbox', { name: 'Short description' });await user.click(short_desc);await user.type(short_desc, 'Cannot connect to VPN');
// Click Submitawait sn_atf.delay(1000);const [submitBtn] = screen.getAllByRole('button', { name: 'Submit' });await user.click(submitBtn);await waitFor(() => {  const numField = screen.getBySelector('[name="incident.number"]');  expect(numField.value).toMatch(/^INC/);}, { timeout: 10000 });

Test as an impersonated user

JavaScript
// Accepts a user_name or sys_id. The iframe reloads automatically.// The original session is always restored when the step ends.await sn_atf.impersonate('beth.anglin');await sn_atf.navigate('/now/sow/home');const listTab = await screen.findByRole('tab', { name: 'List', timeout: 10000 });await user.click(listTab);const incidentItem = await screen.findByRole('treeitem', { name: 'Incidents', timeout: 10000 });expect(incidentItem).toBeVisible();

Upload an attachment to the current form

JavaScript
// Pass a sys_id to copy an existing attachment server-side (no file bytes transferred).// Pass a File object (from sn_atf.getAttachmentFile) to upload through REST.await sn_atf.navigate('/incident.do?sys_id=' + steps('PREVIOUS_STEP_SYS_ID').record_id);await sn_atf.upload(steps('PREVIOUS_STEP_SYS_ID').attachment_sys_id);await screen.findByText('evidence.pdf');

Wait for an async condition by using waitFor

JavaScript
await sn_atf.navigate('/incident.do?sys_id=<sys_id>');await screen.findByRole('heading', { name: /INC/ });const [updateBtn] = screen.getAllByRole('button', { name: 'Update' });await waitFor(  () => expect(updateBtn).toBeEnabled(),  { timeout: 10000 });

Access step outputs and parameter values

JavaScript
// steps() retrieves output variables from a prior step by its sys_id.// params() retrieves parameter values when running a parameterized test.// Both support dotwalking for reference fields, for example// steps('...').assigned_to.department.name.// Use == or String() for comparisons — not ===.const dept = String(steps('PREVIOUS_STEP_SYS_ID').assigned_to.department.name);const expected = String(params('expected_department'));expect(dept == expected).toBe(true);

Note:

steps(SYS_ID) takes the sys_id of the step record, not the step result. Find it in the URL when you open the step record.

Verify an element on a classic form

JavaScript
await sn_atf.navigate('/incident.do?sys_id=<sys_id>');const heading = await screen.findByRole('heading', { name: /INC/ });expect(heading).toBeVisible();const shortDesc = screen.getByRole('textbox', { name: 'Short description' });expect(shortDesc).toBeVisible();
JavaScript
await sn_atf.navigate('/incident.do?sys_id=<sys_id>');await screen.findByRole('heading', { name: /INC/ });const shortDesc = screen.getByRole('textbox', { name: 'Short description' });await user.tripleClick(shortDesc);await user.type(shortDesc, 'Updated by ATF');const [updateBtn] = screen.getAllByRole('button', { name: 'Update' });await user.click(updateBtn);await screen.findByRole('heading', { name: /INC/ });

Note:

On classic forms, findByLabelText can throw a "found multiple elements" error because ServiceNow uses both <label for> and aria-labelledby associations at the same time. Prefer getByRole('textbox', { name: '...' }) for text inputs, or getByRole('searchbox', { name: '...' }) for reference fields. Classic forms also render every action button — Submit, Update, Delete — in both the header and the footer. Use getAllByRole and destructure to take the first one.

Wait for an async condition

Use waitFor to poll a condition that is not simply a new element appearing. The callback is retried until it stops throwing or the timeout expires.

JavaScript
await sn_atf.navigate('/incident.do?sys_id=<sys_id>');await screen.findByRole('heading', { name: /INC/ });const [updateBtn] = screen.getAllByRole('button', { name: 'Update' });await waitFor(  () => expect(updateBtn).toBeEnabled(),  { timeout: 10000 });

Test as an impersonated user

JavaScript
await sn_atf.impersonate('beth.anglin');await sn_atf.navigate('/now/sow/home');const listTab = await screen.findByRole('tab', { name: 'List', timeout: 10000 });await user.click(listTab);const incidentItem = await screen.findByRole('treeitem', { name: 'Incidents', timeout: 10000 });expect(incidentItem).toBeVisible();

Upload an attachment

JavaScript
// Copy an existing attachment to the current form (no file bytes transferred)await sn_atf.navigate('/incident.do?sys_id=<sys_id>');await sn_atf.upload('<source_attachment_sys_id>');await screen.findByText('<file_name>;);

Upload to a Workspace record

JavaScript
await sn_atf.navigate('/now/sow/record/incident/<sys_id>');const result = await sn_atf.uploadInWS('<source_attachment_sys_id>');expect(result.name).toBe('evidence.pdf');

Use step outputs with dotwalking

JavaScript
// steps(<step_sys_id>) — use the sys_id shown in the step record's URLconst assigneeDept = String(steps('abc123def456abc123def456abc12345').assigned_to.department.name);expect(assigneeDept).toBe('IT');

Use parameter set values

JavaScript
// In a parameterized test, read values from the active parameter rowawait sn_atf.navigate('/incident.do?sys_id=-1');const shortDesc = screen.getByRole('textbox', { name: 'Short description' });await user.type(shortDesc, String(params('description')));const [submitBtn] = screen.getAllByRole('button', { name: 'Submit' });await user.click(submitBtn);await waitFor(() => {  const numField = screen.getBySelector('[name="incident.number"]');  expect(numField.value).toMatch(/^INC/);}, { timeout: 10000 });

Use within to scope queries

JavaScript
// Scope queries to a specific section of the page to avoid ambiguous matchesconst form = screen.getBySelector('form');const shortDesc = within(form).getByRole('textbox', { name: 'Short description' });expect(shortDesc).toBeVisible();

Find the visible instance of a duplicated element

JavaScript
// The page renders two elements with the same text; find the visible oneconst matches = await screen.findAllByText('Number');const label = matches.find(el => isVisible(el));expect(label).toBeTruthy();
Keywords Run UI Test ScriptexamplesATFUI testing
Search documentation
Search document titles and file paths on the brazil branch