Skip to main content

SWELL - Language Manual

This guide describes the SWELL language which is a DSL used to describe a suite of tests to the SWELL interpreter.

Test Suite

A test suite is a text-file containing a SWELL script structured as explained in A SWELL Hello-World. The component statements of such a test suite are listed and described below.

Statements

The table below lists all SWELL statements. Those classified as top-level statements (such as After-Each-Test) may only be used at the outer most level of a test suite, but never as a part of a list of statements embedded within another statement. Statements within such a list are each preceded with a hyphen ("-"). The following explanations apply to the example SWELL scripts shown:

  • the part in blue is a swing query explained further in Swing Query Language below
  • the part in red is a tree-path explained further in Tree Path below
  • the part in magenta is a boolean-expression explained further in Boolean Expression below
  • the part in green is a time-duration explained further in Time Duration below
  • the pattern {{...}} is inline embedded Scala code explained further in Embedded Code below
  • the pattern ${...} is a script variable explained further in Variables below

The example SWELL scripts provided depict simple uses of the permitted syntax. For a full understanding of the syntax of each statement, use visualLangLab to inspect the grammar as explained in SWELL Grammar.

StatementDescriptionGrammar-Tree Name
After-Each-Test An optional top-level statement that introduces a list of (one or more) statements that are executed after the completion of each and every test (irrespective of the test outcome). Example:
after each test
 - perform {{System.gc()}}
 - delay 500 ms
Note that a "-" precedes each statement that is part of the list belonging to the After-Each-Test statement. The top-level statement following the After-Each-Test will not be preceded by a "-".
stmtAfterEachTest
Before-Each-Test An optional top-level statement that introduces a list of (one or more) statements that are executed before each test. Example:
before each test
 - clear the first textarea
 - click the button with ToolTipText = "Clear log"
stmtBeforeEachTest
Clear-Text Clears the text in the specified Component. Example:
 - clear the 2nd textarea
A Clear-Text statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtClearText
Click Performs a simple mouse-click over the middle of the specified Component. Left Click and Right Click are also available. Example:
 - click the "Save" button of the dialog
 - right click the tree at / 0
A Click statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtClick
Collapse Collapses the specified tree node. Example:
 - collapse tree node / "Nodes" of the tree
The word tree is optional. A Collapse statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtCollapse
Delay Causes the test execution to be delayed by the specified duration. Examples:
 - delay 3 seconds
A Delay statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtDelay
Display Displays the specified string in the test log (same as print). Example:
 - display "Connection established"
A Display statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtDisplay
End Ends either the current test or the entire test suite and prints the specified message to the test log. Examples:
 - end test with message "Config file missing"
 - end suite with message "No host connection"
The words with and message are both optional. An End statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtEnd
Enter-Text Enters the supplied string into the specified Component. Examples:
 - enter "operator123" into the passwordfield
 - enter ${userName} into the 2nd textfield of the dialog
An Enter-Text statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtEnterText
Exec Exectues the specified SWELL script file as a sub-process. Example:
 - exec "TestConnection.txt"
An Exec statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtExec
Expand Recursively expands the specified tree node. Example:
 - expand tree node / 2 of the tree
The word tree is optional. An Expand statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtExpand
Fail-If Specifies a condition (and associated message) for a negative test outcome. Examples:
 - fail the test with message "No client found" 
 - fail the test with message "Connect failed" if the first textarea contains "Error"
 - fail the test with message "Bad parse result" unless ${logTextPane} contains 
       "Array(Array(Pair(0, 3), List(Pair(0, Pair(0, 5)))), List())" within 1 s
The words the, test, with, and message are optional. A Fail-If statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtFailIf
Focus Moves focus to the specified Component. Example:
 - focus on the passwordfield
The on is optional. A Focus statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtFocus
If A conditional control flow statement. Example:
- if the textarea contains "Error" then
  - click the "Reset" button
  - fail with message "General error found"
 else if the textarea contains "Warning" then
  - warn with message "Unspecified warning"
  - perform {{System.err.println("Unspecified warning")}}
 else 
  - pause "Test OK"
 end
The else if and else portions are optional. Any number (0 or more) else if portions may be used. An If statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtIf
Key-Text Keys the supplied text into the specified Component. Has the same form as the Enter-Text statement except that the word key is used instead of enter. A Key-Text statement is never allowed at the top-level, and thus is always preceded by a "-". stmtKeyText
Launch-GUI Launches the specified GUI program. Examples:
 - launch vll.gui.VllGui.main()
 - launch new a.b.CName(x, y, z)
The first statement above starts a program with a public static void main(...) with or without literal arguments, while the second statement starts a program by instantiating a class with the supplied arguments. The on is optional. A Launch-GUI statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtLaunchGui
List-Components Lists (on the test log) all the Components selected. Examples:
 - list button of the dialog
A List-Component statement is never allowed at the top-level, and thus is always preceded by a "-"..
stmtListComponents
Locate-Components Helps to locate one or more Components by coloring them. Examples:
 - locate button of the dialog
A Locate-Components statement is never allowed at the top-level, and thus is always preceded by a "-"..
stmtLocate
Maximize Maximizes the named internal frame. Examples:
 - maximize "Statistics"
 - maximize {{"Window-" + clientID}}
The first form above maximizes the internal frame with the title statistics. The second form maximizes the internal frame with a title matching the string produced by the Scala expression provided (the text between the {{ and the }}). A Maximize statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtMaximize
Minimize Minimizes the named internal frame. Examples:
 - minimize "Statistics"
 - minimize {{"Window-" + clientID}}
See notes for maximize above. A Minimize statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtMinimize
Move-Mouse Moves the mouse over the middle of the specified component. Example:
 - move mouse to the "Exit" button
The mouse is optional. A Move-Mouse statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtMoveMouse
Pause Pops up a blocking dialog with the specified message. Example:
 - pause "Click OK after connecting client"
A Pause statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtPause
Perform Executes a previously declared group or some inline embedded code, or a method invocation on a swing-query. Examples:
 - perform setupConnections
 - perform {{System.out.println("Done")}}
 - perform setBackground(java.awt.Color.blue) of the second button
A Perform statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtPerform
Print Prints the supplied string (with variable substitutions) to the test log. Example:
 - print "Client count = ${clientCount}"
The ${clientCount} is substituted with the value of the variable clientCount created by a Reference or Assignment statement (see below). A Print statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtPrint
Reference (or Assignment) Assigns a value to a variable. Examples:
 - clearLogButton is the button with ToolTipText = "Clear log"
 - clearLogButton = the button with ToolTipText = "Clear log"
The first form above (using as) makes the variable accessible to the SWELL script only, but not to embedded Scala code. The second form (using the "=" sign) makes the variable accessible to embedded Scala code as well. A Reference statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtReference
Select Executes a GUI operation involving one or more selections from menus or lists. Example:
 - select "Help" -> "Sample grammars" -> "ArithExpr" from the menubar
A Select statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtSelect
Set Obsolete, do not use stmtSet
Suite-Begins The mandatory top-level statement that begins a test suite. Example:
suite swell_demo_01 begins with
 - Launch vll.gui.VllGui.main()
 - Wait for frame "VisualLangLab/S"
If there are no statements to be executed, the with should also be dropped.
stmtSuitBegins
Suite-Ends The mandatory top-level statement that ends a test suite. Example:
suite swell_demo_01 ends with
 - click the "Reset" button
 - pause "Done! Click OK to exit."
If there are no statements to be executed, the with should also be dropped.
stmtSuitEnds
Trace Starts or stops tracing of tests. Examples:
 - trace on
 - trace off
A Trace statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtTrace
Unless The unless statement has the same form as an if statement but with a unless in place of the if. It works like an if statement that first inverts the value of the condition part stmtUnless
Wait Causes execution to be delayed till the specified event occurs. Example:
 - wait for dialog "Error"
 - wait 3.5 s until the 1st textarea contains "Done!"
The first statement delays execution till a dialog titled "Error" appears, the second statement delays execution for a maximum of 3.5 seconds till the specified boolean expression becomes true. A Wait statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtWait
WarnIf Causes a warning to be issued to the test log if the specified condition occurs. Has the same form as a fail statement with a warn in place of the fail. A Perform statement is never allowed at the top-level, and thus is always preceded by a "-". stmtWarnIf
While The usual procedural control flow statement. Example:
while the last textarea does not contain "Error" do
 - enter "123" into the first textarea
 - click the "Next" button
end while
A While statement is never allowed at the top-level, and thus is always preceded by a "-".
stmtWhile

Inline Embedded Scala Code

Several SWELL statements allow the use of embedded Scala code. Embedded Scala code must be enclosed within doubled curly-braces, as in the following examples:

  • {{System.gc()}} - used only for its side-effect; the returned value (if any) is ignored
  • {{"Window-" + clientID}} - returns a String value that is used by the embedding statement

Examples in the table above show some uses of inline embedded Scala code. You can reviw the SWELL grammar, looking for the token INLINE_CODE to discover all uses of inline embedded Scala code in SWELL.

Variables

Several SWELL statements require (or optionally permit) the use of variables. Variable names are user-chosen following the usual conventions of contemporary programming languages. Variable references are given using the form ${variable name}. Check the token called VAR

Swing Query Language

A swing-query (informally called SQL in SWELL documentation) is perhaps SWELL's most important feature, and contributes most to its English-like characteristic. SQL enables SWELL scripts to perform the following functions:

  • identify or refer any Swing Component of the GUI under test using plain English
  • identify or refer any node of a Swing JTree
  • identify or refer any cell of a Swing JTable

SQL also provides a notation to invoke member functions on the objects listed above. The following subsections provide further details.

Refer Swing Components

SWELL scripts can access the GUI's Swing components via an unstructured, DOM-like (in the web-browser sense) collection. So the SQL is required to select specific GUI elements from the DOM. SQL uniquely identifies Components by specifying a type and (optionally) an attribute value. The following SWELL script illustrates these mechanisms. In this script we use the SWELL locate statement (which just highlights the Components identified by the supplied SQL) to demonstrate these concepts.

Suite swell_tutorial_sql begins with
 - Launch vll.gui.VllGui.main()
 - Wait for frame "VisualLangLab/S"
Test locateByTypeOnly is
 - locate the tree
 - delay 2 seconds
Test locateByTypeAndAttributeValue is
# the output of the following line can be found in the log file
 - list all button
# the following two lines are equivalent, and any one may be used
 - locate the button with toolTipText = "Parse input"
# - locate the 17th button
 - delay 3 seconds
Test locateByTypeAndImpliedAttributeValue is
 - locate the "Save" button
 - delay 3 seconds
Test locateWithinScope is
 - move mouse to the button with toolTipText = "Save"
 - delay 0.5 second
 - click the button with toolTipText = "Save"
 - wait for dialog "Save"
 - delay 0.5 second
 - enter "abc.vll" into the textfield
 - delay 0.5 second
 - move mouse to the "Save" button of the dialog
 - delay 2 seconds
 - click the "Save" button of the dialog
Suite swell_tutorial_sql ends

Figure-1 below shows the state of the GUI after the above SWELL script ends.

Result of running SQL-demo script
Figure 1. Result of running SQL-demo script

The Swing Components accessed by the SWELL script are also marked on Figure-1 along with the SQL used to locate them. But how do these swing-queries work? The following description explains:

the tree uses just the type (tree) to identify the Component, and it works because there only is one object of that type. SWELL scripts can use the following words to specify the type of a Swing component: button, checkbox, combobox, component, dialog, frame, internalframe, label, list, menu, menubar, menuitem, panel, passwordfield, popupmenu, progressbar, radiobutton, scrollbar, scrollpane, slider, spinner, splitpane, tabbedpane, table, textarea, textcomponent, textfield, textpane, togglebutton, toolbar, tree, window,

the button with toolTipText = "Parse input" specifies the type (button) as well as the value of one attribute. Providing only the type would not have worked here as there are many buttons in scope. The specific button required can however be identified by it's unique tool-tip text. SWELL allows any bean-style getter method to be used as an attribute-name for this purpose.

the "Save" button specifies the type (button) as well as the value of one attribute (Save). When a string-valued attribute is given in this way (preceding the type) SWELL takes the string provided to be the value returned by getTitle(), getText(), or toString().

the "Save" button of the dialog is required because after the file-save dialog is posted there are two "Save" buttons in scope, and just the "Save" button would not have worked. This swing-query creates a structured view of the DOM (a 2-level hierarchy connected by the of) in which all elements are unique.

Another useful technique (though not used in this example) is to specify the sequence number of a Comopnent. To use this technique you must first obtain the list of all Components of the same type in the applicable scope by using the list statement. The commented out line (- locate the 17th button) is an example of such use.

Several examples of SQL used in more complex GUIs can be found at SWELL has DOM and SQL Too.

JTree Operations

A swing-query can identify a particular tree-node by using a tree path as its left-most segment. Examples can be found at SWELL has DOM and SQL Too.

JTable Operations

A swing-query can identify a particular table-cell by using a cell identifier as its left-most segment. Examples can be found at SWELL has DOM and SQL Too.

Tree Path

A tree-path can take any of the following forms:

  • / (the root node of the tree)
  • / 0 (the first child of the root node)
  • / 4 (the fifth child (0-based index) of the root node)
  • / "Agents" (the child of the root node called "Agent")
  • / 4 / 3 / 0 (the first child of the fourth child of the fifth child of the root node)
  • / 4 / "SubSystems" / 0 (the first child of the child called "SubSystems" of the fifth child of the root node)

A tree-path can contain any number (1 or more) of path segments. Each path segment is designated either by an integer (representing the child-index) or a string (representing the node's label).

Boolean Expression

A boolean-expression can take any of the forms illustrated in the following examples:

  • the textarea contains "error"
  • the textarea does not contain "error"
  • the textarea matches "Error: .+"
  • the textarea does not match "Error: .+"
  • the tree has a treenode / "Systems"
  • the tree has no treenode / "Systems"
  • any "Error.*" dialog appear
  • any "Error.*" dialog exist
  • no "Error.*" dialog appears
  • no "Error.*" dialog exists
  • SLC  ==  SLC (here "SLC" represents a Swing Query, or a Java literal value, or an inline embedded Scala code)
  • SLC  !=  SLC

The swing-query and tree-path used in the above forms are merely illustrative, and can obviously be replaced with any other swing-query or tree-patch as required.

Time Duration

A time-duration can take any of the following forms (where 999 represents a number with or without a decimal point):

  • 999 s
  • 999 ms
  • 999 second
  • 999 seconds
  • 999 milli second
  • 999 milli seconds

In the above forms, second and seconds can be used interchangeably irrespective of the magnitude of the duration.

 
 
Close
loading
Please Confirm
Close