ContributionsMost RecentMost LikesSolutionsCannot set Project Script Library for composite projects Hello, I had a look at this casebut the resolution is not applicable. First I had a project in single-file format stored under "C:\ReadyAPI\flowTester\flowTester-project.xml" The project property "Script Library" contains "${projectDir}\scripts" which translates into "C:\ReadyAPI\flowTester\scripts". The "C:\ReadyAPI\flowTester\scripts" directory contains the groovy code used by the project groovy test steps. Everything was nice. I could give my colleagues the content of "C:\ReadyAPI\flowTester\" and they were happy. Now, we want to take advantage of Git and ReadyAPI transformed the project into a composite one. The composite project (directory) path is then"C:\ReadyAPI\flowTester\flowTester-project" The things stored in Git should contain everything needed for the project to run. Hence, I would need to move the "script" directory under the "C:\ReadyAPI\flowTester\flowTester-project\" containing the composite files. The problem is that "${projectDir}\scripts" translates into "C:\ReadyAPI\flowTester\scripts" and not "C:\ReadyAPI\flowTester\flowTester-project\scripts". I tried setting "Script Library" to${=context.testCase.getTestSuite().getProject().getPath() + '\\scripts'} The problem is that context.testCase does not exists and the ReadyAPI log shows: Tue Jan 24 13:45:10 CET 2023: ERROR: Error evaluating script java.lang.NullPointerException: Cannot invoke method getTestSuite() on null object at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:44) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:34) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:53) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130) at Script4.run(Script4.groovy:1) at com.eviware.soapui.support.scripting.groovy.SoapUIGroovyScriptEngine.runAndGetResult(SoapUIGroovyScriptEngine.java:111) at com.eviware.soapui.support.scripting.groovy.SoapUIGroovyScriptEngine.run(SoapUIGroovyScriptEngine.java:97) at com.eviware.soapui.support.scripting.groovy.SoapUIProGroovyScriptEngineFactory$SoapUIProGroovyScriptEngine.run(SoapUIProGroovyScriptEngineFactory.java:98) at com.eviware.soapui.model.propertyexpansion.resolvers.EvalPropertyResolver.doEval(EvalPropertyResolver.java:161) at com.eviware.soapui.model.propertyexpansion.resolvers.EvalPropertyResolver.resolveProperty(EvalPropertyResolver.java:149) at com.eviware.soapui.model.propertyexpansion.PropertyExpander.expand(PropertyExpander.java:213) at com.eviware.soapui.model.propertyexpansion.PropertyExpander.expand(PropertyExpander.java:156) at com.eviware.soapui.model.propertyexpansion.PropertyExpander.expand(PropertyExpander.java:152) at com.eviware.soapui.model.propertyexpansion.PropertyExpander.expand(PropertyExpander.java:148) at com.eviware.soapui.model.propertyexpansion.PropertyExpander.expand(PropertyExpander.java:257) at com.eviware.soapui.model.propertyexpansion.PropertyExpander.expandProperties(PropertyExpander.java:261) at com.eviware.soapui.support.scripting.groovy.SoapUIProGroovyScriptEngineFactory$SoapUIProProjectGroovyClassLoader.getScriptsFolder(SoapUIProGroovyScriptEngineFactory.java:154) at com.eviware.soapui.support.scripting.groovy.SoapUIGroovyClassLoader.syncExternalClasses(SoapUIGroovyClassLoader.java:80) at com.eviware.soapui.support.scripting.groovy.SoapUIGroovyClassLoader.run(SoapUIGroovyClassLoader.java:67) at java.base/java.lang.Thread.run(Thread.java:833) So... How can I get the project FULL path to use it to set the the Script Library for Composite Projects ? Thank you in advance, Pierre Re: Property Expansion Dynamic Expression issue with brace character. Hello sonya_m, Thank you for looking into this case. nmrao has been kind enough to look at my post but I'm afraid he did not address the question raised in the first place. I know that the braces are the problem. This the the aim of my question: how to quote them ? If the cannot be quoted, how can I do in property expansion something without braces that would do this: ${= use (groovy.time.TimeCategory) {2.years.from.now.format('yyyy-MM-dd')}} I went through the documentations and the forum already but this did not raise a solution. ReadyAPI accepts groovy code as written in the documentation you refer to:${=Groovy code} Isn't braces valid Groovy code ? Thanks, Pierre Re: Property Expansion Dynamic Expression issue with brace character. Thank you for replying. What other detail do you need on top of the ${} bloc used for the property definition, provided in my initial question ? I'm specifically asking how to escape brace or any work-around to achieve the same as per my groovy oneliner: Well. I understand that I cannot use braces but then how can I achieve my goal ? Isn't there a way to escape the braces ? Property Expansion Dynamic Expression issue with brace character. Here is my Property Dynamic Expression: ${= use (groovy.time.TimeCategory) {2.years.from.now.format('yyyy-MM-dd')}} Upon evaluation, this trows this error: startup failed: Script47.groovy: 1: expecting '}', found '' @ line 1, column 71. .from.now.format('yyyy-MM-dd') ^ org.codehaus.groovy.syntax.SyntaxException: expecting '}', found '' @ line 1, column 71. at org.codehaus.groovy.antlr.AntlrParserPlugin.transformCSTIntoAST(AntlrParserPlugin.java:143) Well. I understand that I cannot use braces but then how can I achieve my goal ? Isn't there a way to escape the braces ? Thank you. Pierre SolvedRe: Project Custom Properties and Environments Custom Properties Yes. Sure I know the Global Properties. I still think one should have Project Global Properties:smileyhappy: Or a boolean that would set a Project Properties "instanciated per environment" or "always equal in all environments". Re: How can I trap Oracle errors in script assertion Hello, I run into the same problem. My JDBC Test Step does query a table that obviously does not exist in the database. I have a "JDBC Status" assertion but it is not evaluated and the Test Case does not turn RED. The only place I can see things went wrong is when I open the log pane at the bottom of ReadyAPI. How can I add an assertion that checks that the query could be run ? What is the aim of the "JDBC Status" if this does not cover such case ? Thanks in advance for your help. Pierre Re: Project Custom Properties and Environments Custom Properties Thank you for the script. I still think that one should have a way to define a project property that is global to all environments. Re: WSS Config Signature - BSP Compliant option enabled upon ReadyAPI restart Here is the answer from SmartBear support: SmartBear Supportwrote: We have an internal defect for this issue of RIA-7944. Until this is fixed you can try the workaround of changing any of the other options' drop-down lists (e.g. Key Identifier Type, Signature Algorithm, etc.), unchecking the bsp compliant option, and then it will be saved when restarting ReadyAPI when you save your project. I confirm this is a working work-around. WSS Config Signature - BSP Compliant option enabled upon ReadyAPI restart For some web services, we must make sure that in the WSS Configuration the WSS Signature entry has the BSP Compliant unchecked (I mean unchecking the "Enable Basic Security Profile compliancy). The problem is that for a reason we do not understand, this option is enabled as soon as we restart ReadyAPI. This is quite blocking for us as this really block some regression testing processes. Can you please correct this ? Thanks, Pierre SolvedRe: Get current TestStep.operation from a DataGen property of type script. Well... Yes and no. But first : A big thank you to@msiadakfor his time spent on trying to understand my case and propose something. I will try to explain my challenge. My TestSuite has a property "dossier" that may be empty or set by the user of my TestSuite. The TestCase has: One TestStep Soap Operation : operation1 One TestStep Soap Operation : operation2 ... Each soap operation has an xml node <dossier></dossier> I wanted my user to be able to define somehow a specific dossier for each operation, without modifying the operation itself. This dossier node should be set to : if a specific dossier is somehow declared for this operation then set the dossier to this specific dossier in the operation xml else if the user set a global dossier in the TestSuite "dossier" property then set the dossier to this global dossier in the operation xml else if a specific dossier is specified somehow for that soap operation (by soap.operation, I mean something like testStep.operation.name ???) then set the dossier to this operation specific dossier in the operation xml else if a default dossier exists for that soap operation then set the dossier to this default operation dossier in the operation xml elseset the dossier to this default dossier in the operation xml Still with me ;-) Well. The solution proposed bygroovyguy did not help me because the Groovy script is executed from the script part of a DataGen Test Step. I always got as "TestStep name" the name of the DataGen test step although the variable substitution was made in my test step "operation1". I then tried another route, mainly because this project will be used as a template and I can't afford having to correct my future Groovy bugs in plenty DataGen Test Step duplicates. My current route is to implement this in an external Groovy Library. Here below is a dump of what I tried so far, hoping this may save some hours to others: Open ReadyAPI preferences Go to the ReadyAPI section Set the Script library path. eg:C:\Program Files\SmartBear\ReadyAPI-2.7.0\bin\scripts Note: Be careful that this path will not change when upgrading to ReadyAPI-2.8 (which made me loose some time after the upgrade from 2.6). Best is therefore to store this somewhere else. At the really bottom of the main ReadyAPI window, click the "Show Logs" (This took me some time scratching my head trying to understand how to debug my "compilation errors"). ReadyAPI Log tab will show you whenever your Groovy script is reloaded and any error if any upon execution of your classes. The Script Log is displaying output of log.info calls, which may be useful for debugging purposes ;-) In the directory specified in the settings, create a directory with your package name. Example:C:\Program Files\SmartBear\ReadyAPI-2.7.0\bin\scripts\mypackage In that package directory, create a text file and give it the name of your Class. Example:C:\Program Files\SmartBear\ReadyAPI-2.7.0\bin\scripts\mypackage\MyClass.groovy Note: At this moment, the ReadyAPI Log tab will show that the file was detected and loaded. This will happen every time you save changes into the file so changes are taken into account within seconds. In thi MyClass.groovy file, add some code that will return "hello world!" string. Note: I'm totally newbie in Java/Groovy so everything here is probably bad. Feedback is welcome. package mypackage class MyClass { def static hello() { return "hello world!" } } In my Soap Test Step request, I can now write <dossier>${=mypackage.MyClass.hello()}</dossier> This will be dynamically be changed upon execution to <dossier>hello world!</dossier> Now, my next steps will be to implement the logic to access the TestSuite property "dossier". I plan to have a TestStep of type "Properties" containing: dossier for operation1 dossier for operation2 ... This Properties TestStep could be autogenerated by the TestCase setup script amongst other things. To be able to read the TestCase property related to the current TestStep name (or better based on the real soap operation name), I still had to determine programmatically the Current TestStep name... I was therefore back to the beginning ;-) I found that I can access to the current TestStep context by passing the context object when calling my class method. Same goes to be able to log messages, one need to pass the log object. Here is an example: package mypackage import com.eviware.soapui.SoapUI class MyClass { def static getCurrentStepName(log, context) { String currentStepName = context.getCurrentStep().getLabel() log.info(currentStepName) return(currentStepName) } } To fill my dossier with the current TestStep name, I can call: <dossier>${=mypackage.MyClass.getCurrentStepName(log,context)}</dossier> Well. This is far from finished but I wanted to give some feedback togroovyguy I will be 2 weeks off starting in a few minutes and it was better to have a dump of what I found before going on holidays anyhow ;-) Here are a few links that helped me a lot : https://support.smartbear.com/readyapi/docs/testing/scripts/library.html https://support.smartbear.com/readyapi/docs/configure/logs.html https://community.smartbear.com/t5/SoapUI-Pro/How-to-run-SoapUI-API-commands-in-an-external-script/td-p/143098 https://stackoverflow.com/questions/43254590/how-to-place-the-groovy-in-centralized-groovy-library-and-access-that-class-from/43269724#43269724 http://www.ou-ryperd.net/soapui.html https://www.soapui.org/extension-plugins/old-style-extensions/developing-old-style-extensions.html