usebruno / bruno

Opensource IDE For Exploring and Testing Api's (lightweight alternative to postman/insomnia)
https://www.usebruno.com/
MIT License
27.92k stars 1.3k forks source link

[Feature Request] Collection-Level Pre/Post Request Scripts #334

Open giuseppemilicia opened 1 year ago

giuseppemilicia commented 1 year ago

I would like to propose the addition of a feature that allows users to define pre/post request scripts at the collection level in order to execute them before/after each call made within that collection. This would greatly enhance the flexibility and functionality of the platform.

Is it possible to consider implementing this feature in future updates? Thank you for your consideration.

Tasks

helloanoop commented 1 year ago

Is it possible to consider implementing this feature in future updates?

Yes, we will implement this.

The plan is to have index.bru at the collection level that can render an ui to configure pre/post request scripts as well as collection level vars. This would take some time, but its a priority on our roadmap.

In the meanwhile, I also want to propose a concept called hooks so that users who are willing to get their hands dirty and code this in an editor can implement collection level pre and post requests before the UI support comes up.

Hooks Design

A property called "hooks" can be added to the bruno.json file.

{
  "version": "1",
  "name": "bruno-testbench",
  "type": "collection",
  "hooks": "./hooks.js"
}

The hooks.js file

const preRequest = ({
  request,
  envVars,
  collectionVariables,
  collectionPath,
  processEnvVars
}) => {
  // do something with the request
  return request;
};

const postRequest = ({
  response,
  envVars,
  collectionVariables,
  collectionPath,
  processEnvVars
}) => {
  // do something with the response
  return response;
};

module.exports = {
  preRequest,
  postRequest
}

Hooks is medium level feature that can be implemented by our community. I am hoping we should be able to enhance our existing script scripting run time make hooks work.

@DivyMohan14 You have experience with our script runtime, Let me know what you think of this approach and if you have some bandwidth to take a stab at this.

We can gradually enhance hooks later to support things like preCollectionRun and postCollectionRun

helloanoop commented 1 year ago

Ignore above commit. This fix is actually related to issue #333

giuseppemilicia commented 1 year ago

Thank you for considering this enhancement! I've taken the initiative to contribute to this feature by creating a pull request. In my pull request, I've included an initial version of the proposed functionality. Your feedback on the implementation would be greatly appreciated.

Pull Request: #366

helloanoop commented 1 year ago

Collection level Auth, Headers, Scripts and Tests are now available in v0.22.0 🚀🚀

image

giuseppemilicia commented 1 year ago

@helloanoop do you think it would be possible to leverage collection.bru to extend this functionality to a directory level? This way, the collection level would be applied, and for each directory within, their respective scripts/headers/ecc.. would be interpreted.

martinsefcik commented 1 year ago

@helloanoop Does it make sense to have two files bruno.json and collection.bru ? Couldn't it be better to merge it all to one collection.bru file ?

Are you planning to add such bru file for folder level ? This file in folder could be automatically created when new folder is created, so this way only folders with this bru file will be displayed in UI, because I don't want to see some folders in UI (e.g. folders with scripts, attachment files, ...)

giuseppemilicia commented 1 year ago

@helloanoop Does it make sense to have two files bruno.json and collection.bru ? Couldn't it be better to merge it all to one collection.bru file ?

Are you planning to add such bru file for folder level ? This file in folder could be automatically created when new folder is created, so this way only folders with this bru file will be displayed in UI, because I don't want to see some folders in UI (e.g. folders with scripts, attachment files, ...)

Additionally, this feature could also provide the ability to define a specific order or sequence for the directories, enhancing organization and accessibility within the UI.

vaurat commented 1 year ago

Hello, It's for me the killer feature that would make me switch definitely from Postman to Bruno.

helloanoop commented 1 year ago

do you think it would be possible to leverage collection.bru to extend this functionality to a directory level?

@giuseppemilicia @martinsefcik Yes. Folder/Directory level scripts, headers, auth etc are in the roadmap.

Does it make sense to have two files bruno.json and collection.bru ? Couldn't it be better to merge it all to one collection.bru file ?

I don't have a strong reason on why need we need to have them separate. This evolved naturally. First there was bruno.json and the collection.bru got introduced.

helloanoop commented 1 year ago

Additionally, this feature could also provide the ability to define a specific order or sequence for the directories, enhancing organization and accessibility within the UI.

Hello, It's for me the killer feature that would make me switch definitely from Postman to Bruno.

@giuseppemilicia @vaurat We will support directory sequencing once we support for folder.bru inside each folder.

Meanwhile a temporary workaround is to prefix your folders with numbers

|-collection
  |- 1 - folder 1
  |- 2 - folder 2
  |- 3 - folder 3

I know its a pretty bad work around :P

zDavidB commented 1 year ago

It appears to me that the collection post-response script executes before the request post-response script; e.g. some console.log output....

Starting collection pre-req script; Ending collection pre-req script; Starting request pre-request script; Ending request pre-request script; Starting collection post-resp script Ending collection post-resp script Starting request post-resp script; Ending request post-resp script;

Is it not more logical to have the collection post-response script run after the request post-response ?

p.s. my first issue here, great app, looking forward to contributing more :-)

martinsefcik commented 1 year ago

@zDavidB Postman and Thunder Client do not have post-response scripts but have tests which can be considered the same as post-response scripts and the order is the same as in Bruno:

Postman:

collection script
folder script
request script
GET https://www.google.com/
collection tests
folder tests
request tests

Thunder Client:

Script Log: collection script
Script Log: folder script
Script Log: request script

---------------- Running Request: ----------------

Script Log: collection tests
Script Log: folder tests
Script Log: request tests

So I think to have it opposite as in other commonly used clients would be confusing.

zDavidB commented 1 year ago

Good explanation thanks @martinsefcik

Giako commented 10 months ago

Hi, I have been experimenting with collection pre-request and post-response scripts to have a cookie being picked up when running bru run, but I keep getting an error when running the collection:

Running Folder 

collection (getaddrinfo ENOTFOUND undefined)   <-- error here
1-setcookie (200 OK) - 279 ms
manually saving the cookie
2-getcookie (200 OK) - 137 ms

Requests:    2 passed, 1 failed, 3 total
Tests:       0 passed, 0 total
Assertions:  0 passed, 0 total

It looks like collection.bru is mistakenly being picked up as a runnable request, which in turn has no URL, resulting in the host being undefined.

The collection.bru file looks like this:

script:pre-request {
  if (bru.getVar("THE_COOKIE")) {
      req.setHeader("Cookie", bru.getVar("THE_COOKIE"));  
  }
}

script:post-response {
  const cookie = res.getHeader("set-cookie");
  if (cookie) {
      console.log("manualing saving the cookie");
      bru.setVar("THE_COOKIE", cookie);  
  }
}

Basically, the scripts in the post-response looks for a Set-Cookie header, and it stores it in the collection variable THE_COOKIE. For every subsequent request, if the collection var is set, it adds a Cookie header with its value.

Here attached is a Proof of Concept to help reproduce the issue.

To reproduce this:

$ cd dev-integration/
$ npm install
$ npx bru run .

Running Folder 

collection (getaddrinfo ENOTFOUND undefined) 
1-setcookie (200 OK) - 279 ms
manually saving the cookie
2-getcookie (200 OK) - 137 ms

Requests:    2 passed, 1 failed, 3 total
Tests:       0 passed, 0 total
Assertions:  0 passed, 0 total

I expected Requests: 2 passed, 0 failed, 2 total, but maybe I'm doing something wrong myself 👀