How to set HTTP header with variable?

Hello,
I have a problem. What I want to do is to obtain a token from RESTFul request, and parse that token to HTTP Header.

Here is my code

import internal.GlobalVariable as GlobalVariable
import com.kms.katalon.core.testobject.RequestObject

'Get response'
def response = WS.sendRequest(findTestObject('API/Authentication'))

'Verify if login was successfully'
WS.verifyElementPropertyValue(response, 'msg.ok[0]', 'Login successfull!')

def slurper = new groovy.json.JsonSlurper()

def result = slurper.parseText(response.getResponseBodyContent())

'Get token'
def token = result.data."X-Auth-Token"

'Print token'
println(token)

RequestObject ro2 = new RequestObject("y")
ro2.setHttpBody("id": "ab8e52e92deb459596e3911f9f09934c")
ro2.setHttpHeaderProperties("X-Auth-Token" : token)
ro2.setRestRequestMethod("POST")
ro2.setRestUrl("http://localhost/api/projects/scopeTo/")

WS.sendRequest(ro2)

1. I’m authenticating.
2. Verify whether there is a message in the response (Login successfull!)
3. Parse response with JSONSlurper
4. Save token to variable token

Now, when I have a token, I want to authenticate to another endpoint. What I need to do is to send in body an extra ID, and send in HTTP Header “X-Auth-Token” with token from variable.

Response from console:

02-19-2018 07:40:48 AM - [START]  - Start action : Statement - println(token)
ojear3mndj1sarskbjl1r64dd5
02-19-2018 07:40:48 AM - [END]    - End action : Statement - println(token)
02-19-2018 07:40:48 AM - [START]  - Start action : Statement - ro2 = new com.kms.katalon.core.testobject.RequestObject(y)
02-19-2018 07:40:48 AM - [END]    - End action : Statement - ro2 = new com.kms.katalon.core.testobject.RequestObject(y)
02-19-2018 07:40:48 AM - [START]  - Start action : Statement - ro2.setHttpBody(["id":"ab8e52e92deb459596e3911f9f09934c"])
02-19-2018 07:40:48 AM - [END]    - End action : Statement - ro2.setHttpBody(["id":"ab8e52e92deb459596e3911f9f09934c"])
02-19-2018 07:40:48 AM - [ERROR]  - Test Cases/API/Authentication FAILED because (of) groovy.lang.MissingMethodException: No signature of method: com.kms.katalon.core.testobject.RequestObject.setHttpBody() is applicable for argument types: (java.util.LinkedHashMap) values: [[id:ab8e52e92deb459596e3911f9f09934c]]
Possible solutions: setHttpBody(java.lang.String), getHttpBody(), setSoapBody(java.lang.String), getSoapBody()

How should be that parsed and send to HTTP Header?

1 Like

Mariusz,

The error you got from the console is: ro2.setHttpBody(“id”: “ab8e52e92deb459596e3911f9f09934c”) since the function requires a String. I am not sure how the API is setup, you could try to send it as a String, ie “id:ab8e52e92deb459596e3911f9f09934c” instead.

Trong,

Thanks for tips. I’ve changed some part of code and split and moved some stuff to Test Suites and that is how it looks like now

'Get token'
String token = WebUI.callTestCase(findTestCase('API/Authentication'), [:], FailureHandling.CONTINUE_ON_FAILURE)

'Scope to a project'
RequestObject ScopeToProject = findTestObject('API/ScopeToProject')

'Create new ArrayList'
ArrayList<TestObjectProperty> HTTPHeader = new ArrayList<TestObjectProperty>()

'Send token in HTTP header'
HTTPHeader.add(new TestObjectProperty('X-Auth-Token', ConditionType.EQUALS, token))

'Set that token'
ScopeToProject.setHttpHeaderProperties(HTTPHeader)

'Get response text'
response = WS.sendRequest(ScopeToProject)

'Verify if scope to project was successfull'
WS.verifyElementPropertyValue(response, 'data.currentProject', 'ab8e52e92deb459596e3911f9f09934c')

Maybe someone may take advantage of this :slight_smile:

10 Likes

Your script looks great. Thank you for sharing with us.

Mariusz said:

Trong,

Thanks for tips. I’ve changed some part of code and split and moved some stuff to Test Suites and that is how it looks like now

'Get token'

String token = WebUI.callTestCase(findTestCase(‘API/Authentication’), [:], FailureHandling.CONTINUE_ON_FAILURE)

‘Scope to a project’
RequestObject ScopeToProject = findTestObject(‘API/ScopeToProject’)

‘Create new ArrayList’
ArrayList HTTPHeader = new ArrayList()

‘Send token in HTTP header’
HTTPHeader.add(new TestObjectProperty(‘X-Auth-Token’, ConditionType.EQUALS, token))

‘Set that token’
ScopeToProject.setHttpHeaderProperties(HTTPHeader)

‘Get response text’
response = WS.sendRequest(ScopeToProject)

‘Verify if scope to project was successfull’
WS.verifyElementPropertyValue(response, ‘data.currentProject’, ‘ab8e52e92deb459596e3911f9f09934c’)


Maybe someone may take advantage of this :)  

  
Thank you. This is what i was looking for!

It worked for my advantage :slight_smile:

Just to add to your code, these 2 import statements are required as well.

import com.kms.katalon.core.testobject.TestObjectProperty

import com.kms.katalon.core.testobject.ConditionType

2 Likes

I try to set HTTP header with a variable in the test case.
I write this, but it doesn’t work

ArrayList HTTPHeader = new ArrayList()

HTTPHeader.add(new TestObjectProperty(((‘X - OAPI) - Application) - Id’, ConditionType.EQUALS, ‘1111’))

request = WSResponseManager.getInstance().getCurrentRequest()

request.setHttpHeaderProperties(HTTPHeader)

Thank you for your help

I am a bit confused what is what in your request. And I can’t even see any variable in a header.

Please post here:

  • header name
  • header value
  • variable and a place, where you want to put it

Also, brackets on the second line aren’t correct.

Header name: X-OAPI-Application-Id
Header value ‘1111’ ( I will then change it by a variable later)

In this statement I give the name and the value of header
HTTPHeader.add(new TestObjectProperty(‘X-OAPI-Application-Id’, ConditionType.EQUALS, ‘1111’))

Yes, the row looks correct now.

And the other line, I guess you’d like to pick an existing request (from Object Repository), put a new header and run the request, right?

Yes an existing request from object repository, put the header and run it

Ok so this should work for you:

ArrayList HTTPHeader = new ArrayList()

String headerValue = '1111'
HTTPHeader.add(new TestObjectProperty('(X - OAPI) - Application) - Id', ConditionType.EQUALS, headerValue))

RequestObject request = ObjectRepository.findTestObject("Misc/WStest")
request.setHttpHeaderProperties(HTTPHeader)

WSBuiltInKeywords.sendRequest(request)
1 Like

Hi Marek,

RequestObject request = WSResponseManager.getInstance().getCurrentRequest()
ResponseObject response = WSResponseManager.getInstance().getCurrentResponse()

ArrayList HTTPHeader = new ArrayList()
string headerValue = ‘Long_access_token’
HTTPHeader.add(new TestObjectProperty(‘Authorization’, ConditionType.EQUALS, headerValue))
request.setHttpHeaderProperties(HTTPHeader)

and then i click “Test Request and Verify”

but the status always 401 unauthorized

if i tried to put Authorization manually at HTTP Header then it will work fine.

can help?

The code does not compile with ‘setHttpHeaderProperties’ method, does this one require any Import particularly?
Thanks

1 Like

This helped a lot. This i was looking for hours.

1 Like

Here are a couple of keyword functions to get a token and set the property in the request.

import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject

import com.kms.katalon.core.annotation.Keyword
import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.testobject.RequestObject
import com.kms.katalon.core.testobject.ResponseObject
import com.kms.katalon.core.testobject.TestObjectProperty
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS

@Keyword
def String getToken(){
	def authResponse = WS.sendRequestAndVerify(findTestObject('Auth/AuthenticateUser'))
	def slurper = new groovy.json.JsonSlurper()
	def result = slurper.parseText(authResponse.getResponseBodyContent())
	return result.token
}


@Keyword
def ResponseObject sendAuthorizedRequest(RequestObject restRequest, String access_token){

	// Build the authentication header
	def authRequest = restRequest
	ArrayList<TestObjectProperty> httpHeader = new ArrayList<TestObjectProperty>()
	httpHeader.add(new TestObjectProperty('Authorization', ConditionType.EQUALS, "Bearer " + access_token))

	// Set the header property and pass it back out
	authRequest.setHttpHeaderProperties(httpHeader)
	def response = WS.sendRequestAndVerify(authRequest)
	return response
}

And to use it in a test case, I call it like this:

import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS

def token = CustomKeywords.'tokens.TokenUtilities.getToken'()
def secureResponse = CustomKeywords.'tokens.TokenUtilities.sendAuthorizedRequest'(findTestObject('SystemUser/GetSystemUsers'), token)

WS.verifyResponseStatusCode(secureResponse, 200)
WS.verifyElementPropertyValue(secureResponse, 'data[0].registeredEmailAddress', 'samplename@samplemail.com')

This approach has worked for me so far…I hope it helps.

1 Like

hello friends,

Based on POST method sign-in API i would like to pass my response(access token & token type) of sign-in API into authentication of next API
i would like to pass it in a script mode not manually , i have declared the response as global variable
access token in dynamic every time i hit sign-in API access token changes

so how to set the dynamic acess token and token type(Bearer) as http header in script mode please help

‘Get response’
def response = WS.sendRequest(findTestObject(‘EMP/EMP Login’))

‘Verify if login was successfully’
WS.verifyElementPropertyValue(response, ‘result’, ‘Successful’)

WS.verifyResponseStatusCode(response, 200)

def slurper = new groovy.json.JsonSlurper()

def result1 = slurper.parseText(response.getResponseBodyContent())

println(result1)

‘Get token’
def token1 = result1.‘token’
println(token1)

‘Scope to a project’
RequestObject ScopeToProject = findTestObject(‘EMP/GetAllTenants’)

‘Create new ArrayList’
ArrayList HTTPHeader = new ArrayList()

‘Send token in HTTP header’
HTTPHeader.add(new TestObjectProperty(‘Authorization’, ConditionType.EQUALS,'Bearer ’ +token1))

‘Set that token’
ScopeToProject.setHttpHeaderProperties(HTTPHeader)

‘Get response text’
response = WS.sendRequest(ScopeToProject)

‘Verify if scope to project was successfull’

WS.verifyResponseStatusCode(response, 200)

i used this… it worked for me.