Custom Step Configuration for Pausing an ATF Test for Debugging
Something I've found helpful in developing ATF tests is having the ability to Pause an ATF test, so that I can see what is happening while a test is in a particular state. Using this method, I've found things that were breaking tests that I don't think I would have found any other way. To give a recent example, I learned that when you set the password on a user record using a Record Update step, the password doesn't get encrypted, so you can't use that password for that user later in a REST call step. However, if you enter the encrypted value in the Record Update step, then you can use the password later.
You can pause a step with a record, catalog item, or custom page displayed in the client test runner, or without anything displayed in the test runner. The test will pause for the length of the step's timeout, or until you press the escape key.
To be able to Pause an ATF test, you'll need to do the following:
- Create a custom UI step configuration.
- Code the Pause step configuration.
- Add a Pause step to your test.
Create a Custom UI Step Configuration
The first thing you'll need to do is create a custom UI step configuration. For how to do that, see this article.
Code for the Pause Step Configuration
Open a custom UI Step Configuration you have created, change the name to something clever like Pause, and then do an Insert and Stay to create your step configuration, and then populate it with the following values:
- Name: Pause
- Step environment: UI
- Category: Form
- Template reminder: Pause
- HTML description: This step is used to pause the execution of the test execution. The test will be paused for the length of the Time Out. This step can be used for debugging. When you no-longer need to pause the test execution, you should either delete or disable this step, or simply set the time out to 0.
- Description generation script: -- see below --
- Step execution script: -- see below --
Description generation script
This is the script that will generate the description that appears in steps created from the step configuration.
function generateDescription() {
// the global variable 'step' represents the current glide record
var timeOut = current.timeout;
if (gs.nil(timeOut)) {
timeOut = 0;
} else {
// var x = new GlideDuration();
timeOutString = timeOut.getDurationValue();
var parts = timeOutString.split(":");
var hrsSeconds = parseInt(parts[0].replace(/^0/, "")) * 60 * 60;
var minSeconds = parseInt(parts[1].replace(/^0/, "")) * 60;
var seconds = parseInt(parts[2].replace(/^0/, ""));
timeOut = hrsSeconds + minSeconds + seconds;
}
var description = "Pause for " + timeOut + " seconds";
return description;
}
generateDescription();
Step execution script
This is the script that is executed by the client test runner.
(function(step, stepResult, assertionObject) {
assertionObject.executeStep = function(step, stepResult) {
var MESSAGE_KEY_PAUSING = "Running pause. Click on the page and then press the escape key to continue running or else wait for the timeout of " + step.timeout + " seconds";
var messages = new GwtMessage().getMessages([MESSAGE_KEY_PAUSING]);
g_ui_testing_util.setTestStepStatusMessage(messages[MESSAGE_KEY_PAUSING]);
var testFrameWindow = g_ui_testing_util.getTestIFrameWindow();
var pauseCount = step.timeout;
if (isNaN(pauseCount))
pauseCount = 0;
var utilInterval = null;
var pauseInterval = null;
if (pauseCount > 0) {
// Add this event listener so make the wait happen
try{
testFrameWindow.document.body.addEventListener("keydown", cancelWait);
}
catch(e){
}
utilInterval = g_ui_testing_util._getAngularInjector("$interval");
pauseInterval = utilInterval(doPause, 1000);
} else {
doPause(0);
}
function breakWait() {
stepResult.success = true;
if (utilInterval != null)
utilInterval.cancel(pauseInterval);
g_ui_testing_util.setTestStepStatusMessage(stepResult.message);
step.defer.resolve();
}
function doPause(iterationCount) {
var testFrameWindow = g_ui_testing_util.getTestIFrameWindow();
testFrameWindow.document.body.addEventListener("keydown", cancelWait);
testFrameWindow.alert = function(){ return true;};
testFrameWindow.confirm = function(){ return true;};
if (iterationCount >= pauseCount || utilInterval == null) {
breakWait();
}
}
function cancelWait(event) {
var x = event.keyCode;
if (x == 27) { // escape key
breakWait();
}
}
};
assertionObject.canMutatePage = step.can_mutate_page;
})(step, stepResult, assertionObject);
UI Policy to Make the Timeout Field Visible
To make the timeout field visible, you need to add a custom UI policy.
Create a UI Policy record with the following properties
- Table: Test Step [sys_atf_step]
- Short description: Show timeout (Custom)
- Conditions: Step config.Step environment is UI -and- Step config.Protection policy is --None--You will need to dot-walk to these fields. In the field list, click Show Related fields, which will be at the bottom of the list. Then in the field list, choose Step Config --> Test step config fields. The list will refresh and you can choose Step Environment field. Go through the same process to select the Step Config.Protection field.
- Global: true
- On load: true
- Reverse if false: false
- Inherit: false
- Order: 500
You'll need to set the order on the list view. We are using 500 so our UI policy doesn't conflict with the out of the box UI policy for showing/hiding the timeout field.
Add a UI Policy Action with the following properties
- Field name: Timeout
- Mandatory: Leave alone
- Visible: True
- Read only: Leave alone
Now we'll be able to see the timeout field.
That's it. You can now add this step to your test and pause the test execution. When you no longer want to pause the execution, disable the step or delete it.
Being able to Pause my ATF tests has been really helpful to me. I hope you find it helpful too.
Thanks,
Cody
https://www.servicenow.com/community/developer-articles/custom-step-configuration-for-pausing-an-atf-test-for-debugging/ta-p/2297441