| myVar=method1 | arg1 | arg2 | | returnValue |
….
….
or You can use a variable “params” in a test table like this to store the SUT (System Under Test, which is a HashMap here) itself:
!| Generic Fixture | params=java.util.HashMap |
| put | curr_id | 128 |
| size | | 1 |
| toString | |
and later to use this variable myVar in an argument list use this syntax:
| method2 | myVar= | arg2 | | returnValue |
….
or to use this variable myVar in return value use this syntax:
| method3 | arg1 | | myVar= |
….
or You can even use this variable myVar to instantiate a new class, use this syntax:
!| Generic Fixture | myClass | myVar= |
….
Or you can even use this variable myVar in a new table as SUT WITHOUT a new instantiation. In this case GenericFixture starts a new test table with the class type derived from the type of the variable itself. After that you are free to call all the available methods in the class type of myVar. Use this syntax:
!| Generic Fixture | myVar= |
….
myVar=method call will store method’s return value in variable named “myVar”. And subsequent myVar= will populate the stored value.There is a special variable named “this”, that will mean assigning a new value to the System Under Test (SUT) object itself.Variables in Generic Fixture can store any Java object or primitive type, that included arrays also. To re-use the varialbe “params” we used above for storing HashMap in a new table just write this:
!| Generic Fixture | params= |
| size | | 1 |
| toString | |
Now lets take a look at another example:
!| Generic Fixture | Address | 123 | Nutley Street | New York | 21019 | NY | | getStreetNo | | 123 | | getCity | | New York | | state=getState | | NY | | getFullAddress | | 123 Nutley Street, New York, NY - 21019 | | setStreetNo | 111 | | setPostcode | 20133 | | getPostcode | | 20133 | | getStreetNo | | 111 | | getState | | state= | | setName | John Smith | | name=getName | | John Smith | !| Generic Fixture | Address$Name | name= | | getSurname | | Smith | | getFirstname | | John | | toString | | John Smith | !| Generic Fixture | name= | | getSurname | | Smith | | getFirstname | | John | | toString | | John Smith |
Here first I am storing return value of getState() (String type) in a variable “state” and later using state to compare return value of getState in the test.
We are also using another variable called “name” to store return value of getName() which is of Address$Name type. We are using variable “name” in the constructor of a new new table that operates on Address$Name class. And in the 3rd table we are once again using variable “name” without instantiating a new class by marking variable “name” as SUT.
These examples show how variables can be used to store all standard Java as well as user defined objects.
Code for class Address and inner Address$Name is attached here for reference:
Source Code Address.java
public class Address {
public static class Name {
private String surname = null;
private String firstname = null;
public Name() {
}
public Name(Name n) {
this.surname = n.surname;
this.firstname = n.firstname;
}
public static Object parse(String s) {
Name n = new Name();
String[] arr = s.split(" ");
if (arr.length == 2) {
n.setFirstname(arr[0]);
n.setSurname(arr[1]);
}
return n;
}
@Override
public String toString() {
return this.firstname + " " + this.surname;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
}
private int streetNo = 0;
private String street = null;
private String city = null;
private int postcode = 0;
private String state = null;
private Name name = null;
public Address() {
super();
}
public Address(Integer streetNo, String street, String city, int postcode,
String state) {
super();
setAddress(streetNo, street, city, postcode, state);
}
public void setAddress(Integer streetNo, String street, String city,
int postcode, String state) {
this.streetNo = streetNo.intValue();
this.street = street;
this.city = city;
this.postcode = postcode;
this.state = state;
}
public void setStreetNo(Integer streetNo) {
this.streetNo = streetNo;
}
public Integer getStreetNo() {
return this.streetNo;
}
public String getStreet() {
return this.street;
}
public void setCity(String city) {
this.city = city;
}
public String getCity() {
return this.city;
}
public void setPostcode(int postcode) {
this.postcode = postcode;
}
public int getPostcode() {
return this.postcode;
}
public String getFullAddress() {
return this.streetNo + " " + this.street + ", " + this.city + ", "
+ this.state + " - " + this.postcode;
}
public void setStreet(String street) {
this.street = street;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Name getName() {
return name;
}
public void setName(Name name) {
this.name = name;
}
}
How to input Array parameter: Simply start the value with array: suffix and use delimiter comma ‘,’ to separate out items in array. For example array:G,e,n,e,r,i,c,F,i,x,t,u,r,e means an array of characters or array:1,4,9,16,25 means an array of integers.
Let’s take a look at another example where simple type, this type and array type variables are being used.
!| Generic Fixture | java.lang.String | It's a cool fixture | | toString | | | i=indexOf | cool | | 7 | | this=concat | ; indeed | | It's a cool fixture; indeed | | equals | It's a cool fixture; indeed | | true | | equalsIgnoreCase | blank | | false | | str=concat | blank | | It's a cool fixture; indeed | | equals | str= | | true | | matches | ^.*cool fix.*$ | | true | | indexOf | cool | | i= | | arr=toCharArray | | | concat | !!! | | It's a cool fixture; indeed !!! | !| Generic Fixture | java.lang.String | arr= | | toString | | str= | | toCharArray | | arr= | !| Generic Fixture | java.lang.String | str= | | toString | | str= | | toCharArray | | arr= | !| Generic Fixture | java.lang.String | array:G,e,n,e,r,i,c,F,i,x,t,u,r,e | | toString | | GenericFixture | | toCharArray | | G,e,n,e,r,i,c,F,i,x,t,u,r,e | !| Generic Fixture | java.lang.Math | | abs | i= | | 7 |
You can see how I am using this to overwrite the value of the object itself on which all the methods are being executed. Execution of above test will produce below result. Note how actual value of a variable is appended in the result. Also note the use of array type variable “arr” in various operations.
UPDATE:
Added support of in-table variable.method() invocation. eg: if you already have a return value stored in a variable called “myvar” then calling a method foo() on myvar is now allowed in the same test table. Just use following syntax:
| myvar=.foo | arg1 | arg2 | | ret |
Take a look at this example:
!| Generic Fixture | java.lang.String | It's a cool fixture | | toString | | | i=indexOf | cool | | 7 | | this=concat | ; indeed | | It's a cool fixture; indeed | | equals | It's a cool fixture; indeed | | true | | equalsIgnoreCase | blank | | false | | str=concat | blank | | It's a cool fixture; indeed | | equals | str= | | true | | str=.substring | 21 | | indeed | | matches | ^.*cool fix.*$ | | true | | indexOf | cool | | i= | | arr=toCharArray | | | concat | !- !!!-! | | It's a cool fixture; indeed !!! | | substring | 3 | | | str=.toCharArray | | arr= |
Note how this test table is using variable “str” to store original string and then calling methods directly on variable “str” using str=.substring and str=.toCharArray calls. You can even do substr=str=.substring to create another variable “substr” to store return value of str=.substring call.
[...] Next Part: Use of variables, arrays and complex types in Generic Fixture [...]
Hello,
Using Generic Fixture, DSL and Selenium, we are trying to implement this:
| check that the field | username | contains value | user1 | |true|
Is there a way to do that?
We could only find a workaround, however it involves 2 calls, which breaks somehow the ‘friendliness’ of the DSL:
!| Generic Fixture | ${sel} |
|strVal=get value from field| username| |
!| Generic Fixture | java.lang.String | strVal=|
| equals | user1 | | true |
Thanks in advance.
Hi Aristotelis,
First please download latest genericfixture.jar from this link:
http://sourceforge.net/projects/genericfixture/files/genericfixture/genericfixture.jar/download
Now I will straight go to an example to answer your question:
Here is the DSL for your interest.
!| DSL Adapter || check if | % | contains | % | {1}.contains | {2} |
| check if | % | matches | % | java.util.regex.Pattern.matches | ^.*{2}.*$,{1} |
And here is a simple Selenium script.
!| Generic Fixture | selenium= || user opens the URL | http://anubhava.wordpress.com |
| mystr=page has the title | |
| check if | mystr= | contains | Anubhava | | true |
| check if | mystr= | matches | Anubhava | | true |
I just showed you 2 ways to get your DSL working using
1) java.lang.String.contains method and
2) java.util.regex.Pattern.matches method.
Both calls will return true. But I will suggest use the 1st one since it directly operate on the object type of variable mystr which is java.lang.String.
cheers,
Anubhava
Dear Anubhava,
Thank you for your answer.
We get an error trying to apply it (using the latest jar):
DSL:
!| DSL Adapter |
| check if | % | contains | % | {1}.contains | {2} |
Test 1:
!| Generic Fixture | ${sel} |
| check if | The name of the rose | contains | rose | | true |
java.lang.ClassNotFoundException: The name of the rose
Test 2:
| check if | reasonsList= | contains | REASON_TWO | | true |
java.lang.NoSuchMethodException: Method [java.lang.String[].contains()] could not be found matching given parameters
What are we doing wrong?
The ‘match’ works great.
Thanks.
Hi Aristotelis,
Looking at the error you are getting it seems you are trying to check if a given array contains an element (Error ‘Method [java.lang.String[].contains()] could not be found’ indicates it clearly) rather than checking if a given String contains a token. Please understand these are two different checks.
Now to solve your issue I have 2 solutions. First download genericfixture.jar one more time from the link above.
Jumping to examples straightway again
Here is the DSL you can use:
!| DSL Adapter || check if | % | matches | % | java.util.regex.Pattern.matches | ^.*{2}.*$,{1} |
| check if | % | contains | % | {1}.contains | {2} |
| check if list | % | contains | % | java.util.Arrays.binarySearch | {1},{2} |
| check if array | % | contains | % | GenericFixture.arrayHasElement | {1},{2} |
And here is a simple Selenium script.
!| Generic Fixture | selenium= || user opens the URL | http://anubhava.wordpress.com |
| mystr=page has the title | |
| check if | mystr= | contains | Anubhava | | true |
| check if | mystr= | matches | Anubhava | | true |
...
...
| check if list | reasonsList= | contains | REASON_TWO | |
| check if array | reasonsList= | contains | REASON_TWO | | true |
1st call will return a number >=0 if REASON_TWO is found in array reasonsList=. 2nd call will return true in that case. I will suggest use the 2nd one since it returns true/false which is easier to assert.
Hope that helps.
cheers,
Anubhava
Hi Anubhava,
Thanks again for your help.
We seem to have a difficulty in understanding how to use the variables… Shouldn’t the following work?
!| DSL Adapter |
| user clicks on Edit button of message with id | % | click | //input[@id=concat('btn_edit_' \, {1} )] |
!| Generic Fixture | ${sel} |
| ofsmsg1=get value from field | someTextField | | 123456 |
| user clicks on Edit button of message with id | ofsmsg1= |
However, the click gives the following error:
com.thoughtworks.selenium.SeleniumException: ERROR: Invalid xpath [2]: //input[@id=concat('btn_edit_', ofsmsg1= )]
It seems that the variable ‘ofsmsg1=’ does not get interpreted/substituted. Shouldn’t it?
Dear Aristotelis,
Thanks for writing to me. In your DSL you are trying to combine 2 methods in 1 call (String.concat() and Selenium.click()). This is not yet supported in DSL. Though I am going to release this feature in the next version.
For now to fulfill your requirement I had to make a small change in the code. Please download the latest genericfixture.jar file from the link above.
Then write your DSL script like this (note no call to String.concat is needed):
!| DSL Adapter || user clicks on Edit button of message with id | % | click | //input[@id=btn_edit_{1}] |
Your Selenium script is fine as is.
Cheers,
Anubhava
Hi Anubhava,
We have another smal problem that we are not able to find a way around.
We want to include in the javascript passed a logical OR operator (||) but unfortunately Generic Fixture (or Fitnesse) interprets it wrongly…
We tried escaping it (using both \|\| and !-||-!) but it didn’t work in either case.
Here is our example (complicated, I am sorry):
!| DSL Adapter |
| wait for element with id | % | to not be visible | waitForCondition | (window.document.evaluate( ‘count(//node()[@id=\'{1}\'])’, document, null, XPathResult.NUMBER_TYPE, null ).numberValue <=0 !-||-! window.document.getElementById('{1}').scrollWidth <= 0 ), ${GlinttLargetWait}000 |
!| Generic Fixture | ${sel} |
| wait for element with id | dynamicElement | to not be visible |
which gives us the following error:
java.lang.NoSuchMethodException: Method [com.thoughtworks.selenium.DefaultSelenium.waitForCondition()] could not be found matching given parameters
Help would be greatly appreciated!
Thanks in advance,
Aristotelis
Hi Anubhava again,
After many hours we have come to realise that the problem is in the passing of the parameters to the call of a function within the javascript script, and in particular with the caracter “,”
Here is another, simpler, example:
!| DSL Adapter |
| max to seven | getEval | Math.max(5,7) |
!| Generic Fixture | ${sel} |
| max to seven | | 7 |
this gives the following error:
java.lang.NoSuchMethodException: Method [com.thoughtworks.selenium.DefaultSelenium.getEval()] could not be found matching given parameters
this problem ‘breaks’ some of the DSL commands we had created in the past (and that we believe that used to work). Hence this problem may have been introduced in one of the latest upgrades.
Ofcourse we tried to escape the comma, but we could not find a way of doing that successfully.
Please help!
thanks.
Hi Aristotelis,
I’m sorry for replying late as I am traveling these days and not accessing my emails regularly.
Comma character “,” indeed needs escaping using backspace character. Your DSL should be written like this:
!| DSL Adapter |
| max to seven | getEval | Math.max(5\,7) |
Please try it and let me know if it still doesn’t work. I will be happy to fix this if it doesn’t work for you.
cheers,
Anubhava
Hi Anubhava,
Thanks for your reply.
I confirm that the above example does not work. It returns the following error:
com.thoughtworks.selenium.SeleniumException: ERROR: Threw an exception: illegal character
The log from the selenium RC is:
# info(1249565573284): Executing: |getEval | Math.max(5\,7) | |
# error(1249565573284): Threw an exception: illegal character
If we do the following though, it works (ofcourse this is not a solution..):
!| Generic Fixture | java.lang.String | Math.max(5,7) |
| jstr=toString | | Math.max(5,7) |
!| DSL Adapter |
| count the ps2 | % | getEval | jstr= |
!| Generic Fixture | ${sel} |
| count the ps2 | jstr= | | 7 |
What are we doing wrong?
(This error stops us from using getEval with document.evaluate function which is proving to be very important for us.)
Thanks again,
Aristotelis.
Hi Aristotelis,
Please download newly updated genericfixture.jar from the link above.
This script should work ‘as is’ now although I could not personally run the test since I’m remote these days.
!| DSL Adapter |
| max to seven | getEval | Math.max(5\,7) |
Please let me know how it behaves.
Also regarding your other suggestion of grouping multiple expressions/statements in DSL I have made a very important upgrade in Generic Fixture using bean shell. I just could not find time to publish detailed BLOG article. I will do so as soon as I reach back.
cheers,
Anubhava
Hi Anubhava,
Thanks, we appreciate you are taking the time to reply while travelling.
We downloaded the latest jar (8/8/09) and tested it.
Indeed, the above example works fine. Yet, others do not…
Considering you do not have the possibility to test and develop at this time, we tried to help by figuring out what the error pattern is ; we reached the conclusions listed below.
We also add at the end of this post some examples of calls that we have been developing and could serve for testing purposes (or could be of help to other users of Generic Fixture).
» Within-argument level – Single argument
»» example:
!| DSL Adapter |
| max to seven | getEval | Math.max(5\,7) |
»»» interpreted as the class call:
»»» (OK:) |getEval | Math.max(5,7) | |
» Within-argument level – More than one arguments
»» example:
!| DSL Adapter |
| wait to nine | waitForCondition | Math.max(5\,9)==9, 120000 |
!| Generic Fixture | ${sel} |
| wait to nine |
»»» interpreted as the class call:
»»» (ACTUAL:) |waitForCondition | Math.max(5\,9)==9 | 120000 |
»»» (CORRECT:) |waitForCondition | Math.max(5,9)==9 | 120000 |
Here are some examples of our calls:
!| DSL Adapter |
| wait for element with id | % | to not be visible | waitForCondition | window.document.evaluate( ‘count(//node()[@id=\'{1}\'])’, document, null, XPathResult.NUMBER_TYPE, null ).numberValue == 0 !-||-! window.document.getElementById(‘{1}’).scrollWidth =1, ${GlinttLargetWait}000 |
| check that the cell in column | % | of table | % | contains text | % | getEval | window.document.evaluate( ‘count(//table[@id=\'{2}\']//td[position()={1} and contains (.\, \'{3}\')]‘, document, null, XPathResult.NUMBER_TYPE, null ).numberValue >= 1 |
thanks and enjoy your trip,
Aristotelis.
Hi Anubhava,
I’m working in same project that Aristotelis.
We’re trying to define a DSL for a method that has two arrays as parameters.
Such as:
| create ship with imoNumber | % | and name | % | setUp | shipFieldSetMapper , array:{1}\,{2}\,”\,” , array:ImoNumber\,Name\,NameEffectDate\,MmsiNumber |
And invoke it with:
| ship=create ship with imoNumber | phillip | and name | fry |
But when running the test we get an error because the escape char (\) is not removed from the array values.
Do you have any idea what the problem might be?
Do we have an error in the DSL definition?
Thanks in advance for your help,
Sérgio
Hi Sérgio,
Thanks for writing to me.
Taking a quick look at your DSL it appears that DSL is not correctly defined. What is the method you are trying to invoke? Is it setUp(arr1, arr2) or shipFieldSetMapper(arr1, arr2)? If it is setUp then your DSL is passing 3 parameters instead of 2 as you desired.
If possible can you send your method call in Java then I will be able to give you precise DSL syntax for your method call.
Thanks,
Anubhava
Hi Anubhava,
Thanks a lot for your help.
The method call in Java is something like this:
Ship ship = this.fixtureContext.setUp(“shipFieldSetMapper”, new String[] { “9999888″, “Helliopolis”, “1000 days past” }, new String[] { “ImoNumber”, “Name”, “NameEffectDate” });
What am I doing wrong?
Thanks,
Sérgio
Dear Sérgio,
Thanks for your prompt response. Looking at your Java method call your DSL should be defined like this:
| setup a ship | setUp | shipFieldSetMapper, array:9999888\,Helliopolis\,1000 days past, array:ImoNumber\,Name\,NameEffectDate |
I could not test this DSL though because I’m replying from my phone in between my travel.
Let me know if it doesn’t work. I’ll be back to work in USA tomorrow and will be able to test and modify the Generic Fixture code to suit your needs.
Thanks,
Anubhava
Hi Anubhava,
Thanks a lot for your help we managed to solve that problem.
However we came up with another.
Using a variable as parameter in the DSL:
!| Generic Fixture | foodb= |
| delete ship | ship= |
it causes the following error:
java.lang.ClassCastException: package.Ship cannot be cast to java.lang.String
at DSLAdapter$CommandRow.matchIt(DSLAdapter.java:90)
at DSLAdapter$CommandRow.matchIt(DSLAdapter.java:65)
at DSLAdapter$CommandRow.getParameters(DSLAdapter.java:144)
at GenericFixture.readRow(GenericFixture.java:343)
at GenericFixture.doRows(GenericFixture.java:765)
at fit.Fixture.doTable(Fixture.java:153)
at fit.Fixture.interpretFollowingTables(Fixture.java:119)
at fit.Fixture.interpretTables(Fixture.java:105)
at fit.Fixture.doTables(Fixture.java:79)
at fit.FitServer.process(FitServer.java:71)
at fit.FitServer.run(FitServer.java:52)
at fit.FitServer.main(FitServer.java:43)
I think the error is because de DSLAdapter class assumes that the variables are either String or arrays. Is this a restriction?
Thanks,
Sérgio
Dear Sérgio,
I’m glad that you were able to resolve the previous issue.
No DSLAdapter doesn’t assume a variable to be String or Array or of any other type. Your script is like this:
!| Generic Fixture | foodb= |
| delete ship | ship= |
Which is basically calling a method defined by DSL “delete ship” on the object stored by a variable foodb= and you are supplying a variable ship= to your DSL.
Are your variables foodb= and ship= storing the values of the correct type?
To debug further can you check it by creating a variable foodClass= by calling getClass() and then getCanonicalName() method on it. something like this:
!| Generic Fixture | foodb= |
| foodClass=getClass |
| foodClass=.getCanonicalName | |
| shipClass=ship=.getClass |
| shipClass=.getCanonicalName | |
| delete ship | ship= |
Make sure above script prints correct object types in both calls of getCanonicalName methods.
Let me know how it goes.
Cheers,
Anubhava
Hi Anubhava,
I’ve tried the debug trick you’ve mentioned as the variables do have the correct type.
After taking a look at your code I’ve noticed that the error was in following lines:
Object v = GenericFixture.fetchVariable( str );
if ( v != null && !v.getClass().isArray() )
str = (String) v;
Hence my question regarding the expected types for the variables.
Are we doing something wrong?
Thanks in advance,
Sérgio
Hi Sérgio,
I found the issue and fixed it. Thanks a lot for bringing it up. New genericfixture.jar has been uploaded to the sourceforge repository. Please download the latest jar file for your test. It should fix the problem for you because I was able to reproduce the problem and then test it again after the fix.
Let me know how it goes.
Cheers,
Anubhava
Hi Anubhava,
With your fix we’ve managed to solve the previous error, however a new one as come up.
The getParameters method in the DSL Adapter class has a return type of List.
This disallows the use of non String objects in the DSL such as the example I’ve mentioned in a previous reply.
What happens now is that the ship object that is returned from:
| create ship with imoNumber | % | and name | % | setUp | shipFieldSetMapper , array:{1}\,{2}\,”\,” , array:ImoNumber\,Name\,NameEffectDate\,MmsiNumber |
when invoking the following example is being converted to a String and causing a an error inside the method
!| Generic Fixture | foodb= |
| delete ship | ship= |
Is this the expected behavior?
Thanks a lot for your help,
Sérgio
Dear Sérgio,
Thanks for writing back to me.
Actually the problem was not the getParameters returning a list it was in fact the dilemma of resolving the variables either at “DSL to Java translation” stage or at execution stage. As you notice that a variable can store any object not just String or String compatible objects therefore I have decided to leave variable resolution at the late stage i.e. execution stage.
New genericfixture.jar has been uploaded to the sourceforge repository. Please download the latest jar file for your test. It should fix the problem for you.
cheers,
Anubhava
Hi Anubhava,
We’ve tried your new genericfixture.jar and everything worked perfectly.
Thanks a lot for your help.
Cheers,
Sérgio
Hi Anubhava,
Thank you for your constant support.
Regarding the last issue I had mentioned, the escaping of the comma seems to work ok, but now we get another error that we can not resolve and I’d like to ask for your help.
The dsl is:
!| DSL Adapter |
| wait for element with id | % | to not be visible | waitForCondition | window.document.evaluate( “count(//node()[@id='{1}'])”, document, null, XPathResult.NUMBER_TYPE, null ).numberValue == 0 !-||-! window.document.getElementById(’{1}’).scrollWidth =1, 120000 |
And the error returned is the following:
com.thoughtworks.selenium.SeleniumException: Node cannot be used in a document other than the one in which it was created
We also tried using instead of window.document.
this:
selenium.browserbot.getCurrentWindow().document.
and this:
document.importNode(window.document\,true).
but none works.
any help would be greatly appreciated.
Thanks in advance.
Dear Aristotelis,
There are couple of syntax errors in your DSL. As you are aware now that comma characters inside parameters need to be escaped out in DSL. Additionally you have used assignment(=) instead of comparison(==) in the 2nd condition of your Javascript.
Let me give you the syntax corrected definition:
!| DSL Adapter || wait for element with id | % | to not be visible | waitForCondition | window.document.evaluate( "count(//node()[@id='{1}'])"\, document\, null\, XPathResult.NUMBER_TYPE\, null ).numberValue == 0 !-||-! window.document.getElementById('{1}').scrollWidth == 1, 120000 |
Please try it and see if it resolves your error.
If not I would suggest to include this code in a small JUnit test case and call your Selenium server from there since you are getting this exception from Selenium API. Once working in JUnit code you can always translate it back to Generic Fixture’s DSL.
Cheers,
Anubhava
Anubhava,
First of all I wanted to say thanks for putting this together. It makes jumping into Fitnesse testing much easier. I was curious if you had considered or implemented anything in the GenericFixture with regards to flow control (if, for, while, etc). One of the powers of Fitnesse is the ability to define a table of values that you can have Fitnesse churn through via a fixture. Just curious.
Thanks,
Michael
Hi Michael,
Thanks for the nice words.
Now regarding if, for, while, etc: I was initially using fit.decorator’s loop fixture for looping support but since fit.decorator didn’t have support of variables I had to modify it locally.
As a much better support of these constructs (if, for, while, etc) I have actually integrated bean shell interpreter via GenericFixture and DSLAdapter. I have yet to publish a Blog post on examples and how-to’.
But in summary:
1. Get bsh.jar and put it in FitNesse’s classpath, using !path directive.
2. Then use a DSL like this anywhere in your scripts:
!| DSL Adapter || check if array | % | has | % | GenericFixture.bsh | boolean has=false; if (java.util.Arrays.binarySearch({1}, "{2}") > 0) has=true; return has; |
| check if | % | is between | % | and | % | GenericFixture.bsh | return {1} > {2} && {1} <= {3}; |
3. And finally call this DSL script like:
| check if | someVar | is between | 4 | and | 7 | | true || check if array | arr | has | indeed | | true |
I know it wont's be very clear from this comment so please pardon me till I create a proper Blog post with full working examples and detailed instructions.
Cheers,
Anubhava
PS; However as a matter of practice I don’t recommend writing a complex test script with all kind ifs, whiles, dos etc. It makes it harder to maintain and less readable. I would rather create a helper class and do complex looping, branching, calculations inside that and then call helper class methods via Generic Fixture.