cancel
Showing results for 
Search instead for 
Did you mean: 

Script Assertion To Grab 4 'Set-Cookies' To Set 1 'Cookie' Header In Follow Up Request

SOLVED
Community Hero

Script Assertion To Grab 4 'Set-Cookies' To Set 1 'Cookie' Header In Follow Up Request

Hi,

 

This is related to my other 'cookie' post - but that other post has side tracked onto another issue I need to solve - so I've created a second post with a specific issue.

 

A while back @nmrao created the script assertion below to extract the 'Set-Cookie' http header values and write them to corresponding 'Cookie' http headers, so if 4 'Set-Cookie' headers are included on the initial request, 4 'Cookie' headers with the relevant values (including all the additional header value attributes) are added to the nextStep.

//Courtesy of Rao
//This script assetion reads the http response, //collect the cookies for the next http request //Provide the next step name where you want to set the Cookie to the request or //Use property expansion for below def nextStepName = 'REST Request' def nextRequest = context.testCase.testSteps[nextStepName].httpRequest def headers = nextRequest.requestHeaders if (messageExchange.responseHeaders.containsKey('Set-Cookie')) { log.info "Found Cookie in the response headers" def cookiez = messageExchange.responseHeaders['Set-Cookie'].value def list = [] cookiez.each { cookies -> //def (name, value) = cookies.toString().split('=',2) list.add(cookies.toString()) } headers['Cookie'] = list } else { log.warn "Not Found Cookie in the response headers" } nextRequest.requestHeaders =

The above is great - exactly what I was told I needed - however, what the developers have now told me is that what I need is slighlty different from the above - despite them saying the above gave me what I need!  aah! frustrating!

 

The http Set-Cookie/Cookie theory (according to the following links (link1 and link2) indicates that the 'Set-Cookie' header values (without the additional attributes) are used to populate the follow up single Cookie header value.

 

so if we receive in the initial message

 

Set-Cookie: returnurl=345678; Max-Age=3600; Expires=Tue, 18-Jun-2019 22:58:30 GMT; Path=/; Secure; HttpOnly

Set-Cookie: authtype=234567; Max-Age=3600; Expires=Tue, 18-Jun-2019 22:58:30 GMT; Path=/; Secure; HttpOnly

Set-Cookie: state=123456; Max-Age=3600; Expires=Tue, 18-Jun-2019 22:58:30 GMT; Path=/; Secure; HttpOnly

Set-Cookie: nonce=456789;  Max-Age=3600; Expires=Tue, 18-Jun-2019 22:58:30 GMT; Path=/; Secure; HttpOnly

 

The follow up request would have ONE individual 'Cookie' http header and the value would be made up of the semi colon delimited Set-Cookie values without the additional attributes - so the follow up message's 'Cookie' header would appear as follows:

 

Cookie: returnurl=345678; authtype=234567; state=123456; nonce=456789

Apparently what I've described above is standard http Set-Cookie/Cookie handling and I was told I should've known about this already!

 

I'm stuck updating the script. 

 

Essentially I need to concatenate all the Set-Cookie header VALUES into a single string (semi colon delimiter for each value) - but strip out the additional attributes like Max-Age, Expires, http, secure etc.

 

Can anyone help out?  I know I'm asking a lot here - especially when everyone's already helped so much already

 

I need to pass the 4 'Set-Cookie' header values into the 1 'Cookie' value (stripping out all the attributes so the only the Set Cookie header values are included - apparently this is supposed to be how http 'Set-Cookie' and http 'Cookie' headers work.  The server sends the Set-Cookie headers to tell the client to send a single Cookie http header and the value populating the Cookie are.

 

Thanks guys - really!

 

richie

 

if this helped answer the post, could you please mark it as 'solved'? Also if you consider whether the title of your post is relevant? Perhaps if the post is solved, it might make sense to update the title of the post to something more descriptive? This will help people when searching for problems.
1 ACCEPTED SOLUTION

Accepted Solutions
Community Hero

Re: Script Assertion To Grab 4 'Set-Cookies' To Set 1 'Cookie' Header In Follow Up Request

@richie 

 

Finally, simulated the issue.

 

Here you go:

 

def nextStepName = 'REST Request'
def headerToLook = 'Set-Cookie'
def headerToSet = 'Cookie'

def nextRequest = context.testCase.testSteps[nextStepName].httpRequest
def headers = nextRequest.requestHeaders
def showHeaderCount = {msg -> log.info "Header count ${msg} is: headers.size()" }
showHeaderCount('before')
if (headerToSet in headers.getKeys()) {
	headers.remove(headerToSet)
	showHeaderCount('after')
}
if (messageExchange.responseHeaders.containsKey(headerToLook)) {
  log.info "Found ${headerToLook} in the response headers"
  def cookiez = messageExchange.getResponseHeaders().get(headerToLook)
  def computedValue = cookiez.collect { it.split(';').first()}.join('; ')
  log.info "Value for Cookie header is evaluated to : ${computedValue}"
  headers.put(headerToSet, computedValue)
  log.info 'Headers updated'
  nextRequest.requestHeaders = headers
  log.info headers
} else {
  log.warn "Not Found ${headerToLook} in the response headers"
}


Regards,
Rao.
12 REPLIES 12
Community Hero

Re: Script Assertion To Grab 4 'Set-Cookies' To Set 1 'Cookie' Header In Follow Up Request

@richie 

You mean, below header is expected for the following request(s)?

Cookie: returnurl=345678; authtype=234567; state=123456; nonce=456789


Regards,
Rao.
Community Hero

Re: Script Assertion To Grab 4 'Set-Cookies' To Set 1 'Cookie' Header In Follow Up Request

@richie 

What does it show if you add below statement after

"def cookiez = messageExchange.responseHeaders['Set-Cookie'].value"

 

log.info cookiez.size()

Also you may try adding  below instead of "list.add(cookies.toString())"

list.add(cookies.split().first())

 

 



Regards,
Rao.
Community Hero

Re: Script Assertion To Grab 4 'Set-Cookies' To Set 1 'Cookie' Header In Follow Up Request

Hey @nmrao 

 

exactly - the individual 'Set-Cookie' values (without the additional attribute name/values pair properties) sourced via the initial request's response are apparently concatenated into a single http 'Cookie' header which is then used in the follow up request

 

So using my genuine detail from a request - the RAW details for the initial response are as follows:

Set-Cookie: returnurl=881d9208ca983dcf9a2cc1971d02a8465eefd47cccdeafb751826e947204b8626f505fa6cf1e06dd9f9ceed91a8f0390dfbdf4077b308be6eb91306b6620ad2fd92d06c68387cddcc87a19c9909218dc-87b5428103f85588; Max-Age=3600; Expires=Tue, 18-Jun-2019 22:58:30 GMT; Path=/; Secure; HttpOnly
Set-Cookie: authtype=b1a5ce49f6c1d7d0b3ccf284e38b9f377ae00744db3862e50c1a78a0c6cd2ad5-58170217357c5777; Max-Age=3600; Expires=Tue, 18-Jun-2019 22:58:30 GMT; Path=/; Secure; HttpOnly
Set-Cookie: state=968a0b1b4944485e8d2b371d9bde404687b8bb939af05837d52c90c54844d3645b46ff6702dd6ff389e5d05d47917e6da5f2752dd5543e6cd7f4fe8e4d6c624f-707229dfb48ff182; Max-Age=3600; Expires=Tue, 18-Jun-2019 22:58:30 GMT; Path=/; Secure; HttpOnly
Set-Cookie: nonce=2eee71dfa7b10994120ec98ffe927a47ae41d13409c484a936288463be1dc938-314d577578aaf35d; Max-Age=3600; Expires=Tue, 18-Jun-2019 22:58:30 GMT; Path=/; Secure; HttpOnly

Should generate the 'Cookie' http header for the following request as

 

Cookie: returnurl=881d9208ca983dcf9a2cc1971d02a8465eefd47cccdeafb751826e947204b8626f505fa6cf1e06dd9f9ceed91a8f0390dfbdf4077b308be6eb91306b6620ad2fd92d06c68387cddcc87a19c9909218dc-87b5428103f85588; authtype=b1a5ce49f6c1d7d0b3ccf284e38b9f377ae00744db3862e50c1a78a0c6cd2ad5-58170217357c5777; state=968a0b1b4944485e8d2b371d9bde404687b8bb939af05837d52c90c54844d3645b46ff6702dd6ff389e5d05d47917e6da5f2752dd5543e6cd7f4fe8e4d6c624f-707229dfb48ff182; nonce=2eee71dfa7b10994120ec98ffe927a47ae41d13409c484a936288463be1dc938-314d577578aaf35d

Am I being clear enough?

 

thanks guys Smiley Happy

 

rich

if this helped answer the post, could you please mark it as 'solved'? Also if you consider whether the title of your post is relevant? Perhaps if the post is solved, it might make sense to update the title of the post to something more descriptive? This will help people when searching for problems.
Community Hero

Re: Script Assertion To Grab 4 'Set-Cookies' To Set 1 'Cookie' Header In Follow Up Request

Hey!

 

@nmrao adding the following

 

log.info cookiez.size()

immediately after 

def cookiez = messageExchange.responseHeaders['Set-Cookie'].value

Returned the following:

 

Wed Jun 19 01:08:49 BST 2019: INFO: Found Cookie in the response headers
Wed Jun 19 19:53:36 BST 2019: INFO: Found Cookie in the response headers
Wed Jun 19 19:53:36 BST 2019: INFO: 4

 

but when I commented out 

list.add(cookies.toString())

and replaced with

list.add(cookies.split().first())

I got an assertion failure on the script assertion - it was a nullpointer - I've attached the stacktrace if it helps at all.

 

Currently the script assertion is as follows:

 

//Courtesy of Rao
//This script assetion reads the http response, 
//collect the cookies for the next http request
//Provide the next step name where you want to set the Cookie to the request or
//Use property expansion for below
def nextStepName = 'REST Request'
def nextRequest = context.testCase.testSteps[nextStepName].httpRequest
def headers = nextRequest.requestHeaders
if (messageExchange.responseHeaders.containsKey('Set-Cookie')) {
  log.info "Found Cookie in the response headers"
  def cookiez = messageExchange.responseHeaders['Set-Cookie'].value
log.info cookiez.size()  
  def list = []  
  cookiez.each { cookies ->
     //def (name, value) = cookies.toString().split('=',2)
     list.add(cookies.toString())
     //list.add(cookies.split().first())
     
  }
  headers['Cookie'] = list
} else {
  log.warn "Not Found Cookie in the response headers"
}
nextRequest.requestHeaders = headers

Thanks guys - Im sorry I cant do anymore to help - feels a bit cheeky - but I just dont know how to proceed!

 

rich

 

 

if this helped answer the post, could you please mark it as 'solved'? Also if you consider whether the title of your post is relevant? Perhaps if the post is solved, it might make sense to update the title of the post to something more descriptive? This will help people when searching for problems.
Community Hero

Re: Script Assertion To Grab 4 'Set-Cookies' To Set 1 'Cookie' Header In Follow Up Request

@richie 

 

Would you please try below?

 

def nextStepName = 'REST Request'
def nextRequest = context.testCase.testSteps[nextStepName].httpRequest
def headers = nextRequest.requestHeaders
if (messageExchange.responseHeaders.containsKey('Set-Cookie')) {
  log.info "Found Cookie in the response headers"
  def cookiez = messageExchange.responseHeaders['Set-Cookie'].value
  def computedValue = []
  computedValue << cookiez.flatten().collect { it.split(';').first()}.join('; ')
  headers['Cookie'] = computedValue
} else {
  log.warn "Not Found Cookie in the response headers"
}
log.info headers
nextRequest.requestHeaders = headers


Regards,
Rao.
Highlighted
Community Hero

Re: Script Assertion To Grab 4 'Set-Cookies' To Set 1 'Cookie' Header In Follow Up Request

@nmrao,

 

Hey man - unfortunately the script assertion failed with the following snippet from the stacktrace Smiley Sad

Thu Jun 20 23:18:43 BST 2019: ERROR: Error in assertion script of the [GET Cookies] test step
Thu Jun 20 23:18:43 BST 2019: ERROR: groovy.lang.MissingMethodException: No signature of method: java.lang.Character.split() is applicable for argument types: (java.lang.String) values: [;]
Possible solutions: split(groovy.lang.Closure), wait(), wait(long), print(java.io.PrintWriter), plus(java.lang.Character), sprintf(java.lang.String, [Ljava.lang.Object;)
   groovy.lang.MissingMethodException: No signature of method: java.lang.Character.split() is applicable for argument types: (java.lang.String) values: [;]
   Possible solutions: split(groovy.lang.Closure), wait(), wait(long), print(java.io.PrintWriter), plus(java.lang.Character), sprintf(java.lang.String, [Ljava.lang.Object;)

I got real excited when I thought this was it - this is the last piece in my ridiculous 16 step authentication process!

 

As always  - I really appreciate the help - feels like you're doing all the work (which you are) - so please dont think I dont appreciate what you're doing,

 

nice one,

 

richie

if this helped answer the post, could you please mark it as 'solved'? Also if you consider whether the title of your post is relevant? Perhaps if the post is solved, it might make sense to update the title of the post to something more descriptive? This will help people when searching for problems.
Community Hero

Re: Script Assertion To Grab 4 'Set-Cookies' To Set 1 'Cookie' Header In Follow Up Request

Here doing guess work. So..
What does show for below statement?

log.info cookies.flatten()


Regards,
Rao.
Community Hero

Re: Script Assertion To Grab 4 'Set-Cookies' To Set 1 'Cookie' Header In Follow Up Request

@richie 

 

Finally, simulated the issue.

 

Here you go:

 

def nextStepName = 'REST Request'
def headerToLook = 'Set-Cookie'
def headerToSet = 'Cookie'

def nextRequest = context.testCase.testSteps[nextStepName].httpRequest
def headers = nextRequest.requestHeaders
def showHeaderCount = {msg -> log.info "Header count ${msg} is: headers.size()" }
showHeaderCount('before')
if (headerToSet in headers.getKeys()) {
	headers.remove(headerToSet)
	showHeaderCount('after')
}
if (messageExchange.responseHeaders.containsKey(headerToLook)) {
  log.info "Found ${headerToLook} in the response headers"
  def cookiez = messageExchange.getResponseHeaders().get(headerToLook)
  def computedValue = cookiez.collect { it.split(';').first()}.join('; ')
  log.info "Value for Cookie header is evaluated to : ${computedValue}"
  headers.put(headerToSet, computedValue)
  log.info 'Headers updated'
  nextRequest.requestHeaders = headers
  log.info headers
} else {
  log.warn "Not Found ${headerToLook} in the response headers"
}


Regards,
Rao.
Community Hero

Re: Script Assertion To Grab 4 'Set-Cookies' To Set 1 'Cookie' Header In Follow Up Request

But if the 'Cookie' header is required for all following test requests (irrespective of test cases), it needs to be changed. Ignore if that is not the case.



Regards,
Rao.
New Here?
Join us and watch the welcome video:
API Testing Mistake #2
APITestingMistake#2
Top Kudoed Authors