How to enter url as global parameters - karate

I had gone through below.
https://github.com/intuit/karate/
How to enter url as parameter?
Here is my feature file.#demo
Feature: Test feature
Background:
* configure ssl = true
Scenario: Verify my service is up and running
Given url 'https://qa.mygroupservices.int/Version'
When method get
Then status 200

In the documentation, refer to the heading "Configuration".
For example like in the demo this can be your karate-config.js:
function() {
return { myUrl: 'https://qa.mygroupservices.int/Version' };
}
Then you can do
Given url myUrl

Related

Advice for implementing custom authentication scheme [duplicate]

First of all, thanks for build karate it's a very useful for test API's and UI's. We are using it to test a lot of our endpoints but we would like to know if there is a way or which is the best approach to handle requests with signature as part of the request in the header.
In our case we have two headers:
ApiKey: this value is always the same
Signature: this value depends on the request body content
Is there any way to inject the signature value just before the request is executed based on the request body content?
Here you can see two samples of the requests
Sample 1:
* url 'https://dev.sample.com'
* path '/api/user/getAll'
* header Content-Type = 'application/json'
* header ApiKey = 'XXX'
* header Signature = 'YYY'
And request { }
When method POST
Then status 200
Sample 2:
* url 'https://dev.sample.com'
* path '/api/user/getAll'
* header Content-Type = 'application/json'
* header ApiKey = 'XXX'
* header Signature = 'ZZZ'
And request { name: 'John' }
When method POST
Then status 200
Thanks
Karate has a "hook" for generating headers, but as of now it is not "aware" of the currently built request body + headers: https://github.com/intuit/karate#configure-headers
We got a similar request here, and are thinking of adding this capability: How to retrieve raw request contents before making a REST call in Karate DSL?
Maybe the OAuth examples will give you the way forward for your case for now: https://stackoverflow.com/a/55055111/143475
Feel free to raise an enhancement request, and we can get this in to the next version (with your help to test it). I'm thinking - what if you are able to call karate.get('request') from within the header JS function.
But for now all you need to do is do something like this:
* def body = { some: 'json' }
* karate.set('requestBody', body)
* url someUrl
* request body
* method post
And in the header.js function
function fn() {
var body = karate.get('requestBody');
var sign = Utils.sign(body);
return { Signature: sign };
}
EDIT: this will be implemented in Karate 1.0 onwards: https://github.com/intuit/karate/issues/1385

Handling Basic Authentication in Karate UI scenario

I have just started implementing karate UI (v0.9.5). Have already implemented api testing using karate and it works perfectly.
Following the HTTP basic auth strategy on this page - https://github.com/intuit/karate#http-basic-authentication-example the basic auth handling works for api tests. I set the HTTP headers once and run all api tests.
Now for the UI testing, the URL that I open brings up the basic auth pop-up as shown below:
So I thought that I could use the same strategy that I used for api tests to handle this. In the background section of my feature file, i call the feature file that does the authentication and sets headers as below:
The called feature file to set headers (admin-headers.feature). This feature file gets the token after admin user login is performed via karate-config.js. Then assigns the token along with the Base64 encoded basic auth to the headers calling headers.js. The Base64 user and password are being input as maven arguments and read via karate-config variables.
(/admin-headers.feature)
Feature: karate-config.js will perform one time login for admin and
set the session token for all subsequent requests
Background:
* def session = adminAuthInfo.authSession
* def basic_auth = call read('classpath:basic-auth.js') { username: '#(basicAuthUser)', password: '#(basicAuthPassword)' }
* configure headers = read('classpath:headers.js')
Scenario: One-time login for user and set the
session token in request header
The js code for returning Auth and Cookie to above feature file (/headers.js).
function() {
var session = karate.get('session');
var basic_auth = karate.get('basic_auth');
if(session){
return {
Authorization: basic_auth,
Cookie: "SESSION=" + session
};
} else {
return {};
}
}
My UI test feature file (/ui-test.feature):
Feature: Login test
Background:
# Authorise via api
* callonce read('classpath:common/headers/admin-headers.feature')
* configure driver = { type: 'chrome' }
Scenario: Test login
Given driver 'https://test.internal.mysite.com/names'
Running the above feature file still shows the auth pop-up.
I then tried to set the cookies while I am initialising the driver (which I think is probably not the right way?) as below:
Feature: Login test
Background:
# Authorise via api
* def login = callonce read('classpath:common/headers/admin-headers.feature')
* def uiCookie = { name: 'SESSION', value: '#(login.userAuthInfo.authSession)', domain: 'test.internal.mysite.com' }
* configure driver = { type: 'chrome', cookie: '#(uiCookie)' }
Scenario: Test login
Given driver 'https://test.internal.mysite.com/names'
The above also does not work. What is it that I am doing wrong here? the pop-up keeps coming up because the cookie is not set when the driver is initialised and then opens the specified url?
Help is much appreciated.
I think you raised a very good feature request, that configure driver should take cookies also, so that you can navigate to the page and set cookies in one-shot, and I opened a feature request: https://github.com/intuit/karate/issues/1053
So try this sequence, refer docs for cookie(): https://github.com/intuit/karate/tree/master/karate-core#cookieset
* driver 'about:blank'
* cookie(uiCookie)
* driver 'https://test.internal.mysite.com/names'
And now it should work !
Feature: Windows Authentication feature
Background:
* configure driver = { type: 'chrome' }
Scenario: Windows Authentication Valid Login test case
Given driver 'http://the-internet.herokuapp.com/basic_auth'
And delay(3000)
And screenshot()
* robot {}
* robot.input('admin' + Key.TAB)
* robot.input('admin')
* robot.click('Sign in')
And delay(3000)
And screenshot()
works fine with chrome, edge

Karate.toMap() using 0.9.5.RC4 works with Scenario but not Works with Scenario Outline

As suggested in here Migration form karate 0.9.2 to 0.9.3 Issue - javascript evaluation failed i have update karate verions to 0.9.5.RC4.
JavaScript fun is like
function fn(config) {
var OAuth2 = {};
var userAccessToken = Java.type("com.OAuth2Token");
OAuth2.adminUser = function () {
return userAccessToken.getAuthorizationHeader(name, url, users, "ADMIN");
};
config.OAuth2 = karate.toMap(OAuth2);
return config;
}
Feature file with Scenario **worked*
Scenario: <scenarioName>
Given path 'url'
And header Authorization = OAuth2.adminUser()
And def Authorization = OAuth2.adminUser()
And print Authorization
Feature file with Scenario outline not worked
Scenario Outline: <scenarioName>
Given path 'url'
And header Authorization = OAuth2.adminUser()
And def Authorization = OAuth2.adminUser()
And print Authorization
Examples:
| data |
Error : javascript evaluation failed: OAuth2.adminUser(), TypeError: OAuth2.adminUser is not a function in at line number 1 , I am having same error with 0.9.3 and moving function to common feature file.
This is a bug and will be fixed in the next version: https://github.com/intuit/karate/issues/982
A workaround is that you re-init the function for each loop under the Scenario Outline:
Scenario Outline:
* def OAuth2 = karate.call('classpath:com/utils.feature)

How to obtain response to be used on hooks

I am trying to make a simplified version of test report where I am generating a single HTML file report containing only assertion and error response message when there is any (attempting to not publish all the logs and steps).
I understand that we have hooks in karate. However I have looked for karate objects in the github but unable to found any objects where I can extract the response from (to be passed to the js function called on hook)
What I am doing right now is this:
Config:
//karate-config.js
karate.configure('afterScenario', karate.call('classpath:hooks.js'));
Hook:
//hooks.js
//Looking on how to extract the response and log it here
function(){
var info = karate.tags;
karate.log('Tags', info);
}
Am I missing anything on the karate objects? Or this should be achieved in another way?
Thanks a lot!
Try this:
var response = karate.get('response');
EDIT better example:
Background:
* configure afterScenario = function(){ karate.log('***', karate.get("response.headers['X-Karate']")) }
Scenario:
Given url 'http://httpbin.org'
And path 'headers'
And header X-Karate = 'test'
When method get
# this will fail
Then status 400
I have tried with both karate.get('response') and response directly, and both work. If you use karate.call() pass the response as a parameter.

Google Apps Script: Salesforce API Call

Just finished breakfast and already hit a snag. I'm trying to call the salesforce REST api from my google sheets. I've written a working script locally in python, but converting it into JS, something went wrong:
function authenticateSF(){
var url = 'https://login.salesforce.com/services/oauth2/token';
var options = {
grant_type:'password',
client_id:'XXXXXXXXXXX',
client_secret:'111111111111',
username:'ITSME#smee.com',
password:'smee'
};
var results = UrlFetchApp.fetch(url, options);
}
Here is the error response:
Request failed for https://login.salesforce.com/services/oauth2/token
returned code 400. Truncated server response:
{"error_description":"grant type not
supported","error":"unsupported_grant_type"} (use muteHttpExceptions
option to examine full response) (line 12, file "Code")
Mind you, these exact parameters work fine in my local python script (putting the key values inside quotations).
Here are the relevant docs:
Google Script: Connecting to external API's
Salesforce: REST API guide
Thank you all!
Google's UrlFetchApp object automatically defaults to a GET request. To authenticate, you have to explicitly set in the options the method "post":
function authenticateSF(){
var url = 'https://login.salesforce.com/services/oauth2/token';
var payload = {
'grant_type':'password',
'client_id':'XXXXXXXXXXX',
'client_secret':'111111111111',
'username':'ITSME#smee.com',
'password':'smee'
};
var options = {
'method':'post',
'payload':payload
};
var results = UrlFetchApp.fetch(url, options);
}