UISpec4J in Fitnesse Test Java POS

Automated Testing Tools are used to assure modifications are always backward compatible and safe for production
Forum rules
This forum is personally pruned to avoid redundant posts. Related topics are moved to the same sub-forum. Language will be corrected for readability.

UISpec4J in Fitnesse Test Java POS

Postby red1 » Sun Aug 07, 2011 8:58 am

Here i document the way to use UISpec4J together with Fitnesse that can do wonderful testing on ADempiere Java client panels such as the POS (Point of Sales). This was discovered while reviewing the POS here (see lower part of the long thread).

Remembering how we use Fitnesse before in this wiki, we now see how to incorporate UISpec4J API into the framework:

Code: Select all
import org.uispec4j.UISpec4J;
import org.uispec4j.UISpecTestCase;

public abstract class ModelLogin extends UISpecTestCase {
   static {
        UISpec4J.init();
   }

Your project has to get the jar as shown in the Fitnesse script:

Code: Select all
classpath: /Users/red1/Documents/workspace/POSFitnesse/uispec4j-2.4-jdk16.jar

Your POJO (plain java objects) test code then just extends the ModelLogin and execute WindowTriggers:

Code: Select all
public class DumpGUIObjects extends ModelLogin {

   private ClassLoader classload = ClassLoader.getSystemClassLoader();
   private Class clazz;
   private String results;
   protected String press1;
   
   //pressing GUI buttons containing productnames

   //TODO -- getting values from returned GUI actions
   //
   
   //execute triggers from UISpec4J
   public boolean execute() {
         if (getMainWindow() == null)
         return false;
      return true;
      }
   
   public void setClassName(String classname) throws ClassNotFoundException{
      clazz = classload.loadClass(classname);
   }
   
   public void setPress1(String item){
      press1 = item;
   }
   
   public String Results(){
      return results;
   }
   
   public Window getMainWindow() {
       final Window[] result = new Window[3];
       WindowInterceptor.init(new MainClassTrigger(clazz, new String[0]))
          .process(new WindowHandler(){
          public Trigger process(Window window) throws Exception{   
             results=window.getTitle();
             window.getTextBox("userTextField").setText("SuperUser");
             window.getPasswordField("passwordField").setPassword("System");
             window.getButton("Ok").click(); //1st window login preset to SuperUser
             window.getComboBox("orgCombo").select("Store Central");
             window.getButton("Ok").click();
             //
             return window.getButton("Cancel").triggerClick(); //
            }
          })             
          .process(new WindowHandler(){
             public Trigger process(Window window) throws Exception{
                try {
                  result[1]=window; //2 selections pressed, with values passed from FitnesseStory script
                  window.getButton(press1).click();
                  window.getButton("non existent").click();
                }catch (Exception e){
                   results = e.toString();
                   return window.getButton("Oak").triggerClick();
                }
            return window.getButton("Ok").triggerClick();//same window fallbacks
             }
             })
          .run();
       return result[1];
       }
}

The above is called from the following Fitnesse page:

DumpGui.gif
DumpGui.gif (32.91 KiB) Viewed 9643 times

As you can see, it is passing the parameters into the POJO above. The purpose of this particular testing is not yet running off the POS as shown earlier. This marvelous little sample test is actually doing a dump of the panel names for easier developer reference during test creation! See what i mean below:

DumpResults.gif
DumpResults.gif (18.44 KiB) Viewed 9643 times

Now we can see what panels or buttons actually appear. The lower part of the Fitnesse output is this:

Code: Select all
BPartner,Cancel,Delete,Edit,History,Logout,Minus,New,Next,Payment,Plus,Preference,Previous,Print,Product]

What this means is that we can directly 'touch' these visible buttons or panels just by:
Code: Select all
window.getButton("any name").click()

and it will get programmatically clicked, without launching anything onto the desktop. It is clicked by its object name displayed and unlike other tests such as Selenium (for Web-based apps), it is not doing things via macro steps to look for relative positioning of the GUI. Thus the panel can be anywhere on the screen and the code will click on it. This means fast, sure testing.
red1
Site Admin
 
Posts: 2760
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia

Re: UISpec4J in Fitnesse Test Java POS

Postby red1 » Mon Aug 08, 2011 7:43 pm

I have added two more tests:
A. To test pressing all the key functions on the right touch pad of 16 items iteratively
B. To test Barcode input and Product Search function.

Both tests are finalised as working and test code, sourcecode and scripts committed to ADempiere SVN../branches/POSFitnesse with /JavaPOS and /FitnesseStory respectively.

A. Below shows the test resulting in the POS having all product items in the keypad selected and it is achieved by the test shown below it. Compare the Total figures shown.

TestAll.png
TestAll.png (90.33 KiB) Viewed 9620 times

ManyOrders.gif
ManyOrders.gif (45.6 KiB) Viewed 9620 times


B. Below shows the result of the Barcode test - the barcode of 1234567890 summons Azalea Bush and the pop-up request for 'S' gives two products which the first one was clicked on. The Fitnesse test is below it that does all those actions.

Barcode1.png
Barcode1.png (24.65 KiB) Viewed 9620 times

Barcode2.png
Barcode2.png (19.07 KiB) Viewed 9620 times

BarcodeFitnesse.gif
BarcodeFitnesse.gif (44.01 KiB) Viewed 9620 times


The core sourcecode to achieve above is:
A. For Clicking on all keypad items.
Code: Select all
          public Trigger process(Window window) throws Exception{
             result[0]=window;
            //red1 - start of login dialog, commencing login sequence...
             window.getTextBox("userTextField").setText("SuperUser");
             window.getPasswordField("passwordField").setPassword("System");
             window.getButton("Ok").click(); //1st window login preset to SuperUser
             window.getComboBox("orgCombo").select("Store Central");
             window.getButton("Ok").click(); //2nd window Client is preset to GardenAdmin and StoreCentral
             return window.getButton("Cancel").triggerClick();
            }
          })             
          .process(new WindowHandler(){
             public Trigger process(Window window) throws Exception{
                try {
                  result[1]=window; // values passed from FitnesseStory script
                  window.getButton(press1).click();
                  window.getButton(press2).click();
                  window.getButton("exception").click();
                }catch (Exception e){
                   results = e.toString();
                   itemArray = getAllItems(results);
                   for (int i=0;i<n;i++){
                      window.getButton(itemArray[i]).click(); //click on each item in array
                   }
                  grandtotal = (window.getTextBox("GrandTotal")).getText();
                }
            return window.getButton("Logout").triggerClick();//same window fallbacks
             }
             })
          .run();
       return result[1];
       }

   protected String[] getAllItems(String results) {
      // concatenate out the substrings after <p>
      //and add into an array.
      //pass array back to Trigger Process.
      int i = 0;
      String ch = "<p>";
      int x = 0;
      for (int c=0;c<16;c++) {
         int b = results.indexOf(ch, x);
         String item = results.substring(b+3, b+9);
         x = b+6;
         if (item.equals("All Pr")) {
            c--;
            continue;
         }
         itemArray[c] = item;         
      }
      return itemArray;
   }   

B. For Barcode and Product Search.
Code: Select all
          .process(new WindowHandler(){ //2
             public Trigger process(Window window) throws Exception{
                result[1]=window; //selected POS button values passed from FitnesseStory script
                window.getTextBox("ProductInput").setText(barcode);
                window.getTextBox("ProductInput").pressKey(Key.ENTER);
                window.getButton("ProductSearch").click();               
                grandtotal = (window.getTextBox("GrandTotal")).getText();
                  
                return window.getButton("Logout").triggerClick();
             }
             }) //subsequent windows from above action placed consecutively
         .process(new WindowHandler(){ //3
             public Trigger process(Window window) throws Exception{
                result[2]=window;
                window.getTextBox("ProductKey").setText(search);
               return window.getTable().triggerDoubleClick(0, 0);               }
             })
red1
Site Admin
 
Posts: 2760
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia

Re: UISpec4J in Fitnesse Test Java POS

Postby red1 » Mon Aug 08, 2011 11:36 pm

All these tests can be run at one go or a single click via the Fitnesse Suite (which is simply created by just checking the Suite box within properties):

Suite1.png
Suite1.png (50.19 KiB) Viewed 9615 times

Then you just click on the Suite link and it runs all the tests listed in the contents. This saves you time and effort to run each single test separatedly. Note that you can still run any single test if you want to zoom in on something.

Suite2.png
Suite2.png (60.48 KiB) Viewed 9615 times
red1
Site Admin
 
Posts: 2760
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia

Re: UISpec4J in Fitnesse Test Java POS

Postby red1 » Tue Aug 09, 2011 7:43 pm

I added this final test to the suite:

POSPaymentTender.gif
POSPaymentTender.gif (74.8 KiB) Viewed 9600 times

Note that we can use the useful row format to pass multiple runs on the GUI. The CHECK and CREDITCARD payment modes produced different Accounting Consequence at the bottom. I put different product selection and BPartners to differentiate the results further.
red1
Site Admin
 
Posts: 2760
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia

Re: UISpec4J in Fitnesse Test Java POS

Postby red1 » Fri Aug 12, 2011 5:20 pm

I have written a guide in PDF format and uploaded it here. You can double click on it and try to save it to read offline. Or download from SourceForge.net.

red1
Site Admin
 
Posts: 2760
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia

Re: UISpec4J in Fitnesse Test Java POS

Postby red1 » Wed Dec 21, 2011 7:31 pm

I have finally thrown in the towel to make UISpec4J+FItnesse to really work hands-free for Jenkins and taken the plain JUnit in Jenkins approach. But firstly i can prove that JUnit testing for UISpec4J GUI testing can work hands-free here. From here i will investigate a more elegant way to setup the right plugin of JUnit into Jenkins for the rest of GUI testing which should be quite grand - covering quite all the ADempiere main menu itself.
red1
Site Admin
 
Posts: 2760
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia


Return to Quality Assurance

Who is online

Users browsing this forum: No registered users and 2 guests

cron