Solution Script to Cleanup of Custom property values in the project
It is noticed that many were looking for a feature where users like to clean the custom property values. This eases to push the actual changes to repository (instead of just property values changes). Here is the context and feature request that was submitted long time ago and many were seeking this feature. https://community.smartbear.com/t5/ReadyAPI-Feature-Requests/Saving-without-property-values/idi-p/154115 Here I came up with a script which does exactly users are asking for. - In order to make the script flexible and dynamic, user need to add a project level property, say CLEAN_PROPERTIES and "false" as default value. - Though users like to clean property values, some might still wish to keep value for certain properties. To accomodate, users can add the property names which they don't want to clean up. Allows properties at test case, suite, and project levels. You don't have to do anything if you want to clean all properties. - The script has to be copied in the "Save Script" tab at the project level (double click project to see the same) - You don't have to run this script manually, this will automatically get triggered when project is saved on a condition that CLEANUP_PROPERTIES value is set true. Once it cleans the properties, the value is set to false to allow users not show the (repository) differences. This condition helps not to lose the property values while work in progress and project is saved. Once user changes to the project are complete and about to check-in the changes in to repositories, set the value to true and save. Now the project is ready the way users wanted. Here goes the script: /** * Project level's Save Script * Cleans up all the custom properties * If CLEAN_PROPERTIES value of project property is set to true * And save the project * */ def ignoreTestCaseProperties = [ ] def ignoreTestSuiteProperties = [ ] def ignoreProjectProperties = ['CLEAN_PROPERTIES'] def cleanProperties = { model, list -> model.properties.keySet().findAll{ !(it in list) } each { tProp -> model.setPropertyValue(tProp,'') } } if ('true' == project.getPropertyValue('CLEAN_PROPERTIES')) { project.testSuiteList.each { tSuite -> cleanProperties(tSuite, ignoreTestSuiteProperties) tSuite.testCaseList.each { tCase -> cleanProperties(tCase, ignoreTestCaseProperties) } } cleanProperties(project, ignoreProjectProperties) project.setPropertyValue('CLEAN_PROPERTIES', 'false') } Hope this is useful.Solved5.8KViews6likes18CommentsAPI Masterminds - How do you use event handlers?
Hi everyone! Most probably, many of you know about the event handlersfunctionality in ReadyAPI. It lets you execute a custom Groovy script when an event occurs. For example, if you want to pre-process a request before it’s sent to the server, you would use the RequestFilter.filterRequest event handler, and if you would like to pre-process a response before it’s displayed in the Response Editor and before it’s verified with assertions, you would use the RequestFilter.afterRequest event. I’ve got a couple of nice examples of the RequestFilter.afterRequest usage. An XML response payload contains a CDATA section. Within this section, you have content that is known to be a well-formed XML and you’d like to apply XML-specific assertions to it. What you can do is tounwrap CDATA with the following code snippet: def response = context.httpResponse.responseContent; response = response.replaceAll("<!\\[CDATA\\[","").replaceAll("]]>",""); context.httpResponse.responseContent = response; A JSON response payload contains a string value that is known to be an escaped JSON string. For this response { "applicationResponse" : "{\"header\":{\"status\":\"OK\"},\"response\":{\"id\": 1,\"date\":\"03-26-2020\"}}" } the code to unescape the value of the "applicationResponse" property can be as follows: import groovy.json.JsonSlurper import groovy.json.JsonOutput def response = context.httpResponse.responseContent try{ def jsonSlurper = new JsonSlurper() def responseObj = jsonSlurper.parseText(response) def applicationResponseVal = responseObj.applicationResponse def applicationResponseValUnescaped = applicationResponseVal.replaceAll("\\\\", ""); responseObj.applicationResponse = jsonSlurper.parseText(applicationResponseValUnescaped) log.info(JsonOutput.toJson(responseObj)) context.httpResponse.responseContent = JsonOutput.toJson(responseObj) } catch (e){ log.info("The response was not modified " + e) } In the above examples, ReadyAPI will try to pre-process every response in your project. If this is not what you need, you can limit the scope of the handler by specifying a target for it. Refer to thisKB articlefor more examples of filters. Questions: Do you use event handlers? Do you use filtering by target? What are the most common scenarios for your testing process?2.7KViews2likes7CommentsReadyAPI: Using automated Authorization from Auth Repository
Hi all (TanyaYatskovskaNastya_Khovrina nmrao ....) I've tried to use Auhtorization OAuth 2.0 to set it in Auth Repository level to be able to use this in a different projects but the automations doesn't seem to work. On Auth Repository I've added a OAuth 2.0 profile. The Get Access Token has an OAuth 2 Flow = Client Credentials Grant. Client identification and client secret are filled in, Access Token URL is pointing to our access token URL. When I click the 'Get Access Token" the token is generated successfully. I've saved this. I've created 2 environments (TA and INT) that I initiated with Authorization Profile AdminV2.0 as per created on Auth Repository. The environments are set on 'Inherit from parent' automatically when I select my profile. But, when I close ReadyAPI at evening and re-open in the morning I notice that I've lost the token value as it only substains for 3000sec. Not a problem, though I would like to automate it to check on startup that the token is still valid. So In the documentation on SmartBear I saw the automation code for webbased authentication. My URL is not really a webpage. I get response from our server by forward proxy in the form of a webpage. It's just a page with data. But the only 'login' that is necessary is not a password and login name but the token generated at Auth Report level. Does someone know how to write that script that I can put in the [ Auth Repository > Profile created > Automation scripts ] ? Or isn't that the way to automate the token to use in all projects? Thanks in advance for reading this, I hope I was a little clear... Cheers, AABSolved3.5KViews0likes5CommentsHow to write a reusable script Library
I've found the need to define a common Library of reusable Groovy Scripts for use with SOAPUI community edition, there isn't a tutorial or established examples on how this can be achieved so here is an example of how I did this. 1) Define a new TestSuite in the root of your project called Library. 2) Disable the Library TestSuite so that it doesn't get run in an uncontrolled manner. 3) Define a TestCase under Library, I name this after the module-name. 4) Define a Groovy Script, I give this the name of the Groovy Class that is going to contain my reusable code. class Example { def log def context def testRunner // Class constructor with same case as Class name def Example(logIn,contextIn,testRunnerIn) { this.log = logIn this.context = contextIn this.testRunner = testRunnerIn } } 5) Add the reusable code as method, pass parameters as necessary. def execute(message) { // do some stuff to prove I've run with right context, etc. log.info testRunner log.info context log.info "return "+message return message } 6) We need to instance of the class; add the following to the end of the Script, outside the class definition. This will place the instance in the project's context. context.setProperty( "example", new Example( log, context, testRunner) ) log.info "Library Context:"+context 7) You can now reuse the instance in any Groovy Script, with the following Groovy code. // get a reference to the library TestSuite library = testRunner.testCase.testSuite.project.testSuites["Library"] // find the module within the library module = library.testCases["module-name"].testSteps["Example"] // initialise the library; which places an instance of Example in the context module.run(testRunner, context) // get the instance of example from the context. def example = context.example // run the method, with parameter log.info "example.execute() = " + example.execute("Tester") 😎 Add more modules, classes or methods as necessary. 9) The instance can be added to the Global context if you want to use it across SOAPUI projects.47KViews5likes30CommentsGroovy Script to identify a file timestamp
Just sharing this groovy script I am using to disable a "DataCollection" step based on a filetime stamp. Use case: Identify when datasource file is modified If datasource file is already generated then skip/disable datacollection step which in the end writes data to datasource file why to disable - if you want to run the same API tests (but different versions say due to refactoring) against same dataset Below is the sample test case structure DataSource check script is shown below import com.eviware.soapui.support.GroovyUtils import java.text.DateFormat import java.text.SimpleDateFormat //## Get test step name // def currentStepInd = context.currentStepIndex def TestStepName = testRunner.testCase.getTestStepAt(currentStepInd).name log.info "------------------------------------------------" log.info "Running $TestStepName..." //## Get current Date ##// def CurrentDate = new Date() log.info "Current Date is $CurrentDate..." // Get datasource file // def DataSourceFile = context.expand('${projectDir}') + "\\DataSource.txt" File DataFile = new File(DataSourceFile) log.info "DataSource File is: $DataFile" def fileDate if (DataFile.exists()) { // Get the last modification information. Long lastModified = DataFile.lastModified() // Create a new date object and pass last modified fileDate = new Date(lastModified) //fileDate = sdf.format(fileDate) log.info "File modified time is: $fileDate" } //## To find Date Diff ##// def diff use(groovy.time.TimeCategory) { diff = (CurrentDate - fileDate).days } //## Skip DataCollection if DataSource is older than today ##// if(diff == 0) { //## disable teststep to skip data collection ##// log.info "Disabling testStep DataCollection..." testRunner.testCase.getTestStepByName( "DataCollection" ).setDisabled(true) }else{ //## enable teststep to run data collection ##// log.info "Enabling testStep DataCollection..." testRunner.testCase.getTestStepByName( "DataCollection" ).setDisabled(false) } log.info "Finished $TestStepName..." log.info "------------------------------------------------" thanks!4.8KViews4likes1CommentHow to get cookies in Groovy scripts?
Hi Community, Let meshare an answer to the above question with you 🙂 If theSession optionis enabled, ReadyAPI maintains the HTTP session on the TestCase level automatically, which means that it storescookiesreceived from the server and sends them back in the subsequent requests to the same endpoint. If you need to get programmatic access to the stored cookies, you can use this Groovy script (it's applicable to ReadyAPI v.1.7.0 and later): import org.apache.http.protocol.HttpContext import com.eviware.soapui.model.iface.SubmitContext import org.apache.http.impl.client.BasicCookieStore import org.apache.http.client.protocol.HttpClientContext HttpContext httpContext = context.getProperty(SubmitContext.HTTP_STATE_PROPERTY) BasicCookieStore cookieStore = httpContext.getAttribute(HttpClientContext.COOKIE_STORE) //iterate through the cookies store and output the name-value pairs to the log cookieStore.getCookies().each{ log.info(it.name + "=" + it.value) } Example:3.7KViews7likes0CommentsTesting approach Business logic - Scenarios as TCs in Excel Use Groovy to run these TCs
I think Ihave read some very inspiring threads and that gave a motivation to reflect on how I ave changed the testing approach where I work So before I came: We had throusands of tests cases and guess what, only thing or things would a very params in the requets So I said this is bloody in efficient and not cool! I have strong dev background in java and already used apache POI in my previous life to create excel spreadsheets. So here is what I did: I have all my test data which is referenced by test case ID I am basically using groovy to read from this spreadsheet and run the templated test step. Properties in excel are mapped on to test suite properties and these properities are expanded onto the requests. So before it would take days to do TCs. Now it takes minutes Rest of of time is spent hitting the gym or having a coffeee lol Not really Now they got me doing other stuff. for eg now I ma interested in service virtualization. But the point is spent time up front and do things right! Here is example of groovy code I use (added here from the reply below by a moderator) // Declare content to be tested import com.google.common.html.HtmlEscapers import com.soapuitests.* def tempExelParser = new ExcelParser() String path = "U:\\git\\ens-automated-tests\\odm-content.xls" String excelSheet = "test-24hr" tempExelParser.readXLSFile(path,false,excelSheet) String key = "test-PNR" String value = "test-yyc-cashlessjun" def tempMap = tempExelParser.getData(key,value) log.info("starting tests: ${value} ----------------") log.info("data map : ${tempMap}") //def contentMap = tempMap // initialize props with blanlk values // now set with new values form excel // set test case content def prop = testRunner.testCase.testSuite.propertyList log.info("value : ${prop}") def propArr = testRunner.testCase.testSuite.getProperties() for ( item in propArr ) { testRunner.testCase.testSuite.setPropertyValue(item.key, "") log.info("value : ${item.key} ${item.value}") } for ( item in tempMap) { testRunner.testCase.testSuite.setPropertyValue(item.key, item.value) log.info("value : ${item.key} ${item.value}") } // run test case def project = testRunner.testCase.testSuite.project def testsuite= testRunner.testCase.testSuite tc = testsuite.getTestCaseByName("Templates") def testStep = tc.testSteps['24hr Test Template'] //def testStep = testRunner.testCase.testSteps['24HRRequestTest'] def status = testRunner.status log.info("status : ${status}") def result= testStep.run(testRunner,context).getStatus().toString() log.info("test case result : ${result}") // get response def currentTestStep = context.testCase.getTestStepAt(context.currentStepIndex) String propertySpec = '${' + testStep.name + '#Response}' assert result == "OK" : testStep.name + " ${value} Failed" log.info("ending tests: ${value} ----------------")2KViews1like4CommentsAPI Masterminds - How do you reuse your ReadyAPI Groovy scripts?
How are you doing, API testers? If you do a lot of Groovy scripting in ReadyAPI, you might have already come to a need to use the same scripts in different tests and projects. Instead of copying over the same code snippets again and again, you, of course, thought about a way to have them all in one place from where you could easily access them from other scripts. The ways to achieve this are: Create custom Groovy classes, embed your reusable Groovy scripts into their methods, save them as separate files with the .groovy extension and voila - your Script Library is ready. You just need to point ReadyAPI where to find it (Preferences>ReadyAPI > Script library). If you change anything in those external classes, ReadyAPI will detect this and reload the classes automatically. Convert your Groovy code to Java code and embed it into methods of Java classes. Once the classes are compiled and packed into a .jar file, you can point to it from ReadyAPI (Preferences>ReadyAPI > Custom Java libraries) and start calling your Java methods right from your Groovy scripts. Making changes in Java classes is more time-consuming than in Groovy classes as you need to re-compile them, but you may find it more convenient to share them with your co-workers when it’s just a single .jar file. Questions: Do you use script libraries or custom Java libraries to reuse parts of your ReadyAPI scripts? And if so, what tasks are your reusable scripts for?2.9KViews2likes4CommentsHow to generate a random Number, String, AlphaNumeric string
This below function will generate random Number, String, alphaNumeric string as what you pass in parameters. Refer below code and help yourself in generating random numbers def num = generateRndString(10, "numeric"); log.info num def str = generateRndString(10, "string"); log.info str def alphaNum = generateRndString(10, "alphanumeric"); log.info alphaNum testRunner.testCase.getTestStepByName("Properties").setPropertyValue("RndNum", num) testRunner.testCase.getTestStepByName("Properties").setPropertyValue("RndString", str) testRunner.testCase.getTestStepByName("Properties").setPropertyValue("RndAlpha", alphaNum) def generateRndString(int num, String type){ def randValue = ""; if( type.equalsIgnoreCase("numeric") ){ def alphaNumeric = ('0'..'9').join() randValue = RandomStringUtils.random(num, alphaNumeric) while (randValue.size()!=num) { randValue = RandomStringUtils.random(num, alphaNumeric) } } else if( type.equalsIgnoreCase("string") ){ def alphaNumeric = (('a'..'z')+('A'..'Z')).join() randValue = RandomStringUtils.random(num, alphaNumeric) while (randValue.size()!=num) { randValue = RandomStringUtils.random(num, alphaNumeric) } } else if( type.equalsIgnoreCase("alphanumeric") ){ def alphaNumeric = (('0'..'9')+('a'..'z')+('A'..'Z')).join() randValue = RandomStringUtils.random(num, alphaNumeric) while (randValue.size()!=num) { randValue = RandomStringUtils.random(num, alphaNumeric) } } return randValue }2.8KViews1like2CommentsScript challenge for Groovy DataSource - API Summer 2018
HiOlga_T I have developed a code for Groovy DataSource, hope this will meets the need of Question. import jxl.* def groovyUtils1 = new com.eviware.soapui.support.GroovyUtils(context) def projectPath = groovyUtils1.projectPath projectPath = projectPath.replace("\\","/") def dataFile = projectPath + "/DataFile.xls" def f = new File(dataFile) def wk = Workbook.getWorkbook(f) def s1 = wk.getSheet(0) def rows = s1.getRows() def cols = s1.getColumns() def flag = 0 for(def i=1;i<rows;i++) { for(def j=0;j<cols;j++) { //For placing null for(def k = 0; k < 5; k++) { //Get Header Row Column Cell def c1 = s1.getCell(k, 0) //Get Value Row Column Cell def c2 = s1.getCell(k, i) testRunner.testCase.getTestStepByName("Properties").setPropertyValue(c1.getContents().toString(), "null") } //for placing value in front on particular iteration if(flag == j) { def c3 = s1.getCell(j, 0) def c4 = s1.getCell(j, 1) testRunner.testCase.getTestStepByName("Properties").setPropertyValue(c3.getContents().toString(),c4.getContents().toString()) } flag = flag + 1 } testRunner.testCase.getTestStepByName("Properties").setPropertyValue("Counter",i.toString()) } Do Like and Accept if you find it as Solution. Thanks, Himanshu Tayal1.7KViews1like2Comments