Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] add ability to skip requests or halt runner #113

Closed
faelin opened this issue Oct 15, 2024 · 11 comments
Closed

[FEATURE] add ability to skip requests or halt runner #113

faelin opened this issue Oct 15, 2024 · 11 comments
Labels
enhancement New feature or request

Comments

@faelin
Copy link

faelin commented Oct 15, 2024

Is your feature request related to a problem?

When running a collection, sometimes I want a request to be skipped conditionally based on the result of a pre-request script. Similarly, I might want to conditionally halt the run of requests based on the result of a request.

Describe the solution you'd like

Skip Request

In Postman, I can call pm.execution.skipRequest() to tell the collection-runner to immediately skip to the next request without sending the current request. This would be very useful to have in JetClient.

Halt Run

Related to this, I would also like the ability to conditionally halt the entire collection runner, preventing any more requests from being sent during the current run. Using Postman, I can do this via pm.execution.setNextRequest(null).

Ideally this would look something like jc.haltRun() and would simply stop the current runner context,
meaning that if I run a folder and a request in that folder calls jc.runTestSuite(...) and a request in that suite calls jc.haltRun() the suite would stop but folder runner would continue:

  1. run TestsFolder
  2. TestsFolder/RequestA script calls jc.runTestSuite('some_test_suite')
  3. some_test_suite.SomeOtherRequest script calls jc.haltRun()
  4. some_test_suite is STOPPED
  5. TestsFolder is STILL RUNNING

Additional context

@faelin faelin added the enhancement New feature or request label Oct 15, 2024
@faelin
Copy link
Author

faelin commented Oct 15, 2024

...you know what, it suddenly occurred to me that, unlike Postman, I could just throw an empty error to halt: throw ''

Sorry for wasting your time 😣

@faelin faelin closed this as completed Oct 15, 2024
@faelin faelin reopened this Oct 15, 2024
@faelin faelin closed this as completed Oct 15, 2024
@faelin
Copy link
Author

faelin commented Oct 15, 2024

Okay, I'm actually re-opening this because it would be nice to be able to skip or halt execution without having an error appear in the console.

@faelin faelin reopened this Oct 15, 2024
@AntonShuvaev
Copy link
Collaborator

Thanks for reporting this issue and for your suggestions.

Personally, I’m not a big fan of controlling request flow from inside request scripts using setNextRequest. It makes it harder to understand the overall request sequence because you have to go through each request, looking for where setNextRequest is used and trying to piece together the logic.

In JetClient, I recommend handling this differently. You can create a test suite and reuse requests with jc.sendRequest('requestName') or jc.runRequest('requestName'). This gives you full control of the request flow.
If you need to conditionally skip, repeat, or stop execution, you can use simple if/else, loops, or return statements.

There are two approaches you can take:

  1. Keep requests scripts empty and write the entire logic in the test suite, like you would in any programming language, while reusing requests for the actual endpoints.
  2. Write some test logic in the requests scripts and manage the sequence in the test suite.

Let me know if you think this approach doesn’t suit your use case, or if you still feel the setNextRequest style flow control would be better.

By the way, I found that errors thrown in the request script are not propagated to the script where it is called. I will fix this in the next version. So it will be possible to stop the execution of the test suite by throwing an error in a request script.

@faelin
Copy link
Author

faelin commented Oct 28, 2024

The reason I need to control flow is to account for dynamic responses from the API endpoints that I am testing. True, I could create a test-suite that contains all the logic I need. HOWEVER, the way I am using JetClient involves testing endpoints using dynamic variable selection for use in request templating. The way I am simulating this involves the user selecting requests that exist only to set variables. I specifically DO NOT want this selection to be hard-coded in the suite, as there are currently at least 240 possible combinations of variables (and that value is expected to grow). Creating that many separate test suites in order to allow a tester to choose certain combinations of variables is absolutely untenable.

To get around this, in Postman for example, the tester sends a "request" that simply sets a collection-variable and then moves on to the next request without completing. This way, the request can be selected or deselected on the fly. This could be done by commenting out lines in a test suite, but that requires additional changes, and the comments would effect every tester.

In general, I understand your hesitance to "bury" flow control in request scripts. However, that should really be a choice left up to the developer. It makes sense to document a suggestion not to use request-flow controls in a request script, but it does not make sense to outright prohibit it. In other words, there are an infinite number of way to use a tool, and it is impossible to predict all of the possible use-cases; the best you can do is to make suggestions.

@AntonShuvaev
Copy link
Collaborator

Could you provide more details on your exact use case? This would be really helpful.

For cases where you're using a request solely for its pre-request script to set a variable and skip the request, consider using a test suite script to handle variable setup. A test suite script is almost the same as a pre-request script without request itself, and you can call it from other scripts or directly run it in the collection runner.

Another option is to use environment groups to define variables for different contexts. For instance, you can create an Environment Group - Users with environments like User_role1, User_role2, User_role3, etc., and assign variables specific to each environment.
You could then select multiple environments—one for each group—to control variables for each context.
Currently, switching between environments is manual, but I plan to add the ability to switch environments programmatically within a script.

Additionally, I’m working on a feature that might be useful: predefined functions in {{...}} expressions. One of them is a function that prompts for user input. It is similar to Insomnia’s feature, but I plan to enhance it with various input types and combine related inputs in a single modal dialog. For example:

{
  myVariables: {
    varA: {{textField('LabelA', 'defaultValue')}},
    varB: {{comboBox('LabelB', ['1', '2', '3'], '1')}},
    varC: {{checkBox('LabelC', false)}}
  }
}

This setup would display a modal dialog with fields for each variable when myVariables is referenced, allowing user input at runtime.

Let me know your thoughts on these options, and if you have any other ideas or specific requirements!

@faelin
Copy link
Author

faelin commented Oct 29, 2024

Prompting for user input would absolutely solve my issue in the best possible way, by prompting at the start of the suite! With that feature, I would be able to completely discard my need to make fake requests to set variables.

As for selecting multiple environments, I don't think that would be a good idea, because of the scope of the parameter matrix. Again, in order to include all possible combinations of variables, we are talking about potentially dozens of environments, e.g. env foo1 for foo=A, foo2: foo=B, foo3: foo=A,B, foo4: foo=C, and so on for all possible combinations of foo, and then MORE environments for the other parameters that have multiple combinations.

The problem comes down to the fact that these parameters aren't on-off switches, they are combinations of multiple elements in a list. This leads to a staggeringly large combinatorial space when combining (currently) four parameters each with multiple elements in a list. The way I have designed my system is that each fake "setup" request in the runner will update an environment variable that contains the desired test parameters in an object; this object later gets decoded into a combinatorial matrix of the parameters for the actual requests.

Therefore, the best possible solution is a check-box model such as in your example above. I hope that feature comes soon ;)

Finally, your first suggestion about using scripts in the test-suite makes some sense, but only in so far as each fake "request" would be turned into a test-suite that ONLY runs a small function to update the environment variable containing the parameters object. Then I could potentially have the runner run each parameter-setting "test-suite" in the same way that we currently run parameter-setting "fake" requests. I will attempt to do it this way for now, but then hopefully your future update will solve my needs in a much cleaner way!

That being said, I still strongly believe that the ability to skip/select-next/halt the request runner is a toolset that should be provided to developers as a "use at your own risk" set of tools...

@AntonShuvaev
Copy link
Collaborator

Thanks for the details, they’re very helpful! I plan to release the predefined functions in {{...}} expressions feature in about two weeks. I’ve also decided to add the setNextRequest feature afterward.

@dudatom4
Copy link

Hello i have a question for this update.

Here's the situation. We have a folder and in the folder another folder and other requests:
until now, when jc.runFolder was used in a request or testSuite, everything was called in the order it was sorted. In my case, folder1, request1 and request2.
But after this update, the order has changed and request1 and request2 are called first and then folder1.
Is this a bug or is this the desired functioning?

thanks

@AntonShuvaev
Copy link
Collaborator

Hello @dudatom4, thank you for reporting this bug. I'll fix it, and the update will be available on Monday or Tuesday.

@AntonShuvaev
Copy link
Collaborator

I’ve added jc.execution.setNextRequest and jc.execution.skipRequest, similar to Postman. Note that they work only for requests run by the collection runner or executed in scripts using jc.runFolder, as requests are executed in a defined sequential order only in these cases.

@faelin
Copy link
Author

faelin commented Dec 13, 2024

Thanks so much @AntonShuvaev, you're spectacular! :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants