Dynamically retrieving the approver user in ATF and impersonating them
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hello community — I'm facing an issue with ATF impersonation and hope someone can point out what I might be missing.
Environment & context
I have an ATF test where:
Step 36 is a Record Query that successfully returns a sysapproval_approver record (I can see the approval record sys_id in Step 36 output).
Step 37 is a Run Server-side Script that should read the Step 36 output, query sysapproval_approver, extract the approver (a reference to sys_user), and return a record output in the format the Impersonate step expects:
outputs.record = { document_id: "<sys_user_sys_id>", table: "sys_user" }
What I expect to happen
Step 37 prepares outputs.record with the approver sys_user id.
Step 38 (Impersonate) is configured to use {{Step 37: Run Server Side Script.Record}} (dot-walk → Step 37 → Record → document_id) and should impersonate that user so the remaining ATF steps run in that user's context.
What actually happens
Step 37 executes successfully (no script error).
However, Step 38 fails with:
User to impersonate not specifiedIn Step 38 I selected the user via the dot-walk UI (Step 37 → Record → document_id). The Impersonate field shows that reference, but the step fails at runtime.
What I tried already
I made the Step 37 script robust so it detects either steps[36].first_record.document_id or steps[36].record_id (I log both).
I tried returning outputs.record as shown above.
I also tried returning an alternative name (outputs.user) and other shapes, but Impersonate only accepts a dot-walkable Record → document_id.
Here´s the code - Step 37 script (full) that I used
(function(outputs, steps, stepResult) {
try {
gs.info("ATF Step 37: starting - reading Step 36 outputs...");
var approvalRecordSysId = null;
if (steps[36] && steps[36].first_record && steps[36].first_record.document_id) {
approvalRecordSysId = steps[36].first_record.document_id;
gs.info("ATF Step 37 debug: found steps[36].first_record.document_id = " + approvalRecordSysId);
} else if (steps[36] && steps[36].record_id) {
approvalRecordSysId = steps[36].record_id;
gs.info("ATF Step 37 debug: found steps[36].record_id = " + approvalRecordSysId);
} else if (steps[36] && steps[36].first_record) {
approvalRecordSysId = steps[36].first_record;
gs.info("ATF Step 37 debug: found steps[36].first_record (fallback) = " + approvalRecordSysId);
}
if (!approvalRecordSysId) {
stepResult.setFailed("Step 37 failed: could not read approval record id from Step 36. Inspect Step 36 outputs.");
return;
}
var grApproval = new GlideRecord("sysapproval_approver");
if (!grApproval.get(approvalRecordSysId)) {
stepResult.setFailed("Step 37 failed: sysapproval_approver record not found for id: " + approvalRecordSysId);
return;
}
var approverSysId = grApproval.getValue("approver");
if (!approverSysId) {
stepResult.setFailed("Step 37 failed: 'approver' field is empty on sysapproval_approver record: " + approvalRecordSysId);
return;
}
gs.info("ATF Step 37 debug: approver sys_id = " + approverSysId);
outputs.record = {
document_id: approverSysId,
table: "sys_user"
};
outputs.record_id = approverSysId;
outputs.record_table = "sys_user";
stepResult.setOutputMessage("Step 37 succeeded: prepared outputs.record for sys_user " + approverSysId);
} catch (ex) {
stepResult.setFailed("Step 37 exception: " + ex.message);
}
})(outputs, steps, stepResult);
Important: If I manually enter the approver’s username in the Impersonate step, the test runs successfully until the end. This confirms that Step 36 is correct and is returning the sys_id of the approval record.
Here´s some prints that might me usefull.
Step 38 failed: User to impersonate not specified
Is the outputs.record = { document_id: "<sys_id>", table: "sys_user" } shape definitely the correct format for the ATF Impersonate step to consume?
Could there be a timing/serialization issue where the Impersonate step evaluates the dot-walk reference before the Run Script outputs are fully available? If so, any workaround?
Has anyone seen the Impersonate step return “User to impersonate not specified” even though the preceding Run Script produced outputs.record? If so, what fixed it?
Thank you in advance for any help or pointers. Any sample working snippet or a note about version-specific behavior would be very appreciated.
Kind regards,
Rafael
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 weeks ago - last edited 2 weeks ago
Hi @rafaelmach7x ,
You can use the below simple script to do the same action.
If my answer helped, please mark it as helpful or accept as the solution.
Regards,
Chidanand
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 weeks ago
Hi Chidanand_VK!
Thanks for your help!
I don’t want to manually enter the sys_id, because that’s not sustainable in tests that may change.
Ideally, the script or ATF itself should be able to dynamically determine the sys_id of step 36, or the step should be configured to pass this information through an output.
In this line of code, I understood that you want me to manually enter the sys_id of step 36.
var prevStep = "XXXXXXXXX"; //Sys Id of Step 36
That’s why I tried this approach below in my script, but it didn’t work...
steps[36] && steps[36].first_record && steps[36].first_record.document_id
Is there a way to dynamically determine the sys_id of step 36?
Kind regards!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
a week ago
Hi @rafaelmach7x ,
"I don’t want to manually enter the sys_id, because that’s not sustainable in tests that may change."
When you mention NOT sustainable, What that mean? any below statement or anything else?
->If you copy the Test and run that New Test, it will not work?
->The execution will NOT successfully works every time?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
a week ago - last edited a week ago
Hi @Chidanand_VK
I really appreciate your effort in helping me.
Every time I run the test, the sys_id is different. I can’t set the sys_id manually, you know?
That’s why I need a way to retrieve the sys_id dynamically from the step 36.