Skip to content

Commit efeb00e

Browse files
committed
Merge branch 'release/7.46.1'
2 parents 7a72ed9 + 32a3ec3 commit efeb00e

File tree

6 files changed

+182
-5
lines changed

6 files changed

+182
-5
lines changed

CHANGELOG.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
7.46.1:
2+
date: 2025-09-15
3+
fixed bugs:
4+
- >-
5+
GH-1526 Fixed a bug where nested requests were aborting the run on
6+
assertion failures
7+
- >-
8+
GH-1527 Add support for invoking parent request trigger from nested
9+
requests
10+
111
7.46.0:
212
date: 2025-09-08
313
new features:

lib/runner/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ _.assign(Runner.prototype, {
4343
['environment', 'globals', 'vaultSecrets', 'data']), this.options.run) || {};
4444

4545
// Ensure we have a default value for max invokable nested requests
46-
!runOptions.maxInvokableNestedRequests && (runOptions.maxInvokableNestedRequests = 5);
46+
!runOptions.maxInvokableNestedRequests && (runOptions.maxInvokableNestedRequests = 10);
4747

4848
// start timeout sanitization
4949
!runOptions.timeout && (runOptions.timeout = {});

lib/runner/nested-request.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ function runNestedRequest ({ executionId, isExecutionSkipped, vaultSecrets, item
109109
environment: environment,
110110
localVariables: localVariables,
111111
vaultSecrets: clonedVaultSecrets,
112-
abortOnFailure: true,
112+
stopOnError: true,
113113
host: {
114114
// Reuse current run's sandbox host across nested executions
115115
external: true,
@@ -155,6 +155,14 @@ function runNestedRequest ({ executionId, isExecutionSkipped, vaultSecrets, item
155155
}
156156
}
157157
},
158+
request (err, _cursor, ...rest) {
159+
// For nested requests, the request event should bubble up to the parent.
160+
// This event is merely used for notifying the consumer that a nested request was sent
161+
// similar to pm.sendRequest. So the consumer can work this into logs & any other logic.
162+
if (typeof self.triggers.request === 'function') {
163+
self.triggers.request(err, self.state.nestedRequest.rootCursor, ...rest);
164+
}
165+
},
158166
exception (_, err) {
159167
if (err) {
160168
exceptionForThisRequest = err;

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "postman-runtime",
3-
"version": "7.46.0",
3+
"version": "7.46.1",
44
"description": "Underlying library of executing Postman Collections",
55
"author": "Postman Inc.",
66
"license": "Apache-2.0",

test/integration/runner-spec/run-collection-request.test.js

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,4 +726,163 @@ describe('pm.execution.runRequest handling', function () {
726726
});
727727
});
728728
});
729+
730+
it('should not abort execution on encountering failure in nested request assertions', function (done) {
731+
const collection = new sdk.Collection({
732+
item: [{
733+
event: [{
734+
listen: 'prerequest',
735+
script: {
736+
exec: `
737+
await pm.execution.runRequest("nested-request-id");
738+
pm.test('[l0-prerequest] this test should have run', function () {
739+
pm.expect(true).to.equal(true);
740+
});
741+
`
742+
}
743+
}, {
744+
listen: 'test',
745+
script: {
746+
exec: `
747+
pm.test('[l0-test] this test should also have run', function () {
748+
pm.expect(true).to.equal(false);
749+
});
750+
`
751+
}
752+
}],
753+
request: {
754+
url: 'https://postman-echo.com/get',
755+
method: 'GET'
756+
}
757+
}]
758+
});
759+
760+
new collectionRunner().run(collection,
761+
{
762+
script: {
763+
requestResolver (_requestId, callback) {
764+
callback(null, {
765+
item: {
766+
id: 'nested-request-id',
767+
event: [
768+
{
769+
listen: 'prerequest',
770+
script: {
771+
exec: `
772+
pm.test('[l1-failure-test] this test should have failed', function () {
773+
pm.expect(true).to.equal(false);
774+
});
775+
`
776+
}
777+
}
778+
],
779+
request: {
780+
url: 'https://postman-echo.com/post',
781+
method: 'POST'
782+
}
783+
}
784+
});
785+
}
786+
}
787+
},
788+
function (_err, run) {
789+
let assertionCount = 0,
790+
expectedOrder = [false, true, false],
791+
actualOrder = []; // Expected order of assertion results
792+
793+
run.start({
794+
assertion (_cursor, assertions) {
795+
assertions.forEach((assertion) => {
796+
assertionCount++;
797+
actualOrder.push(assertion.passed);
798+
});
799+
},
800+
done (err) {
801+
expect(assertionCount).to.eql(3); // All 3 assertions should have run
802+
expect(actualOrder).to.deep.eql(expectedOrder);
803+
done(err);
804+
}
805+
});
806+
});
807+
});
808+
809+
it('should invoke passed-down request trigger callback', function (done) {
810+
const collection = new sdk.Collection({
811+
item: [{
812+
event: [
813+
{
814+
listen: 'prerequest',
815+
script: {
816+
exec: `
817+
await pm.execution.runRequest(
818+
"nested-request-id",
819+
{ variables: { method: "post" } }
820+
);
821+
`
822+
}
823+
}
824+
],
825+
request: {
826+
url: 'https://postman-echo.com/{{parent_method}}',
827+
method: 'GET'
828+
}
829+
}]
830+
});
831+
832+
new collectionRunner().run(collection,
833+
{
834+
script: {
835+
requestResolver (_requestId, callback) {
836+
callback(null, {
837+
item: {
838+
id: 'nested-request-id',
839+
event: [
840+
{
841+
listen: 'prerequest',
842+
script: {
843+
exec: 'pm.globals.set("parent_method", "get");'
844+
}
845+
}
846+
],
847+
request: {
848+
url: 'https://postman-echo.com/{{method}}',
849+
method: 'POST'
850+
}
851+
}
852+
});
853+
}
854+
}
855+
},
856+
function (_err, run) {
857+
let requestConsoleInvocationCount = 0,
858+
invocationOrder = [];
859+
860+
run.start({
861+
request (_err, cursor, response, request, item, cookies, history) {
862+
requestConsoleInvocationCount++;
863+
invocationOrder.push(request.url.toString());
864+
865+
expect(history.execution).to.be.ok;
866+
expect(response.status).to.be.ok;
867+
868+
if (requestConsoleInvocationCount === 1) {
869+
// For nested request cursors: scriptId should be non-empty
870+
// Used by consumers to mark the log as an indirect request
871+
expect(cursor.scriptId).to.be.ok;
872+
}
873+
874+
expect(request).to.be.ok;
875+
expect(item).to.be.ok;
876+
expect(cookies).to.be.ok;
877+
},
878+
done (err) {
879+
expect(requestConsoleInvocationCount).to.eql(2); // Nested request + Parent request
880+
expect(invocationOrder).to.deep.equal([
881+
'https://postman-echo.com/post', 'https://postman-echo.com/get'
882+
]);
883+
done(err);
884+
}
885+
});
886+
});
887+
});
729888
});

0 commit comments

Comments
 (0)