set Karate-config.js values in feature - karate

How can I set values in karate-config.js in a feature?
Ex: I create a cat in one of my features and I would like to put this id in karate-config.js in the value named catId
var config = {
env: env,
baseUrl: 'blabla.com',
catId: 'put id here'
}

It is bad practice to expect a feature to depend on some other feature. Or think of it this way - if you skip a feature (using code-commenting, tags etc), it should not cause some other feature to fail.
So Karate does not support updating anything set via karate-config.js by default.
That said, refer to the doc on "hooks", specifically the karate.callSingle() method - which may be the answer you are looking for.

Related

Ability to use environmental variables in Feature and Scenario Names

How to append Configuration variable in Feature name or in Scenario name. For Instance need to provide Info in reports based on environment run.
I saw there is an option available to add the Examples variable in Scenario outline name. on a similar note, do we have option to append Environment variable in Feature name?
Yes, in 1.0 onwards - if a variable exists in scope, it will be substituted in the Scenario name using the JS string interpolation syntax.
For example if your karate-config.js is like this:
function fn() {
return { test: 'foo' };
}
It means that the variable test will be available when the Scenario is processed. If not, note that the test will fail.
So if your feature is like this:
Feature:
Scenario: ${test}
* print test
You will see this in the report:
So it is up to you how you set up variables in the configuration init.

Karate Runner with ExecutionHook listener

#Peter - As per your suggestion from my previous queries, I have used ExecutionHooks to implement ReportPortal. I am finding difficulties in passing all the required values from my Runner to Base Runner. Below is my configuration-
BaseRunner.java
Results results = Runner.parallel(tags,path,ScenarioName,Collections.singletonList(new
ScenarioReporter()),threads,karateOutputPath);
Runner.java
#KarateOptions(tags = { "#Shakedown" },
features = "classpath:tests/Shakedown"
)
I want to understand how can I pass the attributes like Scenario Name, path and tags. ScenarioReporter() is my class where I have implemented Execution Hook. I have a base runner that will have all the details and a normal runner that will have minimal information. I have just given snippets, please don't mind if there are some syntactical errors.
You don't need the annotations any more, and you can set all parameters including tags using the new "builder" (fluent interface) on the Runner. Refer the docs: https://github.com/intuit/karate#parallel-execution
Results results = Runner.path("classpath:some/package").tags("~#ignore").parallel(5);
So it should be easier to inherit from base classes etc. just figure out a way to pass a List<String> of tags and use it.
Just watch out for this bug, fixed in 0.9.6.RC1: https://github.com/intuit/karate/issues/1061

Is it possible to add tags or have multiple BeforeTestRun hooks in Specflow

So I currently have an automation pack that I have created using Selenium/Specflow.
I wanted to know whether it is possible to have multiple BeforeTestRun hooks?
I've already tried: [BeforeTestRun("example1")] but I receive an error stating BeforeTestRunAttribute does not contain a constructor that takes 1 arguments
I tried the following but that also failed:
[BeforeTestRun]
[Scope(Tag = "example1")]
And referenced the above in the .feature file like this:
#example1
Scenario: This is an example
Given...
When...
Then...
Is there a way to implement this correctly such that in one .feature file I can have two scenarios that can use different [BeforeTestRun]?
If you cannot use [BeforeScenario] like suggested, you can try to manually check for tags using if statements. To get the current tags and compare them to the ones you need, try this:
var tags = ScenarioContext.ScenarioInfo.Tags;
if (tags.Any(x => x.Equals("MyTag")))
{
DoWork();
}
More info here: https://stackoverflow.com/a/42417623/9742876

Is there any API in JUnit 5 to test for included or excluded Tags?

I'd like to enable a test if a certain tag is "included", i.e. passed with option --include-tag of the ConsoleLauncher or useJUnitPlatform.includeTags property in Gradle. Is there any API to retrieve the value of this option in the context of test class or method?
I tried the script-based condition #EnabledIf like this:
#EnabledIf("'true' == systemProperty.get('itest.backendSystemPresent') || junitTags.contains('BackendSystemIT') == true")
But junitTags contains the #Tag annotations of the element in question, not the tags included at runtime.
Reading your question again, my answer is "No". You can't use junitTags to achieve your goals. And no, there's no such API at the moment. You would need something like:
#EnabledIf("'true' == evaluateTagExpression('BackendSystemIT') || ...)
Because you need to take care of tag expression here as well: https://junit.org/junit5/docs/current/user-guide/#running-tests-tag-expressions
But, tags are evaluated earlier in the process. Your condition will not get a chance to be executed when the test was already excluded by tag evaluation. So, I guess, you'll have to stick with the single system property switch to control the enabled state of the test method.
Btw. we are improving the tag expression language with any() and none() tokens, soon. https://github.com/junit-team/junit5/issues/1679
Possible solution:
Annotate your test with #Tag("BackendSystemIT")
Before running your tests, check for itest.backendSystemPresent system property and if it is set, pass a --include-tag "BackendSystemIT" to the test run.
Let Jupiter do the job of evaluating tag expressions
Is there any API to retrieve the value (of this option) of all tags that are attached directly or inherited in the context of test class or method?
Yes. Declare and use a org.junit.jupiter.api.TestInfo parameter in your test method.
#Test
#DisplayName("TEST 1")
#Tag("my-tag")
void test1(TestInfo testInfo) {
assertEquals("TEST 1", testInfo.getDisplayName());
assertTrue(testInfo.getTags().contains("my-tag"));
}
For details see https://junit.org/junit5/docs/current/user-guide/#writing-tests-dependency-injection
But junitTags contains the #Tag annotations of the element in question, not the tags included at runtime.
This is the expected behaviour -- the platform (here: console launcher) already applied the filter passed via --include-tag and other configuration parameters. In short: there's no need to manually check for tags in standard Jupiter tests. If there's problem with the built-in filtering, please create an issue here: https://github.com/junit-team/junit5/issues/new/choose

Cucumber - how to get scenario tag that is currently being executed

I have scenario with multiple tags. For example, #registration, #smoke, #core.
I have a configuration file (test.conf.js file) in which I set targeted tests to be run like this:
cucumberOpts: {
tags: ['#registration', '~#WIP']
}
Running this configuration will only run scenarios with #registration tag.
With this I can get and iterate through all scenario tags (in this case #registration, #smoke, #core):
beforeScenario: function (scenario) {
tags = scenario.getTags();
tags.forEach(function (scenarioTagItem) { ... });
}
My question is how to get in the above function the tag that the test is currently running against? So how to recognize that currently running tag is #registration? Sort of to recognize it as an active tag?
Please help :)
Just called this.cucumberOpts.tags because it was in the same file and build my logic further on that. Stupid overlook from my side :/
Even better way to do it is browser.options.cucumberOpts.tags