===== IDE Script Editor ===== //Script Editor// allows you to create and edit //MScript// (groovy script). [[#Plugins]] may be activated for the model to add specialized functions to interact with AUT or automate processes. {{ wiki:idescreen:ide_script.png }} ---- ==== Editor Overview ==== //Script Editor// is a source code editor with: * auto formatting * code collapse * [[#code assist]] * search * replace * undo / redo The tool pallet on the upper-right corner of the editor gives you quick access to common editor features. {{ wiki:idescreen:ide_script_toolbar.png? 150 }} The info mini-button **i** gives more detailed information on these editor features. Click //P// to open a dialog to activate [[#Plugins]] for the model. ---- ==== Code Assist ==== Code assist is supported on [[https://testoptimal.com/v6/apidocs/|system functions and plugin functions]], which includes your own custom plugins. Code assist can be opened with //Ctrl-Space// in one of the following: * on a blank line or after a "$" {{wiki:idescreen:ide_script_ca.png? 80}} * on chained system or plugin function calls {{wiki:idescreen:ide_script_ca_sys.png? 270}} * on java classes {{wiki:idescreen:ide_script_ca_javaclass.png? 225}} ---- ==== Plugins ==== //Plugins// extends the capability of //TestOptimal// to perform specialized operation. They must be explicitly activated for the model in the scripts. {{ wiki:idescreen:ide_script_plugin.png?450 }} Activated plugins will automatically added to code assist (Ctrl-Space). More info can be found at [[Plugins]] and [[http://testoptimal.com/v7/apidocs/ | System and Plugin Functions]]. ---- ==== MScript Types ==== There are 4 types of //MScript//: * [[#TRIGGER Script]] * [[#PAGES Script]] * [[#STEPS Script]] * [[#MCASES Script]] * [[#User Script]] Except [[#User Script]], all scripts are automatically created when the model is created. All scripts can be left blank. All scripts are executed as model executes. ---- ==== TRIGGER Script ==== //TRIGGER Script// is a collection of //TRIGGER// to be executed when a state or transition is traversed during model execution. A //TRIGGER// is an annotated groovy function. It must be declared with the annotation as show below: @TRIGGER('U1062') def 'state name' () { } where //U1062// is the unique id assigned to the state or transition. === Types of TRIGGER === Besides //TRIGGER// for state and transition, there are system defined //TRIGGER// to help with initialization and error handling. These //TRIGGER// types are: * //MBT_START// - executed at the beginning of the model execution * //MBT_END// - executed at the end of the model execution * //MBT_FAIL// - executed on each failure detected (state or transition) * //MBT_ERROR// - executed on un-caught runtime error * //ALL_STATES// - executed on any state before state trigger * //ALL_TRANS// - executed on any transition before transition trigger * //state// - executed on the specific state * //trans// - executed on the specific transition === Create TRIGGER === To create a //TRIGGER//, press //Ctrl-I// on a blank line and select the desired //TRIGGER// type or a state / transition. The //TRIGGER// script is inserted into the editor. The groovy function name for //TRIGGER// is populated with the state name and transition name. You may change the groovy function name if you desire. But do not change the //UID// field in the annotation line. When the state and transition names are changed after //TRIGGER// is created, you must manually edit the groovy function names to match if desired. === Trigger List === Listing of states and transitions that have TRIGGER script created. Click on the state and transition to quickly scroll to the script. {{wiki:idescreen:ide_script_triggerlist.png?100}} ---- ==== PAGES Script ==== //PAGES Object// is a technique commonly used in UI automation. //PAGES Script// is the place to declare page objects. A page consists of elements and functions that can be performed on the page. Add appropriate //import// statements at the top of the script: import org.openqa.selenium.By; === Create Page Objects === Use the following script to create a new page object: page1 = $SYS.addPage('MainPage') page1 = $SYS.getPageMgr().addPage('MainPage') === Add Page Actions === Pages may contain one or many page actions. Page actions are groovy functions and must be declared with one parameter //page//. Use the following script to add a page action to a page: page1.addAction('getPageSource', { page -> $SYS.log('Getting page source for: ' + page.getName()); $SELENIUM.getWebDriver().findElement(By.tagName('body')).getText(); }) === Add Page Elements === Pages may contain one or many page elements. Use the following script to add a page element to a page: loginElem = page1.addElement('loginID'); === Add Element Actions === Elements may contain one or many element actions. Element actions are groovy functions and must be declared with two parameters: //elem// and //params//, where //params// is an optional array of objects you would pass in when you call the action from //TRIGGER Script//. Use the following script to add an element action to an element: loginElem1.addAction('click', { elem, params -> $SYS.log('Clicking on element ' + elem.getName() + ' on element locator: ' + elem.getLocator()); $SELENIUM.getWebDriver().findElement(elem.getLocator()).click(); }) === Usages / Examples === //Pages, elements, actions// can be called from //TRIGGER Script//. Below are a few examples: @TRIGGER('U1062') def 'Start' () { $SYS.log('Page Source is: ' + $SYS.page('MainPage').perform('getPageSource')); $SYS.page('MainPage').element('loginID').perform('click'); } ---- ==== STEPS Script ==== //STEP Script// enables //Behavior Driven Development (BDD)// scripting like //Cucumber// using natural language. @TRIGGER('U1062') def 'Start' () { >> Open Firefox browser >> Goto URL http://google.com >> Login with user id admin and password admin } === Create Steps === //Steps// are annotated groovy functions as follows: @STEP('Open {browserType} browser') def setBrowserType (String browserType) { $SELENIUM.setBrowserType(browserType); } @STEP('Goto URL {url}') def gotoURL (String url) { $SELENIUM.getWebDriver().get(url); } @STEP('Login with user id {userid} and password {password}') def loginAs (String userid, String password) { $SELENIUM.getWebDriver().findElement(By.id('loginid')).sendKeys(userid); $SELENIUM.getWebDriver().findElement(By.id('password')).sendKeys(password); } ==== MCASES Script ==== //MCASE Script// is where //MCase// are defined. Often times you may have a set of specific test scenarios you want to make sure are covered to complement the system generated test cases. You can achieve just that with //MCase// - a custom test case / workflow that you defined explicitly for the system to generate a sequence path from the model to achieve specific scenario. Consider your model as a map to //GPS//, //MCase// is just a set of way points you want to visit. When you execute //MCase//, a sequence path (trip/route) is auto-generated from your model. $SYS.getMCaseMgr().addMCase('MCase 1').navigateToState('V75Cents').executeTransition('add50', { state -> $SYS.log('MCase 1')}); $SYS.getMCaseMgr().addMCase('MCase 3').navigateToState('V50Cents').executeTransition('add25', { state -> $SYS.log('MCase 3')}).skipToState('End'); In additional to follow through path and execute the automation script (//TRIGGER//) along the path, you have the option to add additional automation/process script to be executed as illustrated in above example. ---- ==== User Script ==== Besides [[#TRIGGER Script]], [[#PAGES Sript]], [[#STEPS Script]] and [[#MCASE Script]], you may also add additional scripts. To create a user script, click on "+". You can rename the script by clicking on the pencil mini-button. //MyScript def add (p1, p2) { return p1 + p2; } def multiply (p1, p2) { return p1 * p2; } === Calling User Script Functions === @TRIGGER('U1062') def 'Start' () { $SYS.log('adding 10 and 20: ' + $MyScript.add(10, 20)); $SYS.log('multiplying 10 and 20: ' + $MyScript.multiply(10, 20)); } ---- ==== Include File ==== You may include script file into your TRIGGER script. Just add the @INCLUDE_FILE below: @INCLUDE_FILE 'absolute file path to include file' The above script will literally inject the content of the included file into current script before TRIGGER script is executed. The side effect of using this INCLUDE_FILE is that the injected scripts will mess up the script line # reported on errors. ---- ==== ShortCut Keys ==== Shortcut keys allow you to perform basic editor functions with a keyboard. Below is the list of the shortcut keys (Windows key in **bold** / Mac key in //italic//): * **Ctrl-Space**: Code assist when cursor is in an attribute or on a blank line * **Ctrl-A** / //Cmd-A//: Select all * **Ctrl-B**: Collapse / Expand current script tag that has children tags * **Ctrl-D** / //Cmd-D//: Delete current line * **Ctrl-E** / //Cmd-E//: Execute highlighted script expression in [[ide_monitor |Execution Monitor]] * **Ctrl-F** / //Cmd-F//: Search and replace a string, enter lower case for case insensitive search * **Ctrl-R** / //Cmd-R//: Code-assist: requirement * **Ctrl-I** / //Cmd-I//: Insert a state/trans trigger (Trigger script only) * **Ctrl-Z** / //Cmd-Z//: Undo changes * **Ctrl-Y** / //Shift-Cmd-Z//: Redo changes * **Ctrl-Home** or **Alt-Up** / //Cmd-Up//: Move cursor to the beginning of the script * **Ctrl-End** or **Ctrl-Down** / //Cmd-Down//: Move cursor to the end of the script * **Ctrl-Left** / //Alt-Left//: Move cursor 1 word to the left * **Ctrl-Right** / //Alt-Right//: Move cursor 1 word to the right * **Alt-Left** / //Cmd-Left//: Move cursor to the beginning of the line * **Alt-Right** / ''Cmd-Right: Move cursor to the end of the line * **Ctrl-Backspace** / //Alt-Backspace//: Delete word to the left * **Ctrl-Delete** / //Ctrl-Alt-Backspace or Alt-Delete//: Delete the word to the right * **Ctrl-[** / //Cmd-[//: shift line to the left (un-indent) * **Ctrl-]** / //Cmd-]//: shift line to the right (indent) Except for **Ctrl-R / Ctrl-I** for windows and //Cmd-R / Cmd-I// for Mac, check out [[https://codemirror.net/doc/manual.html#commands | CodeMirror Commands]] for additional key mappings and details of mapped commands.