Using karate-config parameters in a feature file - karate

The karate header examples do not show how to access config values other than baseUrl. When I switch environments (passing in -Dkarate.env=qual as part of the run command) then baseUrl is set correctly.
The problem is, I want to use other config values as shown here but when I run the test, it fails to access config.ApiKey correctly. Instead I get this error
html report:
file:/C:/bitbucket/karate-checkdigit-api/target/surefire-reports/TEST-features.checkdigitapi.VA.html
Tests run: 250, Failures: 0, Errors: 50, Skipped: 175, Time elapsed: 4.112 sec <<< FAILURE!
* def secretKey = config.apiKey(| XYZ | 2110974841 | 204 | Valid |) Time elapsed: 0.005 sec <<< ERROR!
java.lang.RuntimeException: no variable found with name: config
at com.intuit.karate.Script.getValuebyName(Script.java:323)
at com.intuit.karate.Script.evalJsonPathOnVarByName(Script.java:378)
at com.intuit.karate.Script.eval(Script.java:309)
at com.intuit.karate.Script.eval(Script.java:194)
at com.intuit.karate.Script.assign(Script.java:656)
at com.intuit.karate.Script.assign(Script.java:587)
at com.intuit.karate.StepDefs.def(StepDefs.java:265)
at ✽.* def secretKey = config.apiKey(features/checkdigitapi/XYZ.feature:6)
My .feature file and karate-config.js are below.
XYZ.feature
#regression
Feature: Checkdigit Algorithm API
Background:
* url baseUrl
* def secretKey = config.apiKey
* configure ssl = true
Scenario Outline: Testing XYZ algorithm
* configure headers = { KeyId: secretKey, Accept: 'application/json' }
Given path 'headers'
And param url = baseUrl
And params { customerId: '<custcode>', algoId: '<algo>' }
When method get
Then status <val>
Examples:
| algo | custcode | val | comment |
| XYZ | 2110974841 | 204 | Valid |
| XYZ | 7790011614 | 204 | Valid |
| XYZ | 5580015174 | 204 | Valid |
| XYZ | 2110974840 | 400 | expected check digit 1 |
| XYZ | 211097484 | 400 | not 10 digits |
| XYZ | 211097484x | 400 | not numeric |
karate-config.js
function() {
//set up runtime variables based on environment
//get system property 'karate.env'
var env = karate.env;
if (!env) { env = 'dev'; } // default when karate.env not set
// base config
var config = {
env: env,
baseUrl: 'https://localapi.abc123.example.com/api/v1/validate/customerid',
apiKey: ''
}
//switch environment
if (env == 'dev') {
config.baseUrl = 'https://devapi.abc123.example.com/api/v1/validate/customerid';
config.apiKey = 'fake-1ba403ca8938176f3a62de6d30cfb8e';
}
else if (env == 'qual') { //Pre-production environment settings
config.baseUrl = 'https://qualapi.abc123.example.com/api/v1/validate/customerid';
config.apiKey = 'fake-d5de2eb8c0920537f5488f6535c139f2';
}
karate.log('karate.env =', karate.env);
karate.log('config.baseUrl =', config.baseUrl);
karate.log('config.apiKey =', config.apiKey);
return config;
}
(similar issue here, using a separate headers.js: https://github.com/intuit/karate/issues/94)

Keep in mind that all the keys within the JSON object returned by karate-config.js will be injected as variables, and nothing else. So you will not be able to refer to config, but you will certainly be able to refer to apiKey.
I think if you make this simple change, things will start working:
* def secretKey = apiKey
Also, I think you have a problem in the first line of the scenario, it should be:
* configure headers = { KeyId: '#(secretKey)', Accept: 'application/json' }

FYI my final, correctly working XYZ.feature file looks like this now.
The line Given path 'headers' caused header info to creep into the url so it's removed.
XYZ.feature
#regression
Feature: Checkdigit Algorithm API
Background:
* url baseUrl
* def secretKey = apiKey
* configure ssl = true
Scenario Outline: Testing XYZ algorithm
* configure headers = { KeyId: '#(secretKey)', Accept: 'application/json' }
Given url baseUrl
And params { customerId: '<custcode>', algoId: '<algo>' }
When method get
Then status <val>
Examples:
[...]

Related

istanbul generates empty report

I wanted to launch istanbul in my project, however no matter what I do reports shows only zeros. like below :
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|-------------------
Even though it shows above the coverage report list of the test that passed. For simplicity I created super simple project for replication where I have only one function in indentity.js file :
export const identity = (x) => x;
and one simple test licated in test.js file
import { identity } from "./identity.js";
import assert from "assert";
describe("identity", function () {
it("should return passed argument", () => {
assert.equal(identity(1), 1);
assert.equal(identity("string"), "string");
assert.deepEqual(identity({ a: 1 }), { a: 1 });
});
});
and after I run nyc mocha I expect to see 100% coverage but what I have is the same table with zeros.
Is there some settings I missed to see proper coverage report ?
Thx in advance.

how to call a feature file to generated a Get request , for each element in an ArrayList or JsonArray ( Created by Java function )

basically I want to achieve below result , where the list used in Examples: is dynamic
Scenario Outline:
def ss = 'https:testingurl/'+ < spaceCode > + 'trailPath';
Given url ss
And header Authorization = autGetToken()
When method get
Then status 200
Examples:
| spaceCode |
| space1|
| spac2|
| spaceAbc05|
| space.o2|
| spacesacc|
| spacere |
So I created one.feture and tried to call it from other feature file
one.feature
Background:
def ss = 'https:testingurl/'+ < spaceCode > + 'trailPath';
Scenario: need to run this scenario for each member of the spaceList ArrayList / JsonArray
Given url ss
And header Authorization = autGetToken()
When method get
Then status 200
* print response
* def count = response.value.length
* print count
* karate.set('total', karate.get('total') + karate.get('count') )
* print total
question
how to run above file for each element of the "spaceList" which is an Java ArrayList, i am creating this ArrayList by calling method getSpaceList()
i have tried to call it from other feature file like below
Method1
caller.feature
Background:
* def total = 0
* def helper = Java.type('shared.Helper')
Scenario Outline: calling other feature file for each element of the spaceList Array
def result = call read('one.feature')
Examples:
| spaceCode |
| helper.getSpaceList() |
Method2
caller.feature
Background:
* def total = 0
* def helper = Java.type('shared.Helper')
* def spaceList = helper.getSpaceList() // this returns around 20 different elements from a sql
Scenario Outline: calling other feature file for each element of the spaceList Array
def result = call read('one.feature')
Examples:
| spaceCode |
| spaceList |
i have also tried karate.forEach and karate.setUp
Try this example. Note how it will make two POST requests. Once you understand this, you should be able to do what you want.
Feature:
Scenario Outline:
* url 'https://httpbin.org/anything'
* request __row
* method post
* status 200
Examples:
| [{ a: 1 }, { a: 2 }] |

Use map object in karate framework

I am trying to create a scenario where:
Scenario Outline: Create a request
Given print 'reason=<reason>, detail=<detail>, metainfo=<metainfo>'
When call create_request
Then match response.message == "#notnull"
* call json_to_proto request
* print 'response \n', response
Examples:
reason | detail | metainfo
test | Testing | { foo: bar }
My concern is metainfo is defined as a map, "metainfo": "#(karate.get('metainfo', {}))" how do I set values for it as the current logic gives me error: org.graalvm.polyglot.PolyglotException: Expect a map object but found...
Please read this section of the docs: https://github.com/karatelabs/karate#scenario-outline-enhancements
You can use JSON like this. And note that you don't need the <foo> placeholder system. Normal variables work:
Scenario Outline: ${payload.foo}
* match payload == { foo: 'bar' }
Examples:
| payload! |
| { foo: 'bar' } |

Object.keys(data) Js fu not worked when pass Json object as def in Karate 0.9.5.RC5

Js File with following function
function fn(config) {
config.OAuth2 = function (data) {
var keys = Object.keys(data);
return keys;
}
return config;
}
Feature file with following steps
Feature: Sample Feature
Scenario Outline: Sample Scenario
#This is works
* def a = OAuth2({firstName: '<firstName>',lastName: '<lastName>'})
* print a
#This do not work
And def req = {firstName: '<firstName>',lastName: '<lastName>'}
* def b = OAuth2(req)
* print b
Examples:
| firstName | lastName |
| a | a1 |
Giving error at var keys = Object.keys(data);
javascript evaluation failed: OAuth2(req), TypeError: {firstName=a, lastName=a1} is not an Object in <eval>
Please don't use Object.keys() - use karate.keysOf() instead.

Support passing from Scenario Outline to JSON file

I am going to reuse some features and calling multiple features in a Scenario Outline.
Since the features being called are common, we would like to define its parameters in its own parameter file, while the parameter values are defined in placeholder.
We hope the placeholder can get the value from the Outline Examples.
How to make it?
Feature: verify parameter passing
Scenario Outline: verify 2 calls
* def result1 = call read('baseFeature1.feature')
* def result2 = call read('baseFeature2.feature') result1
* print result2
Examples:
| fooValue |
| value1 |
| value2 |
Feature: feature to verify the parameter passing, no input parameter
Scenario: feature 1
Given def payload = read('classpath:feature_1.json')
* print 'feature 1' + payload
Given def result = { "barValue": "barValue"}
Feature: feature to verify the parameter passing, with input parameter from last step
Scenario: feature 2
Given def payload = read('classpath:feature_2.json')
* print payload
feature_1.json
{
"foo": "#(fooValue)"
}
feature_2.json
{
"foo": "fooValue",
"bar": "#(result1.barValue)"
}
I think the version currently in development will make this possible. Can you take a look at this GitHub issue and see if this addresses your question: https://github.com/intuit/karate/issues/717
It will also be great if you can build from source and try this new capability.
Scenario Outline: magic variables with embedded expressions
* def expected = __num == 0 ? { name: 'Bob', alive: false } : { name: 'Nyan', alive: true }
* match expected == { name: '#(__row.name)', alive: '#(__row.alive)' }
* eval karate.set(__row)
# you can read from a re-usable JSON file instead of the line below
* match expected == { name: '#(name)', alive: '#(alive)' }
Examples:
| name | alive! |
| Bob | false |
| Nyan | true |