Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
tutorial:scripting_state_model [2020/07/17 20:19]
admin [Tutorial: Automation Scripting - State Model]
tutorial:scripting_state_model [2021/01/05 03:00] (current)
Line 9: Line 9:
   * [[#Initialization scripts]]   * [[#Initialization scripts]]
  
 +This tutorial assumes that you are able to create a simple //State-based Model// and have created a simple model to write scripts for. If not, please refer to [[state_modeling | Tutorial - State-based Modeling]].
  
 ===== Model scripting ===== ===== Model scripting =====
Line 24: Line 25:
    @TRIGGER('MBT_START')    @TRIGGER('MBT_START')
    def MBT_Start () {    def MBT_Start () {
-      $SELENIUM.setBrowserChrome (); 
       $SYS.log ('mbt started. ');       $SYS.log ('mbt started. ');
                  
Line 30: Line 30:
    @TRIGGER('U1072')    @TRIGGER('U1072')
    def 'Start: add25'() {    def 'Start: add25'() {
-      $SYS.page('MainPage').element('Quarter').perform('click'); +      $SYS.log('State Starttransition addQuarter');
-      bal = $SYS.page('MainPage').element('Balance').perform('getText'); +
-      if (bal.equals('0.25')) { +
-          passMsg = "Insert one Quarter passedbalance confirmed: " + bal; +
-          $SYS.addReqPassed("Q!", passMsg); +
-      } +
-      else { +
-         failMsg = "Insert one Quarter failed, expecting balance of 0.25, but got " + bal; +
-         $SYS.addReqFailed("Q1", failMsg, 'QUARTER-0-25'); +
-      }+
    }    }
  
-You will need to following import to the beginning of the script for the trigger annotation keyword:+You will need to add following "importto the beginning of the script for the trigger annotation keyword:
    import com.testoptimal.mscript.groovy.TRIGGER    import com.testoptimal.mscript.groovy.TRIGGER
  
-The above examples uses //SELENIUM// plugin with "$SELENIUM.setBrowserChrom()", you must activate //SELENIUM// plugin, see [[#Activating plugins]] for more details. 
  
- +Besides triggers, scripts are also used for building UI Page Objects, //Cucumber// style test step definition and //MCases//, which are out of scope of this tutorial.  Please refer to [[../ide_script | Script Editor]] for more details.
-Besides triggers, scripts are also used for building UI Page Objects, Cucumber style test step definition and MCases.  Please refer to the specific wiki pages/tutorials for more details.+
  
 ===== Model triggers ===== ===== Model triggers =====
Line 74: Line 63:
    @TRIGGER('MBT_START')    @TRIGGER('MBT_START')
    def 'MBT_START' () {    def 'MBT_START' () {
-      $SELENIUM.setBrowser ($SYS.getExecDir().getExecSetting().getOption('ideBrowser')); 
       $SYS.addTestOutput('<html><body><H1>Test Output</H1>');       $SYS.addTestOutput('<html><body><H1>Test Output</H1>');
       $SYS.addTestOutput('<ol>');\       $SYS.addTestOutput('<ol>');\
Line 84: Line 72:
       $SYS.addTestOutput('</ol></body></html>');       $SYS.addTestOutput('</ol></body></html>');
       $SYS.saveTestOutput('testOutput.html');       $SYS.saveTestOutput('testOutput.html');
-   } 
-    
-   @TRIGGER('MBT_FAIL') 
-   def 'MBT_FAIL' () { 
-      // Failure detected 
-      $SELENIUM.snapScreen(''); 
    }    }
        
    @TRIGGER('MBT_ERROR')    @TRIGGER('MBT_ERROR')
       def 'MBT_ERROR' () {       def 'MBT_ERROR' () {
 +      $SYS.log('Fatal error encounter, path to reproduce error: ' + $SYS.trace());
    }    }
        
    @TRIGGER('U1062')    @TRIGGER('U1062')
-      def 'Start' () { +   def 'State_1' () { 
-      $SELENIUM.getWebDriver().get('http://localhost:' + $UTIL.getPort() + '/DemoApp/VendingMachine/VendingMachine.html'); +      $SYS.addTestOutput('<li><span>Test Case  + $SYS.getPathName() + '</span><ul>'); 
-      $SYS.page('MainPage').element('Cancel').perform('click'); +      $SYS.addTestOutput('<li><span>At state State_1</span></li>');
-      bal = $SYS.page('MainPage').element('Balance').perform('getText'); +
-      if (!bal.equals('0.00')) { +
-         $SYS.addReqFailed ('Cancel failed to reset balance to 0.00', 'Cancel', 'CANCEL-FAILED'); +
-         $SYS.abort('Cancel does not work!!!'); +
-      }+
    }    }
        
    @TRIGGER('U1072')    @TRIGGER('U1072')
-   def 'Startadd25'() { +   def 'State_1trans_A'() { 
-      $SYS.addTestOutput('<li><span>Test Case '  + $SYS.getPathName() + '</span><ul>'); +      $SYS.addTestOutput('<li>Step: trans_A</li>');
-    +
-      $SYS.addTestOutput('<li>Step: add a Quarter</li>'); +
-      $SYS.page('MainPage').element('Quarter').perform('click'); +
-      bal = $SYS.page('MainPage').element('Balance').perform('getText'); +
-      if (bal.equals('0.25')) { +
-          passMsg = "Insert one Quarter passed, balance confirmed: " + bal; +
-          $SYS.addReqPassed("Q!", passMsg); +
-      } +
-      else { +
-          failMsg = "Insert one Quarter failed, expecting balance of 0.25, but got " + bal; +
-          $SYS.addReqFailed("Q1", failMsg, 'QUARTER-0-25'); +
-      }+
    }    }
 +
 +Feel free to add any additional scripts you wish.
 +
 +Once scripts are completed, run the model and inspect the output file "testOutput.html" in [[../ide_artifact | ARTIFACT]] tab as well as Model Log file via menu //Run / Model Log//.
 +
 + 
        
-   @TRIGGER('U1073') 
-   def 'Start: add50'() { 
-      $SYS.addTestOutput('<li><span>Test Case '  + $SYS.getPathName() + '</span><ul>'); 
-    
-      $SYS.addTestOutput('<li>Step: add a Half-Dollar</li>'); 
-      $SYS.page('MainPage').element('HalfDollar').perform('click'); 
-      bal = $SYS.page('MainPage').element('Balance').perform('getText'); 
-      if (bal.equals('0.50')) { 
-          passMsg = "Insert one HalfDollar passed, balance confirmed: " + bal; 
-          $SYS.addReqPassed("Q!", passMsg); 
-      } 
-      else { 
-          failMsg = "Insert one HalfDollar failed, expecting balance of 0.50, but got " + bal; 
-          $SYS.addReqFailed("Q1", failMsg, 'QUARTER-0-50'); 
-      } 
-   } 
  
 ===== Activating plugins ===== ===== Activating plugins =====
Line 148: Line 104:
 After the plugins are activated for the model, the plugin IDs are automatically added to the code-assist popup list (//Ctrl-Space//): After the plugins are activated for the model, the plugin IDs are automatically added to the code-assist popup list (//Ctrl-Space//):
  
-{{wiki:idescreen:ide_script_ca.png? 100}}+{{wiki:overview:tut_state_model_scripting_plugin.png? 100}}
  
 +Go ahead and activate [[../plugins#random_plugin | Random Data Generator]].  This adds //$RANDOM// to the code-assist popup list. And now you can use any of the [[https://testoptimal.com/v6/apidocs/com/testoptimal/plugin/RandPlugin.html| plugin functions]] provided by [[../plugins#random_plugin | Random Data Generator]].
  
 +For example:
  
-===== User and environment variables =====+   $SYS.log('Random phone#: ' + $RANDOM.randPhone('999-999-9999') ); 
 +    
 +==== Web App Automation==== 
 +For test automation, for example web application you would activate //Selenium// plugin.  Once you have the plugin activated, you will be able to use //$SELENIUM// to interact with your web application through //Selenium/WebDriver//.  
 + 
 +For example: 
 + 
 +   $SELENIUM.getWebDriver().findElement(org.openqa.selenium.By.id('DrinkWater').click(); 
 + 
 +=== Page Object===    
 +You could also use //PAGES// tab to define page object: 
 +   //PAGES Script 
 +   import org.openqa.selenium.By; 
 +   mainPage = $SYS.addPage('MainPage'
 +   elem = mainPage.addElement('DrinkWater', By.id('Water')) 
 +   elem.addAction('click', { elem, params -> 
 +      $SELENIUM.getWebDriver().findElement(elem.locator).click(); 
 +   }) 
 +    
 +Then in //TRIGGERS// tab, you can do this: 
 +   $SYS.page('MainPage').element('DrinkWater').perform('click'); 
 +    
 +The advantage of using page objects is that all element locators are organized and managed in one central place for easy maintenance. 
 + 
 +=== Find Element Locator === 
 +Web element locator can be xpath, css or by id, etc. as supported by //Selenium//
 + 
 +There are many browser add-on/extension tools that can help you find locators for web element very easily.  Check out [[../externalsources | External Sources]] for a list of such tools. 
 +  
 +===== User variables =====
  
-==== User Variables ==== 
 The variables that you created/declared in groovy scripts are local within the trigger/ function.  Often times you may want to create a global variable that is accessible from multiple triggers / functions.  //User Variable// does exactly that for you. The variables that you created/declared in groovy scripts are local within the trigger/ function.  Often times you may want to create a global variable that is accessible from multiple triggers / functions.  //User Variable// does exactly that for you.
  
Line 174: Line 160:
    }    }
  
-==== Environment Variables ==== 
-//Environment Variables// are global in //TestOptimal// server and thus accessible to all running models. 
  
-//Environment Variables// are configured / initialized in //config/config.properties// file, for example: 
  
-    ENV.var1=value1 +===== Assert and track requirements ===== 
-    ENV.var2=value2+It's the responsibility of your scripts (TRIGGERS) to check and validate that AUT is behaving correctly. Your script does this by checking elements on AUT through //plugins// functions and assert that AUT elements have the expected values.
  
-They can be updated/set by script via //$SYS.setEnvVar(...)//, for example:+For simplicity sake, we will just use a random number generator to simulate the values from your AUT and use that to demonstrate how to perform the assertion and tracking the requirements.
  
-   $SYS.setEnvVar('var1', 'value2');+The assert and tracking requirement are done with one of the two $SYS functions:
  
-The new value is saved back to //config/config.properties// file and will survive server restart. +  $SYS.assertTrue ('tag', condition, 'fail msg', ['assertID']) 
-    +  * $SYS.assertFalse ('tag'condition, 'fail msg', ['assertID'])
-//Environment Variables// are accessed via //$SYS.getEnvVar(...)//for example:+
  
-   $SYS.log("ENV variable var1=" + $SYS.getEnvVar('var1'));+where 'tag' is the requirement tag/id, 'condition' is a boolean script expression and 'fail msg' is the failure description if the 'condition' is not evaluated to the true (for assertTrue()) / false (for assertFalse()).  Optionally you may include 'assertID' which is the unique id assigned to this defect. 
 + 
 +As example, the following script will assert random number is greater than 5: 
 + 
 +   $SYS.assertTrue ('GE5', $RANDOM.randNum(0,10) >5, 'failed to generate a random number with value at least 5'); 
 + 
 +You may also perform check with if/else and then raise the defect explicitly, for example: 
 +     
 +   if ($RANDOM.randNum(0,10) >= 5) { 
 +      $SYS.addReqPassed ('GE5', 'Successfully generated a random number with value at least 5')
 +   } 
 +   else { 
 +      $SYS.addReqFailed ('GE5', 'failed to generate a random number with value at least 5'); 
 +   } 
 + 
 +The requirement 'GE5' will be automatically tracked for the model and the coverage information is available in [[../ide_result | RESULT]] tab. 
 + 
 +Add your own script to perform assertion and requirement tracking to the model TRIGGERS, re-run the model, and check [[../ide_result | RESULT]] tab.
  
  
-    
-===== Assert and track requirements ===== 
 ===== Initialization scripts ===== ===== Initialization scripts =====
 +Often times you may want to pass some configuration settings to your model scripts, for example, the AUT url which might change depending on if you are running your model against your development environment or QA environment or for this tutorial, maybe we want to change the threshold value of the random number the system must generate -  which we have hard-coded to 5. 
 +
 +You could certainly accomplish this by setting //Environment Variable// via //$SYS.getEnvVar(...)// However a better option is to set a user variable for which the initial value can be set dynamically before the model execution starts.   //Initialization scripts// accomplishes just that.
 +
 +//Initialization scripts// can be entered in {{wiki:idescreen:ide_execsettings.png?linkonly | Model Execution Settings}}.
 +
 +
 +