SoapUI to get attachment from response in Groovy - groovy

I tried to use following code to get attachment from reponse as text in Groovy.
def testStep = testRunner.testCase.getTestStepByName("getData")
def response = testStep.testRequest.response
def ins = response.attachments[0].inputStream
log.info(ins);
It contains some binary information too, so it is not fully human readable, but got following in output:
java.io.ByteArrayInputStream#5eca74

It is easy to simply encode it to base64 and store it as a property value.
def ins = response.attachments[0].inputStream
String encoded = ins.bytes.encodeBase64().toString()

Related

Passing base64 .docx to docx.Document results in BadZipFile exception

I'm writing an Azure function in Python 3.9 that needs to accept a base64 string created from a known .docx file which will serve as a template. My code will decode the base64, pass it to a BytesIO instance, and pass that to docx.Document(). However, I'm receiving an exception BadZipFile: File is not a zip file.
Below is a slimmed down version of my code. It fails on document = Document(bytesIODoc). I'm beginning to think it's an encoding/decoding issue, but I don't know nearly enough about it to get to the solution.
from docx import Document
from io import BytesIO
import base64
var = {
'template': 'Some_base64_from_docx_file',
'data': {'some': 'data'}
}
run_stuff = ParseBody(body=var)
output = run_stuff.run()
class ParseBody():
def __init__(self, body):
self.template = str(body['template'])
self.contents = body['data']
def _decode_template(self):
b64Doc = base64.b64decode(self.template)
bytesIODoc = BytesIO(b64Doc)
document = Document(bytesIODoc)
def run(self):
self.document = self._decode_template()
I've also tried the following change to _decode_template and am getting the same exception. This is running base64.decodebytes() on the b64Doc object and passing that to BytesIO instead of directly passing b64Doc.
def _decode_template(self):
b64Doc = base64.b64decode(self.template)
bytesDoc = base64.decodebytes(b64Doc)
bytesIODoc = BytesIO(bytesDoc)
I have successfully tried the following on the same exact .docx file to be sure that this is possible. I can open the document in Python, base64 encode it, decode into bytes, pass that to a BytesIO instance, and pass that to docx.Document successfully.
file = r'WordTemplate.docx'
doc = open(file, 'rb').read()
b64Doc = base64.b64encode(doc)
bytesDoc = base64.decodebytes(b64Doc)
bytesIODoc= BytesIO(bytesDoc)
newDoc = Document(bytesIODoc)
I've tried countless other solutions to no avail that have lead me further away from a resolution. This is the closest I've gotten. Any help is greatly appreciated!
The answer to the question linked below actually helped me resolve my own issue. How to generate a DOCX in Python and save it in memory?
All I had to do was change document = Document(bytesIODoc) to the following:
document = Document()
document.save(bytesIODoc)

how can I get value from json object in groovy

def RawRecordsDateRangeResponse = context.expand('${getRawRecordsForDateRange#Response}')
log.info RawRecordsDateRangeResponse
My response is:
{"2018-09-03":"https://dhap-dconnect-telemetry-data-dev2.s3.amazonaws.com/ULT/d83350d2-af56-11e8-b612-0242ac11001118/temperature/raw-2018-09-03.json"}
Here I want to get the value from the json response key as date.
Your response represents JSON document and it stores it in variable of type String. You can parse it using groovy.json.JsonSlurper class. Consider following example:
import groovy.json.JsonSlurper
def RawRecordsDateRangeResponse = context.expand('${getRawRecordsForDateRange#Response}')
def json = new JsonSlurper().parseText(RawRecordsDateRangeResponse)
def url = json.'2018-09-03'
println url
Output:
https://dhap-dconnect-telemetry-data-dev2.s3.amazonaws.com/ULT/d83350d2-af56-11e8-b612-0242ac11001118/temperature/raw-2018-09-03.json
If it's just the key of the JSON message you need rather than the value, you could use something like:
import groovy.json.JsonSlurper
def rawRecordsDateRangeResponse = '''{"2018-09-03":"https://dhap-dconnect-telemetry-data-dev2.s3.amazonaws.com/ULT/d83350d2-af56-11e8-b612-0242ac11001118/temperature/raw-2018-09-03.json"}'''
def json = new JsonSlurper().parseText(rawRecordsDateRangeResponse)
def date = json.collect({it.key})
print date
This produces [2018-09-03].

groovy extract value from string

I got a string from a server response:
responseString:"{"session":"vvSbMInXHRJuZQ==","age":7200,"prid":"901Vjmx9qenYKw","userid":"user_1"}"
then I do:
responseString[1..-2].tokenize(',')
got:
[""session":"vvSbMInXHRJuZQ=="", ""age":7200", ""prid":"901Vjmx9qenYKw"", ""userid":"user_1""]
get(3) got:
""userid":"user_1""
what I need is the user_1, is there anyway I can actually get it? I have been stuck here, other json methods get similar result, how to remove the outside ""?
Thanks.
If you pull out the proper JSON from responseStr, then you can use JsonSlurper, as shown below:
def s = 'responseString:"{"session":"vvSbMInXHRJuZQ==","age":7200,"prid":"901Vjmx9qenYKw","userid":"user_1"}"'
def matcher = (s =~ /responseString:"(.*)"/)
assert matcher.matches()
def responseStr = matcher[0][1]
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def json = jsonSlurper.parseText(responseStr)
assert "user_1" == json.userid
This code can help you get you to the userid.
def str= 'responseString:"{:"session":"vvSbMInXHRJuZQ==","age":7200,"prid":"901Vjmx9qenYKw","userid":"user_1","hdkshfsd":"sdfsdfsdf"}'
def match = (str=~ /"userid":"(.*?)"/)
log.info match[0][1]
this pattern can help you getting any of the values you want from the string. Try replacing userid with age, you will get that
def match = (str=~ /"age":"(.*?)"/)
#Michael code is also correct. Its just that you have clarified that you want the user Name to be specific

Is there a way to declare a Groovy string format in a variable?

I currently have a fixed format for an asset management code, which uses the Groovy string format using the dollar sign:
def code = "ITN${departmentNumber}${randomString}"
Which will generate a code that looks like:
ITN120AHKXNMUHKL
However, I have a new requirement that the code format must be customizable. I'd like to expose this functionality by allowing the user to set a custom format string such as:
OCP${departmentNumber}XI${randomString}
PAN-${randomString}
Which will output:
OCP125XIBQHNKLAPICH
PAN-XJKLBPPJKLXHNJ
Which Groovy will then interpret and replace with the appropriate variable value. Is this possible, or do I have to manually parse the placeholders and manually do the string.replace?
I believe that GString lazy evaluation fits the bill:
deptNum = "C001"
randomStr = "wot"
def code = "ITN${deptNum}${->randomStr}"
assert code == "ITNC001wot"
randomStr = "qwop"
assert code == "ITNC001qwop"
I think the original poster wants to use a variable as the format string. The answer to this is that string interpolation only works if the format is a string literal. It seems it has to be translated to more low level String.format code at compile time. I ended up using sprintf
baseUrl is a String containing http://example.com/foo/%s/%s loaded from property file
def operation = "tickle"
def target = "dog"
def url = sprintf(baseUrl, operation, target)
url
===> http://example.com/foo/tickle/dog
I believe in this case you do not need to use lazy evaluation of GString, the normal String.format() of java would do the trick:
def format = 'ITN%sX%s'
def code = { def departmentNumber, def randomString -> String.format(format, departmentNumber, randomString) }
assert code('120AHK', 'NMUHKL') == 'ITN120AHKXNMUHKL'
format = 'OCP%sXI%s'
assert code('120AHK', 'NMUHKL') == 'OCP120AHKXINMUHKL'
Hope this helps.
for Triple double quoted string
def password = "30+"
def authRequestBody = """
<dto:authTokenRequestDto xmlns:dto="dto.client.auth.soft.com">
<login>support#soft.com</login>
<password>${password}</password>
</dto:authTokenRequestDto>
"""

Find an element in XML using XML Slurper

"I have a code that is working as expected but now I have to find the element in different format. Example is below
<car-load>
<car-model model="i10">
<model-year>
<year.make>
<name>corolla</name>
</year.make>
</model-year>
</car-model>
</car-load>
I have to find the value of "corolla" from this XML. Please reply.
You can run this in the Groovy console
def text = '''
<car-load>
<car-model model="i10">
<model-year>
<year.make>
<name>corolla</name>
</year.make>
</model-year>
</car-model>
</car-load>'''
def records = new XmlSlurper().parseText(text)
// a quick and dirty solution
assert 'corolla' == records.toString()
// a more verbose, but more robust solution that specifies the complete path
// to the node of interest
assert 'corolla' == records.'car-model'.'model-year'.'year.make'.name.text()

Resources