├── .gitignore ├── Adding HTTP Delete Request using Groovy In SOAPUI ├── Adding HTTP Get Request Via Groovy in SOAPUI ├── Adding HTTP POST Request Via Groovy in SOAPUI ├── Adding HTTP PUT Request Via Groovy in SOAPUI ├── All About SOAPUI Properties ├── Calculate Epoch Time in Different Time Zone ├── Calling Step in Another project Via Groovy ├── Checking TestCase Run Status Via Groov ├── Coding Conventions for SOAPUI └── READY API Projects ├── Command Templates to run on Remote server via JSCH Channel ├── Connect MySQL ├── Connect ORACLE DB Via java ├── Controlling Test Execution and Reading Status-Property Via Groovy ├── Controlling Test Step Execution Via Groovy ├── Cool Groovy Collections that Helps to Generate Data ├── Create PDF Report From HTML ├── Create Reusable Script Lib and Load Using Groovy Scripting Engine ├── Create Unique Random String ├── CreatePropertyViaGroovy ├── Creating Folder to Save Logs Via Groovy ├── Creating Reusable Script library ├── Creating Test Suite to work on both Open Source and Commercial Versions Of SOAPUI ├── Creating Time Stamp in Different Time Zone ├── Date and Time Stamp String Generation In Groovy ├── Detecting OS and User Via Groovy ├── Dom XML Parser ├── Enabling TLS 1.2 in SoapUI ├── Executing Command and Getting output using pattren Matching ├── G String Uses ├── Get List testSteps in a Test Case using Groovy Script in soapUI ├── Getting Mails As Collections ├── Getting Http Status Code from Response ├── Groovy -Cleaning SOAPUI Properties Values ├── Groovy -Reading Data from CSV ├── Groovy File IO Samples ├── Groovy Method To Get System IP4 Address List ├── Groovy Regex Pattern to Extract a String from a given line of text ├── Groovy Running A Step in another Test Suite Via Groovy ├── Groovy Script to get Test Case-Suite-ProjectName ├── Groovy Snippet To Compare Two Time Stamps ├── Groovy for to Extract Cookie From Login Response ├── Groovy maps to query strings ├── Groovy script can run the soapui project and generate junit result ├── Groovy-Encoding File in Groovy ├── Groovy-setFailOnError @ Test Case level ├── HTTP Protocol Basics ├── Header Manipulation Via Groovy in SOAPUI ├── Helpful Groovy Builtin Functions in Scripting ├── How to JSON Path -to Get a Attribute Value from JSON Response ├── Http Status Codes ├── Implementing a way to exit from test execution loop ├── Importing Custom Jars In SOAPUI ├── Increasing Socket Time Out to 5 mins ├── Installing Groovy On Windows Machine ├── License Install From Command Line on Linux ├── Load Properties From External File Using Groovy ├── Maintaining Properties For Different Environemnts ├── Mocking Web Services ├── My Swagger Hub Account ├── Objects Available in Side a Groovy Step ├── Optimum Care While Creating Test Suite ├── Parsing_JSON_Using_JSONSlurper ├── Play With Collections ├── Print Step Name and Step Request and Step Response ├── README.md ├── ReadPropertyViaGroovy ├── Reading Performance logging Times ├── ReadyAPI_Linux Specific Issues ├── References ├── Research_Item:Generate PDF Report ├── Retrying Whole Test Case If any Test Step Fails ├── Running Multiple Test Projects via Batch file from Command Line Using testRunner ├── Running SOAPUI Project From ANT and Generating Junit HTML Report ├── Running-ReadyAPI-tests-from-Jenkins-on-Windows-Nodes ├── SOAP UI Step Execution Basics ├── SOAPUI -Running Specific Step in another Test Suite ├── SOAPUI Free Reading Properties from Properties Step ├── SOAPUI OS Free Version Sending Email Test Report ├── SOAPUI OS Managing Session Across the Test Suites ├── SOAPUI Open Source Script Library ├── SOAPUI VM Options File ├── SOAPUI With Ant ├── SOAPUIWithANT ├── Procedure ├── References: ├── build.propertiesfile └── build.xml File ├── SOAPUI_Tips_and_Tricks ├── SOPUIOS-Managing Multiple Environment Properties ├── Sample WSDL Files For Practice ├── Setting End Point Via Groovy Script ├── Setting parameters in SOAPUI request using a groovy script ├── Solution for Null Pointer Exception-While Constructing Project Object from Groovy-While Running Project from testRunner ├── Steps to Make Scripts Open Source Version Compatible ├── String Tokeniser ├── Swagger Definition File Import-Create Test Suite-Create Mock Services ├── Syntax Problems between SOAPUI Versions ├── Test Runner Object ├── Test Suite Tear Down Script ├── Useful SOAP UI API Methods ├── Using Custom Templates to Generate Report Using Template Engine ├── Validate JSON with JsonUtil Class ├── Ways to Collect Web Services information ├── Web Service Related KeyWords ├── Working with Context Property Using Groovy ├── Working with XAPATH in SOAPUI ├── Writing Assertion Results into File and Customized Test Resport ├── groovy ├── ChangeRunTestCaseDynamically.groovy ├── ConditionalExecution.groovy ├── ContainsAssertion.groovy ├── CustomTestReport.groovy ├── DateDifferenceCalculation.groovy ├── DisableTestSteps.groovy ├── ExecuteCommandAndGetOutput.groovy ├── ExportTestCaseProperties.groovy ├── GetMatchingString.groovy ├── ImportPropertiesToTestCase.groovy ├── LogRawDataOnTestFailure.groovy ├── MIMEAttachmentExample.groovy ├── NamespaceSample.groovy ├── QueryRawData.groovy ├── RandomizeTests.groovy ├── RegexSample.groovy ├── SetHttpHeaders.groovy ├── SetJsonRequest.groovy ├── TestRunner.groovy ├── ToggleSuitesBasedOnCommandlineInput.groovy ├── UpdateResponseSLA.groovy ├── UpdateWSDLDefinition.groovy ├── VerifyHTTPResponse.groovy ├── VerifyHeaders.groovy ├── WriteResponseValueToFile.groovy ├── compare │ └── xmlAndJdbc_sample1.groovy ├── json │ ├── AssertJsonArrayElement.groovy │ ├── IsResponseValidJson.groovy │ ├── JsonArrayEmpty.groovy │ ├── UpdateNextJsonRequestFromCurrentResponse.groovy │ └── cdata │ │ └── JsonInsideCdata.groovy ├── mockServiceScripts │ └── MockResponseDispatcherWithDynamicValues.groovy ├── scriptAssertions │ ├── cdata │ │ └── CdataInsideXml.groovy │ ├── cookies │ │ ├── AddCookiesToNextRequest.groovy │ │ └── AddCookiesToStore.groovy │ └── headersToMultipleSteps │ │ ├── AddCurrentResponseHeaderToMultipleSteps.groovy │ │ ├── AddHeadersToMultipleSteps.groovy │ │ └── SetCookieForNextRequest.groovy ├── shareData │ └── AccessComplexObjectsFromOtherScripts.groovy └── xml │ ├── AssertValueBetweenRange.groovy │ ├── builder │ ├── BuildSoapRequestFromCsv.groovy │ └── GenerateDynamicSoapRequest.groovy │ └── cdata │ ├── CdataXpathExists.groovy │ ├── SaveCdataXmlToCsv.groovy │ └── XmlInsideCdata.groovy ├── in EST Time Zone Create Current Date and DayBefore YesterDay Time Strings and Then Convert into Milliseconds └── jsch Sftp Script to connect and Copy File from Remote Server /.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajendrapenumalli/SOAPUI-Useful-Concepts-and-Groovy-Scripts/5c2ac3d5a2b880f447be07412016c01ccf8ffe95/.gitignore -------------------------------------------------------------------------------- /Adding HTTP Delete Request using Groovy In SOAPUI: -------------------------------------------------------------------------------- 1 | import static com.eviware.soapui.impl.wsdl.teststeps.registry.HttpRequestStepFactory.HTTPREQUEST_TYPE 2 | //Provide the http request endpoint in the below 3 | def endpoint = 'http://google.com' 4 | //Valid http method GET | PUT | POST | DELETE etc 5 | def method = 'DELETE' 6 | def stepName = 'httpRequestStep7' 7 | def tc=testRunner.testCase 8 | //Adds http request step to given test case assumes tc is valid object of TestCase 9 | tc.addTestStep(HTTPREQUEST_TYPE , stepName, endpoint, method) 10 | -------------------------------------------------------------------------------- /Adding HTTP Get Request Via Groovy in SOAPUI: -------------------------------------------------------------------------------- 1 | Adding HTTP Get Request Via Groovy in SOAPUI 2 | 3 | import static com.eviware.soapui.impl.wsdl.teststeps.registry.HttpRequestStepFactory.HTTPREQUEST_TYPE 4 | //Provide the http request endpoint in the below 5 | def endpoint = 'http://google.com' 6 | //Valid http method GET | PUT | POST | DELETE etc 7 | def method = 'POST' 8 | def stepName = 'httpPostRequestStep' 9 | def tc=testRunner.testCase.getTestStepByName(stepName).s 10 | //Adds http request step to given test case assumes tc is valid object of TestCase 11 | tc.addTestStep(HTTPREQUEST_TYPE , stepName, endpoint, method) 12 | -------------------------------------------------------------------------------- /Adding HTTP POST Request Via Groovy in SOAPUI: -------------------------------------------------------------------------------- 1 | Adding HTTP POST Request Via Groovy in SOAPUI 2 | 3 | import static com.eviware.soapui.impl.wsdl.teststeps.registry.HttpRequestStepFactory.HTTPREQUEST_TYPE 4 | //Provide the http request endpoint in the below 5 | def endpoint = 'http://google.com' 6 | //Valid http method GET | PUT | POST | DELETE etc 7 | def method = 'POST' 8 | def stepName = 'httpRequestStep4' 9 | def tc=testRunner.testCase 10 | //Adds http request step to given test case assumes tc is valid object of TestCase 11 | tc.addTestStep(HTTPREQUEST_TYPE , stepName, endpoint, method) 12 | 13 | //Setting Post Body 14 | def request = context.testCase.getTestStepByName(stepName).getTestRequest() 15 | def jsonText = '''{ 16 | "id" : "sample id", 17 | "name" : "sample name", 18 | "tags" : [ "sample tags" ], 19 | "address" : { 20 | "street" : "sample street", 21 | "zipcode" : "sample zipcode", 22 | "city" : "sample city" 23 | } 24 | }''' 25 | context.testCase.getTestStepByName(stepName).testRequest.setMediaType('application/json123') 26 | request.setRequestContent(jsonText) 27 | -------------------------------------------------------------------------------- /Adding HTTP PUT Request Via Groovy in SOAPUI: -------------------------------------------------------------------------------- 1 | import static com.eviware.soapui.impl.wsdl.teststeps.registry.HttpRequestStepFactory.HTTPREQUEST_TYPE 2 | //Provide the http request endpoint in the below 3 | def endpoint = 'http://google.com' 4 | //Valid http method GET | PUT | POST | DELETE etc 5 | def method = 'PUT' 6 | def stepName = 'httpRequestStep5' 7 | def tc=testRunner.testCase 8 | //Adds http request step to given test case assumes tc is valid object of TestCase 9 | tc.addTestStep(HTTPREQUEST_TYPE , stepName, endpoint, method) 10 | 11 | //Setting Post Body 12 | def request = context.testCase.getTestStepByName(stepName).getTestRequest() 13 | def jsonText = '''{ 14 | "id" : "sample id", 15 | "name" : "sample name", 16 | "tags" : [ "sample tags" ], 17 | "address" : { 18 | "street" : "sample street", 19 | "zipcode" : "sample zipcode", 20 | "city" : "sample city" 21 | } 22 | }''' 23 | context.testCase.getTestStepByName(stepName).testRequest.setMediaType('application/json123') 24 | request.setRequestContent(jsonText) 25 | -------------------------------------------------------------------------------- /All About SOAPUI Properties: -------------------------------------------------------------------------------- 1 | All About SOAPUI Properties:: 2 | 3 | Property is Key Value Pair. 4 | In Test Step we can use the key(Variable Name) 5 | 6 | Properties allows to Supply: 7 | Input Data/Initial Configuration Date 8 | To Store Runtime Properties 9 | To solve correlation problem. 10 | 11 | Types of Properties: 12 | User Defined /Custom Properties 13 | ReadOnly Properties 14 | 15 | Becareful: 16 | If test case running in a loop, Properties Must be Cleared once interation is over. 17 | 18 | 19 | Properties are organised in following levels: 20 | Test Step 21 | Test Case 22 | Test Suite 23 | Project(Per Environement) 24 | Work Space 25 | Global 26 | 27 | Way to Set Properties: 28 | testRunner.testCase.setPropertyValue("key","value"); 29 | testRunner.testCase.testSuite.setPropertyValue("key","value"); 30 | testRunner.testCase.testSuite.property.setPropertyValue("key","value"); 31 | com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils.globalProperties.setPropertyValue('key', 'value') 32 | 33 | Way to Get Properties: 34 | def tcPropertyValue=testRunner.testCase.getPropertyValue("key"); 35 | def tspropertyValue=testRunner.testCase.testSuite.getPropertyValue("key"); 36 | def proPropertyValue=testRunner.testCase.testSuite.project.getPropertyValue("key"); 37 | 38 | Property Expansion in soapUI: 39 | SOAPUI Provides a common syntax to dynamically insert ("expand") property values during processing 40 | 41 | where scope can be one of the following literal values: 42 | #Project# - references a Project property(Reference properties across a particular SoapUI project) 43 | #TestSuite# - references a TestSuite property in the containing TestSuite 44 | #TestCase# - references a TestCase property in the containing TestCase 45 | #MockService# - references a MockService property in the containing MockService 46 | #Global# - references a global property. Found in File>Preferences>Global Properties tab. Reference properties across all projects 47 | #System# - references a system property. Found in Help>System properties. 48 | #Env# - references an environment variable 49 | [TestStep name]# - references a TestStep property 50 | 51 | If no scope is specified, the property is resolved as follows: 52 | 53 | Check the current context (for example the TestRunContext) for a property with the matching name 54 | Check for a matching global property 55 | Check for a matching system property 56 | 57 | Property expansion further includes an XPath expression, 58 | this will be used to select the corresponding value from the referenced property value (which must contain XML): 59 | 60 | ${Search Request#Response#//ns1:Item[1]/n1:Author[1]/text()} 61 | 62 | def propertyValue = context.expand('${#Global#propertyKey}') 63 | ${Search Request#Response#//ns1:Item[1]/n1:Author[1]/text()} 64 | 65 | 66 | ${[scope]propertyName[#xpath-expression]} 67 | Syntax: ${#Scope#Property-name[#xpath-expression]} 68 | ${Property-name} refers to a Global Property (example: ${UserName} to a global Property named “UserName”) 69 | ${#Project#Property-name} refers to a Project Property (example: ${#Project#UserName} to a Property on Project level named “UserName”) 70 | ${#TestSuite#Property-name} refers to a TestSuite Property (example: ${#TestSuite#UserName} to a Prop on TestSuite level named “UserName”) 71 | ${#TestCase#Property-name} refers to a TestCase Property (example: ${#TestCase#UserName} to a Prop on TestCase level named “UserName”) 72 | ${TestStep-name#Property-name} refers to a property in a named TestStep. 73 | 74 | 75 | Dynamic Properties: 76 | SOAPUI allows to write groovy scripts directly inside a PropertyExpansion 77 | Prefix the content with a '=' and the remaining content up to the closing brace will be evaluated as a script and its result will be inserted. 78 | 79 | ${=(int)(Math.random()*1000)} 80 | ${=import java.text.SimpleDateFormat ; new SimpleDateFormat("YYYY-MM-DDT00:00:00").format(new Date())} 81 | ${=request.name} 82 | ${=request.operation.interface.project.name} 83 | 84 | In Groovy Script Step: 85 | 86 | // Set values to the same properties. 87 | testRunner.testCase.setPropertyValue( "PropertyName", 'someValue' ) 88 | testRunner.testCase.testSuite.setPropertyValue( "PropertyName", 'someValue' ) 89 | testRunner.testCase.testSuite.project.setPropertyValue( "PropertyName", 'someValue' ) 90 | com.eviware.soapui.SoapUI.globalProperties.setPropertyValue( "PropertyName", 'someValue' ) 91 | 92 | // Get properties from the test case, test suite and project. 93 | def testCaseProperty = testRunner.testCase.getPropertyValue( "PropertyName" ) 94 | def testSuiteProperty = testRunner.testCase.testSuite.getPropertyValue( "PropertyName" ) 95 | def projectProperty = testRunner.testCase.testSuite.project.getPropertyValue( "PropertyName" ) 96 | def globalProperty = com.eviware.soapui.SoapUI.globalProperties.getPropertyValue( "PropertyName" ); 97 | 98 | In Groovy Script Assertion Step:Access test cases in a different way: 99 | def testCaseProperty = messageExchange.modelItem.testStep.testCase.getPropertyValue( "MyProp" ) 100 | 101 | -------------------------------------------------------------------------------- /Calculate Epoch Time in Different Time Zone: -------------------------------------------------------------------------------- 1 | import java.text.SimpleDateFormat; 2 | TimeZone zone = TimeZone.getTimeZone("America/New_York"); 3 | SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:sss"); 4 | timeStampFormat .setTimeZone(zone); 5 | def instantTimeStamp=timeStampFormat.format(new Date()); 6 | Date date = timeStampFormat.parse(instantTimeStamp); 7 | def timeInMilliSecond = date.getTime(); 8 | log.info timeInMilliSecond 9 | -------------------------------------------------------------------------------- /Calling Step in Another project Via Groovy: -------------------------------------------------------------------------------- 1 | // Replace names of a project, test suite, case and step with those you need. 2 | 3 | // Connecting to the test step in another project. 4 | def prj = testRunner.testCase.testSuite.project.workspace.getProjectByName("ProjectName") 5 | tCase = prj.testSuites['TestSuiteName'].testCases['TestCaseName'] 6 | tStep = tCase.getTestStepByName("TestStepName") 7 | 8 | // Calling the test runner and checking if it can run the specified step. 9 | def runner = tStep.run(testRunner, context) 10 | log.info ("runner status ....... : " + runner.hasResponse()) 11 | -------------------------------------------------------------------------------- /Checking TestCase Run Status Via Groov: -------------------------------------------------------------------------------- 1 | 2 | Use the following to get the status of the entire testcase. 3 | testRunner.status 4 | OR 5 | testRunner.getStatus() 6 | -------------------------------------------------------------------------------- /Coding Conventions for SOAPUI/READY API Projects: -------------------------------------------------------------------------------- 1 | Coding Conventions for SOAPUI/READY API Projects 2 | 3 | 1. Following strict naming conventions 4 | In Request Names 5 | In property Names 6 | In Groovy Scripts 7 | Cookie Names 8 | 9 | 2. Organisaing variavles: 10 | @Project level 11 | @TestSuite level 12 | @TestCase level 13 | 14 | 3. Keeping Logging Statements to make it easy for debugging 15 | Phase wise log statements 16 | Final log statement 17 | 18 | 4. Null checks in groovy bscripts 19 | 20 | 5. Retry logics with 21 | max retry count 22 | max retry timeout 23 | 24 | 6. Keeping neat interface definitions 25 | -------------------------------------------------------------------------------- /Command Templates to run on Remote server via JSCH Channel: -------------------------------------------------------------------------------- 1 | 1. Command Templates to Delete File on Remote server via jsch Channel 2 | String LogFileName=test.log; 3 | String command1="rm -rf /home/"+lyxUserName+"/"+LogFileName 4 | 5 | 2. Command Templates to Tail log and Redirecting to a file in BackGround Process 6 | String LogFileName=test.log; 7 | String command1="tail -f -n 0 "+logPathOnServer+" > /home/"+lyxUserName+"/"+LogFileName+" &" 8 | 9 | 3. Command to get Process Id of Tailing Job that running in BackGround 10 | String command1="echo `ps -ef | grep tail | grep -v grep | awk '{print \$2}'`"; 11 | -------------------------------------------------------------------------------- /Connect MySQL: -------------------------------------------------------------------------------- 1 | http://www.mkyong.com/jdbc/how-to-connect-to-mysql-with-jdbc-driver-java/?utm_source=mkyong&utm_medium=author&utm_campaign=top-pv&utm_content=18 2 | -------------------------------------------------------------------------------- /Connect ORACLE DB Via java: -------------------------------------------------------------------------------- 1 | http://www.mkyong.com/jdbc/connect-to-oracle-db-via-jdbc-driver-java/?utm_source=mkyong&utm_medium=author&utm_campaign=top-pv&utm_content=16 2 | -------------------------------------------------------------------------------- /Controlling Test Execution and Reading Status-Property Via Groovy: -------------------------------------------------------------------------------- 1 | Experiment 2 | 3 | Create a three test suites 4 | 5 | Each tetestSuite with three testcases: 6 | 7 | Each Test Cases must have three groovy steps 8 | 9 | Each Step has one string "I am in Step{1/2/3}" 10 | 11 | Test Following 12 | testRunner.cancel(arg0) 13 | testRunner.fail(arg0) 14 | testRunner.results 15 | testRunner.status 16 | testRunner.getReason() 17 | testRunner.isRunning() 18 | testRunner.gotoStep(arg0) 19 | testRunner.gotoStepByName(arg0) 20 | testRunner.runTestStepByName(arg0) 21 | -------------------------------------------------------------------------------- /Controlling Test Step Execution Via Groovy: -------------------------------------------------------------------------------- 1 | 1. SOAPUI API's allows us to Control test execution control via groovy scripting. 2 | 3 | testRunner.gotoStepByName( "targetStepName") 4 | testRunner.runTestStepByName( "targetStepName") 5 | testRunner.cancel("Decribe Cancellation Reason") "Simplay Stops an ongoing test run with the specified reason". 6 | testRunner.fail("Decribe Failure Reason") "Fails an ongoing test run with the specified reason". 7 | testRunner.run() 8 | 9 | Running a Test Step: 10 | def tCase = testRunner.testCase.testSuite.testCases["Name of test cases"] 11 | def tStep = tCase.testSteps["test step you want to run"] 12 | tStep.run(testRunner, context) 13 | 14 | If we want to Specific Step in another Test Suite: 15 | def tCase = testRunner.testCase.testSuite.project.testSuites["test suite Name "].testCases["test case Name"] 16 | def tStep = tCase.testSteps["test step you want to run"] 17 | tStep.run(testRunner, context) 18 | -------------------------------------------------------------------------------- /Cool Groovy Collections that Helps to Generate Data: -------------------------------------------------------------------------------- 1 | //Cool Groovy Collections that Helps to Generate Data 2 | 3 | Permutations: 4 | Sample: 5 | 6 | Input: [field1,field2,field3].permutations() 7 | Output: /[[field1,field2,field3], [field3, field2, field1], [field2, field1, field3], [field3, field1, field2], [field1, field3,field2], [field2, field3, field1]] 8 | 9 | 10 | Combinations: 11 | letters = ['a', 'b', 'c'] 12 | numbers = [1, 2, 3] 13 | combos = [letters, numbers].combinations() 14 | //[[a, 1], [b, 1], [c, 1], [a, 2], [b, 2], [c, 2], [a, 3], [b, 3], [c, 3]] 15 | 16 | 17 | Subsequences: 18 | [1,2,3].subsequences() 19 | //===> [[1], [1, 2, 3], [2], [2, 3], [1, 2], [3], [1, 3]] 20 | 21 | 22 | Intersect: 23 | [1,2,3,4].intersect([2,4]) 24 | //===> [2, 4] 25 | -------------------------------------------------------------------------------- /Create PDF Report From HTML: -------------------------------------------------------------------------------- 1 | https://github.com/Jahia/html2pdf/blob/master/src/main/java/org/jahia/modules/html2pdf/HtmlPdfWriter.java 2 | 3 | -------------------------------------------------------------------------------- /Create Reusable Script Lib and Load Using Groovy Scripting Engine: -------------------------------------------------------------------------------- 1 | ####Create Reusable Script Lib and Load Using Groovy Scripting Engine 2 | 3 | import groovy.lang.Binding 4 | import groovy.util.GroovyScriptEngine 5 | 6 | def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context ) // location of script file is relative to SOAPUI project file. 7 | String scriptPath = groovyUtils.projectPath + "/groovyLib/" 8 | // Create Groovy Script Engine to run the script. 9 | GroovyScriptEngine gse = new GroovyScriptEngine(scriptPath) 10 | // Load the Groovy Script file 11 | externalScript = gse.loadScriptByName("LoadProperties.groovy") 12 | // Create a runtime instance of script 13 | script = externalScript.newInstance() 14 | // Sanity check 15 | assert script!= null 16 | // run the foo method in the external script 17 | log.info script.loadProjectProperties(log,context,testRunner) 18 | 19 | 20 | ####Create dir with name:groovyLib in project directory/path 21 | Create a script :LoadProperties.groovy 22 | with Following Code: 23 | 24 | def loadProjectProperties(def log,def context,def testRunner){ 25 | def groovyUtils=new com.eviware.soapui.support.GroovyUtils(context) 26 | def projectPath = groovyUtils.projectPath 27 | def env = testRunner.getTestCase().getTestSuite().getProject().getActiveEnvironmentName() 28 | log.info('Environment Choosen to Execute Test = ' + env) 29 | 30 | //Constructing Environment Project Specific Config File Name 31 | def projectFilePath=testRunner.getTestCase().getTestSuite().getProject().getPath() 32 | log.info "Project Path: "+projectFilePath 33 | def projectFileObj = new File(projectFilePath); 34 | String projFileName=projectFileObj.getName(); 35 | String projFileNameWithOutExtn=projFileName.substring(0,projFileName.indexOf('.')); 36 | log.info "Project File Name Without Extension : $projFileNameWithOutExtn"; 37 | 38 | //Constructing Environment Project Specific Config File Path 39 | String envSpecDataConfigFileName=projFileNameWithOutExtn+".properties" 40 | String sperator=System.getProperty("file.separator");//Finding OS Specific File Seperator 41 | String envSpecDataConfigFilePath=projectPath+sperator+env+sperator+envSpecDataConfigFileName 42 | def dataConfigFile=new File(envSpecDataConfigFilePath); 43 | 44 | //Checking for File Existence ,If File not exist then whole test execution will be aborted 45 | if(dataConfigFile.exists()){ 46 | log.info "Data Config File $envSpecDataConfigFilePath Found"; 47 | } 48 | else{ 49 | log.info "Opps.....! Data Config File $envSpecDataConfigFilePath Not Found!!!!" 50 | testRunner.fail("Opps.....! Data Config File $envSpecDataConfigFilePath Not Found!!!!") 51 | } 52 | 53 | //Removing the Existing Config Data @ Project Level 54 | def project=testRunner.testCase.testSuite.project; 55 | for( prop in project.properties) { 56 | project.removeProperty( prop.value.name ) 57 | } 58 | 59 | //Loading the Env Specific Config data 60 | def props = new Properties() 61 | new File(envSpecDataConfigFilePath).withInputStream { 62 | stream -> props.load(stream) 63 | } 64 | 65 | //Updating the Project Properties 66 | log.info("Loading Env: "+env+" Specific Project Data"); 67 | props.each { 68 | String propKey=it.key; 69 | String propValue=it.value; 70 | project.setPropertyValue(propKey,propValue) 71 | def propValue1=project.getPropertyValue(propKey); 72 | log.info "$propKey:$propValue1" //Later this can be commented out to stop shoing properties in Log 73 | } 74 | log.info("Data Loading Completed"); 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /Create Unique Random String: -------------------------------------------------------------------------------- 1 | def ts = new java.text.SimpleDateFormat("yyyy-MM-dd-HH:mm:ss.SSS"); //Time Steamp Object 2 | def randomString = System.currentTimeMillis() //Current Epouch object 3 | -------------------------------------------------------------------------------- /CreatePropertyViaGroovy: -------------------------------------------------------------------------------- 1 | Anyways you can use set to create new properties 2 | def testCaseProperty = testRunner.testCase.setPropertyValue("myTest", "blah") 3 | -------------------------------------------------------------------------------- /Creating Folder to Save Logs Via Groovy: -------------------------------------------------------------------------------- 1 | Creating Folder to Save Logs Via Groovy 2 | 3 | //Generate Time STamp String 4 | import java.text.*; 5 | import java.nio.file.Files; 6 | import java.nio.file.Paths; 7 | 8 | SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss"); 9 | Date now = new Date(); 10 | String dateString = sdfDate.format(now); 11 | testRunner.testCase.testSuite.project.setPropertyValue( "dateString", dateString) 12 | log.info dateString 13 | //Determine the Project file Path 14 | def groovyUtils=new com.eviware.soapui.support.GroovyUtils(context) 15 | def projectPath = groovyUtils.projectPath 16 | log.info projectPath 17 | //Construct Directory Name 18 | String execLogsDirPath= projectPath+"\\"+"ExecutionLogs"+"\\"+dateString 19 | File dir=new File(execLogsDirPath); 20 | dir.mkdirs(); 21 | testRunner.testCase.setPropertyValue( "execLogsDirPath", execLogsDirPath) 22 | String logMsg="Setting Audit logs @Path: "+execLogsDirPath 23 | -------------------------------------------------------------------------------- /Creating Reusable Script library: -------------------------------------------------------------------------------- 1 | Creating jar files and deploying it in ext folder of SOAP UI: 2 | 3 | 1.Create a new groovy script file with a class (follows java standards in file naming i.e. class name and file name should be same) 4 | 2.Compile the groovy code file 5 | 3.Create the jar file 6 | 4.Deploy the jar file at SoapUI_Home/bin/ext folder 7 | 5.Restart the SoapUI if was already open 8 | 6.Create the object of class and use the methods anywhere in the SoapUI projects 9 | 10 | Note: If you are migrating your project to some other machine, make sure to migrate these libraries as well if you are using them in projects 11 | 12 | ***********Detailed Example********************: 13 | 14 | Step 1: Create a new groovy script file with a class structure 15 | 16 | i. Considering the class ScriptLibrary that contain a method named printTestDetails as in following code in it: 17 | 18 | class ScriptLibrary { 19 | 20 | def context 21 | def testRunner 22 | def log 23 | 24 | def printTestDetails(def PrintThisToo) { 25 | log.info 'Name of the test case is :'+testRunner.testCase.name 26 | log.info 'Name of the test suite is : '+testRunner.testCase.testSuite.name 27 | log.info PrintThisToo 28 | } 29 | } 30 | 31 | ii. Save the file with class name, ScriptLibrary.groovy in this case 32 | 33 | Step 2: Compile the code 34 | 35 | i. Open command prompt and fire following command (from the folder where where your .groovy file is kept) 36 | 37 | Compile the code: 38 | groovyc -d classes SimplePrint.groovy 39 | 40 | Step 3: Create the jar file 41 | 42 | i. After compiling the code we can create the jar Create jar file: 43 | 44 | jar cvf SimplePrint.jar -C classes . 45 | 46 | Step 4: Deploy the jar file at SoapUI_Home/bin/ext folder 47 | 48 | Step 5: Restart the SoapUI if was already open 49 | 50 | Step 6: Create the object of class and use the methods anywhere in the SoapUI projects 51 | 52 | i. Creating object 53 | 54 | def scripts = new ScriptLibrary(context:context, log:log, testRunner:testRunner) 55 | 56 | ii. Calling methods 57 | scripts.printTestDetails(“This is my argument”) 58 | 59 | 60 | References: 61 | 1.https://stackoverflow.com/questions/35331821/creating-script-library-in-soapui-free-version 62 | 2.http://webservice-testing.blogspot.in/2012/05/groovy-script-library-in-soapui.html 63 | 64 | -------------------------------------------------------------------------------- /Creating Test Suite to work on both Open Source and Commercial Versions Of SOAPUI: -------------------------------------------------------------------------------- 1 | Creating Test Suite to work on both Open Source and Commercial Versions Of SOAPUI 2 | 3 | Dont Use Enviornments: Use Groovy +Peroperties Step Combination 4 | Dont Use Envents: Manually Add headers like cookies to each step 5 | Dont Use Data Source Step for Looping: Use Goovy Looping logic 6 | 7 | So what you need to know: 8 | You must be good or intermediate level coding skills in groovy 9 | You must be familier with SOAPUI API and Its Methods to use. 10 | -------------------------------------------------------------------------------- /Creating Time Stamp in Different Time Zone: -------------------------------------------------------------------------------- 1 | Creating Time Stamp in Different Time Zone 2 | 3 | import java.text.SimpleDateFormat; 4 | TimeZone zone = TimeZone.getTimeZone("America/New_York"); 5 | SimpleDateFormat hoursFormat = new SimpleDateFormat("HH"); 6 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 7 | hoursFormat.setTimeZone(zone); 8 | dateFormat.setTimeZone(zone); 9 | String currentHours=hoursFormat.format(new Date()); 10 | String currentDate=dateFormat.format(new Date()); 11 | 12 | testRunner.testCase.setPropertyValue("currentHours",currentHours); 13 | testRunner.testCase.setPropertyValue("currentDate",currentDate); 14 | log.info ("""----------->>>>>Current Time Hours $currentHours 15 | ----------->>>>>Current Date $currentDate"""); 16 | 17 | //Output :INFO:----------->>>>>Current Time Hours 23 ----------->>>>>Current Date 2017-06-16 18 | 19 | 20 | //Generating Time Stamp in Given Time Zone and Adding 30 minutes to minutes part 21 | 22 | import java.text.SimpleDateFormat; 23 | import java.util.Calendar; 24 | 25 | 26 | def cal = Calendar.getInstance(); 27 | TimeZone zone = TimeZone.getTimeZone("EST"); 28 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); 29 | dateFormat.setTimeZone(zone); 30 | String currentDate=dateFormat.format(new Date()); 31 | log.info "Exact Time in EST Time Zone: "+currentDate 32 | cal.setTime(dateFormat.parse(currentDate)) 33 | cal.add(Calendar.MINUTE, 30); 34 | String latestCurrentDate = dateFormat.format(cal.getTime()); 35 | log.info latestCurrentDate 36 | log.info "30 Mins After Time in EST Time Zone: "+latestCurrentDate 37 | -------------------------------------------------------------------------------- /Date and Time Stamp String Generation In Groovy: -------------------------------------------------------------------------------- 1 | Date and Time Stamp String Generation In Groovy 2 | 3 | #Date Time Stamp: 4 | 5 | import java.text.*; 6 | SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy_MM_dd_HHmmss"); 7 | SimpleDateFormat startDate = new SimpleDateFormat("MM/dd/yyyy"); 8 | Date now = new Date(); 9 | String strDate = sdfDate.format(now); 10 | Date date = new Date(); 11 | String startDate1 = startDate.format (date) 12 | Date prevDay = new Date()-1; 13 | String preday = startDate.format (prevDay) 14 | testRunner.getTestCase().setPropertyValue("TC_TimeStamp", strDate); 15 | -------------------------------------------------------------------------------- /Detecting OS and User Via Groovy: -------------------------------------------------------------------------------- 1 | //1.Getting OS Name of The Machine 2 | String osName = System.getProperty( "os.name" ).toLowerCase(); 3 | log.info osName 4 | 5 | 6 | //2.Following Snippet will give System User Name 7 | def userName=System.getProperty("user.name") 8 | log.info userName 9 | 10 | 11 | //3.OS Specific File Seperator: 12 | String seperator = File.separator 13 | log.info seperator 14 | //File.separator = / for Unix 15 | //File.separator = \ for Windows 16 | -------------------------------------------------------------------------------- /Dom XML Parser: -------------------------------------------------------------------------------- 1 | http://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/ 2 | -------------------------------------------------------------------------------- /Enabling TLS 1.2 in SoapUI: -------------------------------------------------------------------------------- 1 | By Default SOAPUI Will not be enabled TLS 1.2 2 | 3 | This requires to be added : SoapUI-5.3.0.vmoptions file 4 | 5 | Path: C:\Program Files (x86)\SmartBear\SoapUI-5.3.0\bin\SoapUI-5.3.0.vmoptions 6 | 7 | -XX:MinHeapFreeRatio=20 8 | -XX:MaxHeapFreeRatio=40 9 | -Xms128m 10 | -Xmx1000m 11 | -Dsoapui.properties=soapui.properties 12 | -Dsoapui.home=C:\Program Files (x86)\SmartBear\SoapUI-5.3.0/bin 13 | -Dsoapui.ext.libraries=C:\Program Files (x86)\SmartBear\SoapUI-5.3.0/bin/ext 14 | -Dsoapui.ext.listeners=C:\Program Files (x86)\SmartBear\SoapUI-5.3.0/bin/listeners 15 | -Dsoapui.ext.actions=C:\Program Files (x86)\SmartBear\SoapUI-5.3.0/bin/actions 16 | -Dwsi.dir=C:\Program Files (x86)\SmartBear\SoapUI-5.3.0/wsi-test-tools 17 | -Djava.library.path=C:\Program Files (x86)\SmartBear\SoapUI-5.3.0/bin 18 | -Djava.util.Arrays.useLegacyMergeSort=true 19 | -Dsoapui.https.protocols=SSLv3,TLSv1.2 20 | 21 | 22 | -Dsun.net.http.allowRestrictedHeaders=true 23 | -agentlib:jdwp=transport=dt_socket,address=53677,suspend=n,server=y 24 | -splash:SoapUI-Spashscreen.png 25 | 26 | 27 | What happens if Server requires TLs1.2 and SOAPUI is not Suporting for that: 28 | 29 | javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure no 30 | -------------------------------------------------------------------------------- /Executing Command and Getting output using pattren Matching: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | import java.util.regex.Matcher; 5 | import java.util.regex.Pattern; 6 | 7 | String command = "ipconfig /all"; 8 | Process p = Runtime.getRuntime().exec(command); 9 | 10 | BufferedReader inn = new BufferedReader(new InputStreamReader(p.getInputStream())); 11 | Pattern pattern = Pattern.compile(".*Physical Addres.*: (.*)"); 12 | while (true) { 13 | String line = inn.readLine(); 14 | if (line == null) 15 | break; 16 | Matcher mm = pattern.matcher(line); 17 | if (mm.matches()) { 18 | System.out.println(mm.group(1)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /G String Uses: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Get List testSteps in a Test Case using Groovy Script in soapUI: -------------------------------------------------------------------------------- 1 | //List testSteps using Groovy Script in soapUI: 2 | 3 | def testSteps = context.testCase.getTestStepList() 4 | testSteps.each{ 5 | log.info(it.name) 6 | } 7 | -------------------------------------------------------------------------------- /Getting Mails As Collections: -------------------------------------------------------------------------------- 1 | Getting Mails As Collections : 2 | Following java Class helps to retrieve latest email messages as Colleaction(HashMap) 3 | HashMap Key: Unique Email Id Subject 4 | HashMap Value:is an Array List 5 | ArrayList[0] ="Sender Email Address"; 6 | ArrayList[1] ="Email Body Text"; 7 | 8 | 9 | -------------------------------------------------------------------------------- /Getting Http Status Code from Response: -------------------------------------------------------------------------------- 1 | Getting Http Status Code from Response 2 | 3 | def monServerTestRespheaders = testRunner.testCase.testSteps['GetTestToMonServer'].testRequest.response.getResponseHeaders() 4 | String httpStatusCode =monServerTestRespheaders["#status#"]; 5 | -------------------------------------------------------------------------------- /Groovy -Cleaning SOAPUI Properties Values: -------------------------------------------------------------------------------- 1 | Groovy -Cleaning SOAPUI Properties Values 2 | 3 | #Clean All Project Level Properties 4 | def projectProperties=testRunner.testCase.testSuite.project.getPropertyNames(); 5 | def project=testRunner.testCase.testSuite.project; 6 | projectProperties.each{ propName -> 7 | log.info "remove prop: $propName" 8 | if(!propName.equals("env")){ 9 | project.setPropertyValue(propName,'') 10 | } 11 | } 12 | 13 | #Clean All TestSuite Level Properties 14 | def tsProperties=testRunner.testCase.testSuite.getPropertyNames(); 15 | def ts=testRunner.testCase.testSuite; 16 | tsProperties.each{ propName -> 17 | log.info "remove prop: $propName" 18 | if(!propName.equals("env")){ 19 | ts.setPropertyValue(propName,'') 20 | } 21 | } 22 | 23 | #Clean All TestCase Level Properties 24 | def tcProperties=testRunner.testCase.getPropertyNames(); 25 | def tc=testRunner.testCase; 26 | tcProperties.each{ propName -> 27 | log.info "remove prop: $propName" 28 | if(!propName.equals("env")){ 29 | tc.setPropertyValue(propName,'') 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Groovy -Reading Data from CSV: -------------------------------------------------------------------------------- 1 | Reading Data from CSV 2 | 3 | def prj = testRunner.testCase.getTestSuite().getProject(); 4 | def groovyUtils=new com.eviware.soapui.support.GroovyUtils(context) 5 | def projectPath = groovyUtils.projectPath+"\\" 6 | log.info projectPath 7 | def fileName="TestData"+".csv"; 8 | def filePath=projectPath+fileName; 9 | log.info "Loaded "+filePath 10 | 11 | def file = new File(filePath); 12 | def listofLines=[]; 13 | if(!file.exists()) { 14 | log.info "File does not exist" 15 | testRunner.cancel("Expected Input Data File:$filePath is Not Avilable,Aborting Test Execution") 16 | } 17 | else { 18 | (file as List).each { 19 | listofLines<=1){ 37 | if(field){ 38 | propertyValues< 24 | writer.writeLine 'Into the ancient pond' 25 | writer.writeLine 'A frog jumps' 26 | writer.writeLine 'Water’s sound!' 27 | } 28 | 29 | 2. file<< '''Into the ancient pond 30 | A frog jumps 31 | Water’s sound!' 32 | 33 | 34 | 35 | 3. File Seperator system Property 36 | File.separator 37 | 38 | -------------------------------------------------------------------------------- /Groovy Method To Get System IP4 Address List: -------------------------------------------------------------------------------- 1 | Method Call 2 | getMachineIpStrList() 3 | 4 | 5 | //Actual Method 6 | def getMachineIpStrList(){ 7 | def ipList=[]; 8 | try { 9 | def ip; 10 | def interfaces = NetworkInterface.getNetworkInterfaces(); 11 | while (interfaces.hasMoreElements()) { 12 | def iface = interfaces.nextElement(); 13 | // if (iface.isLoopback() || !iface.isUp())--> filters out 127.0.0.1 and inactive interfaces 14 | if (!iface.isUp()){ // filters out inactive interfaces 15 | continue; 16 | } 17 | def addresses = iface.getInetAddresses(); 18 | while(addresses.hasMoreElements()) { 19 | def addr = addresses.nextElement(); 20 | if (addr instanceof Inet6Address) { 21 | continue; 22 | } 23 | ip = addr.getHostAddress(); 24 | log.info(ip); 25 | ipList.add(ip); 26 | } 27 | } 28 | } catch (SocketException e) { 29 | throw new RuntimeException(e); 30 | } 31 | String strIpList=ipList.join(","); 32 | log.info strIpList 33 | return strIpList 34 | } 35 | -------------------------------------------------------------------------------- /Groovy Regex Pattern to Extract a String from a given line of text: -------------------------------------------------------------------------------- 1 | Groovy Regex Pattern to Extract a String from a given line of text: 2 | 3 | Problem: 4 | Given Test String:"1234:Oct 9 03:49:12 apache1 /usr/sbin/openjava" 5 | Extract TimeStamp from 'Oct 9 03:49:12' from above string 6 | 7 | Solution: 8 | String givenText="1234:Oct 9 03:49:12 apache1 /usr/sbin/openjava": 9 | def timeStampPattrenPattren = ~/[A-Z a-z]{3} [0-9]{1,2} [0-2][0-9]:[0-5][0-9]:[0-5][0-9]/; 10 | def timeStampMatcher = ( givenText =~ timeStampPattrenPattren ) 11 | def timeStampString= timeStampMatcher[0]; 12 | log.info timeStampString 13 | 14 | 15 | Next: 16 | Collect IP Address Regex pattren 17 | Collect Mobile Number Regex Pattren 18 | Collect Creditcard Regex Pattren 19 | 20 | 21 | Pattern pattern; 22 | Matcher matcher; 23 | 24 | String EMAIL_PATTERN ="^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; 25 | 26 | public EmailValidator() { 27 | pattern = Pattern.compile(EMAIL_PATTERN); 28 | } 29 | 30 | public boolean validate(final String hex) { 31 | matcher = pattern.matcher(hex); 32 | return matcher.matches(); 33 | } 34 | 35 | 36 | 37 | 38 | 39 | 40 | Java Regex Usage Example: 41 | 42 | //Example validating the parameter “zip” using a regular expression: Validating an U.S. Zip Code (5 digits plus optional -4) 43 | 44 | private static final Pattern zipPattern = Pattern.compile("^\d{5}(-\d{4})?$"); 45 | try { 46 | String zipCode = request.getParameter( "zip" ); 47 | if ( !zipPattern.matcher( zipCode ).matches() { 48 | log.info( "Improper zipcode format." ); 49 | } 50 | } catch(YourValidationException e ) { 51 | log.info( "Bad Input." ); 52 | } 53 | } 54 | 55 | 56 | 57 | 58 | Good References: 59 | https://www.owasp.org/index.php/Input_Validation_Cheat_Sheet 60 | -------------------------------------------------------------------------------- /Groovy Running A Step in another Test Suite Via Groovy: -------------------------------------------------------------------------------- 1 | log.info testRunner.testCase.testSuite.project.workspace.getProjectByName("myProject").testSuites["yourTestSuite"].testCases["TestCase 1"].testSteps["delete"].run(testRunner, context) 2 | -------------------------------------------------------------------------------- /Groovy Script to get Test Case-Suite-ProjectName: -------------------------------------------------------------------------------- 1 | // Set names for the test case, test suite, and project. 2 | testRunner.testCase.label = 'Sample Test Case Name' 3 | testRunner.testCase.testSuite.label = 'Sample Test Suite Name' 4 | testRunner.testCase.testSuite.project.name = 'Sample Project Name' 5 | -------------------------------------------------------------------------------- /Groovy Snippet To Compare Two Time Stamps: -------------------------------------------------------------------------------- 1 | def startTime="Oct 9 03:49:09"; 2 | def endTime ="Oct 9 03:50:09"; 3 | def timeToChk="Oct 9 03:49:12"; 4 | 5 | Following Snippet helps to Check Given Time String between two time intervals or not: 6 | 7 | import java.text.SimpleDateFormat; 8 | def zone = TimeZone.getTimeZone("America/New_York"); 9 | def dateFormat = new SimpleDateFormat("MMM d HH:mm:ss"); 10 | 11 | Date timeObjToChk = dateFormat.parse(timeToChk); 12 | 13 | Date startTimeObj = dateFormat.parse(startTime); 14 | Date endTimeObj = dateFormat.parse(endTime); 15 | 16 | if(timeObjToChk.after(startTimeObj)&&timeObjToChk.before(endTimeObj) ) { 17 | log.info("Within Interval") 18 | } 19 | else{ 20 | log.info("Outside Interval") 21 | } 22 | -------------------------------------------------------------------------------- /Groovy for to Extract Cookie From Login Response: -------------------------------------------------------------------------------- 1 | Suppose If Log in Response Equal to: 2 | HTTP/1.1 200 OK 3 | Server: Apache-Tomcat/1.2 4 | Set-Cookie: JSESSIONID=12121323232332321321321321; Path=/sdsdsdsdsdsdsdsdsds/ 5 | Content-Length: 1567 6 | Date: Wed, 27 Sep 2017 18:07:58 GMT 7 | 8 | 9 | def cookie = testRunner.testCase.getTestStepByName("LoginStep").httpRequest.response.responseHeaders["Set-Cookie"][0]; 10 | // then cookie=JSESSIONID=12121323232332321321321321; Path=/sdsdsdsdsdsdsdsdsds/ 11 | testRunner.testCase.setPropertyValue("cookie", cookie); 12 | 13 | 14 | -------------------------------------------------------------------------------- /Groovy maps to query strings: -------------------------------------------------------------------------------- 1 | https://chart.googleapis.com/chart?chs=250x100&chd=t:60,40&cht=p3&chl=Hello|World 2 | 3 | def base = 'https://chart.googleapis.com/chart?' 4 | def params = [chs:'250x100', chd:'t:60,40', cht:'p3', chl:'Hello|World'] 5 | def url = base + params.collect { k,v -> "$k=$v" }.join('&') 6 | -------------------------------------------------------------------------------- /Groovy script can run the soapui project and generate junit result: -------------------------------------------------------------------------------- 1 | Groovy script can run the soapui project and generate junit result 2 | 3 | 4 | /** 5 | * this groovy script can run the soapui project and generate junit result 6 | **/ 7 | import com.eviware.soapui.tools.SoapUITestCaseRunner 8 | def runner = new SoapUITestCaseRunner() 9 | runner.with { 10 | //change the paths as needed to suit your environment 11 | setProjectFile('/path/to/Sample-soapui-project.xml') 12 | //Ignore below if you do not have any special settings. 13 | setSettingsFile('/path/to/soapui-settings.xml') 14 | setOutputFolder('/tmp/results') 15 | setPrintReport(true) 16 | setExportAll(true) 17 | setJUnitReport(true) 18 | run() 19 | } 20 | -------------------------------------------------------------------------------- /Groovy-Encoding File in Groovy: -------------------------------------------------------------------------------- 1 | // Replace the file path with the one you need. 2 | // Getting the file content. 3 | def inputFile = new File("C:\\Work\\MyFile.txt").getText('UTF-8') 4 | 5 | // Encoding the file content. 6 | String encoded = inputFile.bytes.encodeBase64().toString() 7 | 8 | // Outputting results. 9 | log.info encoded // with the Groovy Script test step, you can use return encoded. 10 | -------------------------------------------------------------------------------- /Groovy-setFailOnError @ Test Case level: -------------------------------------------------------------------------------- 1 | 2 | 3 | testRunner.testCase.testSuite.project.getTestSuiteList().each{ 4 | it.getTestCaseList().each{ 5 | it.setFailOnError(true) 6 | } 7 | } 8 | 9 | testRunner.testCase.getPropertyCount(); 10 | 11 | 12 | 13 | 14 | 15 | log.info testRunner.metaClass.methods*.name 16 | 17 | Fri Dec 22 23:23:20 IST 2017:INFO:[ 18 | equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, 19 | wait, cancel, fail, getLog, getReason, getRunContext, getStartTime, 20 | getStatus, getTestRunnable, getTimeTaken, isRunning, setRunContext, start, waitUntilFinished, getResults, getRunContext, 21 | getTestCase, gotoStep, gotoStepByName, runTestStep, runTestStepByName, setMockRunContext] 22 | 23 | log.info testRunner.testCase.metaClass.methods*.name 24 | 25 | Fri Dec 22 23:24:09 IST 2017:INFO:[equals, getClass, hashCode, notify, 26 | notifyAll, toString, wait, wait, wait, addPropertyChangeListener, 27 | addPropertyChangeListener, fireIndexedPropertyChange, fireIndexedPropertyChange, 28 | fireIndexedPropertyChange, getChildren, getProject, notifyPropertyChanged, 29 | notifyPropertyChanged, notifyPropertyChanged, notifyPropertyChanged, 30 | removePropertyChangeListener, removePropertyChangeListener, 31 | afterLoad, beforeSave, dependsOn, getConfig, getDescription, 32 | getExternalDependencies, getIcon, getId, getName, getParent, 33 | getSettings, getWsdlModelItemById, getWsdlModelItemByName, 34 | release, resolve, setConfig, setDescription, setIcon, setName, 35 | addPropertiesFromFile, addProperty, addTestPropertyListener, 36 | getModelItem, getProperties, getPropertiesLabel, getProperty, 37 | getPropertyAt, getPropertyCount, getPropertyList, getPropertyNames, 38 | getPropertyValue, hasProperty, moveProperty, removeProperty, 39 | removeTestPropertyListener, renameProperty, setPropertyValue, addNewLoadTest, 40 | addNewSecurityTest, addTestRunListener, addTestStep, addTestStep, addTestStep, 41 | afterCopy, buildLoadTest, cloneLoadTest, cloneSecurityTest, cloneStep, 42 | exportTestCase, findNextStepOfType, findPreviousStepOfType, getAmfAuthorisation, 43 | getAmfEndpoint, getAmfLogin, getAmfPassword, getChildren, getCreateActions, 44 | getDiscardOkResults, getFailOnError, getFailTestCaseOnErrors, 45 | getIndexOfLoadTest, getIndexOfSecurityTest, getIndexOfTestStep, getKeepSession, 46 | getLabel, getLoadTestAt, getLoadTestByName, getLoadTestCount, getLoadTestList, 47 | getLoadTests, getMaxResults, getRunFromHereContext, getSearchProperties, 48 | getSecurityTestAt, getSecurityTestByName, getSecurityTestCount, getSecurityTestList, getSecurityTests, 49 | getSetupScript, getTearDownScript, getTestRunListeners, getTestStepAt, getTestStepById, getTestStepByName, 50 | getTestStepCount, getTestStepIndexByName, getTestStepList, getTestSteps, getTestStepsOfType, 51 | getTestStepsOrdered, getTestSuite, getTimeout, getWsrmAckTo, getWsrmEnabled, getWsrmExpires, getWsrmVersion, 52 | getWsrmVersionNamespace, importSecurityTests, importTestStep, importTestSteps, insertTestStep, 53 | insertTestStep, insertTestStep, insertTestSteps, isDisabled, isForLoadTest, moveTestStep, release, 54 | removeLoadTest, removeSecurityTest, removeTestRunListener, removeTestStep, resetConfigOnMove, 55 | run, runSetupScript, runTearDownScript, setAmfAuthorisation, setAmfEndpoint, setAmfLogin, 56 | setAmfPassword, setDisabled, setDiscardOkResults, setFailOnError, setFailTestCaseOnErrors, 57 | setKeepSession, setMaxResults, setName, setRunFromHereContext, setSearchProperties, setSetupScript, 58 | setTearDownScript, setTimeout, setWsrmAckTo, setWsrmEnabled, setWsrmExpires, setWsrmVersion, addPropertyChangeListener] 59 | -------------------------------------------------------------------------------- /HTTP Protocol Basics: -------------------------------------------------------------------------------- 1 | Http Protocol versions 2 | HTTP 1.0 3 | HTTP 2.1 4 | 5 | 6 | Basic HTTP Method: 7 | GET 8 | 200 OK 9 | 10 | POST 11 | 200 OK 12 | 201 Created 13 | 204 No Content 14 | 15 | PUT 16 | 17 | 18 | DELETE 19 | 200 Ok 20 | 202 Accpted 21 | 204 No Content 22 | 23 | Http Request: 24 | Request URL: 25 | Headers 26 | Body 27 | 28 | 29 | Http Response: 30 | Response Content 31 | Headers 32 | Body 33 | 34 | Maximum POST Body Size: Protocol never define sizes,it is left server settings that it can handle 35 | Maximum Get Header Length: Protocol never define sizes,it is left server settings that it can handle 36 | 37 | Body Content: 38 | XML 39 | JSON 40 | HTML 41 | 42 | 43 | 44 | Http Status Codes 45 | - 1xx: Informational - Request received, continuing process 46 | 100 47 | - 2xx: Success - The action was successfully received,understood, and accepted 48 | 200 49 | 201 50 | 203 51 | - 3xx: Redirection - Further action must be taken in order to complete the request 52 | 303 53 | - 4xx: Client Error - The request contains bad syntax or cannot be fulfilled 54 | 401 55 | - 5xx: Server Error - The server failed to fulfill an apparently valid request 56 | 501 57 | 58 | Http Request Payload/Message Content Type: 59 | 60 | Http Content Types: 61 | 62 | Link Definition: 63 | A link can be viewed as a statement of the form "{context IRI} has a {relation type} resource at {target IRI}, which has {target attributes}". 64 | The Link entity-header field provides a means for serialising one or more links in HTTP headers 65 | 66 | References: 67 | HTTP 1.1 RFC: https://tools.ietf.org/html/rfc2616#section-7 68 | 69 | 70 | -------------------------------------------------------------------------------- /Header Manipulation Via Groovy in SOAPUI: -------------------------------------------------------------------------------- 1 | Header Manipulation Via Groovy in SOAPUI 2 | 3 | #Getting Cookie Header from Headers: 4 | def headerValue = testRunner.testCase.getTestStepByName("LoginOperation").httpRequest.response.responseHeaders["Set-Cookie"][1] 5 | -------------------------------------------------------------------------------- /Helpful Groovy Builtin Functions in Scripting: -------------------------------------------------------------------------------- 1 | Groovy Provides lots of Ready to Eat Stuff. 2 | 3 | Many Times we might need to store Map As String in Test Case/Test Suite/Project Level Properties. 4 | 5 | Because setPropertyValue method will accept only String type Key and String Type Valve, 6 | Here is the Syntax: 7 | testRunner.testCase.setPropertyValue( , ) 8 | We cannot directly store Map object into Test Case Properties> 9 | 10 | In order to do that we must convert the HashMap to String. 11 | def testResults = [testCase1: 'Passed',testCase2: 'Passed',testCase3: 'Failed'] 12 | log.info testResults.toMapString() 13 | Output:[testCase1:Passed, testCase2:Passed, testCase3:Failed] 14 | 15 | So testResults HashMap Just converted to String but still you can see box brackets in begining and ending of the String 16 | Now simplay strip them off and output will get as following 17 | 18 | log.info testResults.toMapString().replace("[","").replace("]",""); 19 | Output: testCase1:Passed, testCase2:Passed, testCase3:Failed 20 | 21 | : Add Some notes on: 22 | Similarly we can also convert ArrayList as a String 23 | 24 | : Add Some notes on: 25 | Similarly we can also convert File Text Content as a String 26 | 27 | : Add Some notes on: 28 | Groovy Trouth 29 | 30 | : Add Some notes on: 31 | Groovy Trouth to check empty or null objects safely 32 | 33 | : Add Some notes on: 34 | Groovy Strings 35 | 36 | 37 | : Add Some notes on: 38 | context.setProperty(), 39 | context.getProperty() 40 | Using context object passing the values between groovy scripts(to Aggregate Results). 41 | 42 | : Add Some notes on: 43 | Difference between context.setProperty() Vs testRunner.testCase.setPropertyValue( , ) 44 | When to use which? 45 | 46 | -------------------------------------------------------------------------------- /How to JSON Path -to Get a Attribute Value from JSON Response: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Http Status Codes: -------------------------------------------------------------------------------- 1 | Http Status Codes 2 | 3 | HTTP Status Codes 4 | 5 | Registration Procedure(s) 6 | IETF Review 7 | Reference 8 | [RFC7231] 9 | Note 10 | 1xx: Informational - Request received, continuing process 11 | 2xx: Success - The action was successfully received, understood, and accepted 12 | 3xx: Redirection - Further action must be taken in order to complete the request 13 | 4xx: Client Error - The request contains bad syntax or cannot be fulfilled 14 | 5xx: Server Error - The server failed to fulfill an apparently valid request 15 | 16 | Available Formats 17 | 18 | CSV 19 | Value Description Reference 20 | 100 Continue [RFC7231, Section 6.2.1] 21 | 101 Switching Protocols [RFC7231, Section 6.2.2] 22 | 102 Processing [RFC2518] 23 | 103 Early Hints [RFC-ietf-httpbis-early-hints-05] 24 | 104-199 Unassigned 25 | 26 | 200 OK [RFC7231, Section 6.3.1] 27 | 201 Created [RFC7231, Section 6.3.2] 28 | 202 Accepted [RFC7231, Section 6.3.3] 29 | 203 Non-Authoritative Information [RFC7231, Section 6.3.4] 30 | 204 No Content [RFC7231, Section 6.3.5] 31 | 205 Reset Content [RFC7231, Section 6.3.6] 32 | 206 Partial Content [RFC7233, Section 4.1] 33 | 207 Multi-Status [RFC4918] 34 | 208 Already Reported [RFC5842] 35 | 209-225 Unassigned 36 | 226 IM Used [RFC3229] 37 | 227-299 Unassigned 38 | 39 | 300 Multiple Choices [RFC7231, Section 6.4.1] 40 | 301 Moved Permanently [RFC7231, Section 6.4.2] 41 | 302 Found [RFC7231, Section 6.4.3] 42 | 303 See Other [RFC7231, Section 6.4.4] 43 | 304 Not Modified [RFC7232, Section 4.1] 44 | 305 Use Proxy [RFC7231, Section 6.4.5] 45 | 306 (Unused) [RFC7231, Section 6.4.6] 46 | 307 Temporary Redirect [RFC7231, Section 6.4.7] 47 | 308 Permanent Redirect [RFC7538] 48 | 309-399 Unassigned 49 | 50 | 400 Bad Request [RFC7231, Section 6.5.1] 51 | 401 Unauthorized [RFC7235, Section 3.1] 52 | 402 Payment Required [RFC7231, Section 6.5.2] 53 | 403 Forbidden [RFC7231, Section 6.5.3] 54 | 404 Not Found [RFC7231, Section 6.5.4] 55 | 405 Method Not Allowed [RFC7231, Section 6.5.5] 56 | 406 Not Acceptable [RFC7231, Section 6.5.6] 57 | 407 Proxy Authentication Required [RFC7235, Section 3.2] 58 | 408 Request Timeout [RFC7231, Section 6.5.7] 59 | 409 Conflict [RFC7231, Section 6.5.8] 60 | 410 Gone [RFC7231, Section 6.5.9] 61 | 411 Length Required [RFC7231, Section 6.5.10] 62 | 412 Precondition Failed [RFC7232, Section 4.2][RFC8144, Section 3.2] 63 | 413 Payload Too Large [RFC7231, Section 6.5.11] 64 | 414 URI Too Long [RFC7231, Section 6.5.12] 65 | 415 Unsupported Media Type [RFC7231, Section 6.5.13][RFC7694, Section 3] 66 | 416 Range Not Satisfiable [RFC7233, Section 4.4] 67 | 417 Expectation Failed [RFC7231, Section 6.5.14] 68 | 418-420 Unassigned 69 | 421 Misdirected Request [RFC7540, Section 9.1.2] 70 | 422 Unprocessable Entity [RFC4918] 71 | 423 Locked [RFC4918] 72 | 424 Failed Dependency [RFC4918] 73 | 425 Unassigned 74 | 426 Upgrade Required [RFC7231, Section 6.5.15] 75 | 427 Unassigned 76 | 428 Precondition Required [RFC6585] 77 | 429 Too Many Requests [RFC6585] 78 | 430 Unassigned 79 | 431 Request Header Fields Too Large [RFC6585] 80 | 432-450 Unassigned 81 | 451 Unavailable For Legal Reasons [RFC7725] 82 | 452-499 Unassigned 83 | 84 | 85 | 500 Internal Server Error [RFC7231, Section 6.6.1] 86 | 501 Not Implemented [RFC7231, Section 6.6.2] 87 | 502 Bad Gateway [RFC7231, Section 6.6.3] 88 | 503 Service Unavailable [RFC7231, Section 6.6.4] 89 | 504 Gateway Timeout [RFC7231, Section 6.6.5] 90 | 505 HTTP Version Not Supported [RFC7231, Section 6.6.6] 91 | 506 Variant Also Negotiates [RFC2295] 92 | 507 Insufficient Storage [RFC4918] 93 | 508 Loop Detected [RFC5842] 94 | 509 Unassigned 95 | 510 Not Extended [RFC2774] 96 | 511 Network Authentication Required [RFC6585] 97 | 512-599 Unassigned 98 | 99 | Reference: 100 | http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml 101 | -------------------------------------------------------------------------------- /Implementing a way to exit from test execution loop: -------------------------------------------------------------------------------- 1 | Implementing a way to exit from test execution loop 2 | 3 | Different ways to exit the test execution: 4 | 1.Creating one second delay step in the end of test case and jumping to that step by using testRunner.gotoStepByName(); 5 | 2.Creating one dummy groovy step in the end of test case and jumping to that step by using testRunner.gotoStepByName(); 6 | 3.Using testRunner.Cancel 7 | -------------------------------------------------------------------------------- /Importing Custom Jars In SOAPUI: -------------------------------------------------------------------------------- 1 | In order to extend SOAPUI functionality we might need to use external jars: 2 | 3 | For example in SOAPUI Free Version, 4 | 1. There is no builtin test Step to send Email . 5 | 2. These is no builtin support to use Excel File as a Data Source 6 | 3. Database drivers to connect required DB 7 | 8 | SOAPUI Allows to use external jars to extend the functionality> 9 | Those Jars we can keep in \bin\ext directory. 10 | 11 | Here are the Path: 12 | OpenSource Verion Ext Version Path: C:\Program Files (x86)\SmartBear\SoapUI-5.3.0\bin\ext 13 | Commercial Version Path: C:\Program Files\SmartBear\ReadyAPI-1.9.0\bin\ext 14 | -------------------------------------------------------------------------------- /Increasing Socket Time Out to 5 mins: -------------------------------------------------------------------------------- 1 | Increasing Socket Time Out to 5 mins 2 | 3 | import com.eviware.soapui.SoapUI 4 | import com.eviware.soapui.settings.HttpSettings 5 | import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus 6 | 7 | def settings = SoapUI.getSettings();// get the settings 8 | // save the possible previous timeout 9 | def bk_timeout = settings.getString(HttpSettings.SOCKET_TIMEOUT,""); 10 | // set the new timeout... in your case 5 minutes in miliseconds 11 | settings.setString(HttpSettings.SOCKET_TIMEOUT,"300000"); 12 | // save the new settings 13 | SoapUI.saveSettings(); 14 | -------------------------------------------------------------------------------- /Installing Groovy On Windows Machine: -------------------------------------------------------------------------------- 1 | Installing Groovy On Windows Machine: 2 | 3 | 1. Download Groovy Binary and keppt in C: 4 | 2. Unzip it 5 | 3. Open the Groovy Folder and Navigate to C:\groovy-2.4.13\bin Folder 6 | 4. Copy the Path 7 | 5. Add GROOVY_HOME Environment System variable 8 | GROOVY_HOME:C:\groovy-2.4.13 9 | 6. Add C:\groovy-2.4.13\bin to Path Variable 10 | 11 | 7. Then test installation: 12 | 13 | C:\Users\Raj>groovy -version 14 | Groovy Version: 2.4.13 JVM: 1.8.0_151 Vendor: Oracle Corporation OS: Windows 10 15 | 16 | C:\Users\Rajgroovyc -version 17 | Groovy compiler version 2.4.13 18 | Copyright 2003-2017 The Apache Software Foundation. http://groovy-lang.org/ 19 | 20 | -------------------------------------------------------------------------------- /License Install From Command Line on Linux: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /Load Properties From External File Using Groovy: -------------------------------------------------------------------------------- 1 | def props = new Properties() 2 | //replace the path with your file name below. use / instead of \ as path separator even on windows platform. 3 | new File("/absolute/path/of/test.properties").withInputStream { s -> 4 | props.load(s) 5 | } 6 | props.each { 7 | context.testCase.testSuite.setPropertyValue(it.key, it.value) 8 | } 9 | -------------------------------------------------------------------------------- /Maintaining Properties For Different Environemnts: -------------------------------------------------------------------------------- 1 | Maintaining Properties For Different Environemnts 2 | 3 | Maintaining Properties For Different Environemnts 4 | Generally Same Applications are deployed into different environement: 5 | 1.Test Server or TEST Environemnt 6 | 2.Staging Environment or STAG Environment 7 | 3.Production Environemnt-1: or PROD1 8 | 4.Production Environemnt-2: or PROD2 9 | Since the application is same, One suite created for one environemnt must run in other environments too. 10 | But different environments may have different configuration/test data: 11 | for example: 12 | EndPoint Will different for each environment 13 | Application Login Credentails may be same or different based on configuration 14 | Other application specific input data. 15 | For manging the Different environment Data We have superb feature in SOAPUI Pro/Ready API 16 | But how can we handle this with OpenSource SOAPUI? 17 | 18 | Here are the two Solutions: 19 | 1. Create External CSV File (Data Source) for each environment and Load then conditionally 20 | 2. Create one property file for each environment and based on required requirement enable only that property step and disable other properties steps. 21 | -------------------------------------------------------------------------------- /Mocking Web Services: -------------------------------------------------------------------------------- 1 | ####Mocking Services 2 | 3 | //Mock Handler Objects 4 | A number of objects are commonly available in most scripts; here comes a quick overview with links to their corresponding javadoc: 5 | context – used for storing MockService-wide objects, for example database connections, security tokens, etc 6 | requestContext – used for storing Mock Request-wide objects, for example dynamic content to be inserted into the response message 7 | mockRequest – an object corresponding to the actual request made to the MockService. Through this object you can get hold of the incoming message, its headers, etc. Also the underlying HttpRequest and HttpResponse objects are available for “low-level” processing 8 | mockResult – an object encapsulating the result of the dispatched request, this is available in the MockService.afterRequest script. 9 | mockResponse/mockOperation – objects available at the corresponding levels for accessing the underlying configuration and functionality 10 | mockRunner – the object corresponding to the execution of the MockService; this gives you access to previous mock results, etc 11 | 12 | //Setting mock request headers 13 | mockRequest.httpResponse.setHeader('MyHeader', "HiThere;") 14 | mockRequest.httpResponse.setContentLength(456) 15 | mockRequest.httpResponse.sendError(404) 16 | def queryString = mockRequest.getHttpRequest().getQueryString() 17 | 18 | def path = mockRequest.getPath() 19 | 20 | //Getting parameters 21 | mockRequest.getRequest().getParameter("paramName") 22 | mockRequest.getRequest().parametersMap(); 23 | 24 | //Setting response properties 25 | def resp = mockOperation.getMockResponseByName('MyResponse') 26 | resp.setResponseHttpStatus(202) 27 | return 'MyResponse' 28 | 29 | //get target TestCase 30 | def project = mockResponse.mockOperation.mockService.project 31 | def testCase = project.testSuites["TestSuite Name"].testCases["TestCase Name"] 32 | 33 | // Get target request 34 | def project = mockResponse.mockOperation.mockService.project 35 | def request = project.interfaces["NewWebServicePortBinding"].operations["sum"].getRequestByName("Request 2") 36 | 37 | //Using Files in Response 38 | def file = new File(path) 39 | def file = new File(mockRunner.mockService.docroot + \\foo.txt); 40 | 41 | mockRunner.returnFile(mockRequest.httpResponse, new File(responseFolder, "response_file.json") ) 42 | 43 | 44 | 45 | 46 | 47 | 48 | //References: 49 | https://www.soapui.org/rest-testing-mocking/rest-mock-service-creation/rest-mock-from-service.html 50 | https://www.soapui.org/rest-testing-mocking/rest-mock-service-creation/rest-mock-from-service.html 51 | https://www.soapui.org/soap-mocking/creating-dynamic-mockservices.html 52 | https://www.soapui.org/soap-mocking/deploying-mock-services-as-war-files.html 53 | https://www.soapui.org/soap-mocking/tips-and-tricks/securing-mockservices-with-ssl.html 54 | https://www.soapui.org/rest-testing-mocking/service-mocking-overview.html 55 | http://www.robert-nemet.com/ 56 | 57 | EADY API_SERVICE V Specific: 58 | https://www.soapui.org/rest-testing-mocking/rest-mock-service-creation/rest-mock-from-discovery.html 59 | 60 | -------------------------------------------------------------------------------- /My Swagger Hub Account: -------------------------------------------------------------------------------- 1 | My Swagger Hub Account 2 | 3 | Link to My Employee Web Service On 4 | https://app.swaggerhub.com/api/1101001000/Test/1.0.0 5 | -------------------------------------------------------------------------------- /Objects Available in Side a Groovy Step: -------------------------------------------------------------------------------- 1 | Objects Available in Side a Groovy Step 2 | 3 | Using log object inside the groovy Step 4 | Using testRunner inside the groovy Step 5 | -------------------------------------------------------------------------------- /Optimum Care While Creating Test Suite: -------------------------------------------------------------------------------- 1 | Optimum Care While Creating Test Suite 2 | 3 | 1. Use test Case level timeout feature 4 | 2. Use test case level maintain HTTP session feature 5 | 3. Allways implement Some time out mechanism : 6 | -Max Time out 7 | -Max Number of retried (With fixed retry duration or increasing or decreasing retry duration) 8 | 4. Do not repeat any HTTP step 9 | insted testRunner 10 | -------------------------------------------------------------------------------- /Parsing_JSON_Using_JSONSlurper: -------------------------------------------------------------------------------- 1 | import groovy.json.* 2 | def filePath = "/tmp/file.json" 3 | def file = new File(filePath) 4 | assert file.exists() : "file not found" 5 | assert file.canRead() : "file cannot be read" 6 | def jsonSlurper = new JsonSlurper() 7 | def object 8 | try { 9 | object = jsonSlurper.parse(file) 10 | } catch (JsonException e) { 11 | println "File is not valid" 12 | throw e 13 | } 14 | println object 15 | -------------------------------------------------------------------------------- /Play With Collections: -------------------------------------------------------------------------------- 1 | We commonly Use Following collections in Scripting: 2 | 3 | ArrayList : Maintains insertion order 4 | 5 | HashMap : class offers constant time performance for the basic operations (add, remove, contains and size) 6 | 7 | Treemap : Keys will be sorted 8 | 9 | Hashset : No Duplicates 10 | Does not guarantee that the order of elements will remain constant over time 11 | 12 | TreeSet : No Duplicates, Tree Set elements are sorted in ascending order by default 13 | 14 | 15 | 16 | Good references: 17 | https://stackoverflow.com/questions/1463284/hashset-vs-treeset 18 | -------------------------------------------------------------------------------- /Print Step Name and Step Request and Step Response: -------------------------------------------------------------------------------- 1 | Print Step Name and Step Request and Step Response 2 | 3 | def testStepName = context.currentStep.label 4 | log.info testStepName + " REQUEST " + context.currentStep.getPropertyValue("RawRequest") 5 | log.info testStepName + " RESPONSE " + context.currentStep.getPropertyValue("RawResponse") 6 | log.info testStepName + " TestStep has status " + "[" + testStepResult.status + "]" 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SOAPUI Groovy Scripts 2 | =================== 3 | 1.Sample Groovy scripts that helps to do some tasks in SoapUI Tool in SOAPUI Free/Pro
4 | 2.Adding HTTP Delete Request using Groovy In SOAPUI
5 | 3.Adding HTTP Get Request Via Groovy in SOAPUI
6 | 4.Adding HTTP POST Request Via Groovy in SOAPUI
7 | 5.Adding HTTP PUT Request Via Groovy in SOAPUI
8 | 6.Getting Http Status Code from Response
9 | 7.Groovy script can run the soapui project and generate junit result
10 | 8.Mocking Servics
11 | 9.My Swagger Hub Account
12 | 10.Parsing_JSON_Using_JSONSlurper
13 | 11.Print Step Name and Step Request and Step Response
14 | 12.Running Multiple Test Projects via Batch file from Command Line Using testRunner
15 | 13.SOAPUI -Running Specific Step in another Test Suite
16 | 14.SOAPUI_Tips_and_Tricks
17 | 15.Setting parameters in SOAPUI request using a groovy script
18 | 16.Syntax Problems between SOAPUI Versions
19 | 17.Ways to Collect Web Services information
20 | 18.Working with XAPATH in SOAPUI
21 | 22 | SOAPUI -Best Practices 23 | ====================== 24 | 1.Coding Conventions for SOAPUI/READY API Projects
25 | 2.Optimum Care While Creating Test Suite
26 | 3.Creating Test Suite to work on both Open Source and Commercial Versions Of SOAPUI
27 | 28 | 29 | SOAPUI -Controlling Test Execution Flow 30 | ======================================= 31 | 1.Implementing a way to exit from test execution loop
32 | 2.Retrying Whole Test Case If any Test Step Fails
33 | 3.Controlling Test Execution and Reading Status-Property Via Groovy
34 | 4.Creating Reusable Script library 35 | 36 | 37 | SOAPUI -Tweaking Settings 38 | ======================== 39 | 1.Enabling TLS 1.2 in SoapUI
40 | 2.SOAPUI VM Options File
41 | 3.SOAP UI OS: Steps to Make Scripts Open Source Version Compatible
42 | 4.SOAP UI OS: Free Version Sending Email Test Report
43 | 5.Command Templates to run on Remote server via JSCH Channel
44 | 6.SOAP UI OS: Maintaining Properties For Different Environemnts
45 | 7.Increasing Socket Time Out to 5 mins
46 | 8.SOAP UI OS: Managing Session Across the Test Suites
47 | 9.SOAP UI OS:-Managing Multiple Environment Properties
48 | 49 | 50 | SOAPUI -Header Management 51 | =========================== 52 | 1.Groovy for to Extract Cookie From Login Response
53 | 2.Header Manipulation Via Groovy in SOAPUI
54 | 55 | 56 | SOAPUI -Property Management In SOAPUI 57 | =================== 58 | 1.CreatePropertyViaGroovy
59 | 2.ReadPropertyViaGroovy
60 | 3.Groovy -Cleaning SOAPUI Properties Values
61 | 4.SOAP UI OS: Reading Properties from Properties Step
62 | 63 | 64 | Pure-Groovy Stuff: 65 | =================== 66 | 1.Installing Groovy On Windows Machine
67 | 2.Create Unique Random String
68 | 3.Creating Folder to Save Logs Via Groovy
69 | 4.Creating Time Stamp in Different Time Zone
70 | 5.Date and Time Stamp String Generation In Groovy
71 | 6.Detecting OS and User Via Groovy
72 | 7.Groovy -Reading Data from CSV
73 | 8.Groovy File IO Samples
74 | 9.Groovy Regex Pattern to Extract a String from a given line of text
75 | 10.Groovy Snippet To Compare Two Time Stamp
76 | 11.Reading Performance logging Times
77 | 12.Play With Collections 78 | 79 | 80 | Jenkins -SOAPUI _Running Test On Remote Node 81 | ========================== 82 | 1. Running-ReadyAPI-tests-from-Jenkins-on-Windows-Nodes 83 | 84 | 85 | SOAPUI Open Source API DOC: 86 | ========================== 87 | http://www.soapui.org/apidocs/overview-summary.html 88 | 89 | 90 | SOAPUI Pro API DOC: 91 | ========================== 92 | http://www.soapui.org/apidocs/pro/ 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /ReadPropertyViaGroovy: -------------------------------------------------------------------------------- 1 | Read Property Via Groovy: 2 | We can use set to read existing property: 3 | def testCaseProperty = testRunner.testCase.getPropertyValue("myTest"); 4 | -------------------------------------------------------------------------------- /Reading Performance logging Times: -------------------------------------------------------------------------------- 1 | Reading Performance logging Times 2 | 3 | log.info("Response Time :" + messageExchange.getTimeTaken()) 4 | 5 | # Following Can be altered to 6 | 'soapUI log', 7 | 'http log', 8 | 'jetty log', 9 | 'error log' etc. 10 | 11 | def logArea = com.eviware.soapui.SoapUI.logMonitor.getLogArea( "http log" ); 12 | def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context) 13 | if( logArea !=null ) 14 | { 15 | def model = logArea.model 16 | // only continue of logArea not empty 17 | if( model.size > 0 ) 18 | for( c in 0..(model.size-1) ) 19 | 20 | // DO SOMETHING HERE... could write to file, could run assertions, etc. 21 | log.info(model.getElementAt(c)) 22 | } 23 | 24 | http://webservice-testing.blogspot.in/2012/04/capture-soapui-logs-to-file.html 25 | -------------------------------------------------------------------------------- /ReadyAPI_Linux Specific Issues: -------------------------------------------------------------------------------- 1 | When we run Test Suite from Command line using testRunner.sh 2 | some times JVM may complain some font type not available 3 | 4 | Sample: 5 | net.sf.jasperreports.engine.util.JRFontNotFoundException: Font 'Arial' is not available to the JVM. See the Javadoc for more details. 6 | 7 | To solve this issue: 8 | we need to copy the linux equivalent font to : JDK_HOME\\jre\\lib\\fonts 9 | -------------------------------------------------------------------------------- /References: -------------------------------------------------------------------------------- 1 | 2 | http://www.doan.me/Blog/ViewCategory.aspx?cat=5&mid=2&pageid=1 3 | -------------------------------------------------------------------------------- /Research_Item:Generate PDF Report: -------------------------------------------------------------------------------- 1 | http://dynamicreports.org/examples/collectiondatasourcereport 2 | http://dynamicreports.org/examples/conditionalstylereport 3 | http://www.doan.me/reporting-in-soapui-free-edition.aspx 4 | 5 | def currentDate = new Date().format("yyyy-MM-dd hh:mm"); 6 | resultsFile.append('"' + currentDate + '"'); 7 | 8 | 9 | if(context.expand('${#Project#ProduceReports}') == 'true') { 10 | //The path and file to persist results 11 | def resultDir = new File("C:\\SoapUIResults"); 12 | if(!resultDir.exists()) { 13 | resultDir.mkdirs(); 14 | } 15 | def resultsFile = new File(resultDir, "CSVReport.csv"); 16 | -------------------------------------------------------------------------------- /Retrying Whole Test Case If any Test Step Fails: -------------------------------------------------------------------------------- 1 | Retrying Whole Test Case If any Test Step Fails 2 | 3 | import com.eviware.soapui.model.testsuite.Assertable; 4 | int maxRetryThresholdCount = context.expand( '${#Project#maxRetryThresholdCount}' ).toInteger(); 5 | int retryCount = context.expand( '${#TestCase#retryCount}' ).toInteger(); //retryCount=3 ; 6 | 7 | def testCase=testRunner.testCase; 8 | testCase.testStepList 9 | //int retryCount=0 10 | def failed = false 11 | for(testStep in testCase.testStepList) { 12 | if(testStep.name.equals("GetMOLogsAndAssert")){ 13 | log.info testStep.name 14 | retryCount=retryCount+1; 15 | testRunner.testCase.setPropertyValue("retryCount", retryCount.toString()); 16 | if( testStep instanceof Assertable && testStep.assertionStatus.toString() != "VALID" ) { 17 | failed = true 18 | if(retryCount<=maxRetryThresholdCount){ 19 | testRunner.gotoStepByName("PrintLogAboutCurrentCarrier");// Looping back to First Step the the Test CaSE 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Running Multiple Test Projects via Batch file from Command Line Using testRunner: -------------------------------------------------------------------------------- 1 | Running Multiple Test Projects via Batch file from Command Line Using testRunner 2 | 3 | @echo off 4 | set SOAPUI_HOME=C:\DevTools\soapui\SoapUI-Pro-5.0.0 5 | call %SOAPUI_HOME%\bin\testrunner.bat -sUnitTesting -f Project1-soapui-project.xml 6 | call %SOAPUI_HOME%\bin\testrunner.bat -sUnitTesting2 -f Project1-soapui-project.xml 7 | call %SOAPUI_HOME%\bin\testrunner.bat -sotherTests -f Project2-soapui-project.xml 8 | call %SOAPUI_HOME%\bin\testrunner.bat -sotherTests2 -f Project2-soapui-project.xml 9 | 10 | @echo off 11 | set SOAPUI_HOME=C:\Program Files\SmartBear\ReadyAPI-1.3.1 12 | call %SOAPUI_HOME%\bin\testrunner.bat -a -FPDF -f Project1-soapui-project.xml -e 13 | call %SOAPUI_HOME%\bin\testrunner.bat -a -FPDF -f Project1-soapui-project.xml -e 14 | call %SOAPUI_HOME%\bin\testrunner.bat -a -FPDF -f Project2-soapui-project.xml -e 15 | -------------------------------------------------------------------------------- /Running SOAPUI Project From ANT and Generating Junit HTML Report: -------------------------------------------------------------------------------- 1 | Running SOAPUI Project From ANT and Generating Junit HTML Report: 2 | 3 | Tools required to Setup: 4 | 1. SOAPUI Open Source Software 5 | 2. Downdload Ant and Set Class Path 6 | 1. Set ANT_HOME 7 | 2. Ant and Set Class path 8 | 3.Create a Sample SOAPUI Project or Use Any Existing working SOAPUI Project. 9 | 10 | Create build.xml file with Following Content: 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | run ant command 30 | thats it. 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Running-ReadyAPI-tests-from-Jenkins-on-Windows-Nodes: -------------------------------------------------------------------------------- 1 | https://smartbear-cc.force.com/portal/KbArticleViewer?name=Running-ReadyAPI-tests-from-Jenkins-on-Windows-Nodes&sp=all 2 | -------------------------------------------------------------------------------- /SOAP UI Step Execution Basics: -------------------------------------------------------------------------------- 1 | SOAP UI by default each request is waiting for response and then it is executing the other. 2 | SOAP UI by default execution flows down top to bottom( using groovy we can create any order) 3 | 4 | testRunner Object helps to: 5 | jump forward or 6 | back or 7 | Run specific step of choice in the middle of test execution 8 | 9 | 10 | to Jump nth step 11 | testRunner.gotoStepByName( "nameofteststep") 12 | 13 | 14 | to Execute specific step and continue normal top down flow: 15 | testRunner.runTestStepByName( "nameofteststep" ). 16 | 17 | 18 | ### Following snippet will run a particular step and checks the status of the step: 19 | 20 | import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus 21 | myTestStepResult = testRunner.runTestStepByName("RequestName") 22 | myStatus = myTestStepResult.getStatus() 23 | if (myStatus == TestStepStatus.OK) 24 | log.info "The step status is: " + myStatus.toString() 25 | else 26 | log.error "The step status is: " + myStatus.toString() 27 | -------------------------------------------------------------------------------- /SOAPUI -Running Specific Step in another Test Suite: -------------------------------------------------------------------------------- 1 | SOAPUI -Running Specific Step in another Test Suite 2 | 3 | import com.eviware.soapui.model.testsuite.TestRunner.Status 4 | 5 | Running Specific Step in another Test Suite 6 | def project = testRunner.testCase.testSuite.project 7 | testRunner.runTestStep( project.testSuites['TESTSUITE1'].testCases['TESTCASE1'].testSteps['TESTSTEP6'] ) 8 | testRunner.runTestStep( project.testSuites['TESTSUITE1'].testCases['TESTCASE2'].testSteps['TESTSTEP8'] ) 9 | 10 | // get TestCase 11 | def tc = testRunner.testCase.testSuite.project.testSuites["Sample Simple TestSuite"].testCases["TestCase Name"] 12 | 13 | // set login properties 14 | tc.setPropertyValue("Username", "ole" ) 15 | tc.setPropertyValue("Password", "nomoresecrets" ) 16 | 17 | // run test synchrouously 18 | // show that it worked out ok 19 | log.info "Status: $runner.status, time taken for TestCase was: $runner.timeTaken ms" 20 | def runner = tc.run( null, false ) 21 | // assert that it didn't fail 22 | assert runner.status != Status.FAILED : runner.reason 23 | 24 | https://www.soapui.org/functional-testing/modularizing-your-tests.html 25 | -------------------------------------------------------------------------------- /SOAPUI Free Reading Properties from Properties Step: -------------------------------------------------------------------------------- 1 | Reading Properties from Properties Step 2 | 3 | 1.Create: Project>> Test Property Test Step 4 | 2.Create: Test Suite>> Test Suite 5 | 3.Create: Test TestCase>> Test Case 6 | 4.Create: Test Step>> Property Test StepTest Case 7 | Create Thee properties 8 | prop1: 9 | prop2: 10 | prop3: 11 | 5.Create a groovy step and access the properties using following code: 12 | 13 | String prop1=context.expand( '${PropertyStepName#prop1}' ).toString(); 14 | String prop2=context.expand( '${PropertyStepName#prop2}' ).toString(); 15 | String prop3=context.expand( '${PropertyStepName#prop3}' ).toString(); 16 | 17 | Do whatever logic you need based on above config properties. 18 | 19 | 20 | -------------------------------------------------------------------------------- /SOAPUI OS Free Version Sending Email Test Report: -------------------------------------------------------------------------------- 1 | This Section Will describe provedure to implement Email Report(to Send Automatically When Failure/Success Happend). 2 | 3 | Procedure: 4 | Required Jars: 5 | 1. Copy Following jars under path: C:\Program Files (x86)\SmartBear\SoapUI-5.3.0\bin\ext 6 | • activation-1.1.1.jar 7 | • java-mail-1.4.4.jar 8 | 9 | 2. Restart SOAPUI to Pick The jars 10 | 11 | 3. Create SOAPUI Project :Email Test 12 | Create SOAPUI TestSuite:Email Test Suite 13 | Create SOAPUI TestTestCase:Email Test Case 14 | Create a Properties Step: MailHostProperties 15 | Create Following Properties in that: 16 | mailHost= 17 | userName= 18 | password=KY6aYWMHTd%25sSC 19 | fromEmail= 20 | toEmailList= 21 | isTestStatusEmailReportEnabled=true 22 | 23 | Create a Groovy Step: SendTestReportEmail: 24 | 25 | import javax.activation.DataHandler; 26 | import javax.activation.DataSource; 27 | import javax.activation.FileDataSource; 28 | import javax.mail.BodyPart; 29 | import javax.mail.Message; 30 | import javax.mail.MessagingException; 31 | import javax.mail.Multipart; 32 | import javax.mail.PasswordAuthentication; 33 | import javax.mail.Session; 34 | import javax.mail.Transport; 35 | import javax.mail.internet.InternetAddress; 36 | import javax.mail.internet.MimeBodyPart; 37 | import javax.mail.internet.MimeMessage; 38 | import javax.mail.internet.MimeMultipart; 39 | 40 | MAILHOST=context.expand( '${MailHostProperties#mailHost}' ).toString();//Global Variable 41 | USERNAME=context.expand( '${MailHostProperties#userName}' ).toString();//Global Variable 42 | PASSWORD=context.expand( '${MailHostProperties#password}' ).toString(); //Global Variable 43 | FROMEMAIL=context.expand( '${MailHostProperties#fromEmail}' ).toString();//Global Variable 44 | TOEMAIL=context.expand( '${MailHostProperties#toEmailList}' ).toString();//Global Variable 45 | 46 | boolean isTestStatusEmailReportEnabled=context.expand( '${MailHostProperties#isTestStatusEmailReportEnabled}' ).toBoolean(); 47 | String testResult=testRunner.testCase.getPropertyValue("testResult").toString(); //Get Pass/Fail Status from Properties 48 | String emailSubject; 49 | String emailBody; 50 | String emailAttachmentPath; 51 | String emailAttachmentFileName; 52 | 53 | if(isTestStatusEmailReportEnabled){ 54 | testResultsFile="testResults.log"; 55 | testResultsFilePath= testResultsgFolderPath+"//"+tmoLevelLogResultsFile; 56 | 57 | emailSubject="Test Report: TEST STATUS: $carrierTestResult"; //Construct Accordingly Whatever you need 58 | emailBody=""" //Construct Accordingly Whatever you need 59 | Test Item -1: $ 60 | Test Item-2 : $ 61 | Detailed Log Report[Attached]:\t\t$testResultsFile 62 | """; 63 | emailAttachmentPath=tmoLevelLogResultsFilePath; 64 | emailAttachmentFileName=testResultsFile; 65 | sendEmailReport(emailSubject,emailBody,emailAttachmentPath,emailAttachmentFileName); 66 | } 67 | 68 | //Reusable Groovy Function to Send Mails 69 | def sendEmailReport(def emailSubject,def emailBody,def emailAttachmentPath,def emailAttachmentFileName){ 70 | this.emailSubject=emailSubject; 71 | this.emailBody=emailBody; 72 | this.emailAttachmentPath=emailAttachmentPath; 73 | this.emailAttachmentFileName=emailAttachmentFileName; 74 | 75 | boolean isEmailSentOperationSuccessful=false; 76 | Properties props = new Properties(); 77 | props.put("mail.smtp.auth", "true"); 78 | props.put("mail.smtp.starttls.enable", "true"); 79 | props.put("mail.smtp.host", MAILHOST); 80 | props.put("mail.smtp.port", "587"); 81 | 82 | def emailUserName=USERNAME; 83 | def emailPassword=PASSWORD; 84 | Session session = Session.getInstance(props,new javax.mail.Authenticator() { // Get the Session object. 85 | protected PasswordAuthentication getPasswordAuthentication() { 86 | return new PasswordAuthentication(emailUserName, emailPassword); 87 | } 88 | }); 89 | 90 | try { 91 | Message message = new MimeMessage(session); 92 | message.setFrom(new InternetAddress(FROMEMAIL)); 93 | message.setRecipients(Message.RecipientType.TO,InternetAddress.parse(TOEMAIL)); 94 | message.setSubject(emailSubject); 95 | BodyPart messageBodyPart = new MimeBodyPart(); 96 | messageBodyPart.setText(emailBody); 97 | Multipart multipart = new MimeMultipart(); 98 | multipart.addBodyPart(messageBodyPart); 99 | messageBodyPart = new MimeBodyPart(); 100 | DataSource source = new FileDataSource(emailAttachmentPath); 101 | messageBodyPart.setDataHandler(new DataHandler(source)); 102 | messageBodyPart.setFileName(emailAttachmentFileName); 103 | multipart.addBodyPart(messageBodyPart); 104 | message.setContent(multipart); 105 | Transport.send(message); 106 | log.info ("Sent message successfully...."); 107 | isEmailSentOperationSuccessful=true; 108 | } catch (MessagingException e) { 109 | throw new RuntimeException(e); 110 | isEmailSentOperationSuccessful=false; 111 | } 112 | return isEmailSentOperationSuccessful; 113 | } 114 | 115 | 116 | -------------------------------------------------------------------------------- /SOAPUI OS Managing Session Across the Test Suites: -------------------------------------------------------------------------------- 1 | SOAPUIPro/Ready API allow to write events. 2 | Using events we can perform some special and general purpose actions on each request(). 3 | Like, Pass session id generated by Login Step to each subsequent HTTP request (All Test Steps in any testsuite or test case )so that SOAPUI can 4 | add automatically session id/cookie as a header. 5 | 6 | But this feature is lacking in SOAPUI free version. 7 | 8 | But SOAPUI(both free/Commercial Pro) allows to pass session ID/cookie to all subsequent requests with in test case by Just checking 'Maintain HTTP Session' 9 | option at test case level properties. 10 | 11 | But the same cannot be done accross the testcases and accross the test suites. 12 | 13 | So how to solve this problem in Open Source SOAPUI Open source. 14 | 15 | Procedure: 16 | 1. Extract session ID/Cookie from Login Response. 17 | 2. Set that to a project level property 18 | 3. Then add a header for each request with name sessionId/Cookie and refer the property defined @ Project level, mentioned in step 2 19 | 20 | Some people may feel it is very difficult to do this,but if you are going for free version it is ok,also in each test suite , the unique requests are less 21 | 22 | 23 | -------------------------------------------------------------------------------- /SOAPUI Open Source Script Library: -------------------------------------------------------------------------------- 1 | 2 | Hint: 3 | Builtin SoapUI Structure : Use Test Suite to organize scripts/classes into logical space, 4 | much like namespaces or different libraries of classes(This can be located easily from other scripts) 5 | 6 | Procedure: 7 | 1. Creating a Test Suite with a name of "Script Library" 8 | 2. Disabled this Test Suite "Script Library" 9 | 3. Add a Test Case 'Demo' 10 | 4. Added a Groovy Script test step to the 'Demo' Test Case with a name of "HelloWorld" 11 | 5. Add following simple code for groovy Script: 12 | //Following script both defines the class and adds an instance of class to the context object 13 | 14 | context.setProperty("helloWorld", new helloWorld()); 15 | class helloWorld{ 16 | def sayHello(name) 17 | { 18 | return "Hello " + name + "!"; 19 | } 20 | } 21 | 22 | 6. Create Different Test Suite(To Call Methos in Demo Test Case in Test Suite "Script Library") 23 | 24 | scripts = testRunner.testCase.testSuite.project.testSuites["Script Library"]; //1 25 | scripts.testCases["Demo"].testSteps["HelloWorld"].run(testRunner, context); //2 26 | log.info(context.helloWorld.sayHello("Kerry")); //3 27 | 28 | 29 | Explanation: 30 | 1. First line just gets the instance of the "Script Library" Test Suite 31 | 2. Second line runs the "HelloWorld" Groovy Script test step that resides in the "Demo" Test Case 32 | 33 | 34 | -------------------------------------------------------------------------------- /SOAPUI VM Options File: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SOAPUI With Ant: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /SOAPUIWithANT/Procedure: -------------------------------------------------------------------------------- 1 | 2 | A SOAP/Rest Project must be is Available locallty. 3 | 4 | Running from ANT 5 | 6 | Procedure: 7 | 1.Install ANT 8 | 2.Generate Build.xml 9 | 3.Trigger from Command Lin 10 | -------------------------------------------------------------------------------- /SOAPUIWithANT/References:: -------------------------------------------------------------------------------- 1 | ###References: 2 | 3 | http://code-dojo.blogspot.in/2015/02/run-soapui-project-using-ant-script.html 4 | https://paste.plurk.com/show/848526/ 5 | http://sys2sys.blogspot.in/2013/05/running-soapui-tests-from.html 6 | https://smudali.wordpress.com/2012/06/28/automated-web-services-testing-using-soapui/ 7 | http://roadtoautomation.blogspot.in/2013/08/road-to-command-line-execution-of.html 8 | -------------------------------------------------------------------------------- /SOAPUIWithANT/build.propertiesfile: -------------------------------------------------------------------------------- 1 | soapui.project=sample-soapui-project.xml 2 | soapui.testsuite=xxxx 3 | wsdl.url= 4 | user.name= 5 | user.password= 6 | -------------------------------------------------------------------------------- /SOAPUIWithANT/build.xml File: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /SOAPUI_Tips_and_Tricks: -------------------------------------------------------------------------------- 1 | 2 | Use log.info to get the class of a variable, such as the testRunner. 3 | 4 | Then you can refer to this class in the SoapUI API documentation. 5 | 6 | Use the Groovy shortcut notation for getters and setters. 7 | 8 | For example, use 9 | testRunner.testCase 10 | instead of testRunner.getTestCase() 11 | and 12 | project.abortOnError = true 13 | instead of project.setAbortOnError(true) 14 | 15 | 16 | https://www.soapui.org/scripting-properties/tips-tricks.html 17 | 18 | http://www.soapui.org/apidocs/overview-summary.html 19 | -------------------------------------------------------------------------------- /SOPUIOS-Managing Multiple Environment Properties: -------------------------------------------------------------------------------- 1 | SOAPUI Pro allows to Manage Test Data for Multiple Enviornments 2 | 3 | For eaxmple ,it is very common that same API (application) might deployed on multiple environments like: 4 | 1. Dev Server 5 | 2. QA Server 6 | 3. Staging Server 7 | 4. Production -1 Server 8 | 5. Production -2 Server 9 | 10 | By default SOAPUI OS will not help us to Manage Test Data for Multiple Enviornments. 11 | 12 | But it is possible to implement Similar to that for SOAPUI Opensource Version. 13 | 14 | All you need to know little groovy scripting 15 | 16 | Since it is same application API calls will be same but the data will be different. 17 | 18 | Hint: 19 | 1. Define a 'env' Property @ Project elevel 20 | by just changing this property test suite can be switched to eny environment. 21 | 2. Create a Test Case exclusively to hold propertys of each enviornment 22 | 3. Create a property step for each environemnt 23 | Like: 24 | Project 25 | TestSuite 26 | TestCase 27 | Property Step-DevServer 28 | Property Step-QAServer 29 | Property Step-StgServer 30 | Now create property Names Like(In all above properties): 31 | endPoint/Host //Remember this will be different for each Environemnt 32 | UserName 33 | Password 34 | Groovy Step to Load Specific Properties to Project Level Properties: 35 | 4. Make sure resmaining Test Cases are refferrning the Project level properties 36 | 5. Refer example Test Suite @ 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Sample WSDL Files For Practice: -------------------------------------------------------------------------------- 1 | Sample WSDL Files For Practice: 2 | 3 | 1. Currency Converter Service: http://www.webservicex.net/CurrencyConvertor.asmx?WSDL 4 | 2. Geocoder Service: http://geocoder.us/dist/eg/clients/GeoCoderPHP.wsdl 5 | 3. Temperature Converter Service: http://webservices.daehosting.com/services/TemperatureConversions.wso?WSDL 6 | 4. Global Weather: http://www.webservicex.com/globalweather.asmx?WSDL 7 | 5. Bank BLZ Service (Bank Sort Codes) http://www.thomas-bayer.com/axis2/services/BLZService?wsdl 8 | 6. Graphical Weather: https://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php?wsdl 9 | 10 | 11 | 12 | 13 | 14 | 15 | References: 16 | https://smudali.wordpress.com/2012/06/28/automated-web-services-testing-using-soapui/ 17 | -------------------------------------------------------------------------------- /Setting End Point Via Groovy Script: -------------------------------------------------------------------------------- 1 | 2 | 3 | testRunner.testCase.properties['endpoint'].setValue('new endpoint') 4 | or 5 | testRunner.testCase.getTestStepByName(requestName).getHttpRequest().setEndpoint(ENDPOINT) 6 | 7 | 8 | -------------------------------------------------------------------------------- /Setting parameters in SOAPUI request using a groovy script: -------------------------------------------------------------------------------- 1 | Setting parameters in SOAPUI request using a groovy script 2 | 3 | ${#TestCase#ResquestID} 4 | ${#TestSuite#ResquestID} 5 | ${#Project#ResquestID} 6 | ${#EnV#ResquestID} 7 | -------------------------------------------------------------------------------- /Solution for Null Pointer Exception-While Constructing Project Object from Groovy-While Running Project from testRunner: -------------------------------------------------------------------------------- 1 | 2 | ##Solution for Null Pointer Exception-While Constructing Project Object from Groovy-While Running Project from testRunner 3 | # Project object can be constructed and used "testRunner.testCase.testSuite.project" while running project from Ready API GUI 4 | # if Project object is constructed using "testRunner.testCase.testSuite.project" 5 | then testRunner will throw null Pointer Exception- if Running Project from testRunner 6 | # Reason : testRunner cannot be acces project object directly if test triggered from commend line. 7 | 8 | ##Solution snippet 9 | 10 | import com.eviware.soapui.model.project.ProjectFactoryRegistry 11 | import com.eviware.soapui.impl.wsdl.WsdlProjectFactory 12 | 13 | def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context) 14 | def projectDir = groovyUtils.projectPath 15 | log.info(projectDir) 16 | 17 | def projectName = testRunner.testCase.testSuite.project.name 18 | log.info "projectName: "+projectName 19 | def workspace = testRunner.testCase.testSuite.project.workspace 20 | def testProject = (workspace==null) ? 21 | ProjectFactoryRegistry.getProjectFactory(WsdlProjectFactory.WSDL_TYPE).createNew(projectDir+".xml") : 22 | workspace.getProjectByName(projectName) 23 | log.info testProject 24 | 25 | 26 | Refernce; https://community.smartbear.com/t5/SoapUI-Open-Source/java-error-when-running-from-command-line/td-p/5677 27 | 28 | -------------------------------------------------------------------------------- /Steps to Make Scripts Open Source Version Compatible: -------------------------------------------------------------------------------- 1 | Steps to Make Scripts Open Source Version Compatible 2 | 3 | 1.Avoid using events for cookie sharing: 4 | instead create Property @ project level and use that prioperty as header for each step to share the cookie 5 | 2.Avaoid using Data Sources : 6 | instead use jsonslurper and get array of values and loop the steps 7 | 3.Avoid Multiple Environments instead load data freom csv conditionally 8 | Create a variable to specify environemnt @project level 9 | conditionally load the data from properties file 10 | 4.Avoid External Libraries 11 | 12 | Open Source Limitations 13 | 1.No Data Sources 14 | 2.No Environent specific End Point and Project Level Propeties 15 | 3.No Events to share cookies 16 | 4.No Context Menu Suggestions 17 | 5.No Test Execution Summary 18 | 6.In All groovy script editors there is no content assist/auto-completion *******biggest drawback 19 | -------------------------------------------------------------------------------- /String Tokeniser: -------------------------------------------------------------------------------- 1 | 2 | import java.util.StringTokenizer; 3 | 4 | def str = "This is String , split by StringTokenizer, created by Rajendra"; 5 | def st = new StringTokenizer(str); 6 | 7 | log.info("---- Split by space ------"); 8 | while (st.hasMoreElements()) { 9 | log.info(st.nextElement()); 10 | } 11 | 12 | log.info("---- Split by comma ',' ------"); 13 | def st2 = new StringTokenizer(str, ","); 14 | 15 | while (st2.hasMoreElements()) { 16 | log.info(st2.nextElement()); 17 | } 18 | -------------------------------------------------------------------------------- /Swagger Definition File Import-Create Test Suite-Create Mock Services: -------------------------------------------------------------------------------- 1 | Tasks List: 2 | 1.Swagger Definition File Import 3 | 2.Create Test Suite 4 | 3.Create Mock Services 5 | 6 | Sample Swagger Definition File URL: http://petstore.swagger.io/#/pet/addPet 7 | Swagger URL(To Import): 8 | http://petstore.swagger.io/v2/swagger.json 9 | 10 | Steps to import Sawgger Definition File into SOAP UI: 11 | 1. Create Empty Project 12 | 2. Right Click on Project and Choose ''import Sawgger' option 13 | 3. Add Swagger Definition Dialog will open 14 | 4. Enter following URL in 'Swagger Definition Text Field and Choose Definition Type as:'Resource Listing' Click on OK button 15 | http://petstore.swagger.io/v2/swagger.json 16 | 5. API interface will be cerated 17 | 6. Right Click on Create REST Mock Service 18 | 7. Now Virtual Server will start and mocked version of API can be ac. cessed via browser and SOAPUI as well 19 | 8. Right Click on Create REST Test Suite for the same interface 20 | 21 | -------------------------------------------------------------------------------- /Syntax Problems between SOAPUI Versions: -------------------------------------------------------------------------------- 1 | Syntax Problems between SOAPUI Versions 2 | 3 | Apparently soapUI 5.x is a bit more strickt in its syntax checks than 4.x. Or it is a bug in 4.x. 4 | 5 | http://some_server/basemap/{param0}/{param1}/{param0}_{param1}_16.png worked in 4.x it did not in 5.x. 6 | 7 | However after changing this url into http://some_server/basemap/${param0}/${param1}/${param0}_${param1}_16.png everything worked again. 8 | 9 | -------------------------------------------------------------------------------- /Test Runner Object: -------------------------------------------------------------------------------- 1 | testRunner - a TestCaseRunner object, 2 | 3 | which is the entry-point to the soapUI API for accessing project items, results, etc. 4 | The testRunner is the object that is actually executing the TestCase by cycling through the 5 | TestSteps in the TestCase and executing them. It exposes methods related to test execution and 6 | the underlying object model (via the testCase property). Common usage scenarios are: 7 | 8 | using testRunner.testCase to get hold of the containing TestCase from which all other objects in the 9 | project can be accessed and manipulated using testRunner.fail(...) (or testRunner.cancel) to abort the 10 | ongoing TestCase when an error occurs using 11 | testRunner.gotoStepByName(...) 12 | or 13 | testRunning.runTestStepByName( ... ) 14 | to transfer execution to another step than the one after the Script TestStep in the TestCase (see ...) 15 | -------------------------------------------------------------------------------- /Test Suite Tear Down Script: -------------------------------------------------------------------------------- 1 | UseCase: Print Summary of execution for my testCases Test Suite 2 | Place to Keep Script: teardown script of 3 | 4 | def runner = context.testRunner; 5 | for (testRun in runner.getResults()) 6 | { 7 | testCase = testRun.getTestCase() 8 | log.info context.expand( '${#Project#testcase_flag}' ) + testCase.getName() 9 | for (testResult in testRun.getResults()) 10 | log.info testResult.getTestStep().getName() + " : " + testResult.getStatus() 11 | log.info context.expand( '${#Project#testcase_status_flag}' ) + " : " + runner.getStatus() 12 | } 13 | -------------------------------------------------------------------------------- /Useful SOAP UI API Methods: -------------------------------------------------------------------------------- 1 | 2 | 3 | Whithin Current TestSuite and Current TestCase Context 4 | def tCase=testRunner.testCase; 5 | def tSuite=testRunner.testCase.testSuite; 6 | def tProject=testRunner.testCase.testSuite.project; 7 | 8 | //Whithin diffrent TestSuite's TestCase Context 9 | def targetSuite=testRunner.testCase.testSuite.project.testSuite["TestSuiteName"] 10 | def targetTestCase=testRunner.testCase.testSuite.project.testSuite["TestSuiteName"].testCase["TestCase"] 11 | 12 | //Above line scan be minimised as 13 | def targetSuite=tProject.testSuite["TestSuiteName"] 14 | def targetTestCase=tProject.testSuite["TestSuiteName"].testCase["TestCase"] 15 | 16 | 17 | //Cookie 18 | def agentCookie = testRunner.testCase.getTestStepByName("PostAgentLogin").httpRequest.response.responseHeaders["Set-Cookie"][0] 19 | 20 | testRunner.gotoStepByName( "targetStepName") 21 | testRunner.runTestStepByName( "targetStepName") 22 | testRunner.cancel("Decribe Cancellation Reason") "Simplay Stops an ongoing test run with the specified reason". 23 | testRunner.fail("Decribe Failure Reason") "Fails an ongoing test run with the specified reason". 24 | testRunner.run() 25 | 26 | //Run a TestCase located in another project 27 | def prj = testRunner.testCase.testSuite.project.workspace.getProjectByName("ProjectName") 28 | tCase = prj.testSuites['TestSuiteName'].testCases['TestCaseName'] 29 | 30 | 31 | //Checking Whether the project Started from cmd line or GUI 32 | if( com.eviware.soapui.SoapUI.isCommandLine() ) 33 | { 34 | log.info "This code is executed by Command Line SoapUI" 35 | } 36 | if( context.LoadTestContext != null ) 37 | { 38 | log.info "This code is executed from a LoadTest" 39 | } 40 | -------------------------------------------------------------------------------- /Using Custom Templates to Generate Report Using Template Engine: -------------------------------------------------------------------------------- 1 | Sample to Use Custom Templates to Generate Report by using Groovy Template Engine: 2 | 3 | import groovy.text.* 4 | 5 | def simple = new SimpleTemplateEngine(); 6 | 7 | def source = '''Test Report $name, 8 | Please respond to this e-mail before ${(now + 7).format("dd-MM-yyyy")} 9 | Kind regards, mrhaki'''; 10 | 11 | def binding = [now: new Date(109, 11, 1), name: 'Hubert Klein Ikkink'] 12 | 13 | def output = simple.createTemplate(source).make(binding).toString() 14 | log.info output 15 | 16 | 17 | Using Groovy Template 18 | 19 | import groovy.text.* 20 | def gstring = new GStringTemplateEngine() 21 | def gsource = '''Dear <%= name %>, 22 | Text is created for 23 | <% if (gstring) 24 | out << 'GStringTemplateEngine' 25 | else 26 | out << 'other template engine'%>.''' 27 | def gbinding = [name: 'mrhaki', gstring: true] 28 | def goutput = gstring.createTemplate(gsource).make(gbinding).toString() 29 | goutput 30 | -------------------------------------------------------------------------------- /Validate JSON with JsonUtil Class: -------------------------------------------------------------------------------- 1 | JsonUtil Class is available in Open Source Edition 5.1.2 onwards 2 | Following script is used to validate JSON using JsonUtil class: 3 | 4 | import com.eviware.soapui.support.JsonUtil 5 | def json = """{ 6 | "parent":{ 7 | "child":"oldValue" 8 | } 9 | }""" 10 | 11 | log.info JsonUtil.isValidJson(json) 12 | -------------------------------------------------------------------------------- /Ways to Collect Web Services information: -------------------------------------------------------------------------------- 1 | Ways to Collect Web Services information 2 | 3 | Exploring capabilities of Service: 4 | 1. without access to source code, 5 | 2. By reading documentation API Spcification Documnets 6 | 3. through network traffic inspection Using Proxy ,Using Developper Tools 7 | -------------------------------------------------------------------------------- /Web Service Related KeyWords: -------------------------------------------------------------------------------- 1 | REST Service 2 | Resource: An object or an entity that has a URI where it can be manipulated through HTTP requests. 3 | Request 4 | Response 5 | 6 | SLA 7 | Data Formats :XML JSON 8 | End Point 9 | Request Headers 10 | Request Body 11 | Request Headers 12 | Response Headers 13 | Request Parameters 14 | API Key 15 | Rate-Limiting 16 | API Autentication 17 | Basic Auth 18 | Session 19 | Cookie 20 | Set-Cookie 21 | HATEOAS: Hypermedia as the Engine of Application State 22 | HTTP Protocol 23 | HTTP Methods 24 | Http Status Code 25 | Idempotent 26 | Mashup 27 | Parameter 28 | Property 29 | SOAP 30 | cURL 31 | CORS Cross Origin Requests allow javascript in websites to do AJAX requests to domains beyond the one initiating the request. 32 | API Version 33 | Web Service 34 | 35 | 36 | SOAP (Simple Object Access Protocol) 37 | UDDI (Universal Description, Discovery and Integration) 38 | WSDL (Web Services Description Language) 39 | 40 | Synchronous Service 41 | Asynchronous Service 42 | RPC Remote Procedure Calls 43 | SOAP 1.1 44 | SOAP 1.2 45 | Web Service Cline 46 | Web Service Input Validation 47 | 48 | 49 | Data In Plan Text Format 50 | ID:1 51 | Name:Rajendra Prasad 52 | Email:Rajendra.Prasad@gmail.com 53 | Country:India 54 | 55 | Json Message Format: 56 | { 57 | "ID": "1", 58 | "Name": "Rajendra Prasad", 59 | "Email": "Rajendra.Prasad@gmail.com", 60 | "Country": "India" 61 | } 62 | 63 | XML Message Format: 64 | 65 | 1 66 | Rajendra Prasad 67 | Rajendra.Prasad@gmail.com 68 | India 69 | 70 | 71 | Headers: 72 | Headers Mandatory for Every Request/response:No 73 | But if some Data is Exchanging the following headers are mandatory: 74 | Content-Length 75 | Transfer-Encoding 76 | 77 | Request Headers: 78 | Accept: 79 | If specified in request then those types will be accepted in the response to this request 80 | Accept: text/plain, text/ html 81 | Accept: text/x-dvi; q=.8; mxb=100000; mxt=5.0, text/x-c 82 | Accept: *.*, q=0.1 83 | Accept: audio/*, q=0.2 84 | Accept: audio/basic q=1 85 | 86 | 87 | Browser Sniffers: 88 | Chrome Plugin: 89 | 1.network Sniffer 90 | 91 | 92 | Request Format: 93 | https://www.yourmoodle.com/login/token.php?username=USERNAME&password=PASSWORD&service=SERVICESHORTNAME 94 | -------------------------------------------------------------------------------- /Working with Context Property Using Groovy: -------------------------------------------------------------------------------- 1 | context - a TestCaseRunContext object holding context-related properties. 2 | The main usage for this is to store values that can be used in subsequent TestSteps or related scripts. 3 | 4 | For example 5 | context.myProperty = "Hello" 6 | or 7 | context.setProperty("myProperty","Hello") 8 | 9 | will create a property named "myProperty" in the context and assign it the string value "Hello". 10 | In a subsequent script, you can access it with 11 | 12 | context.myProperty will give string "Hello" 13 | 14 | alternatively 15 | 16 | context.getProperty("myProperty") also give result as string "Hello" 17 | 18 | log.info( context.myProperty ) 19 | 20 | 21 | Context Object has following methods 22 | getModelItem, 23 | getProperties 24 | getProperty 25 | getPropertyNames 26 | hasProperty 27 | removeProperty 28 | setProperty 29 | 30 | -------------------------------------------------------------------------------- /Working with XAPATH in SOAPUI: -------------------------------------------------------------------------------- 1 | Working with XAPATH in SOAPUI 2 | 3 | Sample XML: 4 | 5 | 6 | 7 | 8 | 10873286937963711 9 | 10 | 11 | 12 | 13 | 1.To check Xpath: Matching Digits Pattren 14 | dedclare namsespace ns='http://www.example.org/sample/' 15 | matches(//ns:loginResponse[1]/sessionid[1]/text(),'.\d') 16 | 17 | 2.To Check Xpath: Exitence of Path: 18 | dedclare namsespace ns='http://www.example.org/sample/' 19 | exists(//ns:loginResponse/sessionid) 20 | 21 | 3. Xpath:Couting elements: 22 | dedclare namsespace ns='http://www.example.org/sample/' 23 | count(//ns:loginResponse/sessionid) 24 | 25 | 4.Xpath: Getting text of element 26 | dedclare namsespace ns='http://www.example.org/sample/' 27 | //ns:Response[1]/ns:status[1] 28 | //ns:Response[1]/*:status[1] 29 | //*:Response[1]/*:status[1] 30 | //*:Response[1]/*:status 31 | //*:Response/*:status[1] 32 | //*:Response/*:status 33 | All above combinations are correct 34 | 35 | 5. While Writing Property Expansion Using XPATH: 36 | def response = context.expand( '${Get_Campaigns#Response#$[\'dataObj\'][0][\'campaign_state\']}' ) 37 | $[\'dataObj\'][0][\'campaign_state\'] 38 | 39 | 6 While Writing JSON Path : 40 | $['dataObj'][0]['campaign_id'] 41 | -------------------------------------------------------------------------------- /Writing Assertion Results into File and Customized Test Resport: -------------------------------------------------------------------------------- 1 | Writing Assertion Results into File and Customized Test Resport 2 | 3 | 4 | def testStepStatus="passed"; 5 | String testStepName; 6 | def errorsList=[]; 7 | def suucessList=[]; 8 | def tHost = context.expand( '${#TestCase#tHost}' ) 9 | def numbertoDial = context.expand( '${#TestCase#numbertoDial}' ) 10 | 11 | def assertionsList = testRunner.testCase.getTestStepByName("GetTMOLogsAndAssert").getAssertionList(); 12 | int errIndex=0; 13 | int succIndex=0; 14 | for(def assertion:assertionsList){ 15 | String actStatus=assertion.status; 16 | log.info assertion.status; 17 | if(actStatus.equals("FAILED")){ 18 | testStepStatus="failed"; 19 | errIndex++; 20 | errorsList.add(assertion) 21 | //errorsList.add("Failed Asserion - "+errIndex+" "+assertion.getErrors()[0]) 22 | log.info assertion.getErrors()[0]; 23 | } 24 | else{succIndex++; 25 | suucessList.add(assertion); 26 | } 27 | } 28 | log.info "errorsList : $errorsList" 29 | log.info "suucessList : $suucessList" 30 | String isRequired2StoreLogs = context.expand( '${#Project#isRequired2StoreLogs}' ).toString(); 31 | isRequired2StoreLogs=isRequired2StoreLogs.toLowerCase(); 32 | 33 | if(isRequired2StoreLogs.equals("yes")||isRequired2StoreLogs.equals("true")){ 34 | def tLogResponse = context.expand( '${GetTMOLogsAndAssert#Response}' ) 35 | def currentCarName = context.expand( '${#TestCase#currentCarName}' ); 36 | def sessionID = context.expand( '${#TestCase#sessionID}' ) 37 | def currentDate = context.expand( '${#TestCase#currentDate}' ) 38 | def currentHours = context.expand( '${#TestCase#currentHours}' ) 39 | currentCarName=currentCarName.toLowerCase(); 40 | //def tHost = context.expand( '${#TestCase#tHost}' ) 41 | def retryCount = context.expand( '${#TestCase#retryCount}' ) 42 | def logFilePath=testRunner.testCase.getPropertyValue("logsFolderPath"); 43 | //context.getProperty("logsFolderPath"); 44 | def logFileName=tHost+"_"+currentCarName+"_log_"+testStepStatus+"_"+retryCount+".txt" 45 | def logFilePath2=logFilePath+"\\"+logFileName; 46 | def tLogFile = new File(logFilePath2) ; 47 | log.info "----->> tmologFilePath: "+tLogFile 48 | tLogFile<<"\n\n<<----------------------------------Test Result Summary------------------------------>>>>\n"; 49 | tLogFile<<"\nTMO Under Test: $tHost\n"; 50 | tLogFile<<"\nCarrier Under Test: $currentCarName\n"; 51 | tLogFile<<"\nFinal Test Result: $testStepStatus\n"; 52 | tLogFile<<"\nNumber Dialed: $numbertoDial\n"; 53 | tLogFile<<"\nCall Session ID: $sessionID\n"; 54 | tLogFile<<"\nCall Log Seach Date:$currentDate && Hours : $currentHours\n"; 55 | targetLogFile<<"\nTotal Assertions Count: "+assertionsList.size()+"\n"; 56 | targetLogFile<<"\nPASSED Assertions Count: "+suucessList.size()+" FAILED Assertions Count: "+errorsList.size()+"\n"; 57 | 58 | if(suucessList.size()>0){ 59 | tLogFile<<"\n*********Detailed PASSED Assertion Information*********\n"; 60 | index=0; 61 | suucessList.each{ 62 | index++; 63 | def passedAssertion=it; 64 | def passedAssertionLabel=passedAssertion.getLabel(); 65 | def assertionMsg=passedAssertion.getStatus(); 66 | targetLogFile<<" $index . $passedAssertionLabel $assertionMsg\n"; 67 | } 68 | } 69 | 70 | if(errorsList.size()>0){ 71 | tLogFile<<"\n*********Detailed FAILED Assertion Information*********\n"; 72 | index=0; 73 | errorsList.each{ 74 | index++; 75 | def failedAssertion=it; 76 | def faieldAssertionLabel=failedAssertion.getLabel(); 77 | def assertionErros=failedAssertion.getErrors()[0]; 78 | targetLogFile<<" $index . $faieldAssertionLabel: $assertionErros \n"; 79 | } 80 | } 81 | 82 | targetLogFile<<"<<----------------------------------Test Result Summary------------------------------>>>>\n\n\n"; 83 | targetLogFile<<"Detailed Log below for Review:\n\n"; 84 | targetLogFile< responseCodes 42 | 43 | static { 44 | responseCodes = new HashMap<>() 45 | responseCodes["0000"] = new ResponseCodes(code: "0000", description: "Success") 46 | responseCodes["0058"] = new ResponseCodes(code: "0058", description: "Profile Already Exist.", isNextStepToBeExecuted: false) 47 | responseCodes["5002"] = new ResponseCodes(code: "5002", description: "Invalid Request: [JSV0007] Invalid string: '' does not match pattern '^d{1,5}\\\$'.", isNextStepToBeExecuted: true) 48 | //add here if there are more response codes 49 | } 50 | 51 | TestCaseRunContext context 52 | Logger log 53 | 54 | def parseAndEvaluateResponse(String response, String propertyName) { 55 | def currentStatusCode 56 | def currentDescription 57 | def currentResponseCode 58 | def toBeFound = true 59 | def jsonResonponse = new JsonSlurper().parseText(response) 60 | if (jsonResonponse.createProfileAccountResponse) { 61 | log.info("Found createProfileAccountResponse key") 62 | currentStatusCode = jsonResonponse.createProfileAccountResponse.statusCode 63 | currentDescription = jsonResonponse.createProfileAccountResponse.statusDescription 64 | } else if (jsonResonponse.response) { 65 | log.info("Found response key") 66 | currentStatusCode = jsonResonponse.response.header.statusCode 67 | currentDescription = jsonResonponse.response.header.statusDesc 68 | toBeFound = false 69 | } 70 | log.info("Status Code :${currentStatusCode}") 71 | log.info("Status Description :${currentDescription}") 72 | if (responseCodes.containsKey(currentStatusCode)) { 73 | log.info("Found existing statusCode") 74 | currentResponseCode = responseCodes.get(currentStatusCode) 75 | if (currentResponseCode.description == currentDescription) { 76 | log.info("Matched the description") 77 | if (toBeFound) { 78 | if (jsonResonponse.createProfileAccountResponse.rxStatus.rxEncryptedToken) { 79 | log.info("Found rxEncryptedToken and setting true for the next step execution") 80 | currentResponseCode.isNextStepToBeExecuted = true 81 | assert null != jsonResonponse.createProfileAccountResponse.rxStatus.rxEncryptedToken.toString(), "Toke is either empty or null" 82 | context.testCase.setPropertyValue(propertyName, jsonResonponse.createProfileAccountResponse.rxStatus.rxEncryptedToken.toString()) 83 | log.info("Setting a test case level custom property ${propertyName}, this is going to contains token") 84 | } else { 85 | log.info("Could not found rxEncryptedToken and setting false for the next step execution") 86 | currentResponseCode.isNextStepToBeExecuted = false 87 | } 88 | } 89 | } else { 90 | log.error("Not matching description") 91 | } 92 | } else { 93 | log.error("Count not found the status code") 94 | } 95 | currentResponseCode.isNextStepToBeExecuted 96 | } 97 | } 98 | 99 | def setHttpHeaders(String nextStepName, def headers) { 100 | def nextRequest = context.testCase.testSteps[nextStepName].httpRequest 101 | def existingHeaders = nextRequest.requestHeaders 102 | headers.each { 103 | existingHeaders[it.key] = it.value 104 | } 105 | nextRequest.requestHeaders = existingHeaders 106 | } 107 | 108 | def previousStepName = context.testCase.getTestStepAt(context.currentStepIndex - 1).name 109 | def nextStepName = context.testCase.getTestStepAt(context.currentStepIndex + 1).name 110 | def exitStepName = context.testCase.getPropertyValue('EXIT_STEP_NAME') 111 | def conditionalEvaluation = new ConditionEvaluator(context: context, log:log) 112 | def isNextStepExecute = conditionalEvaluation.parseAndEvaluateResponse(context.expand('${'+previousStepName+'#Response}'), 'ACCESS_TOKEN') 113 | /** 114 | * Assuming you need to set the access token as http header for next request. 115 | * Then use below lines, comment otherwise. 116 | */ 117 | def headers = [(context.testCase.getPropertyValue('NEXT_STEP_HEADER_NAME_FOR_TOKEN')): [(context.testCase.getPropertyValue('ACCESS_TOKEN'))]] 118 | setHttpHeaders(nextStepName, headers) 119 | 120 | /** 121 | * Based on below condition it will run or skip execution of Request Step 2 122 | * if true control will go to Request Step2 123 | * otherwise, control will be transferred to EXIT step directly 124 | */ 125 | if (isNextStepExecute) { 126 | testRunner.gotoStepByName(nextStepName) 127 | } else { 128 | testRunner.gotoStepByName(exitStepName) 129 | } -------------------------------------------------------------------------------- /groovy/ContainsAssertion.groovy: -------------------------------------------------------------------------------- 1 | //gets the Script Language project property value from standard property 2 | def stdProjectPropValue = context.testCase.testSuite.project.defaultScriptLanguage 3 | //get the response as text 4 | def responseText = messageExchange.responseContent 5 | //do the contains assert, show error message otherwise. 6 | assert responseText.contains(stdProjectPropValue), "Response does not contain ${stdProjectPropValue}" 7 | -------------------------------------------------------------------------------- /groovy/CustomTestReport.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * This is Project level TearDown Script 3 | * which generates a test report in a file 4 | * Refer: http://stackoverflow.com/questions/41700437/creating-a-test-report-from-project-level-tear-down-script 5 | * Modify the variable "reportFileName" below 6 | **/ 7 | 8 | //Modify the file as needed for report file 9 | def reportFileName = '/tmp/abctestreport.txt' 10 | 11 | 12 | //NOTE: Not required to edit beyond this point 13 | 14 | /** 15 | * This class holds the test case details 16 | **/ 17 | class TestCaseResultHolder { 18 | def log 19 | Map properties = [:] 20 | boolean status 21 | 22 | def createProperties(testCase) { 23 | testCase.getPropertyNames().each { key -> 24 | properties[key] = testCase.getPropertyValue(key) 25 | } 26 | } 27 | 28 | def getCaseResult(caseRunner, caseName) { 29 | log.info "Checking test case status ${caseName}" 30 | if ( caseRunner.status.toString() == 'FAILED' ){ 31 | log.error "Test case $caseName has failed" 32 | for ( stepResult in caseRunner?.results ){ 33 | stepResult.messages.each() { msg -> log.info msg } 34 | } 35 | return false 36 | } else { 37 | log.info "${caseName} is passed" 38 | } 39 | true 40 | } 41 | 42 | def buildCaseResult(caseRunner, caseName) { 43 | status = getCaseResult(caseRunner, caseName) 44 | if (!status) { 45 | createProperties(caseRunner.testCase) 46 | } 47 | } 48 | 49 | } 50 | 51 | /** 52 | * This class holds the test suite details 53 | **/ 54 | class SuiteResultsHolder { 55 | 56 | def log 57 | Map casaeResults = [:] 58 | int testCaseCount = 0 59 | int passedCasesCount = 0 60 | int failedCasesCount = 0 61 | 62 | def buildSuiteResults(suiteRunner, suiteName){ 63 | log.info "Building results of test suite ${suiteName}" 64 | for ( caseRunner in suiteRunner?.results ) { 65 | def caseName = caseRunner.testCase.name 66 | testCaseCount++ 67 | def tcHolder = new TestCaseResultHolder(log: log) 68 | tcHolder.buildCaseResult(caseRunner, caseName) 69 | casaeResults[caseName] = tcHolder 70 | if (tcHolder.status) { 71 | passedCasesCount++ 72 | } else { 73 | failedCasesCount++ 74 | } 75 | } 76 | } 77 | 78 | def getStatus() { 79 | (0 < failedCasesCount) ? false : true 80 | } 81 | 82 | } 83 | 84 | /** 85 | * This class holds the project details 86 | **/ 87 | class ProjectResultsHolder { 88 | 89 | def log 90 | Map suiteResults = [:] 91 | int suiteCount = 0 92 | int passedSuitecount = 0 93 | int failedSuiteCount = 0 94 | 95 | def buildProjectResults(projectRunner, projectName) { 96 | log.info "Building results of test project ${projectName}" 97 | for(suiteRunner in projectRunner?.results) { 98 | def suiteName = suiteRunner.testSuite.name 99 | suiteCount++ 100 | def suiteResultsHolder = new SuiteResultsHolder(log: log) 101 | suiteResultsHolder.buildSuiteResults(suiteRunner, suiteName) 102 | suiteResults[suiteName] = suiteResultsHolder 103 | if (suiteResultsHolder.status) { 104 | passedSuitecount++ 105 | } else { 106 | failedSuiteCount++ 107 | } 108 | } 109 | } 110 | 111 | def getStatus() { 112 | (0 < failedSuiteCount) ? false : true 113 | } 114 | 115 | } 116 | 117 | //Get the status string based on boolean 118 | def getResult(status){ status == true ? 'SUCCEED' : 'FAILED'} 119 | 120 | //Draws a line 121 | def drawLine(def letter = '=', def count = 70) { letter.multiply(count)} 122 | 123 | //Gets the summary report 124 | def getSummaryReport(project, projectResultHolder) { 125 | def report = new StringBuffer() 126 | report.append(drawLine()).append('\n') 127 | report.append("\t\t\tTest Execution Summary\n") 128 | report.append(drawLine('-', 60)).append('\n') 129 | report.append("Project : ${project.name}\n") 130 | report.append("Result : ${getResult(projectResultHolder.status)}\n") 131 | report.append("Total test suites executed: ${projectResultHolder.suiteCount}\n") 132 | report.append("Test suites passed: ${projectResultHolder.passedSuitecount}\n") 133 | report.append("Test suites failed: ${projectResultHolder.failedSuiteCount}\n") 134 | report.append(drawLine()).append('\n') 135 | report 136 | } 137 | 138 | //Gets the test case report 139 | def getTestCaseReport(testCaseReport) { 140 | def report = new StringBuffer() 141 | report.append(drawLine('-', 60)).append('\n') 142 | report.append("\t\tTest Case Details:\n") 143 | report.append(drawLine('-', 60)).append('\n') 144 | testCaseReport.each { kase, tcReport -> 145 | report.append("Name : ${kase}\n") 146 | report.append("Status : ${getResult(tcReport.status)}\n") 147 | if (!tcReport.status) { 148 | report.append("Properties : ${tcReport.properties.toString()}\n") 149 | } 150 | } 151 | report 152 | } 153 | 154 | //Get the detailed report 155 | def getDetailedReport(projectResultHolder) { 156 | def report = new StringBuffer() 157 | report.append(drawLine()).append('\n') 158 | report.append("\t\t\tTest Execution Detailed Report\n") 159 | report.append(drawLine()).append('\n') 160 | projectResultHolder.suiteResults.each { suite, details -> 161 | report.append("Test Suite : ${suite}\n") 162 | report.append("Result : ${getResult(details.status)}\n") 163 | report.append("Total Cases : ${details.testCaseCount}\n") 164 | report.append("Cases Passed : ${details.passedCasesCount}\n") 165 | report.append("Cases Failed: ${details.failedCasesCount}\n") 166 | report.append(getTestCaseReport(details.casaeResults)) 167 | report.append(drawLine()).append('\n') 168 | report.append(drawLine()).append('\n') 169 | } 170 | report 171 | } 172 | 173 | //Save the contents to a file 174 | def saveToFile(file, content) { 175 | if (!file.parentFile.exists()) { 176 | file.parentFile.mkdirs() 177 | log.info "Directory did not exist, created" 178 | } 179 | file.write(content) 180 | assert file.exists(), "${file.name} not created" 181 | } 182 | 183 | def holder = new ProjectResultsHolder(log: log) 184 | holder.buildProjectResults(runner, project.name) 185 | 186 | def finalReport = new StringBuffer() 187 | finalReport.append(getSummaryReport(project, holder)) 188 | finalReport.append(getDetailedReport(holder)) 189 | 190 | def reportFile = new File(reportFileName) 191 | saveToFile(reportFile, finalReport.toString()) 192 | -------------------------------------------------------------------------------- /groovy/DateDifferenceCalculation.groovy: -------------------------------------------------------------------------------- 1 | import groovy.time.DatumDependentDuration 2 | import org.apache.log4j.Logger 3 | 4 | import java.text.SimpleDateFormat 5 | 6 | class AgeCalculator { 7 | 8 | String dob 9 | String when 10 | String format = 'yyyy-MM-dd' 11 | Logger log 12 | 13 | def getDate = { String date, String format -> 14 | def dateFormat = new SimpleDateFormat(format) 15 | dateFormat.parse(date) 16 | } 17 | 18 | def getAge() { 19 | if (!dob) { 20 | log.error "dob is mandatory" 21 | } 22 | Date now 23 | if (!when) { 24 | log.info "Value not provided for when, considering today's date" 25 | now = new Date() 26 | } else { 27 | now = getDate(when, format) 28 | } 29 | Date dob = getDate(dob,format) 30 | dob.clearTime() 31 | now.clearTime() 32 | assert dob < now 33 | Calendar.instance.with { c -> 34 | c.time = dob 35 | def (years, months, days) = [ 0, 0, 0 ] 36 | 37 | while( ( c[ YEAR ] < now[ YEAR ] - 1 ) || 38 | ( c[ YEAR ] < now[ YEAR ] && c[ MONTH ] <= now[ MONTH ] ) ) { 39 | c.add( YEAR, 1 ) 40 | years++ 41 | } 42 | 43 | while( ( c[ YEAR ] < now[ YEAR ] ) || 44 | ( c[ MONTH ] < now[ MONTH ] && c[ DAY_OF_MONTH ] <= now[ DAY_OF_MONTH ] ) ) { 45 | // Catch when we are wrapping the DEC/JAN border and would end up beyond now 46 | if( c[ YEAR ] == now[ YEAR ] - 1 && 47 | now[ MONTH ] == JANUARY && c[ MONTH ] == DECEMBER && 48 | c[ DAY_OF_MONTH ] > now[ DAY_OF_MONTH ] ) { 49 | break 50 | } 51 | c.add( MONTH, 1 ) 52 | months++ 53 | } 54 | 55 | while( c[ DAY_OF_YEAR ] != now[ DAY_OF_YEAR ] ) { 56 | c.add( DAY_OF_YEAR, 1 ) 57 | days++ 58 | } 59 | log.info "Years : ${years}" 60 | new DatumDependentDuration( years, months, days, 0, 0, 0, 0 ) 61 | } 62 | } 63 | } 64 | 65 | //Provide dateFormat as needed 66 | def dateFormat = 'dd/MM/yyyy' 67 | 68 | //Please assign value for dateOfBirth from data driven by editing, for now using assumed values 69 | 70 | def dateOfBirth = '26/12/1995' 71 | def quarterEndDate = '31/12/2015' 72 | def calculate = new AgeCalculator(log: log, 73 | dob: dateOfBirth, 74 | when: quarterEndDate, 75 | format: dateFormat) 76 | assert calculate.age.years >= 18, "Not an adult" 77 | -------------------------------------------------------------------------------- /groovy/DisableTestSteps.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * http://stackoverflow.com/questions/38443128/find-test-step-by-partial-name-using-groovy-in-soapui 3 | * this groovy script disables all the test steps 4 | * whose name contains the string specified in the 5 | * variable 'stepNamePatternToDisable' 6 | **/ 7 | 8 | //You may change the pattern required 9 | def stepNamePatternToDisable = 'WSDLCall' 10 | 11 | //Get the project object 12 | def project = context.testCase.testSuite.project 13 | 14 | //Loop thru the suite lise 15 | project.testSuiteList.each { suite -> 16 | //Loop thru the case list 17 | suite.testCaseList.each { caze -> 18 | //Loop thru the step list of the specific case 19 | caze.testStepList.each { step -> 20 | //if step name contains the given pattern, then disable, enable otherwise. 21 | if (step.name.contains(stepNamePatternToDisable)) { 22 | step.disabled = true 23 | } else { 24 | step.disabled = false 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /groovy/ExecuteCommandAndGetOutput.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Below script runs any command along with it arguments 3 | * and reads the output of the command and set it as 4 | * test case level property whose name is "propertyName" 5 | * provide the value for command as you needed. 6 | **/ 7 | def command = "you batch script command" 8 | log.info command 9 | def process = command.execute() 10 | def outputStream = new StringBuffer() 11 | def errorStream = new StringBuffer() 12 | process.consumeProcessOutput(outputStream, errorStream) 13 | process.waitFor() 14 | log.info("return code: ${process.exitValue()}") 15 | log.error("standard error: ${process.err.text}") 16 | log.info("standard out: ${process.in.text}" + outStream.toString()) 17 | context.testCase.setPropertyValue("propertyName", outStream.toString()) 18 | -------------------------------------------------------------------------------- /groovy/ExportTestCaseProperties.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * http://stackoverflow.com/questions/39229462/soapui-export-and-import-properties-to-file-by-script/39240253#39240253 3 | * this method exports test case properties into a file. 4 | * @param context 5 | * @param filePath 6 | */ 7 | def exportTestCaseProperties(def context, String filePath) { 8 | def props = new Properties() 9 | //Get all the property names of test cases 10 | def names = context.testCase.getPropertyNames() 11 | //loop thru names and set Properties object 12 | if (names) { 13 | names.each { name -> 14 | log.info "Set property ${name}" 15 | props.setProperty(name, context.testCase.getPropertyValue(name)) 16 | } 17 | //Write properties object to a file 18 | def propFile = new File(filePath) 19 | props.store(propFile.newWriter(), null) 20 | log.info "Check the properties file: ${filePath}" 21 | } else { 22 | log.info "There does not seem to have any test case properties to write, check it." 23 | } 24 | } 25 | //How to use above method 26 | exportTestCaseProperties(context, 'D:/Temp/testCase1.properties') 27 | -------------------------------------------------------------------------------- /groovy/GetMatchingString.groovy: -------------------------------------------------------------------------------- 1 | /**This script extracts a partial string of a soap response node value of matching string 2 | **and assigns a test case property 3 | **/ 4 | import com.eviware.soapui.support.XmlHolder 5 | def xml = new XmlHolder(context.response) 6 | //change the xpath as per the need 7 | def responseValue = xml.getNodeValue("//*:CDES-PUT-Response/*:response-message") 8 | //partial string of a node value from the responseValue 9 | def string = 'Job received successfully' 10 | // partial string of the same node value from the responseValue to be matched and extracted 11 | // using regex 12 | def pattern = '[A-Z]+[0-9]+' 13 | if (responseValue.contains(string)) { 14 | def group = (responseValue =~ /${pattern}/) 15 | context.testCase.setPropertyValue('JOB_ID',group[0]) 16 | } else { 17 | log.warning "Unexpected value in the response" 18 | } 19 | -------------------------------------------------------------------------------- /groovy/ImportPropertiesToTestCase.groovy: -------------------------------------------------------------------------------- 1 | //http://stackoverflow.com/questions/39229462/soapui-export-and-import-properties-to-file-by-script/39240253#39240253 2 | /** 3 | * this method imports properties to a test case from a file. 4 | * @param context 5 | * @param filePath 6 | */ 7 | def importPropertiesToTestCase(def context,String filePath) { 8 | def props = new Properties() 9 | def propFile = new File(filePath) 10 | //load the properties files into properties object 11 | props.load(propFile.newDataInputStream()) 12 | //loop thru the properties and set them at test case level 13 | props.each { 14 | context.testCase.setPropertyValue(it.key, it.value.toString()) 15 | } 16 | } 17 | //How to use above method. Make sure you have file with properties, change path if needed. 18 | importPropertiesToTestCase(context, 'D:/Temp/testCase.properties') 19 | -------------------------------------------------------------------------------- /groovy/LogRawDataOnTestFailure.groovy: -------------------------------------------------------------------------------- 1 | /** this script logs raw request and response data on test case failure, 2 | * user need to provide the step name as shown below comment 3 | * this can be used in teardown script of a test case 4 | **/ 5 | import com.eviware.soapui.model.testsuite.TestRunner.Status 6 | 7 | /*You need to provide the request step name(s) that you wanted to log*/ 8 | 9 | def testStepNames = ['Test Request1', 'Test Request2'] 10 | 11 | def logRawData = { stepName -> 12 | def step = testRunner.testCase.getTestStepByName(stepName) 13 | def rawRequest = new String(step.testRequest.messageExchange.rawRequestData) 14 | def rawResponse = new String(step.testRequest.messageExchange.rawResponseData) 15 | log.error rawRequest 16 | log.error rawResponse 17 | } 18 | 19 | if (testRunner.status == Status.FAILED) { 20 | testStepNames.each { step -> logRawData(step) } 21 | } 22 | -------------------------------------------------------------------------------- /groovy/MIMEAttachmentExample.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the attachment from the response and 3 | * Set the attachment string as request for next/given step dynamically 4 | * This assumes single attachment in current response 5 | * Script can be used as script assertion 6 | **/ 7 | 8 | 9 | /*you can use it as property expansion as well for below 10 | two properties if you do not want to modify here*/ 11 | 12 | //set the required content type of attachment 13 | def expectedContentType = 'text/xml; charset=UTF-8' 14 | 15 | //set the next request step name where dynamic request has to be created 16 | def nextStepName='step2' 17 | 18 | def actualContentType = messageExchange.responseAttachments[0].contentType 19 | 20 | //assert if it is matching with response received 21 | assert actualContentType == expectedContentType, "Content type is not matching to ${expectedContentType}" 22 | 23 | //if the assertion is passed then only read the attachment text 24 | def attachmentText = messageExchange.responseAttachments[0].inputStream.text 25 | 26 | //assert the text of attachment is not null 27 | assert attachmentText, "Attachment text is empty or null" 28 | 29 | //Get the existing request for the next step 30 | def nextStepRequest = context.testCase.getTestStepByName(nextStepName).getTestRequest() 31 | 32 | //Set the dynamic value from the attachment text to next step request. 33 | nextStepRequest.setRequestContent(attachmentText) 34 | -------------------------------------------------------------------------------- /groovy/NamespaceSample.groovy: -------------------------------------------------------------------------------- 1 | def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context ) 2 | def holder = groovyUtils.getXmlHolder( messageExchange.responseContent ) 3 | holder.namespaces["ns"] = "http://www.webserviceX.NET/" 4 | def conversionRate = holder.getNodeValue("//ns:ConversionRateResult") 5 | log.info conversionRate 6 | -------------------------------------------------------------------------------- /groovy/QueryRawData.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * http://stackoverflow.com/questions/38007809/soapui-how-to-extract-column-specific-data-form-the-json-response/38009693#38009693 3 | **/ 4 | def str = '''Account Id#%#Territory#%#District#%#Area#%#Region#%#objname#%#~ID~#%#~Lat-Lon Linked~#%#~Latitude~#%#~Longitude~#%#~Lat-Lon Zip~#%#School Name#%#Address#%#City#%#State#%#ZIP#%#ZIP4#%#School Type#%#Status#%#School Level#%#Count Free Lunch#%#Count Reduced Lunch#%#Total Lunch Pgm#%#Total Students#%#PreKindergarten#%#Kindergarten#%#Grade 1#%#Grade 2#%#Grade 3#%#Grade 4#%#Grade 5#%#Grade 6#%#Grade 7#%#Grade 8#%#Grade 9#%#Grade 10#%#Grade 11#%#Grade 12#%#Territory1#%#Region1#%#lat#%#lon#%#terrid\r\n15709#%#Hartford, CT#%#New England#%#Unassigned#%#Unassigned#%#Account#%#15709#%#True#%#41.934711#%#-72.770021#%#06026#%#R. DUDLEY SEYMOUR SCHOOL#%#185 HARTFORD AVENUE#%#EAST GRANBY#%#CT#%#6026#%#9520#%#1#%#1#%#2#%#0#%#0#%#0#%#131#%#0#%#0#%#0#%#0#%#0#%#60#%#71#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#Hartford, CT#%#New England#%#5151204.33051376#%#-8100721.57141633#%#3\r\n15707#%#Hartford, CT#%#New England#%#Unassigned#%#Unassigned#%#Account#%#15707#%#True#%#41.934894#%#-72.730656#%#06026#%#EAST GRANBY HIGH SCHOOL#%#95 SOUTH MAIN STREET#%#EAST GRANBY#%#CT#%#6026#%#9550#%#1#%#1#%#3#%#0#%#0#%#0#%#219#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#57#%#55#%#53#%#54#%#Hartford, CT#%#New England#%#5151231.26605957#%#-8096340.03625871#%#3\r\n15708#%#Hartford, CT#%#New England#%#Unassigned#%#Unassigned#%#Account#%#15708#%#True#%#41.934894#%#-72.730656#%#06026#%#EAST GRANBY MIDDLE SCHOOL#%#95 SOUTH MAIN STREET#%#EAST GRANBY#%#CT#%#6026#%#9550#%#1#%#1#%#2#%#0#%#0#%#0#%#201#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#67#%#73#%#61#%#0#%#0#%#0#%#0#%#Hartford, CT#%#New England#%#5151231.26605957#%#-8096340.03625871#%#3\r\n15706#%#Hartford, CT#%#New England#%#Unassigned#%#Unassigned#%#Account#%#15706#%#True#%#41.944215#%#-72.732696#%#06026#%#ALLGROVE SCHOOL#%#33 TURKEY HILLS ROAD#%#EAST GRANBY#%#CT#%#6026#%#9570#%#1#%#1#%#1#%#0#%#0#%#0#%#275#%#3#%#69#%#65#%#82#%#56#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#Hartford, CT#%#New England#%#5152627.52929053#%#-8096567.12801993#%#3\r\n15710#%#Hartford, CT#%#New England#%#Unassigned#%#Unassigned#%#Account#%#15710#%#True#%#41.944215#%#-72.732696#%#06026#%#HOMEBOUND#%#33 TURKEY HILL ROAD#%#EAST GRANBY#%#CT#%#6026#%#674#%#4#%#3#%#4#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#Hartford, CT#%#New England#%#5152627.52929053#%#-8096567.12801993#%#3\r\n15923#%#Hartford, CT#%#New England#%#Unassigned#%#Unassigned#%#Account#%#15923#%#True#%#42.0027#%#-72.942#%#06027#%#HOMEBOUND#%#30 SOUTH ROAD#%#EAST HARTLAND#%#CT#%#6027#%#9710#%#4#%#3#%#4#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#0#%#Hartford, CT#%#New England#%#5161383.89953631#%#-8119866.29744296#%#3\r\n15922#%#Hartford, CT#%#New England#%#Unassigned#%#Unassigned#%#Account#%#15922#%#True#%#42.0027#%#-72.942#%#06027#%#HARTLAND ELEMENTARY SCHOOL#%#30 SOUTH ROAD#%#EAST HARTLAND#%#CT#%#6027#%#9710#%#1#%#1#%#1#%#0#%#0#%#0#%#2#%#0#%#25#%#17#%#26#%#29#%#37#%#36#%#38#%#35#%#40#%#0#%#0#%#0#%#0#%#Hartford, CT#%#New England#%#5161383.89953631#%#-8119866.29744296#%#3''' 5 | //split by carriage return and new line 6 | def data = str.split('\r\n') 7 | //split by field to get the just column names from header row 8 | def headers = data[0].split('#%#') 9 | //Create map with just header keys, so that it can be used while storing the data 10 | def headerMap = [:] 11 | headers.each { header -> 12 | headerMap[header] = '' 13 | } 14 | /** 15 | * Closure allows you to query the required data 16 | * Need to pass all the records and row (human readable starting with 1) and header key/ field name 17 | * so the information is displaced as well as returns matched value 18 | */ 19 | def getData = { recordList, row, field -> 20 | println "Requested data : \n Row : ${row} \n Column : ${field} \n Column Value : ${recordList[row-1].get(field)}" 21 | recordList[row-1].get(field) 22 | } 23 | // This is the variable which holds all the records 24 | // And each record will be in the form of a map so that it can be queried easily based on the field 25 | def records = [] 26 | for (i=1;i Test2' : 'Login SID Test2 --> pushINID Test2', 8 | 'Login Test2 -> Test1' : 'Login SID TPSP --> requestEmergencyData', 9 | 'Login Test2 -> Test1' : 'Random UID --> pushINID Test1', 10 | 'requestEmergencyData Test2 -> Test1' : 'Random_TSDI', 11 | 'requestEmergencyData Test2 -> Test1' : 'requestEM UID --> pushEM', 12 | 'requestEmergencyData Test2 -> Test1' : 'requestEM SID --> CLDWN', 13 | 'pushEmergencyData Test1 -> Test2' : 'pushEM UID --> CLDWN', 14 | 'pushEmergencyData Test1 -> Test2' : 'pushEM SID --> Test2 -> TPSP Logout', 15 | 'clearDown Test2 -> Test1' : 'CLDWN SID --> Test2 Logout' 16 | ] 17 | 18 | def runDependentStep = { stepName -> 19 | if (stepName in map.keySet()) { 20 | log.info "Found dependent test step : ${stepName}" 21 | context.testCase.getTestStepByName(map[stepName]).run(testRunner, context) 22 | } 23 | } 24 | 25 | def randomize = { list -> Collections.shuffle(list); list } 26 | 27 | def project = testRunner.testCase.testSuite.project 28 | 29 | randomize(project.testSuiteList)?.each { suite -> 30 | randomize(suite.testCaseList)?.each { kase -> 31 | randomize(kase.testStepList)?.each { step -> 32 | log.info "Test step : ${step.label}" 33 | (context.currentStep.name == step.label) ?: step.run (testRunner, context) 34 | runDependentStep(step.label) 35 | if( (step.metaClass.hasProperty(step, 'assertionStatus')) && (step?.assertionStatus == AssertionStatus.FAILED)){ 36 | log.info "${step.name} FAIL..." 37 | testRunner.cancel("TestStep failed") 38 | fail() 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /groovy/RegexSample.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * script to check if there is a single match 3 | * for details: 4 | * https://community.smartbear.com/t5/SoapUI-NG/Script-assertion-using-regex-to-get-a-value-from-the-response/m-p/128147#U128147 5 | **/ 6 | def str = '''{"ProcessingMilliseconds": 11.34,"ResponseCount":1,"ProcessingMachine":"QAC1","ApplicationVersion":"2.1.766.10728","BuildNumber":"2.1.766.10728","EnvironmentName":"QA","MethodName":"/MemberStore/123/2.1/Routers/QualifiedQuotas"}''' 7 | def regEx = "(ProcessingMilliseconds\"[\\s?]*:[\\s?]*[\\d]+[\\.][\\d]*,)" 8 | def result = (str =~ regEx) 9 | //Equal to 1, because there must be one match. 10 | assert result.count ==1 11 | -------------------------------------------------------------------------------- /groovy/SetHttpHeaders.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * below method script will set http headers to the given test step with in the same test case 3 | * user need to pass the test step name, and headers map> 4 | **/ 5 | def setHttpHeaders(String stepName, def headers) { 6 | def nextRequest = context.testCase.testSteps[stepName].httpRequest 7 | def existingHeaders = nextRequest.requestHeaders 8 | headers.each { 9 | existingHeaders[it.key] = it.value 10 | } 11 | nextRequest.requestHeaders = existingHeaders 12 | } 13 | 14 | //calling the above method 15 | def headers = ['header1': ['header1 value'], 'header2': ['header2 value']] 16 | setHttpHeaders('REST Request', headers) 17 | -------------------------------------------------------------------------------- /groovy/SetJsonRequest.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * this script will set the request to 3 | * a specified test step using groovy script 4 | * NOTE: you may modify stepName variable as needed 5 | **/ 6 | def stepName='restStep' 7 | def request = context.testCase.getTestStepByName(stepName).getTestRequest() 8 | def jsonText = ''' 9 | { 10 | "id" : "sample id", 11 | "name" : "sample name", 12 | "tags" : [ "sample tags" ], 13 | "address" : { 14 | "street" : "sample street", 15 | "zipcode" : "sample zipcode", 16 | "city" : "sample city" 17 | } 18 | } 19 | ''' 20 | request.setRequestContent(jsonText) 21 | -------------------------------------------------------------------------------- /groovy/TestRunner.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * this groovy script can run the soapui project and generate junit result 3 | **/ 4 | import com.eviware.soapui.tools.SoapUITestCaseRunner 5 | def runner = new SoapUITestCaseRunner() 6 | runner.with { 7 | //change the paths as needed to suit your environment 8 | setProjectFile('/path/to/Sample-soapui-project.xml') 9 | //Ignore below if you do not have any special settings. 10 | setSettingsFile('/path/to/soapui-settings.xml') 11 | setOutputFolder('/tmp/results') 12 | setPrintReport(true) 13 | setExportAll(true) 14 | setJUnitReport(true) 15 | run() 16 | } 17 | -------------------------------------------------------------------------------- /groovy/ToggleSuitesBasedOnCommandlineInput.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * http://stackoverflow.com/questions/38147995/how-to-select-the-test-suites-dynamically-in-soap-ui-based-on-the-command-line-a 3 | * this script reads System property say EXECUTION_GROUP as command line options 4 | * and toggle to test suites according to the user input 5 | * if list is found enable the suite, disable it otherwise. 6 | * if system property is set, then all the suites are enabled 7 | **/ 8 | //Below closure toggle the suite based on the list of names 9 | def toggleSuite = { suite, list -> 10 | def groups = suite.getPropertyValue('EXECUTION_GROUP').split(',').collect{it.trim()} 11 | def isGroupFound = false 12 | list.each { group -> 13 | if (groups.contains(group)) { 14 | isGroupFound = true 15 | } 16 | } 17 | if (!isGroupFound) { 18 | suite.disabled = true 19 | } else { 20 | suite.disabled = false 21 | } 22 | } 23 | 24 | //Reads the system property 25 | def userInput = System.getProperty('EXECUTION_GROUP') 26 | log.info "Command line input: $userInput" 27 | def cmdLineOptions = [] 28 | 29 | //Checks if the user provided value is null i.e., system property not set 30 | if (null != userInput) { 31 | cmdLineOptions = userInput.split(',').collect{it.trim()} 32 | if (null != cmdLineOptions) { 33 | log.info "User has provided the execution group as input" 34 | log.info cmdLineOptions 35 | project.testSuiteList.each { suite -> toggleSuite(suite, cmdLineOptions) } 36 | } else { 37 | log.info "Receieved empty list of options, so disabling all the suites" 38 | project.testSuiteList.each { suite -> suite.disabled = true } 39 | } 40 | } else { 41 | log.info "All suites are being enabled as no system property input found" 42 | project.testSuiteList.each { suite -> suite.disabled = false } 43 | } 44 | -------------------------------------------------------------------------------- /groovy/UpdateResponseSLA.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * This script updates value of Response SLA assertion in the soapui project 3 | * with value mentioned for 'newSLA' variable below which 4 | * currently assigns project level custom property call RESPONSE_TIME_SLA and 5 | * you need to define it with required value for the request steps of type 6 | * SOAP, REST, JDBC, HTTP 7 | */ 8 | import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep 9 | import com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep 10 | import com.eviware.soapui.impl.wsdl.teststeps.JdbcRequestTestStep 11 | import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequestStep 12 | import com.eviware.soapui.impl.wsdl.teststeps.assertions.basic.ResponseSLAAssertion 13 | //update the new value as needed 14 | def newSLA = '\${#Project#RESPONSE_TIME_SLA}' 15 | //Get the project object 16 | def project = context.testCase.testSuite.project 17 | 18 | //Closure to update the Response SLA assertion value 19 | def updateAssertionSLA = { assertion, sla -> 20 | if (assertion instanceof ResponseSLAAssertion) { 21 | log.info "Found a request step assertion with Response SLA type, and updating its value" 22 | assertion.setSLA(sla) 23 | } 24 | } 25 | //Actual script that traverse thru the project -> suite -> case -> step 26 | project.testSuiteList.each { suite -> 27 | log.info "Looking into test suite: ${suite.name}" 28 | suite.testCaseList.each { tCase -> 29 | log.info "Looking into test case: ${tCase.name}" 30 | tCase.testStepList.each { step -> 31 | log.info "Looking into test step: ${step.name}" 32 | if (step instanceof WsdlTestRequestStep 33 | || step instanceof RestTestRequestStep 34 | || step instanceof JdbcRequestTestStep 35 | || step instanceof HttpTestRequestStep) { 36 | log.info "Found a request step of required type " 37 | def assertions = step.assertionList 38 | assertions.each{ updateAssertionSLA(it, newSLA) } 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /groovy/UpdateWSDLDefinition.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | *This script automatically update the wsdl definition and its test requests in the soapui project 3 | *Check for the variables- projectName, wsdlFiles to be updated before running the script 4 | */ 5 | import com.eviware.soapui.impl.wsdl.WsdlInterface 6 | import com.eviware.soapui.impl.wsdl.WsdlProject 7 | import com.eviware.soapui.model.iface.Interface 8 | import static com.eviware.soapui.impl.wsdl.actions.iface.UpdateInterfaceAction.recreateRequests 9 | import static com.eviware.soapui.impl.wsdl.actions.iface.UpdateInterfaceAction.recreateTestRequests 10 | /** 11 | * Created by nmrao on 12/24/14. 12 | */ 13 | class UpdateWsdls { 14 | 15 | WsdlProject wsdlProject 16 | 17 | public UpdateWsdls(String projectFileName) { 18 | this.wsdlProject = new WsdlProject(projectFileName) 19 | } 20 | 21 | def getBindingNames(String wsdlFile) { 22 | def definitions = new XmlParser().parse(new File(wsdlFile)) 23 | return definitions.getByName('*:binding').@name 24 | } 25 | 26 | void updateInterfaceDefinitions(List wsdlFileNames) { 27 | wsdlFileNames.each { fileName -> 28 | def interfaceNames = getBindingNames(fileName) 29 | interfaceNames.each { 30 | updateInterfaceDefinition(it, fileName) 31 | } 32 | } 33 | } 34 | 35 | void updateInterfaceDefinition(String interfaceName, String fileName) { 36 | List interfacesList = wsdlProject.interfaceList 37 | interfacesList.each { Interface anInterface -> 38 | if (anInterface instanceof WsdlInterface && interfaceName.equals(anInterface.name)) { 39 | WsdlInterface wsdlInterface = (WsdlInterface) anInterface 40 | wsdlInterface.updateDefinition(fileName, false) 41 | } 42 | } 43 | } 44 | 45 | void updateRequests () { 46 | List interfacesList = wsdlProject.interfaceList 47 | interfacesList.each { Interface anInterface -> 48 | WsdlInterface wsdlInterface = (WsdlInterface) anInterface 49 | recreateRequests(wsdlInterface,false,false,true,false) 50 | recreateTestRequests(wsdlInterface,false,false,true,false) 51 | } 52 | } 53 | 54 | void saveWsdlProject() { 55 | wsdlProject.save() 56 | wsdlProject.release() 57 | 58 | } 59 | 60 | } 61 | 62 | String projectName = "/path/to/abc-soapui-project.xml" //absolute path of soapui project file 63 | List wsdlFiles = ["/path/to/service1.wsdl"] //or you can have multiple wsdls from different wsdl files which you want to update in one project 64 | UpdateWsdls updateWsdl = new UpdateWsdls(projectName) 65 | updateWsdl.updateInterfaceDefinitions(wsdlFiles) 66 | updateWsdl.updateRequests() 67 | updateWsdl.saveWsdlProject() 68 | 69 | -------------------------------------------------------------------------------- /groovy/VerifyHTTPResponse.groovy: -------------------------------------------------------------------------------- 1 | def expectedHTTPResponse = ['HTTP/1.1 200 OK'] 2 | def headers = messageExchange.response.responseHeaders 3 | def actualHTTPResponse = headers['#status#'] 4 | assert expectedHTTPResponse == actualHTTPResponse 5 | -------------------------------------------------------------------------------- /groovy/VerifyHeaders.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * this script can verify given http headers both in request and response 3 | * checks if given HEADER_NAMES in request vs response 4 | * also its value and size 5 | * Assumes, a custom test case property HEADER_NAMES is defined with 6 | * appropriate value(s) separated by comma like Content-Type, Cookie etc., any thing for that matter 7 | * This needs to used as Script Assertion 8 | **/ 9 | //Aso published the same at 10 | //http://community.smartbear.com/t5/SoapUI-NG/Fetch-cookies-from-soapUI-Request-and-Response-and-reuse-for/m-p/109182#U109182 11 | import groovy.transform.Canonical 12 | @Canonical 13 | class HeaderVerificationResult { 14 | String name 15 | def requestValue 16 | def responseValue 17 | def failureMessage = new StringBuilder() 18 | boolean result = false 19 | } 20 | 21 | Map verificationMap = [:] 22 | def keysString = context.testCase.properties['HEADER_NAMES'].value 23 | if (keysString) { 24 | keysString.split(',').each { key -> 25 | verificationMap[key] = buildModel(key) 26 | } 27 | } else { throw new Error('No header names provided') } 28 | 29 | def testResultFail = verificationMap.findAll{ it.value.result == false } 30 | def errorMessage = StringBuilder() 31 | testResultFail.each { 32 | log.info "Verifying Header : ${it.key}" 33 | errorMessage.append("\n${it.value.toString()}") 34 | log.info "Failure${it.value.failureMessage.toString()}" 35 | } 36 | if (errorMessage) { throw new Error(errorMessage.toString())} 37 | 38 | def buildModel = { key -> 39 | def currentResultObject = new HeaderVerificationResult(name: key) 40 | addMessageIfNotContainsHeader(messageExchange.requestHeaders.containsKey(key), 'Request', currentResultObject) 41 | addMessageIfNotContainsHeader(messageExchange.responseHeaders.containsKey(key), 'Response', currentResultObject) 42 | if (currentResultObject.requestValue != currentResultObject.requestValue) { 43 | currentResultObject.failureMessage.append('\nValue mismatch') 44 | } 45 | if (currentResultObject.requestValue.size() != currentResultObject.requestValue..size()) { 46 | currentResultObject.failureMessage.append('\nValue size mismatch') 47 | } 48 | if (!currentResultObject.failureMessage) ) { 49 | currentResultObject.result = true 50 | } 51 | currentResultObject 52 | } 53 | 54 | def addMessageIfNotContainsHeader = { value, message, object -> 55 | object.failureMessage 56 | if (!value) { 57 | object.failureMessage.append("\n${message} does not contain header") 58 | } else { 59 | if ('Request' == message) { 60 | object.requestValue = messageExchange.requestHeaders[object.name].value 61 | } else if ('Response' == message) { 62 | object.responseValue = messageExchange.responseHeaders[object.name].value 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /groovy/WriteResponseValueToFile.groovy: -------------------------------------------------------------------------------- 1 | /** this sample reads value of the response, creates an object and reads node value using xpath and writes 2 | ** into a file **/ 3 | import com.eviware.soapui.support.XmlHolder 4 | def xml = new XmlHolder(context.response) 5 | def preValidationMinValue = xml.getNodeValue("//*:PrevalidationMin") 6 | new File('c:/temp/myfile.csv').write(preValidationMinValue) 7 | -------------------------------------------------------------------------------- /groovy/compare/xmlAndJdbc_sample1.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * compare soap response with jdbc response. 3 | * Refer https://community.smartbear.com/t5/SoapUI-Open-Source/How-to-compare-2-response-XMLs-from-2-Different-Test-Steps-and/m-p/139945#U139945 4 | **/ 5 | def xmlResponse = """ 6 | 7 | 8 | 9 | 10 | 11 | 7 12 | Human Resource 13 | 14 | 15 | 5 16 | IT 17 | 18 | 19 | 6 20 | Manufacturing 21 | 22 | 23 | 8 24 | Marketing 25 | 26 | 27 | 28 | 29 | O1GHg65lCq1492324865 30 | dey.avik5@gmail.com 31 | 32 | 33 | 34 | 35 | 36 | """ 37 | 38 | def jdbcResponse = """ 39 | 40 | 41 | 7 42 | Human Resource 43 | 44 | 45 | 5 46 | IT 47 | 48 | 49 | 6 50 | Manufacturing 51 | 52 | 53 | 8 54 | Marketing 55 | 56 | 57 | """ 58 | 59 | getDetails = { data, recordElement, id, name -> 60 | new XmlSlurper().parseText(data).'**'.findAll{it.name() == recordElement && !it."$id".isEmpty() }.inject([:]){map,item -> map[item."$id".text()] = item."$name".text();map}.sort() 61 | } 62 | 63 | def soap = getDetails(xmlResponse, 'item', 'category_id', 'category_name') 64 | log.info soap 65 | def jdbc = getDetails(jdbcResponse, 'Row', 'CATEGORY.CAT_ID', 'CATEGORY.CAT_NAME') 66 | log.info jdbc 67 | assert soap == jdbc, 'both are not matching' 68 | -------------------------------------------------------------------------------- /groovy/json/AssertJsonArrayElement.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * this example shows how to assert a json element of an array 3 | **/ 4 | import net.sf.json.groovy.JsonSlurper 5 | def jsonText = '''{ 6 | "cars": [ 7 | { 8 | "name" : "Jetta", 9 | "madeBy" : "Volkswagen" 10 | }, 11 | { 12 | "name" : "Polo GT", 13 | "madeBy" : "Volkswagen" 14 | }, 15 | { 16 | "name" : "i30", 17 | "madeBy" : "Hyundai" 18 | } 19 | ] 20 | }''' 21 | def jsonSlurper = new JsonSlurper() 22 | def cars = jsonSlurper.parseText(jsonText).cars 23 | def expectedName = 'Jetta' 24 | def expectedValueExists=false 25 | if (cars) { 26 | cars.each{if (it.name==expectedName) {expectedValueExists=true} } 27 | } 28 | if (expectedValueExists) { println "Expected car ${expectedName} exists"} 29 | assert expectedValueExists, "Expected car name does not exists" 30 | -------------------------------------------------------------------------------- /groovy/json/IsResponseValidJson.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * This script assertion 3 | * 4 | **/ 5 | 6 | import com.eviware.soapui.support.JsonUtil 7 | 8 | assert context.response, 'Response is empty or null' 9 | assert true == JsonUtil.isValidJson(json), 'Response is not a valid json' 10 | -------------------------------------------------------------------------------- /groovy/json/JsonArrayEmpty.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | *this example check the json array is empty 3 | **/ 4 | import net.sf.json.groovy.JsonSlurper 5 | def jsonArray = '''{ 6 | "employees":[] 7 | }''' 8 | def jsonSlurper = new JsonSlurper() 9 | def object = jsonSlurper.parseText(jsonArray) 10 | def employees = object.employees 11 | if (!employees) { 12 | log.warn "Array is empty" 13 | } 14 | -------------------------------------------------------------------------------- /groovy/json/UpdateNextJsonRequestFromCurrentResponse.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Refer http://stackoverflow.com/questions/43732160/update-rest-request-data-based-on-the-previous-step-response-data/43733782#43733782 3 | * Below is the script assertion 4 | * reads current response, extract certain data, and update this data into next test step request 5 | * full script with data or for demo, refer : https://groovyconsole.appspot.com/script/5136269650690048 6 | **/ 7 | import groovy.json.JsonSlurper 8 | import groovy.json.JsonBuilder 9 | 10 | //Provide the name of the next request test step name where you need to override the content 11 | def nextStepName = 'step2' 12 | 13 | //DO NOT REQUIRE TO MODIFY 14 | //Check the current step response 15 | assert context.response, 'Response is empty' 16 | 17 | def json = new JsonSlurper().parseText(context.response) 18 | def products = json.response.products 19 | log.info "Products details from current response: $products" 20 | 21 | //Get the next test step request 22 | def nextStepRequest = context.testCase.testSteps[nextStepName].httpRequest 23 | 24 | //Check if the next step request content is empty 25 | assert nextStepRequest.requestContent, "Next step, $nextStepName, request is empty" 26 | 27 | def slurped = new JsonSlurper().parseText(nextStepRequest.requestContent) 28 | def builder = new JsonBuilder(slurped) 29 | 30 | //Change the products of next request 31 | builder.content.products = products.inject([]){l, item -> def map = [:];map['id'] = item.id; l << map; l} 32 | 33 | //Update the product details in the request 34 | nextStepRequest.requestContent = builder.toPrettyString() 35 | log.info "Updated request for the step ${nextStepName} is : ${nextStepRequest.requestContent}" 36 | -------------------------------------------------------------------------------- /groovy/json/cdata/JsonInsideCdata.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * This example illustrates how to extract Json which is inside a cdata of an XML 3 | * http://stackoverflow.com/questions/34136890/transfer-property-from-login-to-logout-in-saopui-pro/34137618#34137618 4 | **/ 5 | import com.eviware.soapui.support.XmlHolder 6 | import net.sf.json.groovy.JsonSlurper 7 | def soapResponse = ''' 8 | 9 | 10 | 11 | 12 | 1JMRXxxxDWF31PXC0EFQ 13 | IN_OK 14 | 15 | 16 | {"timestamp": "2015-12-07T14:14:35Z", "data": {"profile": null, "token": "1a66k111-3177-0000-000b-aed1478c8309", "endpoints": [{"label": "app1", "branches": [{"url": "/app1/v1.0/", "name": "ext-", "api_version": "1.0", "label": "ext"}], "appname": "app1"}]}, "success": true} 17 | 18 | 19 | 20 | ''' 21 | def holder = new XmlHolder(soapResponse) 22 | def response = holder.getNodeValue('//*:response') 23 | def json = new JsonSlurper().parseText(response) 24 | log.info json.data.profile 25 | log.info json.data.endpoints 26 | //appending to previous answer 27 | log.info json.data.token 28 | -------------------------------------------------------------------------------- /groovy/mockServiceScripts/MockResponseDispatcherWithDynamicValues.groovy: -------------------------------------------------------------------------------- 1 | /*This script reads the salesOrderNumber from request using xpath 2 | * and checks corresponding response xml file from 3 | * mockResponses directory of your soapui project location. 4 | * Also expects a soapFault.xml file in the same location 5 | * in order to send soap fault if no sales order number maches the 6 | * existing files. 7 | * For example, soapui project located under C:\soapuiProjects 8 | * create a subdirectory called mockResponses under above directory 9 | * Make sure all your mock response files for sales orders under 10 | * C:\soapuiProjects\mockResponses directory including soapFault.xml 11 | * Assuming that the soap response file extension is xml, not txt 12 | */ 13 | def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context) 14 | def holder = groovyUtils.getXmlHolder(mockRequest.requestContent) 15 | def soNumber = holder.getNodeValue("//*:BillingOrderLoadRequest/*:salesOrderNumber") 16 | def file = new File (groovyUtils.projectPath+"/mockResponses/${soNumber}.xml") 17 | def fileToLoad = 'soapFault' 18 | if (file.exists()) { 19 | fileToLoad = soNumber 20 | } 21 | def tempContent = groovy.xml.XmlUtil.serialize(new XmlParser().parse(groovyUtils.projectPath+"/mockResponses/${fileToLoad}.xml")) 22 | tempContent.replace("\$") 23 | context.content = tempContent 24 | 25 | -------------------------------------------------------------------------------- /groovy/scriptAssertions/cdata/CdataInsideXml.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * refer https://community.smartbear.com/t5/SoapUI-Open-Source/How-to-get-response-property-value-and-use-it-as-next-step-input/m-p/139479/highlight/false#M23744 3 | * this is a script assertion 4 | * Response is xml whic again as cdata and cdata again has xml where user needs to lookup for a name based on sibling value 5 | * then extracted country name should be persisted for later use 6 | **/ 7 | 8 | //Check if there is repose 9 | assert context.response, 'Response is empty or null' 10 | def lookpcode = context.expand('${#TestCase#CountryCode}') 11 | def dataSet = new XmlSlurper().parseText(context.response).'**'.find{ it.name() == 'GetCountryByCountryCodeResult')} as String 12 | def countryName = new XmlSlurper().parseText(dataSet).'**'.find{ it.name() == 'countrycode' && it == lookpcode)}.parent().name.text() 13 | log.info "Country name is ${countryName} where code is ${lookpcode}" 14 | assert countryName, 'Country name empty or null' 15 | context.testCase.setPropertyValue('COUNTRY_NAME', countryName) 16 | -------------------------------------------------------------------------------- /groovy/scriptAssertions/cookies/AddCookiesToNextRequest.groovy: -------------------------------------------------------------------------------- 1 | //This script assertion reads the http response, 2 | //collect the cookies for the next http request 3 | //Provide the next step name where you want to set the Cookie to the request or 4 | //Use property expansion for below 5 | def nextStepName = 'step2' 6 | def nextRequest = context.testCase.testSteps[nextStepName].httpRequest 7 | def headers = nextRequest.requestHeaders 8 | if (messageExchange.responseHeaders.containsKey('Set-Cookie')) { 9 | log.info "Found Cookie in the response headers" 10 | def cookiez = messageExchange.responseHeaders['Set-Cookie'].value 11 | def list = [] 12 | cookiez.each { cookies -> 13 | //def (name, value) = cookies.toString().split('=',2) 14 | list.add(cookies.toString()) 15 | } 16 | headers['Cookie'] = list 17 | } else { 18 | log.warn "Not Found Cookie in the response headers" 19 | } 20 | nextRequest.requestHeaders = headers 21 | -------------------------------------------------------------------------------- /groovy/scriptAssertions/cookies/AddCookiesToStore.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * this script reads the response of a test step 3 | * takes headers with name 'Set-Cookie' and 4 | * adds them to Cookie store 5 | * Use as script assertion 6 | **/ 7 | import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport 8 | import org.apache.http.cookie.Cookie 9 | import org.apache.http.impl.cookie.BasicClientCookie 10 | def myCookieStore = HttpClientSupport.getHttpClient().getCookieStore() 11 | if (messageExchange.responseHeaders.containsKey('Set-Cookie')) { 12 | log.info "Found Cookie in the response headers" 13 | def cookiez = messageExchange.responseHeaders['Set-Cookie'].value 14 | cookiez.each { cookies -> 15 | def (name, value) = cookies.toString().split('=',2) 16 | Cookie cooky = new BasicClientCookie(name, value) 17 | myCookieStore.addCookie(cooky) 18 | } 19 | } else { 20 | log.warn "Not Found Cookie in the response headers" 21 | } 22 | log.info myCookieStore.getCookies().size() 23 | -------------------------------------------------------------------------------- /groovy/scriptAssertions/headersToMultipleSteps/AddCurrentResponseHeaderToMultipleSteps.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Ths is the Script Assertion 3 | * which sets headers to the requested targetted steps 4 | * by extracting header from currest step response 5 | * Refer: http://stackoverflow.com/questions/40059304/passing-jsessionid-from-a-soap-response-to-a-http-request-in-soap-ui/40060851#40060851 6 | **/ 7 | //Assert if response has headers 8 | assert messageExchange.responseHeaders, "Response does not have any headers" 9 | 10 | //Specify all the headers to retrieve from current test step response as keys, target step request headers as values 11 | //key - current response header name 12 | //value - target request header name 13 | //Add more key, values into map if you need to extract and set more headers 14 | def headerMap = ['Set-Cookie' : 'Cookie'] 15 | //Specify the test step name for which headers to be set. 16 | //Add call to setHttpHeaders with different test step names as needed to apply for more steps 17 | setHttpHeaders('step2', headerMap) 18 | 19 | 20 | /** 21 | * method sets headers to targeted step 22 | * step is the step name for which headers to be set 23 | * header map consists key, header name in the current step and value, header name to appear in the 24 | * targeted step 25 | * 26 | **/ 27 | def setHttpHeaders(def step, def headerMap) { 28 | def nextRequest = context.testCase.testSteps[step]?.httpRequest 29 | def existingHeaders = nextRequest?.requestHeaders 30 | headerMap.each { 31 | existingHeaders[it.value] = getHttpHeaderValue(it.key) 32 | } 33 | nextRequest?.requestHeaders = existingHeaders 34 | } 35 | 36 | /** 37 | * method to retrieve the value of the specified header 38 | **/ 39 | def getHttpHeaderValue(def headerToLookup) { 40 | if (messageExchange.responseHeaders.containsKey(headerToLookup)) { 41 | log.info "Found ${headerToLookup} in the response headers" 42 | return messageExchange.responseHeaders[headerToLookup] 43 | } else { 44 | log.warn "${headerToLookup} is not found in the response headers" 45 | } 46 | null 47 | } 48 | -------------------------------------------------------------------------------- /groovy/scriptAssertions/headersToMultipleSteps/AddHeadersToMultipleSteps.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Below is the setup script of the test case 3 | * which adds the headers to SOAP/REST/HTTP request type test steps of that test case 4 | */ 5 | import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep 6 | import com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep 7 | import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequestStep 8 | //define your headers as needed in the below statement 9 | def headers = ['header1': ['header1 value'], 'header2': ['header2 value']] 10 | 11 | def setHttpHeaders(def step, def headers) { 12 | def nextRequest = step.httpRequest 13 | def existingHeaders = nextRequest.requestHeaders 14 | headers.each { 15 | existingHeaders[it.key] = it.value 16 | } 17 | nextRequest.requestHeaders = existingHeaders 18 | } 19 | 20 | //calling the above method 21 | testCase.testStepList.each { step -> 22 | if (step instanceof WsdlTestRequestStep 23 | || step instanceof RestTestRequestStep 24 | || step instanceof HttpTestRequestStep) { 25 | setHttpHeaders(step, headers) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /groovy/scriptAssertions/headersToMultipleSteps/SetCookieForNextRequest.groovy: -------------------------------------------------------------------------------- 1 | 2 | /**Below script should be used as script assertion for login request step 3 | * Assumes below 4 | * a. login response contains http header called 'Set-Cookie' 5 | * b. other request needs to send http header called 'Cookie' 6 | * In case if there is any change in able two you may need to change its references below 7 | **/ 8 | def responseCookieKey = 'Set-Cookie' 9 | def requestCookieKey = 'Cookie' 10 | def setHttpHeaders(String nextStepName, def headers) { 11 | def nextRequest = context.testCase.testSteps[nextStepName].httpRequest 12 | def existingHeaders = nextRequest.requestHeaders 13 | headers.each { 14 | existingHeaders[it.key] = it.value 15 | } 16 | nextRequest.requestHeaders = existingHeaders 17 | } 18 | 19 | 20 | if (messageExchange.responseHeaders.containsKey(responseCookieKey)) { 21 | log.info "Found Cookie in the response headers" 22 | def cookiez = messageExchange.responseHeaders[responseCookieKey] 23 | assert null != cookiez, "Response does not contain Cookie" 24 | def nStepName = context.testCase.testStepList[context.currentStepIndex + 1].name 25 | def headers = [(requestCookieKey) : (cookiez)] 26 | setHttpHeaders(nStepName, headers) 27 | } else { 28 | log.error "Not Found Cookie in the response headers" 29 | } 30 | -------------------------------------------------------------------------------- /groovy/shareData/AccessComplexObjectsFromOtherScripts.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * At times, user like to share objects between the Groovy Scripts. 3 | * SoapUI allows to share properties for test case / suite / project. But these can only hold String Type data. 4 | * If you want to use complex objects like list / map or any custom object, there is no stright way. 5 | * Luckily, since there is groovy script support, one can use power of goovy's meta programming to achieve the same. 6 | * Refer: https://stackoverflow.com/questions/44421624/how-to-pass-a-two-dimensional-list-array-between-groovy-scripts-in-soap-ui/44469058#44469058 7 | * Refer : https://community.smartbear.com/t5/SoapUI-NG/Passing-groovy-lists-via-testcase-properties/m-p/143878#M32513 8 | **/ 9 | 10 | //In script 1: 11 | import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase 12 | WsdlTestCase.metaClass.myList = [1,2,3,4,5] 13 | 14 | //In script 2 : 15 | log.info "From script 2: ${context.testCase.myList}" 16 | assert [1,2,3,4,5] == context.testCase.myList 17 | -------------------------------------------------------------------------------- /groovy/xml/AssertValueBetweenRange.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * This is Script Assertion 3 | * Checks if the response value falls in certain range 4 | * for more details: https://community.smartbear.com/t5/SoapUI-NG/I-need-to-be-able-to-put-a-Range-into-my-Assertions/m-p/128750#U128750 5 | * */ 6 | 7 | //Check if the response is not empty 8 | assert context.response, 'Response is empty or null' 9 | 10 | //Parse the response 11 | def parsedXml = new XmlSlurper().parseText(context.response) 12 | 13 | //Get the Total Results as Integer 14 | def results = parsedXml.'**'.find {it.name() == 'TotalResults'}.text() as Integer 15 | log.info "Total Results : $results" 16 | 17 | //Define the range of values that needs to verified against 18 | def range = 181..200 19 | 20 | //Check if the response value falls in the given range 21 | assert range.contains(results), "Response value is not falling in the given range" 22 | -------------------------------------------------------------------------------- /groovy/xml/builder/BuildSoapRequestFromCsv.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Build soap request xml using csv data 3 | * so reference http://stackoverflow.com/questions/37956927/groovy-reference-repeating-nodes-values-in-xml-with-xpath-interpolation-misuse/37958846#37958846 4 | **/ 5 | import groovy.xml.* 6 | import static com.xlson.groovycsv.CsvParser.parseCsv 7 | //closure which builds the request based on the data provided 8 | def requestBuilder = { csvData -> 9 | def builder = new StreamingMarkupBuilder() 10 | builder.encoding = 'UTF-8' 11 | def soapRequest = builder.bind { 12 | mkp.xmlDeclaration() 13 | namespaces << [soap: 'http://schemas.xmlsoap.org/soap/envelope/', 14 | web : 'http://www.webserviceX.NET'] 15 | soap.Envelope { 16 | soap.Header{} 17 | soap.Body { 18 | //loop thru the rows 19 | csvData.each { row -> 20 | //create GetWeather element for each row 21 | web.GetWeather{ 22 | web.CityName(row.CityName) 23 | web.CountryName(row.CountryName) 24 | } 25 | } 26 | } 27 | } 28 | } 29 | } 30 | //Used fixed csv data. But you can replace it with reading from file too 31 | def csv = '''CityName,CountryName 32 | Cairo,Africa 33 | Heidelberg,Germany 34 | Strasbourg,France''' 35 | /** 36 | //use this to read from file and remove above statement 37 | def csv = new File('/absolute/csv/file/path').text 38 | **/ 39 | //parse the csv using groovy csv library 40 | def data = parseCsv(csv) 41 | //call the above closure get the request and serialize it to string 42 | def request = XmlUtil.serialize(requestBuilder(data)) 43 | log.info request 44 | -------------------------------------------------------------------------------- /groovy/xml/builder/GenerateDynamicSoapRequest.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Below script shows how to build xml using MarkupBuiler with easily 3 | * using element names as need by the user 4 | * just like how xml appears 5 | * (as shown in color code;elements, data) 6 | **/ 7 | 8 | import groovy.xml.StreamingMarkupBuilder 9 | import groovy.xml.XmlUtil 10 | 11 | //Define all your namespaces here 12 | def nameSpacesMap = [ 13 | soap: 'http://schemas.xmlsoap.org/soap/envelope/', 14 | ns: 'http://www.domain1.example.com/person', 15 | ns1: 'http://www.domain2.example.com/student', 16 | xsi: 'http://www.w3.org/2001/XMLSchema-instance' 17 | ] 18 | 19 | //For instance, let us assume the data read[record] 20 | //from datasource 21 | def name = 'John' 22 | def age = 20 23 | def type = 'Student' 24 | def education 25 | def adress 26 | 27 | 28 | //How the request can be built. Optionally you can put the 29 | //below code snippet into a function and pass the data 30 | //to it, then retun the request as String like this 31 | /* 32 | * def createRequest(parameter1...parametern){ 33 | * //below code goes here and have below line be the last line of function 34 | * // so that will convert it into String 35 | * return XmlUtil.serialize(soapRequest) 36 | */ 37 | 38 | def builder = new StreamingMarkupBuilder() 39 | builder.encoding ='utf-8' 40 | def soapRequest = builder.bind { 41 | mkp.xmlDeclaration() 42 | namespaces << nameSpacesMap 43 | soap.Envelope { 44 | soap.Body { 45 | //example for element attribute 46 | ns.UserRequest (type:type){ 47 | ns1.name(name) 48 | ns1.age(age) 49 | //add education element irrespective of data 50 | ns1.education(education) 51 | //add address only if there is data 52 | if(!address) { 53 | ns1.address(address) 54 | } 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /groovy/xml/cdata/CdataXpathExists.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * This is script assertion for the soap request test step. 3 | * Extracts CDATA of response first. 4 | * Later checks if the xpath is ok 5 | * refer for more details: http://stackoverflow.com/questions/40959157/how-to-get-a-node-on-soap-uis-test-case-xpath 6 | **/ 7 | //Closure to extract data of given node name 8 | def searchData = { data, element -> 9 | def parsedData = new XmlSlurper().parseText(data) 10 | parsedData.'**'.find {it.name() == element} as String 11 | } 12 | 13 | //Closure to check the xpath 14 | def searchByXpath = {data, xpath -> 15 | def holder = new com.eviware.soapui.support.XmlHolder(data) 16 | holder.getNodeValue(xpath) 17 | } 18 | 19 | //check if the response is non empty 20 | //assert context.response, "Response is empty or null" 21 | def xml = """ 22 | 23 | 24 | 25 | 26 | Belarus 27 | Riga Airport 28 |
29 | 30 | Mauritius 31 | Plaisance Mauritius 32 |
33 | 34 | Mauritius 35 | Rodrigues 36 |
37 | 38 | Cyprus 39 | Ercan 40 |
41 | 42 | Cyprus 43 | Larnaca Airport 44 |
45 | 46 | Cyprus 47 | Athalassa 48 |
49 | 50 | Cyprus 51 | Paphos Airport 52 |
53 | 54 | Cyprus 55 | Akrotiri 56 |
57 | 58 | Austria 59 | Niederosterreich / Lugplatz Vos 60 |
61 | 62 | Austria 63 | Graz-Thalerhof-Flughafen 64 |
65 | 66 | Austria 67 | Innsbruck-Flughafen 68 |
69 | 70 | Austria 71 | Klagenfurt-Flughafen 72 |
73 | 74 | Austria 75 | Linz / Hoersching-Flughafen 76 |
77 | 78 | Austria 79 | Salzburg-Flughafen 80 |
81 | 82 | Austria 83 | Wien / Schwechat-Flughafen 84 |
85 | 86 | Austria 87 | Aigen Im Ennstal 88 |
89 | 90 | Austria 91 | Horsching Aus-Afb 92 |
93 | 94 | Austria 95 | Schwaz Heliport 96 |
97 | 98 | Austria 99 | Tulln 100 |
101 | 102 | Austria 103 | Zeltweg 104 |
105 | 106 | Russian Federation 107 | Jakutsk 108 |
109 | 110 | Russian Federation 111 | Cul'Man 112 |
113 | 114 | Russian Federation 115 | Ekimchan 116 |
117 | 118 | Russian Federation 119 | Habarovsk 120 |
121 | 122 | Russian Federation 123 | Troickoe 124 |
125 | 126 | Russian Federation 127 | Anadyr 128 |
129 | 130 | Russian Federation 131 | Buhta Providenja 132 |
133 | 134 | Russian Federation 135 | Magadan 136 |
137 | 138 | Russian Federation 139 | Petropavlovsk-Kamchatskij 140 |
141 | 142 | Russian Federation 143 | Juzhno-Sahalinsk 144 |
145 | 146 | Russian Federation 147 | Vladivostok 148 |
149 | 150 | Russian Federation 151 | Chita 152 |
153 | 154 | Russian Federation 155 | Irkutsk 156 |
157 | 158 | Russian Federation 159 | Ust'Ordynskij 160 |
161 | 162 | Russian Federation 163 | Bodajbo 164 |
165 | 166 | Russian Federation 167 | Kirensk 168 |
169 | 170 | Russian Federation 171 | Nizhneudinsk 172 |
173 | 174 | Russian Federation 175 | Horinsk 176 |
177 | 178 | Russian Federation 179 | Ulan-Ude 180 |
181 | 182 | Russian Federation 183 | Arhangel'Sk 184 |
185 | 186 | Russian Federation 187 | Kotlas 188 |
189 | 190 | Russian Federation 191 | St. Peterburg 192 |
193 | 194 | Russian Federation 195 | Murmansk 196 |
197 | 198 | Russian Federation 199 | Velikie Luki 200 |
201 | 202 | Russian Federation 203 | Tot'Ma 204 |
205 | 206 | Russian Federation 207 | Vologda 208 |
209 | 210 | Belarus 211 | Vitebsk 212 |
213 | 214 | Belarus 215 | Minsk 216 |
217 | 218 | Russian Federation 219 | Barnaul 220 |
221 | 222 | Russian Federation 223 | Enisejsk 224 |
225 | 226 | Russian Federation 227 | Novosibirsk 228 |
229 | 230 | Russian Federation 231 | Krasnodar 232 |
233 | 234 | Russian Federation 235 | Mineral'Nye Vody 236 |
237 | 238 | Russian Federation 239 | Rostov-Na-Donu 240 |
241 | 242 | Russian Federation 243 | Adler 244 |
245 | 246 | Russian Federation 247 | Elista 248 |
249 | 250 | Russian Federation 251 | Volgograd 252 |
253 | 254 | Russian Federation 255 | Hanty-Mansijsk 256 |
257 | 258 | Russian Federation 259 | Surgut 260 |
261 | 262 | Russian Federation 263 | Ekaterinburg 264 |
265 | 266 | Russian Federation 267 | Brjansk 268 |
269 | 270 | Russian Federation 271 | Moscow / Sheremet'Ye 272 |
273 | 274 | Russian Federation 275 | Tver 276 |
277 | 278 | Russian Federation 279 | Voronez 280 |
281 | 282 | Russian Federation 283 | Moscow / Vnukovo 284 |
285 | 286 | Russian Federation 287 | Ust', Kulom 288 |
289 | 290 | Russian Federation 291 | Syktyvkar 292 |
293 | 294 | Russian Federation 295 | Penza 296 |
297 | 298 | Russian Federation 299 | Samara 300 |
301 | 302 | Brunei Darussalam 303 | Brunei Airport 304 |
305 | 306 | Australia 307 | Archerfield Aerodrome 308 |
309 | 310 | Australia 311 | Amberley Aerodrome 312 |
313 | 314 | Australia 315 | Alice Springs Aerodrome 316 |
317 | 318 | Australia 319 | Brisbane Airport M. O 320 |
321 | 322 | Australia 323 | Coolangatta Airport Aws 324 |
325 | 326 | Australia 327 | Cairns Airport 328 |
329 | 330 | Australia 331 | Charleville Airport 332 |
333 | 334 | Australia 335 | Gladstone 336 |
337 | 338 | Australia 339 | Longreach Airport 340 |
341 | 342 | Australia 343 | Mount Isa Amo 344 |
345 | 346 | Australia 347 | Mackay Mo 348 |
349 | 350 | Australia 351 | Oakey Aerodrome 352 |
353 | 354 | Australia 355 | Proserpine Airport 356 |
357 | 358 | Australia 359 | Rockhampton Airport 360 |
361 | 362 | Australia 363 | Broome Airport 364 |
365 | 366 | Australia 367 | Townsville Amo 368 |
369 | 370 | Australia 371 | Weipa City 372 |
373 | 374 | Australia 375 | Gove Airport 376 |
377 | 378 | Australia 379 | Tennant Creek Airport 380 |
381 | 382 | Australia 383 | Yulara Aws 384 |
385 | 386 | Australia 387 | Albury Airport 388 |
389 | 390 | Australia 391 | Devonport East 392 |
393 | 394 | Australia 395 | Goldstream Aws 396 |
397 | 398 | Australia 399 | East Sale Aerodrome 400 |
401 | 402 | Australia 403 | Hobart Airport 404 |
405 | 406 | Australia 407 | Launceston Airport 408 |
409 | 410 | Australia 411 | Laverton Aerodrome 412 |
413 | 414 | Australia 415 | Moorabbin Airport Aws 416 |
417 | 418 | Australia 419 | Mount Gambier Aerodrome 420 |
421 | 422 | Australia 423 | Mildura Airport 424 |
425 | 426 | Australia 427 | Melbourne Airport 428 |
429 | 430 | Australia 431 | Macquarie Island 432 |
433 | 434 | Australia 435 | Wynyard West 436 |
437 | 438 | Australia 439 | Adelaide Airport 440 |
441 | 442 | Australia 443 | Albany Airport 444 |
445 | 446 | Australia 447 | Broken Hill Patton Street 448 |
449 | 450 | Australia 451 | Ceduna Airport 452 |
453 | 454 | Australia 455 | Derby 456 |
457 | 458 | Australia 459 | Darwin Airport 460 |
461 | 462 | Australia 463 | Bullsbrook Pearce Amo 464 |
465 | 466 | Australia 467 | Edinburgh M. O. 468 |
469 | 470 | Australia 471 | Forrest Airport 472 |
473 | 474 | Australia 475 | Geraldton Airport 476 |
477 | 478 | Australia 479 | Kalgoorlie Boulder Amo 480 |
481 | 482 | Australia 483 | Kununurra Kununurra Aws 484 |
485 | 486 | Australia 487 | Leigh Creek Airport 488 |
489 | 490 | Australia 491 | Learmonth Airport 492 |
493 | 494 | Australia 495 | Meekatharra Airport 496 |
497 | 498 | Australia 499 | Port Hedland Pardoo 500 |
501 | 502 | Australia 503 | Parafield Airport 504 |
505 | 506 | Australia 507 | Belmont Perth Airport 508 |
509 | 510 | Australia 511 | Katherine Aerodrome 512 |
513 | 514 | Australia 515 | Woomera Aerodrome 516 |
517 | 518 | Australia 519 | Bankstown Airport Aws 520 |
521 | 522 | Australia 523 | Canberra 524 |
525 | 526 | Australia 527 | Coffs Harbour Mo 528 |
529 | 530 | Australia 531 | Cooma 532 |
533 | 534 | Australia 535 | Camden Airport 536 |
537 | 538 | Australia 539 | Dubbo 540 |
541 | 542 | Australia 543 | Norfolk Island Airport 544 |
545 | 546 | Australia 547 | Nowra Ran Air Station 548 |
549 | 550 | Australia 551 | Richmond Aus-Afb 552 |
553 | 554 | Australia 555 | Sydney Airport 556 |
557 | 558 | Australia 559 | Tamworth Airport 560 |
561 | 562 | Australia 563 | Wagga Airport 564 |
565 | 566 | Australia 567 | Williamtown Aerodrome 568 |
569 | ]]>
570 |
571 |
572 |
""" 573 | 574 | assert xml, "Response is empty or null" 575 | //Gets the CDATA part of the response 576 | def cdata = searchData(xml, 'GetCitiesByCountryResult') 577 | 578 | //Gets the xpath result 579 | def cityName = 'Rodrigues' 580 | def result = searchByXpath(cdata, "exists(//Table[City = '$cityName'])") 581 | log.info "Is city ${cityName} exist in the table: ${result}" 582 | 583 | //Check the xpath result 584 | assert result, "${cityName} does not exist in the result table" 585 | -------------------------------------------------------------------------------- /groovy/xml/cdata/SaveCdataXmlToCsv.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * http://stackoverflow.com/questions/38032465/how-to-convert-soap-xml-response-to-delimited/38067469#38067469 3 | * this script will read the previous step response 4 | * extract the cdata at the given xpath 5 | * read all the records and transfroms into csv file 6 | **/ 7 | 8 | import com.eviware.soapui.support.XmlHolder 9 | import groovy.xml.* 10 | 11 | /**Define the output file name in test case custom property say OUTPUT_FILE_NAME and value as absolute file path 12 | * otherwise, it write a file chargedata.csv in system temp directory 13 | **/ 14 | def outputFileName = context.testCase.getPropertyValue('OUTPUT_FILE_NAME') ?: System.getProperty("java.io.tmpdir")+ '/chargedata.csv' 15 | 16 | //csv field separator - change it if needed 17 | def delimiter = ',' 18 | 19 | /** 20 | * Below statement will fetch the previous request step response. 21 | */ 22 | def response = context.testCase.testStepList[context.currentStepIndex - 1].testRequest.response.responseContent 23 | 24 | //Create the xml holder object to get the xpath value which cdata in this case 25 | def responseHolder = new XmlHolder(response) 26 | def xpath = '//*:Charges_FileResponse/*:Charges_FileResult' 27 | 28 | //Get the cdata part from above xpath which is a string 29 | def data = responseHolder.getNodeValue(xpath) 30 | 31 | //This again parses the xml inside of cdata 32 | def chargeRecords = new XmlParser().parseText(data) 33 | 34 | //This is going hold all the data from ChargeRecords 35 | def chargeRecordsDataStructure = [] 36 | 37 | //This is to hold all the headers 38 | def headers = [] as Set 39 | 40 | /** 41 | * This is to create Charge data 42 | **/ 43 | def buildChargeDataStructure = { charge -> 44 | def chargeDataStructure = new Expando() 45 | charge.children().each { 46 | def elementName = it.name() 47 | def elementText = it.value().join() 48 | chargeDataStructure[elementName] = elementText 49 | //Add to headers list if not already added 50 | (elementName in headers) ?: headers << elementName 51 | } 52 | chargeDataStructure 53 | } 54 | 55 | /** 56 | * this is to create a csv row in string format 57 | **/ 58 | def createRow = { recordDataStructure -> 59 | def row = new StringBuffer() 60 | headers.each { 61 | if (row) { 62 | row += delimiter + recordDataStructure[it] ?: '' 63 | } else { 64 | row += recordDataStructure[it] ?: '' 65 | } 66 | } 67 | row.toString()+'\n' 68 | } 69 | 70 | //Build the whole data structure of Charge Records 71 | chargeRecords.Charge.each { charge -> 72 | chargeRecordsDataStructure << buildChargeDataStructure( charge ) 73 | } 74 | 75 | //Build the rows 76 | def rows = new StringBuffer() 77 | rows << headers.join(',') +'\n' 78 | chargeRecordsDataStructure.each { rows << createRow (it)} 79 | 80 | //Write the rows into file 81 | new File(outputFileName).text = rows 82 | -------------------------------------------------------------------------------- /groovy/xml/cdata/XmlInsideCdata.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Below script extract the cdata from xml first 3 | * And then extracts name from the first Table 4 | **/ 5 | import com.eviware.soapui.support.XmlHolder 6 | def response = ''' 7 | 8 | 9 | 10 | 11 | uk 12 | United Kingdom 13 |
14 | 15 | uk 16 | United Kingdom 17 |
18 | ]]>
19 |
20 |
21 |
''' 22 | def holder = new XmlHolder(response) 23 | def countryCodeResult = holder.getNodeValue('//*:GetCountryByCountryCodeResult') 24 | log.info countryCodeResult 25 | def cdataHolder = new XmlHolder(countryCodeResult) 26 | def countryName = cdataHolder.getNodeValue("//Table[1]/name") 27 | log.info countryName 28 | -------------------------------------------------------------------------------- /in EST Time Zone Create Current Date and DayBefore YesterDay Time Strings and Then Convert into Milliseconds: -------------------------------------------------------------------------------- 1 | import java.text.SimpleDateFormat; 2 | 3 | TimeZone zone = TimeZone.getTimeZone("EST5EDT"); 4 | SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd"); 5 | df2.setTimeZone(zone); 6 | String daybeforeYesterdayDate=df2.format(new Date()-2); Calcurating 2 days prior data from Curent data 7 | String endDate=df2.format(new Date()); 8 | log.info "daybeforeYesterday Date: "+daybeforeYesterdayDate 9 | String startTime=daybeforeYesterdayDate+" "+"00:10:00" 10 | String endTime=endDate+" "+"23:59:59" 11 | log.info "startTime: $startTime" 12 | log.info "endTime: $endTime" 13 | Long startMillis = (((new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTime).getTime()/1000)+34200)*1000); 14 | Long endMillis = (((new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTime).getTime()/1000)+34200)*1000); 15 | log.info "startMillis : $startMillis" 16 | log.info "endMillis : $endMillis" 17 | 18 | testRunner.testCase.testSuite.project.setPropertyValue("startMillis", startMillis.toString()) 19 | testRunner.testCase.testSuite.project.setPropertyValue("endMillis", endMillis.toString()) 20 | -------------------------------------------------------------------------------- /jsch Sftp Script to connect and Copy File from Remote Server: -------------------------------------------------------------------------------- 1 | //Following Script Copies the file from remote linux machine to local folder 2 | 3 | import java.io.BufferedInputStream; 4 | import java.io.BufferedOutputStream; 5 | import java.io.File; 6 | import java.io.FileOutputStream; 7 | import java.io.OutputStream; 8 | import com.jcraft.jsch.Channel; 9 | import com.jcraft.jsch.ChannelSftp; 10 | import com.jcraft.jsch.JSch; 11 | import com.jcraft.jsch.Session; 12 | 13 | String lyxHostName = testRunner.testCase.testSuite.project.getPropertyValue("lyxHostName"); 14 | String lyxUserName = context.expand( '${#Project#lynxUserName}' ).toString() 15 | String lyxPassword = context.expand( '${#Project#lynxPassword}' ).toString() 16 | String sftpWorkingDir = "/home/$lyxUserName"; 17 | String logsFolderPath=testRunner.testCase.testSuite.getPropertyValue("logsFolderPath").toString() 18 | String logFileName=testRunner.testCase.testSuite.getPropertyValue("logFileName").toString(); 19 | 20 | Session session = null; 21 | Channel channel = null; 22 | ChannelSftp channelSftp = null; 23 | JSch jsch = new JSch(); 24 | session = jsch.getSession(lyxUserName, lyxHostName, 22); 25 | log.info "Connected" 26 | 27 | try { 28 | session.setPassword(lyxPassword); 29 | java.util.Properties config = new java.util.Properties(); 30 | config.put("StrictHostKeyChecking", "no"); 31 | session.setConfig(config); 32 | session.connect(); 33 | channel = session.openChannel("sftp"); 34 | channel.connect(); 35 | channelSftp = (ChannelSftp) channel; 36 | channelSftp.cd(sftpWorkingDir); 37 | byte[] buffer = new byte[1024]; 38 | BufferedInputStream bis = new BufferedInputStream(channelSftp.get(logFileName)); 39 | File newFile = new File(logsFolderPath+logFileName); //this would be C:/LocalLogsDir/logFileName.txt 40 | OutputStream os = new FileOutputStream(newFile); 41 | BufferedOutputStream bos = new BufferedOutputStream(os); 42 | int readCount; 43 | while ((readCount = bis.read(buffer)) > 0) { 44 | log.info("Writing: "); 45 | bos.write(buffer, 0, readCount); 46 | } 47 | bis.close(); 48 | bos.close(); 49 | } catch (Exception ex) { 50 | ex.printStackTrace(); 51 | } 52 | --------------------------------------------------------------------------------