When trying to execute following robotscript, it added additional element to the login element..
Library Selenium2Library
Library Collections
Library String
Library uuid
Library Dialogs
Library SudsLibrary
Create Soap Client http://xxxxxxxxx:18080/xxxxx_b/xxx?wsdl
${dbl array}= Create Wsdl Object logIn
Set Wsdl Object Attribute ${dbl array} username xxx
Set Wsdl Object Attribute ${dbl array} password xxxx
${result}= Call Soap Method logIn ${dbl array}
log to consol ${result}
original request format
<soapenv:Envelope xmlns:soapenv="http://xxxxxxxxxxxxx/x/x/" xmlns:ws="http://xxxxxxxxxxxxxxx/">
<soapenv:Header/>
<soapenv:Body>
<ws:logIn>
<!--Optional:-->
<username>xxx</username>
<!--Optional:-->
<password>xxx</password>
</ws:logIn>
</soapenv:Body>
</soapenv:Envelope>
Generated code :
<SOAP-ENV:Envelope xmlns:ns0="http://xxxxxxxxxxxxxx/" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="h
ttp://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns1:Body>
<ns0:logIn>
<username>
<username>xxx</username>
<password>xxx</password>
</username>
</ns0:logIn>
</ns1:Body>
</SOAP-ENV:Envelope>
How to remove additional username tag?
<username>
<username>xxx</username>
<password>xxx</password>
</username>
Very likely the problem is that the login method does not take its arguments wrapped in an object, but directly. Suds creates types for all methods, but these are not needed to call the methods.
If you look in the output from Create Soap Client you will probably see something like logIn(username, password). That means you pass the arguments directly and not in some object.
Library Selenium2Library
Library Collections
Library String
Library uuid
Library Dialogs
Library SudsLibrary
Create Soap Client http://xxxxxxxxx:18080/xxxxx_b/xxx?wsdl
${result}= Call Soap Method logIn some_username some_password
log to console ${result}
Related
Would be the following SOAP request valid according to the standard?
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns2:ServiceReq xmlns:ns2="http://www.tibco.com/service" xmlns:ns1="http://www.tibco.com/framework">
<ns1:HeaderIn>
<ns1:countryISO>FR</ns1:countryISO>
<ns1:callerDateTime>2021-11-26T15:50:08.742Z</ns1:callerDateTime>
</ns1:HeaderIn>
<ns2:request>
<entete>
<profile>Default</profile>
</entete>
<input>
<type>W</type>
<codeRegion>X</codeRegion>
</input>
</ns2:request>
</ns2:ServiceReq>
</soapenv:Body>
</soapenv:Envelope>
I am not sure because certain tags don't have a namespace
There are multiple levels of valid here:
Is it a valid SOAP message as per the SOAP standard? Yes. The SOAP envelope and body tags seem valid.
Is it a valid XML format? Yes, it's a well formed XML file.
Are those elements without a namespace prefix valid? Yes. Elements can be in a default namespace or in no namespace at all.
Is the actual content of the body a valid messages? You can only tell if you verify the message you posted against the expected message as defined in the WSDL file of the web service.
All the elements in the body of the SOAP message should belong to specific namespaces, but sometimes a developer forgets to add a namespace annotation on the element, or copy-pastes something from some place else, or whatever, and you end up with weird looking XMLs like that. The service works and the message is correctly parsed, but it just looks funny.
I have problems to get SOAP request through Zeep, I get a (client) validation error... I have also tested with SoapUI and that does NOT give me the same validation error...
The specification below is from the server... Based on that specification, the OrderStatus and SynchStatus are needed to perform the request.
<soapenv:Envelope xmlns:soapenv=http://schemas.xmlsoap.org/soap/envelope/ xmlns:web="WebServiceProvider">
<soapenv:Header/>
<soapenv:Body>
<web:Order_Get>
<!--Optional:-->
<web:orderOptions>
<web:FromDate>?</web:FromDate>
<web:ToDate>?</web:ToDate>
<web:OrderStatus>?</web:OrderStatus>
<web:SynchStatus>?</web:SynchStatus>
<!--Optional:-->
<web:OrderNumber>?</web:OrderNumber>
<web:FromOrderNumberToLastRecieved>?</web:FromOrderNumberToLastRecieved>
<web:PaymentStatus>?</web:PaymentStatus>
</web:orderOptions>
</web:Order_Get>
</soapenv:Body>
</soapenv:Envelope>
However, executing this from the SoapUI without OrderStatus and SynchStatus will give me a list of all the orders for the specified dates:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="WebServiceProvider">
<soapenv:Header/>
<soapenv:Body>
<web:Order_Get>
<web:orderOptions>
<web:FromDate>2021-03-30</web:FromDate>
<web:ToDate>2021-03-31</web:ToDate>
</web:orderOptions>
</web:Order_Get>
</soapenv:Body>
</soapenv:Envelope>
I want to do the same with Zeep (https://github.com/mvantellingen/python-zeep) but the client validation fails...
I initiate the request with the following code:
api_url = 'https://abc.se/Webservice20/v3.0/webservice.asmx?WSDL'
session.auth = HTTPDigestAuth(username, password)
api = Client(api_url, transport=Transport(session=session))
And then I try to execute the following request:
order_options = {
'FromDate': '2021-03-30',
'ToDate': '2021-03-31',
}
orders = api.service.Order_Get(orderOptions=order_options)
This will result in the following error:
zeep.exceptions.ValidationError: Missing element OrderStatus (Order_Get.orderOptions.OrderStatus)
If I add OrderStatus to the request, I will get a validation error saying that SynchStatus is missing. When that has been added as well, the request is sent to the server.
I.e. it seems like the zeep client is more strict with regards to validating the data in the request than what the server is... Is there a way to force the client to skip this validation?
Many thanks in advance!
Searched a bit more and found a workaround in this post: Getting zeep.exceptions.ValidationError: Missing element for method that worked with suds
So the solution in my case looks like this:
from zeep import xsd
...
order_options = {
'FromDate': '2021-03-30',
'ToDate': '2021-03-31',
'OrderStatus': xsd.SkipValue,
'SynchStatus': xsd.SkipValue,
}
response = api.service.Order_Get(orderOptions=order_options)
This will block zeep from doing client side validation of the parameters OrderStatus and SynchStatus.
it seems like the zeep client is more strict with regards to validating the data in the request than what the server is...
Looks like it.
Looking at the request SoapUI generates based on the WSDL, the two fields you mention are mandatory:
<web:orderOptions>
<web:FromDate>?</web:FromDate>
<web:ToDate>?</web:ToDate>
<web:OrderStatus>?</web:OrderStatus>
<web:SynchStatus>?</web:SynchStatus>
<!--Optional:-->
<web:OrderNumber>?</web:OrderNumber>
<web:FromOrderNumberToLastRecieved>?</web:FromOrderNumberToLastRecieved>
<web:PaymentStatus>?</web:PaymentStatus>
</web:orderOptions>
So the error that the zeep client displays is correct. Zeep inspects the WSDL and generates the corresponding code to use the types in the contract. Your WSDL contract says that OrderStatus and SynchStatus are mandatory. The fact that the server doesn't validate them shows a problem: the web service isn't respecting it's own documented contract
The WSDL and the behavior of the web service should be the same. I suggest you contact the web service owners and ask about this behavior. It might be a validation missing on the server and what you get is just some side effect of that, or the behavior is intentional but someone forgot to update the WSDL to say that you can also make the call without those parameters.
Meanwhile, the workaround is very simple. Download the WSDL, change it to make the two fields optional, then feed this changed WSDL to zeep for it to generate the code, instead of using the original WSDL. You should however clarify this with the web service provider. If it's indeed a neglect of someone, this might be spotted at some point and fixed, making your workaround call fail a server validation because of the missing fields.
I'm using Currency Converter webservice to practice groovy script in SoapUI Pro.
In that, I have created a property that should get response / output of the Currency Converter service through groovy script.
For that, I tried the following script which gets all the raw response data :(
I need to get the exact result i.e. converted value and assign to the property.
Can anyone provide me the correct groovy script?
Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET/">
<soapenv:Header/>
<soapenv:Body>
<web:ConversionRate>
<web:FromCurrency>USD</web:FromCurrency>
<web:ToCurrency>INR</web:ToCurrency>
</web:ConversionRate>
</soapenv:Body>
</soapenv:Envelope>
Response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ConversionRateResponse xmlns="http://www.webserviceX.NET/">
<ConversionRateResult>60.54</ConversionRateResult>
</ConversionRateResponse>
</soap:Body>
</soap:Envelope>
Thanks
Karunagara Pandi
First you need access to the Response.
def conversionRateResult = context.expand( '${step_name#Response#//*:ConversionRateResult}' )
Then to assign it to a property depends on multiple things: 1) where are you doing it from, and 2) where do you want the property assigned.
To crawl the hierarchy from a script step, you would do something like:
testRunner.testCase.setPropertyValue("property_name", conversionRateResult)
Consider browsing through the documentation and API.
I am using SoapUI Pro to test web services used for creating postal despatch shipments.
I am using a groovy script to validate my web service requests. If I am expecting the request to succeed I look for a value of ‘Allocated’ in the ‘status’ field. If I am expecting the request to fail I look for the correct error code and errorDescription in the integration footer.
Sometimes a valid request will have a warning message (e.g. to inform user that field data is too long and has been truncated). I also want to validate these warning messages as well.
I specify the element path that I want to validate in my data source file and then pass it to my groovy script that does the validation.
The groovy script retrieves the value in the element path and assigns it to a variable actualReturn1 using ..
actualReturn1 = holder.getNodeValue(testElementOne);
where testElementOne could be either
//NS1:completedShipmentInfo/NS1:status/status/statusCode/code
OR
//NS1:createShipmentResponse/NS1:integrationFooter/errors/error/errorCode
The first path is valid and correctly assigns the value of this status field to actualReturn1.
But the second path does not appear to be valid and assigns null to actualReturn1.
Below are part of my 2 response files the elements I’m trying to extract data from.
Response with status element that is extracted successfully..
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<NS1:createShipmentResponse xmlns:NS1="http://www.royalmailgroup.com/api/ship/V1">
<NS1:integrationHeader>
<dateTime xmlns="http://www.royalmailgroup.com/integration/core/V1">2013-12-02T17:06:11</dateTime>
<version xmlns="http://www.royalmailgroup.com/integration/core/V1">1</version>
<identification xmlns="http://www.royalmailgroup.com/integration/core/V1">
<applicationId>111111113</applicationId>
<transactionId>420642961</transactionId>
</identification>
</NS1:integrationHeader>
<NS1:completedShipmentInfo>
<NS1:status>
<status>
<statusCode>
<code>Allocated</code>
</statusCode>
</status>
Response with errorCode that can not be extracted…
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<NS1:createShipmentResponse xmlns:NS1="http://www.royalmailgroup.com/api/ship/V1">
<NS1:integrationHeader>
<dateTime xmlns="http://www.royalmailgroup.com/integration/core/V1">2013-12-02T17:06:13</dateTime>
<version xmlns="http://www.royalmailgroup.com/integration/core/V1">1</version>
<identification xmlns="http://www.royalmailgroup.com/integration/core/V1">
<applicationId>111111113</applicationId>
<transactionId>420642961</transactionId>
</identification>
</NS1:integrationHeader>
<NS1:integrationFooter>
<errors xmlns="http://www.royalmailgroup.com/integration/core/V1">
<error>
<errorCode>E1101</errorCode>
<errorDescription>Name is a required field</errorDescription>
</error>
</errors>
Could someone tell me why this isn't working for the second response? If I have warning messages in a valid response then I'm also not able to extract the value. Is it because this is in the integrationFooter?
Happened to see this now, so adding the answer.
In the 2nd case, it was not working for you because of the namespace issue.
The element, errors is using default namespace and is different from its parent element integrationFooter. And in your xpath, no namespace was referred to element errors and its child elements.
Here is the script that works for 2nd case:
def xml = '''
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<NS1:createShipmentResponse xmlns:NS1="http://www.royalmailgroup.com/api/ship/V1">
<NS1:integrationHeader>
<dateTime xmlns="http://www.royalmailgroup.com/integration/core/V1">2013-12-02T17:06:13</dateTime>
<version xmlns="http://www.royalmailgroup.com/integration/core/V1">1</version>
<identification xmlns="http://www.royalmailgroup.com/integration/core/V1">
<applicationId>111111113</applicationId>
<transactionId>420642961</transactionId>
</identification>
</NS1:integrationHeader>
<NS1:integrationFooter>
<errors xmlns="http://www.royalmailgroup.com/integration/core/V1">
<error>
<errorCode>E1101</errorCode>
<errorDescription>Name is a required field</errorDescription>
</error>
</errors>
</NS1:integrationFooter>
</NS1:createShipmentResponse>
</soapenv:Body>
</soapenv:Envelope>'''
def holder = new com.eviware.soapui.support.XmlHolder( xml )
holder.declareNamespace('a','http://www.royalmailgroup.com/api/ship/V1')
holder.declareNamespace('b','http://www.royalmailgroup.com/integration/core/V1' )
def errorCode = holder.getNodeValue( "//a:integrationFooter/b:errors/b:error/b:errorCode" )
assert errorCode == 'E1101'
I am making a .net wcf client for java ws. But when I make a request, and response contains fault, it also contains multiRef section. So I get this exception:
Server returned an invalid SOAP Fault.
End element 'Body' from namespace 'http://schemas.xmlsoap.org/soap/envelope expected. Found element 'multiRef' from namespace ''
This is how response from server looks like (taken directly from network):
<soapenv:Envelope>
<soapenv:Header/>
<soapenv:Body>
<soapenv:Fault>...</soapenv:Fault>
<multiRef>...</multiRef>
</soapenv:Body>
</soapenv:Envelope>
Is there any way to configure my wcf client to deserialize that message right ? Or a possibility to get a raw response xml?