From f6e2279fe36d057655d6ff7ef293c459133b0f73 Mon Sep 17 00:00:00 2001 From: sanish-bruno Date: Wed, 12 Nov 2025 15:38:40 +0530 Subject: [PATCH] feat: hooks runtime add: hooks component add support for hooks within bruno-lang fix: hooks is not getting save hooks implemtation add hooks component within folders, requests add: quick js shims for hooks fix: garbage collected hook managers send logs to main rm: hook manager store feat: introduce HOOK_EVENTS constant for improved hook management add folder start/end events add folder run events rm: folder run related events add cli support for hooks support script:hooks instead of hooks move hooks to script tab make outer scope available within callback in safemode added runner, req apis as an abstraction over event based hooks fix: crash while editing folder hooks rm: unused files fix: self review changes refactor, request specific hook manager deleted once add: cm rm: spaces add prompt var rm: indent fix: lint refactor: shims handling for hooks fix: enable async calling in dev mode for gui, cli fix: support async callbacks within safe mode rm: vm instance fix: review comments fix: review comments add cli tests for hooks rm: client certs fix: add hooks to oc yaml fix: rename uid ot path name for better clarity, app crash when saving folder hooks rm: console rm: vm2 runtime leftover rm: check add: handler cleanup function add: playwright test case for hooks rm: review fixes fix: review comments add fallback hook manager add fallback hook manager fix: show error from hooks scripts within response pane change: collection events name feat: add name spaced hooks fix: review comments add: hooks specific collection for testing use hooks manager as a private field fix: tests use collection from bruno-test within playwright rm: databuffer test fix: playwright test rm: unintended changes rm: file --- .../bruno-electron/src/ipc/network/index.js | 51 +++++++++++++++++++ .../collection-run-start-setup.bru | 3 +- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index 1b3f8547e..cf3906e4b 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -1412,6 +1412,57 @@ const registerNetworkIpc = (mainWindow) => { folder = collection; } + // Create a map to store HookManagers for this collection/folder run + // Key format: 'collection:', 'folder:', 'request:' + const hookManagersMap = new Map(); + + // Register collection-level hooks immediately + const collectionHookManagerOptions = { + request: {}, // Placeholder request for hook registration + envVars, + runtimeVariables, + collectionPath, + processEnvVars, + scriptingConfig, + runRequestByItemPathname, + collectionName: collection?.name, + onConsoleLog: (type, args) => { + console[type](...args); + mainWindow.webContents.send('main:console-log', { + type, + args + }); + } + }; + + const collectionRoot = collection?.draft?.root || collection?.root || {}; + const collectionHooks = get(collectionRoot, 'request.script.hooks', ''); + const collectionHookManagerKey = `collection:${collectionPath}`; + await getOrCreateHookManager(hookManagersMap, collectionHookManagerKey, collectionHooks, collectionHookManagerOptions); + const isCollectionRun = folder?.uid === collection?.uid; + + // If a folder is being run (not the collection itself), register folder hooks along the folder path tree + if (folder && !isCollectionRun) { + const folderTreePath = getTreePathFromCollectionToItem(collection, folder); + + // Extract folder hooks from the folder tree path + for (const pathItem of folderTreePath) { + if (pathItem.type === 'folder') { + const folderRoot = pathItem?.draft || pathItem?.root; + const folderHooks = get(folderRoot, 'request.script.hooks', ''); + if (folderHooks && folderHooks.trim() !== '') { + const folderHookManagerKey = `folder:${pathItem.pathname}`; + await getOrCreateHookManager(hookManagersMap, folderHookManagerKey, folderHooks, collectionHookManagerOptions); + } + } + } + } + + if (isCollectionRun) { + const collectionHookManager = hookManagersMap.get(collectionHookManagerKey); + await collectionHookManager.call(HOOK_EVENTS.RUNNER_BEFORE_COLLECTION_RUN, { collection, collectionUid }); + } + mainWindow.webContents.send('main:run-folder-event', { type: 'testrun-started', isRecursive: recursive, diff --git a/packages/bruno-tests/hooks-comprehensive-tests/collection-run-start-setup.bru b/packages/bruno-tests/hooks-comprehensive-tests/collection-run-start-setup.bru index 66e0b9b3f..2f845427d 100644 --- a/packages/bruno-tests/hooks-comprehensive-tests/collection-run-start-setup.bru +++ b/packages/bruno-tests/hooks-comprehensive-tests/collection-run-start-setup.bru @@ -20,10 +20,9 @@ tests { const apiToken = bru.getEnvVar('api-token'); expect(apiToken).to.equal('mock-token-12345'); }); - + test("request should have access to setup vars", function() { const setupComplete = bru.getVar('setup-complete'); expect(setupComplete).to.equal('true'); }); } -