I have a groovy script as the first test step inside a test case, part of it looks like:
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def holder = groovyUtils.getXmlHolder("SampleTestt#Request").getXml()
log.info holder
When SampleTest test step has all element values hardcoded, the request xml can be printed fine.
However if some of the request values is read from a test case property, like the following for example
${#TestCase#Id}
The the above groovy script through error as:
org.apache.xmlbeans.XMLException: error: Unexpected character encountered : '$'
Can you please help?
Thanks.
You can use context.expand() to evaluate the properties inside your request and then parse the result to xmlHolder, your code could looks like:
// get your request replacing the properties inside by their values
def xmlRequest = context.expand('${SampleTestt#Request}')
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def holder = groovyUtils.getXmlHolder(xmlRequest)
log.info holder.getXml()
Note that I use SampleTestt as your test step request name, but I think that the last t could be a typo... check if it's the correct request name before use the code.
Hope this helps,
Related
I need to be able to do what the red x button does, but in a groovy script:
I tried the following script, but it looks like the empty strings only clear the header and its value, but not delete it:
import com.eviware.soapui.support.types.StringToStringMap
def headers = new StringToStringMap()
headers.put("","")
It seems like there is still a header according to the tab:
Looks like the error is in line 4
Please use below groovy script. All you need to do is provide the Rest Request test step's name in the below :
import com.eviware.soapui.support.types.StringToStringMap
//Define / change the step name for which headers to be removed.
def step = 'REST Request'
def nextRequest = context.testCase.testSteps[step]?.httpRequest
nextRequest?.requestHeaders = [:]
EDIT: based on OP's comments
Change from:
nextRequest?.requestHeaders = [:]
To
nextRequest?.requestHeaders = [:] as StringToStringMap
in soapui my project is :
Project
|__Datasource
|__request
|__groovy_code
|__DatasourceLoop
My Datasource contains 100 lines, each one is a request with different parameters.
My groovy_code save the id from the response of the request.
When i run my project, it executes 100 requests without errors.
groovy_code save only the first id.
What i want is to save id for each request, so 100 ids in different variables at project level
Here is my groovy_code:
import groovy.json.JsonSlurper
def response = context.expand( '${login#Response#declare namespace ns1=\'https://elsian/ns/20110518\'; //ns1:login_resp[1]/ns1:item[1]/ns1:response[1]}' )
def slurper = new JsonSlurper()
def result = slurper.parseText(response)
log.info result.data.id
testRunner.testCase.testSuite.project.setPropertyValue("token_id", result.data.id)
Thank you for your help
I never use SOAPUI PRO and I don't have access to datasource testStep or even datasource loop.
However based on the project structure you're showing I suppose that for each time datasource loop founds a element in datasource it sends the flow to request step so request and groovy steps are executed on each iteration; due to this I think that the problem is that your groovy code is overriding each time the same property with a new value.
Then to solve this you can try adding some variable suffix to your property name to avoid override each time the property value. For example you can add to token_id string a counter, some uuid, current ms etc.
For example you can use a counter as a suffix. To keep the counter value you've to save it in the context variable, this way this property are shared between your tests inside the current execution:
import groovy.json.JsonSlurper
// create a suffix function to generate
// the suffixs for your property names based on a count
def getSuffixNameProperty = {
// check if already exists
if(context['count']){
// if exists simply add 1
context['count']++
}else{
// if not exists initialize the counter
context['count'] = 1
}
return context['count']
}
def propertyName = "token_id" + getSuffixNameProperty();
def response = context.expand( '${login#Response#declare namespace ns1=\'https://elsian/ns/20110518\'; //ns1:login_resp[1]/ns1:item[1]/ns1:response[1]}' )
def slurper = new JsonSlurper()
def result = slurper.parseText(response)
testRunner.testCase.testSuite.project.setPropertyValue(propertyName, result.data.id)
I am looking for adding a SOAP request Test step in a test case, from a different TestSuite and test case, i have already coded the part to add Groovy script for same requirement but not able to add a SOAP request test step. Any help?
following is my code:
import com.eviware.soapui.impl.wsdl.teststeps.registry.GroovyScriptStepFactory
suite = context.testCase.testSuite.project.addNewTestSuite("AutomatedTestSuite")
tc = suite.addNewTestCase("automatedTestCase")
gs = tc.addTestStep( GroovyScriptStepFactory.GROOVY_TYPE, "GroovyScript1" )
gs2 = tc.addTestStep( GroovyScriptStepFactory.GROOVY_TYPE, "GroovyScript3" )
gs.properties["script"].value = 'log.info(\'hello world\')'
You can get the another testSuite,testCase and testStep by it's name through project as follows:
def project = context.testCase.testSuite.project
def testStep = project.testSuites['TestSuiteName'].testCases['TestCaseName'].testSteps['testStepName']
Or alternatively instead of array approach using getXXXXbyName method:
def testStep = project.getTestSuiteByName('TestSuiteName').getTestCaseByName('TestCaseName').getTestStepByName('testStepName')
Then to add this testStep to your testCase you can use cloneStep(WsdlTestStep testStep, String name) method.
All together in your script:
def suite = context.testCase.testSuite.project.addNewTestSuite("AutomatedTestSuite")
def tc = suite.addNewTestCase("automatedTestCase")
// get desired testStep
def project = context.testCase.testSuite.project
def testStep = project.testSuites['TestSuiteName'].testCases['TestCaseName'].testSteps['testStepName']
// add it to your new generated testCase
tc.cloneStep(testStep,testStep.name + "_Copy")
EDIT BASED ON COMMENT
If instead of a copy of another SOAP testStep you want to create a new one, you can do it using the follow code. Take in account that to create a testStep of SOAP type more info is needed than when you create a groovy one due to the need for wsdl operation info (in the example we take the first one but if you've more than one take care of what you take).
IMO the first approach is simpler, you can copy another testStep and change the properties you want... anyway if you want to do it this way here you're:
import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestRequestStepFactory
def suite = context.testCase.testSuite.project.addNewTestSuite("AutomatedTestSuite")
def tc = suite.addNewTestCase("automatedTestCase")
// get the WSDL operation... for the example we take the first one
// however if you've more get the correct one
def operation = testRunner.testCase.testSuite.project.getInterfaceAt(0).getOperationList()[0]
// factory to create the testStepConfig
def factory = new WsdlTestRequestStepFactory()
def config = factory.createConfig(operation,'stepName')
// create the testStep
def testStep = tc.addTestStep(config)
// change the request
testStep.properties['Request'].value = '<request>someData</request>'
Hope it helps,
in the line
def holder = groovyUtils.getXmlHolder("myTestStepName#Response")
if I want to refer to a test step belonging to a different test case, how do I do that?
def holder = groovyUtils.getXmlHolder ("testCaseName#myTestStepName#Response")
does not help.
If you just want an object to manipulate XML from another test case, here's an alternative route that gives you an XmlSlurper, assuming you have access to the testRunner:
def testStep = testRunner.testCase.testSuite.getTestCaseByName("testCaseName").getTestStepByName("testStepName")
def responseXml = new XmlSlurper().parseText(testStep.properties['response'].value)
Source: http://www.robert-nemet.com/2011/11/groovy-xml-parsing-in-soapui.html
I am having 2 test cases in my suite.
First test case contains 1 test step with xml request.
Second test case contains 1 test step with groovy script. I want to run the 1st test case from this groovy script a number of times. Every time I want to change the input XML. I am unable to update the input XML in TestCase 1.
I have the following the code for the groovy script:
import com.eviware.soapui.support.XmlHolder
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context);
def tsuite = testRunner.testCase.testSuite
def acctInq_tstepName = tsuite.getTestCaseAt(1).getTestStepAt(0).getName()
def acctInq_requestHolder = tsuite.getTestCaseAt(1).testSteps[acctInq_tstepName].testRequest.getRequestContent()
def acctInq_req = groovyUtils.getXmlHolder("$acctInq_requestHolder")
acctInq_req["//soapenv:Envelope[1]/soapenv:Body[1]/v2:AcctInqRq[1]/ifx:DepAcctId[1]/ifx:AcctId[1]"] = "0009917812344"
acctInq_req.updateProperty()
I also tried using
tstep.setPropertyValue("request",cStr(acctInq_req))
In either case the XML is not getting updated. Please help.
Try set node value like below and check if it fixed the issue:
acctInq_req.setNodeValue("//*:ifx:AcctId[1]", "0009917812344")