fix(variables): correct scripted-variable persistence races and cross-request propagation (#8406)

* feat(collections): implement sliding window for script request UIDs to manage stale updates

- Introduced a bounded sliding window mechanism for tracking recent script request UIDs, allowing for better handling of stale updates from superseded or cancelled requests.
- Updated relevant functions to utilize the new `isStaleScriptRequest` utility for improved clarity and maintainability.
- Enhanced the persistence logic to ensure that updates from retired requests do not interfere with newer requests, improving data integrity during concurrent operations.
- Added comprehensive tests to validate the behavior of the new UID management system and its impact on variable propagation across requests.

* refactor(tests): remove outdated test for persistentEnvVariables in runtime tests

- Eliminated the test case that checked for the inclusion of persistentEnvVariables in the result, as it is no longer relevant.
- Cleaned up the test suite to enhance clarity and maintainability, focusing on relevant assertions for variable management.

* refactor(collections): simplify environment persistence logic and remove stale request handling

- Updated the `persistActiveEnvironment` and related functions to eliminate the requestUid parameter, streamlining the logic for environment persistence.
- Removed outdated checks for stale updates from superseded requests, enhancing clarity and maintainability.
- Deleted the `_scriptRequestUids` management code and associated tests, as they are no longer necessary for the current implementation.
- Improved the handling of environment updates to ensure accurate state management without stale data interference.

* refactor(filesystem): remove unused hasJsExtension function

- Deleted the `hasJsExtension` utility function from the filesystem module as it was no longer needed.
- Cleaned up the exports to enhance clarity and maintainability of the codebase.

* test(network): add unit tests for applyCollectionVarsToCollectionRoot

* refactor(ipc, environments): implement file locking for environment updates

- Updated the environment persistence logic in both `collection.js` and `workspace-environments.js` to utilize file locking during read and write operations.
- This change ensures that concurrent access to environment files is managed safely, preventing potential data corruption and enhancing reliability during updates.
This commit is contained in:
sanish chirayath
2026-07-03 14:44:38 +05:30
committed by GitHub
parent b4e783d9e9
commit e7197d6363
21 changed files with 578 additions and 76 deletions

View File

@@ -0,0 +1,24 @@
import { test } from '../../../../playwright';
import { openCollection, selectEnvironment } from '../../../utils/page';
import { runCollection, validateRunnerResults } from '../../../utils/page/runner';
test.describe('Script collection-variable propagation across requests in one runner invocation', () => {
test('request 2 observes request 1\'s setCollectionVar write', async ({
pageWithUserData: page
}) => {
await openCollection(page, 'collection-var-multi-request-test');
await selectEnvironment(page, 'Test');
await runCollection(page, 'collection-var-multi-request-test');
// Both requests should pass: req-1 sets counter="1"; req-2 reads counter
// (must see "1"), records it in seenInReq2, then sets counter="2".
// If applyCollectionVarsToCollectionRoot didn't propagate the change to
// collection.root.request.vars.req, req-2's mergeVars would rebuild
// collectionVariables from the pre-run "0" and req-2's first test would fail.
await validateRunnerResults(page, {
totalRequests: 2,
passed: 2,
failed: 0
});
});
});

View File

@@ -0,0 +1,9 @@
{
"version": "1",
"name": "collection-var-multi-request-test",
"type": "collection",
"ignore": [
"node_modules",
".git"
]
}

View File

@@ -0,0 +1,7 @@
meta {
name: collection
}
vars:pre-request {
counter: 0
}

View File

@@ -0,0 +1,3 @@
vars {
host: https://testbench-sanity.usebruno.com
}

View File

@@ -0,0 +1,21 @@
meta {
name: req-1-write
type: http
seq: 1
}
get {
url: {{host}}/ping
body: none
auth: none
}
script:post-response {
bru.setCollectionVar("counter", "1");
}
tests {
test("request 1 wrote counter=1", function() {
expect(bru.getCollectionVar("counter")).to.equal("1");
});
}

View File

@@ -0,0 +1,31 @@
meta {
name: req-2-read-and-write
type: http
seq: 2
}
get {
url: {{host}}/ping
body: none
auth: none
}
script:post-response {
// Request 2 must observe request 1's setCollectionVar write. The electron-side
// applyCollectionVarsToCollectionRoot in sendVariableUpdates is what makes this
// visible — without it, mergeVars rebuilds request 2's collectionVariables from
// the original collection.root and req-2's read returns "0".
const prev = bru.getCollectionVar("counter");
bru.setCollectionVar("seenInReq2", prev);
bru.setCollectionVar("counter", "2");
}
tests {
test("request 2 observed request 1's collection-var write", function() {
expect(bru.getCollectionVar("seenInReq2")).to.equal("1");
});
test("request 2 wrote counter=2", function() {
expect(bru.getCollectionVar("counter")).to.equal("2");
});
}

View File

@@ -0,0 +1,10 @@
{
"collections": [
{
"path": "{{collectionPath}}/collection-var-multi-request-test",
"securityConfig": {
"jsSandboxMode": "developer"
}
}
]
}

View File

@@ -0,0 +1,5 @@
{
"lastOpenedCollections": [
"{{collectionPath}}/collection-var-multi-request-test"
]
}