DevTools 1.27.1

Welcome to the DevTools - created and maintained by Sascha Wildgrube.


DevTools contains a number of script includes with useful javascript functions and classes like a GetType() function that really works. A few UI improvements like the Re-Test button in the test result form and shortcuts to various - sometimes hidden - views and system properties in your instance.


DevTools is NOT an officially supported ServiceNow product.

DevTools does NOT come with any kind of warranty. If you use it, you own it!

System Requirements

Security Notice

To leverage the full potential of DevTools functions, some settings need to be changed to allow more cross scope access for scoped apps. This might be considered as a breach of security guidelines and should be validated with those who are responsible for security within the instance!


  1. Create an account on GitHub (if not done already).
  2. Create a personal access token for your GitHub account.
  3. Paris or later: Add credentials to access GitHub (Use "Basic Auth").
  4. Fork the repository
  5. Go to Studio and import the DevTools application from source control.
  6. Switch to global scope.
  7. Create a new update set in the global scope to capture all changes related to the DevTools installation.
  8. The x_snc_devtools.AppInstall() function must be executed.
    Run the following script as a background script in scope x_snc_devtools:
  9. x_snc_devtools.AppInstall();
  10. Set the update set in the global scope to to complete.
  11. Set the sn_atf.runner.enabled system property to true to activate the ATF test execution (if not set already).
  12. Run the DevTools test suite.
  13. In case of errors:
    1. In a domain separated instance it may be necessary to switch to the topmost domain to pass all tests.
    2. If the test "DevTools - RunScriptInGlobalScope" fails: Retry after a few minutes. Some cross-scrope privileges will be set up during the first test run and might take a few minutes to be effective. The function RunScriptInGlobalScope() is used in many other functions, so do look into any other failed tests as long as this test fails.
    3. Tests "DevTools - TestDataAPI": These scripts create various records (e.g. incidents, problems, etc.). If there are customizations in place that make additional fields mandatory, you may have to set up business rules to set these values - but only if the short description (or the corresponding field) starts with "_ATF_".
    4. If the "DevTools - Test data sanity" test fails you can use the following script to clear existing test data:
    5. var testdata = new x_snc_devtools.TestDataAPI('_ATF_DEVTOOLS_');'Before DeleteAllData(): '+x_snc_devtools.RenderValue(testdata.GetAllData()));
      testdata.DeleteAllData(testdata.GetAllData());'After DeleteAllData(): '+x_snc_devtools.RenderValue(testdata.GetAllData()));


Configuration options

UI Actions

  • Add Test (global)

    Adds a test to a suite

  • Delete Update Set (global)

    Delete this update set. Available to admin users only.

  • Execute Now (global)

    Execute a scheduled job on demand and stay on the current form. This UI Action replaces the OOTB Execute Now UI Action.

  • Find Sys ID (global)

    Asks the user for a sys id and if the record exists, navigates to the record's form page. Available to admin users only.

  • List (global)

    The "List" button navigates from a record's form view to it's list view.

  • Run Test (global)

    Run an ATF test directly from any screen that has a reference to a test.

  • Up (global)

    The "Up" button navigates to the record's parent record (if possibe).

Script includes

  • AppBuilder

    AppBuilder adds various application files to a scoped app.

  • AppBuilderAddTestToSuite

    Add an ATF test to an existing test suite.

  • AppGetDependencies

    Retrieves information about the app's dependencies to other apps and required versions.

  • AppGetProperty

    Gets a DevTools system property.

  • AppInstall

    This script installs DevTools

  • AppSanity

    Performs a number of changes to a scoped app's assets to maintain application sanity. E.g., the function removes the copied_from attribute in atf tests, removes unneccesary field level ACLs and removes the is_private flag from system properties.

  • AppSetProperty

    Sets a DevTools system property.

  • ArrayAppend

    Appends the second given array to the first.

  • ArrayRemoveValue

    Removes a value from an array.

  • ArrayUnique

    Returns an array with unique values only.

  • ArrayValueExists

    Checks if a value exists in an array and returns true in that case, otherwise false.

  • BusinessRuleGetOperation

    Returns the operation (of a business rule) based on the provided record.

  • Clone

    Creates a copy of the given value.

  • DatabaseIndexCreate

    Creates a new database index if it doesn't exist yet. Warning, there is no way to undo that operation!

  • Debug

    Produce a debug log output but only if x_snc_devtools.debug.log is set to true.

  • DevToolsClientAPI

    The DevToolsClientAPI is a client callable proxy for ajax calls to some of the functions provided by DevTools.

  • DocumentationAPI

    The DocumentationAPI helps to render fragments of an HTML page that documents the components of a scoped application.

  • GetAppName

    Returns the name of a scoped application (and removes any "work in progress" postfixes).

  • GetArrayValue

    Returns an array no matter what input type is given and performs necessary conversion if another type is provided.

  • GetBoolValue

    Returns either true or false no matter what kind of value is given.

  • GetDatabaseViewsFromTable

    Returns the database views which use a given table.

  • GetGroupsFromUser

    Returns all groups of a given user. An additional filter can be applied to the groups to be returned.

  • GetHash

    Generate a hexadecimal SHA 256 hash string.

  • GetInstanceListPath

    Returns the URL path of a table's list in the instance.

  • GetInstanceRecordPath

    Returns the URL path of a specific record in the instance.

  • GetInstanceRecordURI

    Returns the URL path of a specific record in the instance.

  • GetInstanceRecordURL

    Returns the URL of a specific record in the instance.

  • GetInstanceURL

    Returns the instance root URL.

  • GetIntegerValue

    Returns an integer value.

  • GetKeys

    Returns all key names of an object in an array. Returns an empty array if no object is provided or no members exist.

  • GetLinkDirectory

    Returns the DevTools link directory with many useful links for admins and developers.

  • GetParentRecord

    Get the parent record of a given record if it is possible.

  • GetParentTable

    Returns the parent table of the given table. False if the given table does not exist or is not derived from another table.

  • GetRandomNumericToken

    Get a pseudo-random string token of a given length consisting of numbers only.

  • GetRecord

    Shorthand to get a record from a table based on a sys_id. If the bNoCrossScope parameter is set to true, GetRecord will not attempt to load the record from the global scope if it cannot load it from within the application scope.

  • GetRecordFromTestStep

    Returns the sys_id of the record that has been created or found in the given test step.

  • GetRoleNamesFromUser

    Returns an array with the names the active roles of a user.

  • GetRolesFromUser

    Returns an array with the sys_ids of the active roles of a user.

  • GetShortUniqueString

    Returns a string that represents a version of the input string that does not exceed the specified length. The last characters are replaced by a hash-based alpha-numeric postfix to avoid string collisions.

  • GetStringValue

    Returns a string value in all cases. Arrays and objects are converted into comma separated strings.

  • GetTablesByColumnType

    Returns all tables which have at least one column with the given type.

  • GetTimeNow

    Returns the number of millisenconds passed since the start of the unix epoch.

  • GetTransactionRuntime

    Returns the number of millisenconds passed since the start of this transaction.

  • GetType

    Returns the type of a value.

  • GetUserRecord

    Get a user record based on sys_id, user_name, name or email address.

  • GetValue

    Returns the value of an object that is (or is not) part of an recursive object without generating errors if the object does not exist.

  • GlideRecordDelete

    Executes the delete member function of a glide record in global scope.

  • GlideRecordDeleteMultiple

    Executes the deletemultiple member function of a glide record in global scope.

  • GlideRecordInsert

    Executes the insert member function of a glide record in global scope.

  • GlideRecordQuery

    Executes the query member function of a glide record in global scope.

  • GlideRecordSetValue

    Executes the setValue member function of a glide record in global scope.

  • GlideRecordUpdate

    Executes the update member function of a glide record in global scope. If bGhost is set to true, the record update will not trigger any system field updates or workflows.

  • HtmlEncode

    Converts a string to html.

  • HtmlRenderLink

    Renders an HTML link.

  • HtmlRenderLinkDirectory

    Renders a link directory with based on a given linkdirectory object.

  • HttpRequest

    Performs a single synchronous http request.

  • InstallerAPI

    The InstallerAPI class supports scripted installation steps as part of the installation of a scoped app.

  • IsArray

    Returns true if the given value is an array. False if not.

  • IsEqual

    Checks if two values are equal. The function also supports arrays and can ignore the order of array elements while comparing.

  • IsExistingRecord

    Checks if the given record is really a GlideRecord object representing an existing record.

  • IsObject

    Returns true if the given value is an object. False if not.

  • IsProperty

    Returns true if the given parameter is the name or the sys_id of an existing system property. False if not.

  • IsTableCrossScopeAccessible

    Checks if a table is fully cross-scope accessible. The function returns true if the access is set to public and apps from other scopes are allowed to perform read, create, update and delete operations.

  • IsTechnicalUser

    If the given user is a "technical" user, the function returns true, otherwise false.

  • IsUserAdmin

    Returns true if the user is an admin user, false if not.

  • IsUserHasRoleExactly

    Returns true of the current user has the provided role explicitly. Returns true if that is the case, returns false if not. If an admin does not explicitly have that role, it will also return false.

  • IsUserSecurityAdmin

    Returns true if the current user is elevated to security_admin, false if not.

  • IsValidColumn

    Returns true of the given table column exists. False if not.

  • IsValidDatabaseView

    Returns true of the given string identifies a database view. False if not.

  • IsValidFunction

    Returns true of the given value is a valid function. False if not.

  • IsValidRecord

    Checks if the given record is a valid glide record object. Returns true if it is, false if not.

  • IsValidSysId

    Checks if the given string is a syntactically correct sys_id. Returns true if it is, false if not.

  • IsValidTable

    Returns true of the given table exists. False if not.

  • IsValidVersion

    Returns true if the given string is a valid version number, false if not.

  • IsVersionCompatible

    Checks if the first version is compatible to the second version - whereas the first version is the version of an installed application and the second version is a requirement.

  • LoadMessages

    Loads all local test messages for an "application".

  • Log

    Produces a log output

  • Merge

    Merges two objects.

  • ParseCsv

    Parses a csv formatted string into an array of objects representing each row.

  • ParseDateTime

    Parses a string and returns a time value.

  • ParseJson

    Parses a string and returns an object or false in case of failure (instead of pointlessly throwing an exception).

  • ParseUrl

    Parses a URL and returns its components as an object.

  • ParseUrlParameters

    Parses a the URL parameters and returns the parameters as an object.

  • PerformanceQuery

    Measure the average performance of a query in milliseconds from the perspective of a given user based on a defined number of repetitions.

  • PerformanceQueryMultiple

    Measure the average performance of a number of queries in milliseconds from the perspective of a number of given users based on a defined number of repetitions.

  • RecordBulkProcessor

    A function to process large amounts of records using a callback function. The function makes use of a specified date/time field to determine which record to process next. Multiple instances of a background script can run using this function to work on large amounts of records in a table without interfering with each other. For large tables it is imperative to add an index on the date time field! If the ghost parameter is set to true, records are updated with setWorkflow(false) to avoid business rules etc. being triggered.

  • RecordDelete

    Deletes a single record from a table. Returns true if the record could be deleted successfully.

  • RecordGetValue

    Shorthand to get a single value from a record from a table based on its sys_id.

  • RecordSetValue

    Sets a single field value on a given record. If bGhost is set to true, no business rules are executed as a result of the update.

  • RedirectToRecord

    Redirects to the form view of the given record if it is valid.

  • RenderBytes

    Returns a user-friendly number of bytes using KB, MB and GB where appropriate.

  • RenderDateTime

    Renders a date/time value as an UTC ISO string.

  • RenderRecordSummary

    Renders a string with a technical summary of a record including its table name, sys_id, number if available and other text data that can help to identify the record while debugging.

  • RenderValue

    Render any value as a string. In case of objects, the keys are displayed in alphabetical order. In case of arrays, the elements are displayed in the given order. In case of a GlideRecord, the table name, sys_id and number (if available) are displayed on top, and a selected choice of fields leads the list of values despite the alphabetical order.

  • RunScriptInGlobalScope

    Run any script in the global scope even if the context is a scoped application. Note that the script will be placed into a function body so you cannot assume that declared local variables will be valid after its execution. To return a value from the script, set the "result" variable.

  • RunScriptInScope

    Runs any script in any scope even if the context is a scoped application. Note that the script will be placed into a function body so you cannot assume that declared local variables will be valid after its execution. To return a value from the script, set the "result" variable.

  • SetProperty

    Sets a system property independent of its scope.

  • Sleep

    Sleeps for the given amount of seconds.

  • StopWatch

    The StopWatch class measures time in the same way as a real stopwatch does.

  • StringRemoveCharacters

    The function returns the input string with all characters removed that are contained in the blacklist string.

  • TableSetAttribute

    Sets an attribute of a table to a given value.

  • TestAPI

    The TestAPI class supports scripted tests.

  • TestDataAPI

    A class to create test data records.

  • TransactionCacheAPI

    A class to manage the transaction cache.

  • UpdateSetDelete

    Deletes an update set including all its files.

  • UserAddRole

    Adds a role to a user if the user doesn't have the role already.

  • UserImpersonate

    Impersonates a user based on a user's sys id.

Test step configurations

DevTools contains the following customized test step configurations:

Extension Points

  • DevTools

    The DevTools extension point allows to extend some DevTools features.

    var DevTools = Class.create();
    DevTools.prototype = {
    	initialize: function()
    	GetParentRecord: function(grRecord)
    		var IsValidFunction = x_snc_devtools.IsValidFunction;
    		if (IsValidFunction(x_this_app_scope.DevToolsGetParentRecord))
    			return DevToolsGetParentRecord(grRecord);
    		return false;
    	GetLinkDirectory: function(linkdirectory)
    		var IsValidFunction = x_snc_devtools.IsValidFunction;
    		if (IsValidFunction(x_this_app_scope.DevToolsGetLinkDirectory))
    			return DevToolsGetLinkDirectory(linkdirectory);
    		return linkdirectory;
    	type: 'DevTools'

Business Rules


Copyright 2020-2021 by Sascha Wildgrube

Licensed under the Apache License, Version 2.0 (the "License")

You may not use DevTools except in compliance with the License.

You may obtain a copy of the License at:

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Release Notes

1.27.1 - 2021-11-19

  1. A defect prevented the "Find Sys ID" UI action to be visible. This has been fixed.

1.27.0 - 2021-11-18

  1. Added function RedirectToRecord() to redirect the user agent to the given record.
  2. Added function ParseCsv() to convert a string containing csv formatted data into an array of objects representing the data rows.
  3. HttpRequest() now supports headers and sending a request body.
  4. Test step config "DevTools - App sanity" now checks if test steps' copied_from fields are empty.
  5. AppSanity() function now also accepts a scope name.
  6. AppSanity() now also clears all test steps' copied_from fields.
  7. GetParentRecord() now supports sys_ui_policy_rl_action, sys_ui_policy_action, sys_ui_policy, sys_ui_section, sys_ui_element, sys_ui_list and sys_ui_list_element.
  8. Added sys_ui_policy_rl_action, sys_ui_policy_action, sys_ui_policy, fx_currency, sys_glide_object, sys_ui_section, sys_ui_element, sys_ui_list and sys_ui_list_element to GetLinkDirectory().
  9. AppBuilder() creates the script include for the AppInstall() function.
  10. AppBuilder() creates the "active" system property.
  11. AppBuilder() creates the "" system property und the Log() function respects if the property is set to true.
  12. AppBuilder() creates the script include for the IsActive() function.
  13. AppBuilder() creates the script include for the AppGetProperty() function.
  14. HtmlRenderLinkDirectory() now also renders links specified directly using a url.
  15. TestDataAPI::CreateRequestTask() now uses the third paramter as the opened_by user instead of the assigned_to user for consistency.
  16. Added function InstallerAPI::ShowFieldClass() to show or hide a field class during installation.
  17. GetTableFromSysId() has been improved significantly. Various tables are excluded and tables are searched in a way that makes it more probably that records are found faster.
  18. AppInstall() now unhides the "UI Action List" field class so that it can be used by developers.

1.26.0 - 2021-11-10

  1. Added the new "Links" page with the new link directory with many useful links for admins and developers. The new function GetLinkDirectory() returns the standard DevTools link directory. The directory can be extended using the DevTools extension point.
  2. Removed the "Access Control" sub menu and the "Cross Scope Privileges" module.
  3. Added function RecordInsert() to add a new record into a table with a given set of values.
  4. Added function RecordGetSummary() to render a short hand summary of a record for debugging.
  5. Added function IsExistingRecord() to check if a given GlideRecord object represents an existing record.
  6. Added function TestAPI::TestCase_GetRecord() to check if a record exists.
  7. Added function TestAPI::TestCase_RecordGetValue() to check the value of a field in a given record.
  8. Added function TestAPI::TestCase_IsRecordAccessibleByUser() to check if a given user has access to a given record.
  9. Added function GetInstanceListPath() to generate the path component to access a list view.
  10. Added function HtmlRenderLink() to render the html for a link.
  11. Added function IsUserAdmin() to check if the current or a given user has the admin role.
  12. Added function GetShortUniqueString() to render unique strings and avoid naming collisions.
  13. Added function ParseURL() to return the components of a url in an object.
  14. Added function ParseUrlParameters() to return the key value pairs of a url parameter string in an object.
  15. Added method InstallerAPI::ActivateUiAction() to set an existing UI Action active or inactive during installation.
  16. Added support for core_comapany and ast_contract in TestDataAPI class.
  17. Added function GetRoleNamesFromUser() to get the names of the active roles of a user.
  18. Functions IsUserSecurityAdmin() and IsUserHasRoleExactly() now support a parameter to specify a user to check.
  19. The new UI Action "Find Sys ID" asks the user for a sys id and then redirects the browser to the record form page. That's a real killer feature!
  20. The new UI Action "Execute Now" replaces the OOTB "Execute Now" UI Action on sysauto_script. It triggers the execution, stays on the current form and displays a message that the job has been triggered for execution.
  21. AppInstall() now deactivates the OOTB UI action "Execute Now" on sysauto_script.
  22. TestAPI::TestCase() now uses strict comparison ("===") when comparing the expected value with the result. Affected tests have been adapted accordingly.
  23. GetTableFromSysId() now checks if the sys_id field exists before trying to find the record - thus making the process faster and more robust.
  24. GetTableFromSysId() checks the sys_package, domain, core_company and ast_contract tables first to cover more of the more likely use cases without doing the full scan through all tables.
  25. IsTechnicalUser() now checks parameters against invalid and empty values and returns false if there are multiple technical users sharing the same user_name.
  26. GetParentRecord() now supports sys_storage_alias.
  27. AppBuilder() now also creates the script include for the AppSetDefaults() function.
  28. AppBuilder() now checks if an application menu already exists.
  29. AppBuilder() now creates the extention point instance for the DevTools extension point and the corresponding script includes.
  30. Updated example script for the DevTools extension point.
  31. The "List" button now keeps the filter of the list view from which the current record form was navigated.
  32. The "Delete Update Set" button is now active by default.
  33. Sleep() is now accessible to all application scopes.
  34. Renamed function DeleteUpdateSet() to UpdateSetDelete() and made it accessible to all scopes.
  35. The test step config "DevTools - Check scoped app sanity" now checks if active UI actions have a description (a non-empty comments field).

1.25.0 - 2021-10-11

  1. RunScriptInGlobalScope() and the new RunScriptInScope() functions no longer require configuration changes on the sys_script_include table. If DevTools has been installed in the past you may use the following script to revert the modified configuration back to OOTB:
    var grRecord = new GlideRecord('sys_db_object');
    if (
       grRecord.access = '';
       grRecord.read_access = 'true';
       grRecord.create_access = 'false';
       grRecord.update_access = 'false';
       grRecord.delete_access = 'false';
  2. Added function GetTableFromSysId() to identify the table of the record identified by the given sys_id.
  3. Added function ArrayAppend() to append an array to another and make sure return value is always an array.
  4. Added function DatabaseIndexCreate() to add a new database index.
  5. Added function GetParentTable() to return the name of the super class of a given table.
  6. Added function IsValidColumn() to check if a given column exists in a table (or its parent tables).
  7. Added function IsValidFunction() to check if the given value is a callable function.
  8. Added function RecordGetValue() to get a single value from a given record.
  9. RecordSetValue(), GlideRecordUpdate() and RecordBulkProcessor() now support the ghost parameter which (if set to true) uses setWorkflow(false) and autoSysFields(false) to supress business rules, auditing and sys field updates.
  10. RecordBulkProcessor() now effectively detects if the same record is found again and again to prevent an endless loop. If a business rule prevents the update of a record and the ghost mode is not set, the function returns immediately.
  11. Added function TableSetAttribute() to set an attribute of a table to a given value.
  12. Added method InstallerAPI::SetTableAttribute().
  13. Added method InstallerAPI::ActivateBusinessRule().
  14. Added method InstallerAPI::ActivateClientScript().
  15. Added function DeleteUpdateSet() function and the "Delete Update Set" UI action. A system property controls if the button is available to admin users.
  16. The DevTools AppInstall() function now sets the update_synch attribute of the sysauto_script table to true to make sure that scheduled jobs are captured in update sets and committed to source control.
  17. AppInstall() now enables the creation of cross-scope before query business rules by deactivating a business rule and two client scripts.
  18. AppInstall() modifies the UI action "Execute Now" on sysauto to stay on the current form.
  19. The function TestAPI::TestCase() now displays the milliseconds required to run the given function.
  20. Test "DevTools - RunScriptInGlobalScope - Temporary script includes" was flaky due to race conditions during test executions. Added a threshold of 30 minutes so the test will only alert on left over script includes created more than 30 minutes ago.
  21. Test "DevTools - Installation" now checks if the sysauto_script table is configured so that records are captured in update sets and committed to source control.
  22. Test step configuration "DevTools - Check scoped app sanity" now checks for unwanted entries in sys_index associated with the app.
  23. Test step configuration "DevTools - Check scoped app sanity" now checks for test suite tests where the scope of the record does not match the scope of the associated test suite.
  24. Added the business rule "sys_atf_test_suite_test - match scopes" to make sure a test suite test is using the same scope as the associated suite.
  25. GetParentRecord() is now more effectively checking for the suite most relevant to a test by considering the scope of the test_suite, too.
  26. GetParentRecord() now supports records in tables sys_update_xml, sys_update_set, sys_extension_instance, sys_ux_list, sys_ux_list_category, ts_table, sys_documentation (field labels) and sys_dictionary (table columns).
  27. GetRecord() now checks if the given sys_id is valid, hence avoiding unnecessary queries.
  28. GetRecord() now tries to get a record from within the scope instead of using GlideRecordQuery() and hence RunScriptInGlobalScope() in all cases.
  29. GetRecord() now supports a third parameter: bNoCrossScope. If set to true, GetRecord() will not try to load a record from the global scope if it cannot be loaded from DevTools' scope.
  30. IsValidSysId() now confirms that "global" is a valid sys id.
  31. AppBuilder() now also accepts a scope name as the parameter.

1.24.0 - 2021-09-22

  1. DevTools has been tested with Rome Release.
  2. RunScriptInGlobalScope() now supports seven input parameters.
  3. GetParentRecord() now also supports sys_aw_list and sys_aw_list_category.
  4. GetParentRecord() now checks if the GetParentRecord function in the called extension point really exists.
  5. Added function DocumentationAPI::RenderInstallationInstructionsRunTestSuite() to render instructions on how to enable ATF tests and run the app's test suite.
  6. Added function InstallerAPI::DeleteView() to delete views which (due to a platform defect) reappear after installation.
  7. Added a test to verify there are no temporary script includes left over by RunScriptInGlobalScope().

1.23.0 - 2021-09-16

  1. Orlando is no longer actively supported.
  2. GetParentRecord() now supports sys_atf_test_suite, incident_task, change_task, problem_task, sc_task, sc_req_item, sys_db_view_table and sys_db_view_table_field records.
  3. GetParentRecord() now supports tests which are part of multiple test suites if there is exactly one suite in the same scope.
  4. Introduced the DevTools extension point - to extend the GetParentRecord() function.
  5. Added DocumentationAPI::RenderExtensionPoint() function.
  6. AppBuilder() now also adds the AppSetProperty function.
  7. Fixed a defect in test step configuration "DevTools - Check scoped app sanity".
  8. Fixed a defect in AppSanity() when removing the snc_internal role from an ACL.
  9. Removed view "DevTools Install" as it was no longer needed.

1.22.0 - 2021-09-09

  1. When using the "Run Test" button on a test step form, the UI action will first check if there are unsaved changes and save the test step record instead of running the test.
  2. Introduced class TestAPI to support scripted tests by managing log output, result state and various generic test case functions.
  3. Introduced class InstallerAPI to support scripted installation steps (and refactored AppInstall() to use the new class).
  4. Added test step configuration "DevTools - Check test data sanity" to check if there is any test data left over with a given prefix.
  5. TestDataAPI now also supports sc_req_item and sc_task.
  6. Added function AppBuilder() to help building robust scoped apps.
  7. Added function AppBuilderAddTestToSuite() to add an ATF test to an existing ATF test suite.
  8. Added UI action "Add Test" to add a test to a suite in one click.
  9. Added UI action "Up" to navigate to a record's parent record if possible.
  10. The new function GetParentRecord() delivers a record's parent record if supported.
  11. Added function RenderSystemRequirements() to DocumentationAPI to automatically render system requirements including dependencies to other apps.
  12. Added function RenderInstallationInstructionsConfigureTableCrossScopeAccess() to DocumentationAPI.
  13. Added function RenderInstallationInstructionsBackgroundScript() to DocumentationAPI.
  14. Added function RenderUIActions() to DocumentationAPI.
  15. Added function RenderBusinessRules() to DocumentationAPI.
  16. Added function GetInstanceRecordPath(), GetInstanceRecordURL() and GetInstanceRecordURI() to produce different variants of a deep link to a specific record in the instance.
  17. AppSanity() now removes the snc_internal role from ACLs if there is at least one other role required for the ACL.
  18. AppGetName() now returns false instead of "undefined" if the app cannot be found.
  19. The test step config "DevTools - Check scoped app sanity" checks for unintended configuration of the role snc_internal in ACLs.
  20. Added business rule "sys_ui_action - set table to global" to allow global UI Actions. In a recent family release (Quebec?) the option of defining global UI Actions has been removed as the table field no longer allows to set the value to "global". This business rule fixes this issue by setting an empty table field to "global".
  21. RenderValue() now supports the bUnsortedKeys parameter to avoid sorting object keys.
  22. Introduced the function GetAppDependencies() to retrieve information about an app's dependencies to other apps.

1.21.0 - 2021-08-23

  1. Added function GetUserRecord() to get a user's GlideRecord object based on a sys_id, user_name or email.
  2. Added function PerformanceQuery() to measure query performance given a table, query string, a user, the number of repetitions and a limit of records to be returned. The function will provide the milliseconds of the fastest and slowest repetition, the average speed and the number of records returned.
  3. Added function PerformanceQueryMultiple() to execute multiple performance tests on a number of queries combined with a number of users in one go.
  4. TestDataAPI.CreateUser() can now set the user's email.
  5. RecordBulkProcess() now handles empty tables properly and stops immediately.
  6. AppInstall() is now accessible from all scopes. This enables other installation scripts in other scoped Apps to run the function as part of their own installation procedure.
  7. Extended the installation guide to run a background script to configure cross scope access to the sys_script_include table.

1.20.0 - 2021-07-06

  1. AppSanity() now sets is_private to false for system properties.
  2. AppSanity() now deletes useless ACLs for create and delete operations on fields.

1.19.1 - 2021-07-05

  1. TestDataAPI.GetAllUsers() scanned for users where the "name" started with the prefix instead of the "user_name". This has been fixed.
  2. RenderValue() now also sorts the field "user_name" to the top.
  3. ATF tests "DevTools - GetGroupsFromUser", "DevTools - IsUserHasRoleExactly", "DevTools - TestDataAPI - ITSM" and "DevTools - IsUserSecurityAdmin" were checking for the user name ("name") instead of the user id ("user_name") leading to inconsistent results on customized instances. This has been fixed.

1.19.0 - 2021-06-30

  1. Installation has been simplified. Only the sys_script_include table needs to be configured for cross scope access.
  2. Massive refactoring to remove the dependency to the cross scope configuration to various tables.
  3. Added functions GlideRecordDeleteMultiple() and GlideRecordSetValue() to perform said activities from global scope.
  4. Added function DocumentationAPI.RenderInstallationInstructionsAppInstall() to guide an admin to run the AppInstall() function during installation.
  5. Extended DocumentationAPI.RenderInstallationInstructionsImportFromSourceControl() with a new step to create a personal access token.
  6. Install() has been renamed to AppInstall().
  7. IsValidTable() now checks for an empty table name before getting the record.
  8. ATF test "DevTools - GetRolesFromUser" has been refactored into a single script.

1.18.0 - 2021-06-24

  1. Added function TestDataAPI.DeleteAllData() to delete all test data items.
  2. TestDataAPI.GetAllIncidents() now also lists the related task_sla records.
  3. TestDataAPI.CreateDatabaseView() now sets the order and left_join fields correctly.
  4. Added function IsArray() to check if a given value is an array or not.
  5. RenderValue() now displays nested empty arrays and empty objects as a separate row.
  6. RenderValue() now sorts keys of an object in a way that underscores are sorted to the end. This allows to implement a hierarchy using underscores as a prefix to a key name.
  7. RecordSetValue() is now using GlideRecordUpdate() internally making it more resilient against cross scope restrictions.
  8. Added module "Script Execution History" to access previous executions of background scripts.
  9. Refactoring to limit the use of Object.keys() to the GetKeys() function.

1.17.0 - 2021-06-21

  1. Added function GlideRecordDelete() to execute the deleteRecord member function of a GlideRecord in global scope.
  2. Added function SetProperty() to set any property regardless of its scope.
  3. Added function TestDataAPI.CreateDatabaseView() and associated functions to create database views as part of a test.
  4. TestDataAPI.CreateTestItem() did not delete the existing item before creating a new one, this has been fixed.
  5. Fixed the sort order in the "Query Log" module.
  6. The security notice regarding cross scope access configuration is now more prominent at the beginning of the documentation.
  7. The test step configuration "DevTools - Check scoped app sanity" now checks for notification subscriptions that are associated to the scoped app.

1.16.0 - 2021-06-10

  1. Changed the short description to "Code library and tools for ServiceNow developers".
  2. Added functions GlideRecordQuery(), GlideRecordInsert() and GlideRecordUpdate() to call GlideRecord's corresponding member functions in global scope.
  3. Added function IsValidDatabaseView() to check if the given string identifies a database view.
  4. Added function GetDatabaseViewsFromTable() to return all database views which use the given table.
  5. Added function ArrayRemoveValue() to remove a value from an array.
  6. Added function GetInstanceURL() to return the intance root URL.
  7. Added function GetTablesByColumnType() to return all tables which have at least one column of the given type.
  8. Function UserAddRole() is now public.
  9. Function IsValidTable() is now public.
  10. TestDataAPI.GetAllUsers() now also provides the user's roles.
  11. RecordSetValue() can now set values in records across scopes.
  12. Added the missing script macro for RenderBytes.

1.15.0 - 2021-05-05

  1. WARNING: New York is now longer actively supported.
  2. Added function IsTechnicalUser() to check if a given user is a technical user (i.e. web_service_access_only is set to true).
  3. Added function IsProperty() to check if a given system property exists.
  4. Added function AppSetProperty() to set a DevTools system property to a value.
  5. Added function UserImpersonate() which allows to impersonate a user from within a scoped application!
  6. Added function GetRecord() to serve as a shorthand to get a GlideRecord object for a record in a given table, identified by a sys_id.
  7. Added function GetRandomNumericToken() to create a pseudo-random numeric token string of a given length.
  8. Added function UserAddRole() to add a role to a user if the user doesn't have the role already.
  9. RunScriptInGlobalScope() did not work correctly if different scripts were provided within one transaction. It would always execute the first script during a transaction. This has been fixed. Please note that within a provided script, result values must now be set using "result =" instead of "return".
  10. RenderValue() now treats any object that has the sys_id key in the same way as a real GlideRecord object.
  11. GetGroupsFromUser() now checks for an empty user sys id. If an empty sys id was provided and for whatever reasons the sys_user_grmember has records with an empty sys_id, the associated groups would then be returned.
  12. Added view "DevTools" for scheduled jobs to show the "Run as" field.
  13. Renamed internal function SetDefaults() to AppSetDefaults().
  14. The test step configuration "DevTools - Check scoped app sanity" now uses IsTechnicalUser() to check correct configuration of scheduled jobs.

1.14.0 - 2021-04-20

  1. Added function RenderBytes() to return a user friendly number of bytes using KB, MB and GB where appropriate.
  2. Added function RecordDelete() to delete a single record based on a table name and the record sys id.
  3. RecordBulkProcessor() now detects if updating a record fails and aborts the processing. If the update fails, the maintenance date time field cannot be updated and the function would retry the same record until thresholds are reached.
  4. Added test "DevTools - Test data sanity" to check if all test data has been cleaned up in previous test runs.
  5. Added internal function SetDefaults() to set all DevTools system properties to their default values.

1.13.0 - 2021-04-15

  1. Added the StopWatch class which serves exactly as what its name suggests.
  2. Added function GetTimeNow() which is a shorthand for "new Date().getTime()".
  3. Added function GetTransactionRuntime() to return the amount of milliseconds passed since the start of the current transaction.
  4. GetGroupsFromUser() can now return the list of a user's groups with an encoded filter applied to the groups.
  5. Added function BusinessRuleGetOperation() to return the operation (of a business rule) based on the provided record.
  6. Debug() can now display the current transaction runtime in milliseconds. The new property x_snc_devtools.debug.log.transaction_runtime controls if the transaction runtime should be included or not.
  7. RenderValue() has been improved: In case of a GlideRecord, the table name, sys_id and number (if available) are displayed on top and a selected choice of fields leads the list of values despite the alphabetical order.
  8. The test step configuration "DevTools - Check scoped app sanity" now checks scheduled jobs for only technical users or the system admin serve as the run_as user.
  9. Added module "Query Log" to track invalid queries.
  10. The module "Outbox" is renamed to "Outbox or Sent" and displays sent mails.
  11. Improved column order in module "Storage Column Aliases".

1.12.2 - 2021-03-22

  1. Fixed a defect in IsVersionCompatible().

1.12.1 - 2021-03-22

  1. Fixed a defect in the test step configuration "DevTools - Check scoped app sanity".

1.12.0 - 2021-03-22

  1. RecordBulkProcessor() will no longer process the same record twice in one go.
  2. Test step configuration "DevTools - Check scoped app sanity" now checks for useless field level ACLs.
  3. Test step configuration "DevTools - Check scoped app sanity" now checks for misconfigured test steps.
  4. Test step configuration "DevTools - Check table cross scope access" checks if "Caller access" is set to "Caller Restriction".
  5. Added a comprehensive syntax editor macro for "RecordBulkProcessor" with boilerplate code.

1.11.0 - 2021-03-19

  1. Madrid is no longer supported.
  2. Added function RecordBulkProcessor() to process large amounts of records using a callback function.
  3. Added function Clone() to clone objects. This is to heal the JavaScript inherent design flaw around object references instead of copies.
  4. Added function Merge() to merge two objects.
  5. Added function RecordSetValue() to set a single field value on a given record.
  6. Added function IsObject() to distinguish objects from other types.
  7. Added function IsValidTable() since the TableUtils script include is not accessible from a scoped app.
  8. Added function RenderDateTime() since Javascript has no built-in function to render an ISO date/time string.
  9. Added function Sleep() to do nothing for a set amount of seconds.
  10. RenderValue() now has a second parameter "bHideEmpty". If set to true, empty values in objects are ignored - leading to better readable output.
  11. RenderValue() sorts keys of objects alphabetically. However, the keys "name", "short_description", "number" and "sys_id" will always lead the pack.
  12. RenderValue() now displays empty objects as "{}".
  13. IsEqual() can now compare objects.
  14. TestDataAPI: Added function GetAllData() and corresponding functions for each supported record type GetAllIncidents(), GetAllProblems(), etc.
  15. TestDataAPI: Added function CreateTestItem() and GetAllTestItems() to manage entries in the table x_snc_devtools_test which is used for testing.
  16. ParseDateTime() is now more resilient against incorrect input.
  17. The test step configuration "DevTools - Check scoped app sanity" now checks for empty descriptions in publicly accessible script includes.
  18. Improved installation instructions.

1.10.0 - 2021-02-26

  1. Added function GetAppName() to return the name of a scoped application but without any name postfixes to indicate work in progress. This function is needed to create clean test step configuration descriptions.
  2. Added function AppSanity() which performs a number of changes to a scoped app's assets to maintain applicaton sanity. E.g. the function removes the copied_from attribute in atf tests.
  3. RenderValue() was improved: In case of objects, the keys are displayed in alphabetical order. In case of arrays, the elements are displayed in the given order as before.
  4. Added function DocumentationAPI::RenderListItem() and refactored all Render*() functions.
  5. The test step configuration "DevTools - Check scoped app sanity" now checks for jelly breakpoints in UI pages.
  6. Added configuration options section to the documentation.
  7. Removed unnecessary debug logging in TestDataAPI.

1.9.0 - 2021-02-15

  1. Quebec is now supported.
  2. Added function GetRolesFromUser() to get the sys_ids of all active roles of a user.
  3. Added function TestDataAPI::CreateRole() to create a role for testing purposes.
  4. TestDataAPI::CreateUser() now also accepts the name of a role without the prefix.
  5. Added function DocumentationAPI::RenderInstallationInstructionsImportFromSourceControl() to render installation instructions for importing an application from source control.
  6. Added function DocumentationAPI::RenderDisclaimer().
  7. Improved the rendering of script include documentation in DocumentationAPI::RenderScriptIncludes().
  8. Added missing description to the DocumentationAPI script include.
  9. Test step configuration "DevTools - Check scoped app sanity" now checks if the app's short_description is empty.
  10. Test step configuration "DevTools - Check scoped app sanity" now checks if a module's link_type is set to "HTML" (which doesn't work properly).

1.8.0 - 2021-01-21

  1. Added the DocumentationAPI class to render HTML fragments for a documentation UI page.

1.7.0 - 2021-01-20

  1. Added function IsValidVersion() to check for a valid (ServiceNow app) version string.
  2. Added function IsVersionCompatible() to check a version against a requirement.
  3. Added test step configuration "DevTools - Check scoped app dependency". This test step configuration checks if another required scoped application is installed in a (backward) compatible version.
  4. Added module "Background Script" to open the background script page in a new window.
  5. Added new navigation section "Transaction" and moved all transaction related modules into it.
  6. Added new navigation section "Cache" for easy access to the cache inspection tool and to flush the cache.
  7. Added new navigation section "Events" to easily access the event log, event registry, notifications, and outbox.
  8. Added more test cases for GetIntegerValue().

1.6.0 - 2021-01-14

  1. Added function IsTableCrossScopeAccessible() to check if applications from other scopes can perform read, create, update and delete operations on the given table.
  2. Added function RunScriptInGlobalScope() to run a script in the global scope from within a scoped application. Note that the function required full cross scope access to the sys_script_include table.
  3. IsEqual() now uses type strict comparison and will no longer return true in case of IsEqual(1,"1").
  4. The "Rerun Test" button has been renamed to "Run Test" and is now available on all forms that directly refer to an ATF test (including test steps).
  5. The ATF tests "TestDataAPI" and "GetGroupsFromUser" now make use of the "DevTools - IsTableCrossScopeAccessible" test step configuration to check if the cross scope access to the tables is configured.
  6. The ATF test "Installation" now checks if the system property glide.record.legacy_cross_scope_access_policy_in_script is set to true to avoid cross scope access policy errors. Refer to KB0711970.

1.5.0 - 2020-11-23

  1. Added test step configuration "DevTools - Check scoped app sanity". This test step configuration takes a scoped application and checks if all its sys_properties are NOT set to private, and all ATF tests have an empty copied_from field. More checks will be added later.
  2. Added test step configuration "DevTools - Check table cross scope access"
  3. Added test step configurations to the documentation.
  4. Added test "DevTools - Installation" to check if all relevant tables are configured according to the installation guide.
  5. Added test "DevTools - App Sanity" to check if the app sanity is ok.
  6. Added table sys_user to the list of tables which need full cross scope access.

1.4.0 - 2020-11-16

  1. Added function IsUserSecurityAdmin().

1.3.0 - 2020-11-04

  1. Added class TransactionCacheAPI.
  2. Added function HtmlEncode().
  3. Added function GetKeys().
  4. Added function StringRemoveCharacters().
  5. Part of the documentation is generated automatically based on record descriptions.

1.2.4 - 2020-09-10

  1. ParseDateTime() has been repaired, aligned to UTC and the corresponding test has been implemented.
  2. LoadMessages() now takes the language as the second parameter. Defaults to 'en'.
  3. GetBoolValue() was not accessible out of scope. This has been fixed.
  4. IsValidRecord() now also checks for type ScopedGlideRecord and ScopedGlideRecordSecure. The ATF test has been updated accordingly.
  5. TestDataAPI functions now display the sys_ids of created records in the log.
  6. Added the "Cancel Transactions" module.
  7. Added test and macro for IsUserHasRoleExactly().
  8. Added the system property x_snc_devtools.ui.list_button to control if the "List" button should be visible or not.
  9. Extended documentation with a reference to all script includes.

1.2.3 - 2020-08-21

  1. Added the "Transaction Log" module.
  2. "Evaluator Log", "Debug Log" and "App Log" modules only show the last 30 minutes.
  3. Added the "Storage Column Aliases" module.
  4. RenderValue() can now work properly with nested objects.

1.2.2 - 2020-08-02

  1. RenderValue() no longer causes the following error: com.glide.script.fencing.MethodNotAllowedException: Function getValue is not allowed in scope x_snc_devtools.

1.2.1 - 2020-07-30

  1. GetArrayValue() now returns an empty array for an empty string.

1.2.0 - 2020-07-07

  1. Added TestDataAPI.CreateRequest() and extended the ATF test "DevTools - TestDataAPI"
  2. Refactoring of several functions in TestDataAPI. Caller and Opener users can now be set explicitly.
  3. Added function IsValidRecord()

1.1.0 - 2020-07-03

  1. Added TestDataAPI.CreateProblem() and TestDataAPI.CreateProblemTask()
  2. The install script is now a scheduled script that can be run on demand instead of a fix script that runs automatically.

1.0.0 - 2020-06-23

First baselined version