9

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)

roblogic
  • 1,146
  • 2
  • 12
  • 20
  • Similar question here, but not quite applicable to my use case: https://stackoverflow.com/q/46299245/ – roblogic Nov 23 '17 at 01:03

2 Answers2

9

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' }
Peter Thomas
  • 40,008
  • 10
  • 46
  • 142
  • 1
    Thank you for the amazingly prompt reply – roblogic Nov 23 '17 at 02:40
  • 1
    It works! I've been using karate with maven & intellij IDEA, and it's such a relief not to write glue code for everything. – roblogic Nov 23 '17 at 02:50
  • 2
    @ropata glad to hear that ! do spread the word :) sounds like you have used cucumber in anger before, you may find this an interesting read: https://hackernoon.com/yes-karate-is-not-true-bdd-698bf4a9be39 – Peter Thomas Nov 23 '17 at 03:36
  • 1
    Could you please add this to the main readme in the intuit/karate github? – Jim Showalter May 02 '18 at 19:19
  • hey @PeterThomas what is the difference between `KeyId: secretKey,` and `KeyId: '#(secretKey)'` ? is it possible to use **apiKey** with out assigning to def inside of the message? like `* print "Key in this project is #apiKey" ` Thank you – Said Yusifli Feb 19 '20 at 17:14
  • @SaidYusifli read the docs (yet again :) and ask a specific question if needed: https://github.com/intuit/karate#rules-for-embedded-expressions – Peter Thomas Feb 19 '20 at 17:38
  • @PeterThomas i am doing my best, reading and trying to understand. even how you see i am using stackoverflow to find answers... but will really appreciate if you can just answer to previous question. this project is new for me and its really big. i am trying to learn everything but sometimes need tips like in this situation :) Thank you for this project Peter. – Said Yusifli Feb 19 '20 at 17:44
  • 1
    @SaidYusifli ask a new question please – Peter Thomas Feb 19 '20 at 17:51
1

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:
[...]
roblogic
  • 1,146
  • 2
  • 12
  • 20