Using Javascript in Automation

Pickle supports the insertion and execution of Javascript in browser automation. The following commands are supported:

StatementSyntaxLinkCompatibility
Given I run the local JavaScript file “Filename” Runs a locally stored JavaScript file. Allows the inserting of custom funcitons that can be run later. #use %scriptpath% or %docpath% in the path if needed.
Given I run the JavaScript command “<JsCommand>” Runs a JavaScript command against the browser.
Given the JavaScript function “<JsCommand>” returns true Runs a JavaScript function against the browser and ensures that it returns true.
Given the JavaScript function “<JsCommand>” returns false Runs a JavaScript function against the browser and ensures that it returns false.
Given I record the result of the JavaScript function “<JSCommand>” to {field} Runs a JavaScript function and record the response into the specified field.

Assuming we have a local JavaScirpt file called test.js:

pickleTestObj = new function(){
  this.isTrue=true;
  this.isFalse = false;
  this.isAny = false;
}

I could use the following script to insert and integrate it:

@JavaScript @scripts
Scenario: Web Automation - Basic Test
    Given I go to "http://thinkingengine.net/unittest/AutomUnitTest.html"
    And I run the local JavaScript file "%scriptpath%\unittests\test.js"
    And I run the JavaScript command "pickleTestObj.isAny=true;"
    Then the JavaScript function "pickleTestObj.isTrue;" returns true
    Then the JavaScript function "pickleTestObj.isFalse;" returns false
    Then the JavaScript function "pickleTestObj.isAny;" returns true

Pickle will automatically load the default JavaScript file if it exists. This means you do not have to load the script by a statement.

The default javascript file is always relative to the current test script being executed and should be located in a folder called “js” and called “features.js”.

For example, if the script was located as “c:\myScripts\regression.feature”, the autoload javascript file would have to be located as “c:\myScripts\js\features.js”.

The autoload feature is fragile because modern web applications don't require the script to navigate to new pages but rather either navigate themselves of dynamically load the data into a current page. PIckle provides a method for resolving this. If you provide the following configuration in the scripts JSON file, Pickle TS will check on each web command that the script is loaded. The cost is latency (slower scripts)because it has to fun JavaScript command to verify.

{
"forceScriptLoad": true,
}

It can also be enabled on the config screen:

Pickle maintains a JavaScript global variable called $PickleTS. This variable provides access to TestScript variables/fields via it's vars array.

Syntax

$PickleTS.vars["<field>"]

You can access the last web element used or identified in a gherkin script command.

Pickle maintains a JavaSciprt global variable called $PickleTS. This variable provides access to the last wenbelment via it's lastElement property.

Syntax

$PickleTS.lastelement

You can use the following statement to retrieve data from JavaScript and store it in a variable.

Given I record the result of the JavaScript function "<JSCommand>" to {field}

The example below illustrates the use of pickle data fields in JavaScript.

Gherkin Script

If I execute the following script:

Feature: Test JavaScript Variables

@JavaScript
  Scenario: Unit Test Script
    Given I go to "http://thinkingengine.net/unittest/AutomUnitTest.html"
    Given I should see an "[ByTag]h1" element
    Given I record a unique value to {myfield1}
    Given I record a unique value to {myfield2}
    Given I run the JavaScript command "true;"
    And I record the result of the JavaScript function "$PickleTS.vars['myfield1']" to {jsField}

Browser Console Output

The browsers debug console shows the data created automatically:

Test Output

The Resulting Test Output will be:

Summary
Status:Passed
Failed:0
Passed:1
Total Cases:1

Test Cases

Scenario: Unit Test Script
## Status:Passed
Given I go to "http://thinkingengine.net/unittest/AutomUnitTest.html" ## [Passed]
## Notes: Navigated to {http://thinkingengine.net/unittest/AutomUnitTest.html}.
## Execution Method: AutoWeb
Given I should see an "[ByTag]h1" element ## [Passed]
## Notes: element exists. 
## Execution Method: AutoWeb
Given I record a unique value to {myfield1} ## [Passed]
## Notes: Created unique Id.  Updated {myfield1} = 201906081053506116981
## Execution Method: Calculated
Given I record a unique value to {myfield2} ## [Passed]
## Notes: Created unique Id.  Updated {myfield2} = 201906081053506227439
## Execution Method: Calculated
Given I run the JavaScript command "true;" ## [Passed]
## Notes: Script Executed.
## Execution Method: AutoWeb
And I record the result of the JavaScript function "$PickleTS.vars['myfield1']" to {jsField} ## [Passed]
## Notes: Script Executed and result stored. Updated {jsField} = 201906081053506116981
## Execution Method: AutoWeb

Dynamic Data (Variables)

3 variables declared.

------ Begin Variable List ------
---------------------------------------------------------------------------------------
| myfield1                                 | 201906081053506116981                    |
| myfield2                                 | 201906081053506227439                    |
| jsField                                  | 201906081053506116981                    |
---------------------------------------------------------------------------------------
------ End Variable List ------

It is possible to extend the gherkin statement via JavaScript. Important notes:

  • Standard statement will take precedent - i.e. if you use an identical statement to those build into Pickle, it will be ignored.
  • The statement must be declared in a very specific format - see below.
  • The receiving JavaScript function must be structured correctly.

Statement Scope

The definition of statements is controlled by scope and access to a given statement is dependant on that scope.

Pickle Statements

Pickle internal statements are globally accessible and can be used in all pickle script. The accessibility can be affected by a scenario's tag (for example a web automation statement will become manual if the scenario does not have the @javascript tag.

Statements in Autoloaded Javascript

These custom statements are available within all scenarios for a specific script. If the next script (only applicable to test plans) does not have an autoload script, the previous custom statement will not be available.

Scripts inserted by Statemen

Scripts that are inserted using [Given I run the local JavaScript file “Filename”] statement will be available form the point the statement is executed and will only be available during that scenario.

Scope Summary

  • Pickle Statements : Global
    • Test Plan
      • Test Script/Feature
      • Autoloaded Script : Feature
        • Test Scenario
        • Statement laoded Script : scenario

Defining a custom statement

To define a custom statement, you add a structured comment, anywhere within the script. It's good practice to add the comment above the function it calls but this is not mandatory.

Essentially you create a comment that defines the function to call when the statement expression is matched. It calls that function providing the parameters captured and the web element found (if applicable). In return, the function returns the outcome of the statement.

Example:

//Pickle Statement: $pickleTSCustomStatements.CustomStatement1 =  Given I capture (.*) and (.*)
	CustomStatement1 : function(capturedElement, Capturedvalues)
	{
		this.ele=capturedElement;
		this.params=Capturedvalues;
		
		return "{success: true, message:'ok'}";
	}

Comment Structure

Syntax

//Pickle Statement: <JSFunction> = <Statement Regex>

Use

The definition is created prefixed as a single line JavaScript comment followed by the keyword Pickle Statement: (Pickle Statement:).

The comment then indicated the function in your JavaScript that will be used to process the statement. This is followed by an equals (=) sign.

The remainder of the comment defines the regular expression uses to define the Gherkin Statement.

Example

Taking the example comment above:

//Pickle Statement: $pickleTSCustomStatements.CustomStatement1 = Given I capture (.*) and (.*)

Specifying that a statement needs a web element

It is possible to indicate that one of the parameters captured in the gherkin regular expression statement are search criteria for a web page element. When found, it will use the standard search syntax used by other automation statements pickle (ByName, ByID, etc) to find the element.

To do this set the criteria of one of the regular expression capture groups to “WebElement”.

For example, in the statement above we can change it to capture a web element:

//Pickle Statement: $pickleTSCustomStatements.CustomStatement1 = Given I capture “(webelement)” and (.*)

Defining the JavaScript Function

The functions being called by pickle must be defined to receive two parameters:

function(webElement, capturedParameters)

The function must return a string that containsthe specificJSON Structure below:

{success=<bool> , Message='Message'}

Function Parameters

function(webElement, capturedParameters)

  • webElement - If a web element has been matched, the Reference to the JavaScirpt Object for the element will be provided. Could be null.
  • capturedParameters - A string array listing all the parameters captured during the evaluation of the expression. The first element [0] contains the statement that was matched in its entirety.

Example:

Custom statements Example

In the following example, we autoload a javascript file that defines custom statements for a test script. The third function has an error in its statement declaration (deliberately).

The JavaScrip Function

The following code declares 3 Gherking Statements (the third has an error).

$pickleTSCustomStatements= {
	ele:null,
	params:null,


	//Pickle Statement: $pickleTSCustomStatements.CustomStatement1 =  Given I capture (.*) and (.*)
	CustomStatement1 : function(capturedElement, Capturedvalues)
	{
		this.ele=capturedElement;
		this.params=Capturedvalues;
		
		return "{success: true, message:'ok'}";
	},

	//Pickle Statement: $pickleTSCustomStatements.CustomStatement2 =  Given I find element "(WebElement)" and capture (.*)
	CustomStatement2 : function(capturedElement, Capturedvalues)
	{
		this.ele=capturedElement;
		this.params=Capturedvalues;
		return "{success: false, message:'Broken'}";
	},
	
	//Pickle Statement: $pickleTSCustomStatements.CustomStatement3 =  Given I find element "(WebElement)" and capture (*.)
	//Defintion above has a syntax error (*. should be .*)
	CustomStatement3 : function(capturedElement, Capturedvalues)
	{
		this.ele=capturedElement;
		this.params=Capturedvalues;
		return "{success: false, message:'Broken'}";
	}
}

The Test Script

Feature: Test JavaScript Variables

@JavaScript
  Scenario: Unit Test Script
    Given I go to "http://thinkingengine.net/unittest/AutomUnitTest.html"
    Given I capture 10 and 20
    Given I find element "[ByTag]h1" and capture 33

The browser console

The output after statement 2 & 3 are executed:

You can see that the second output's “ele” property now has the H1 element linked that was being searched for.

Script Output

The results will show as follows:

The report output will be:

Summary
Status:Failed
Failed:1
Passed:0
Total Cases:1

Test Cases

Scenario: Unit Test Script
## Status:Failed
Given I go to "http://thinkingengine.net/unittest/AutomUnitTest.html" ## [Passed]
## Notes: Navigated to {http://thinkingengine.net/unittest/AutomUnitTest.html}.
## Execution Method: AutoWeb
Given I capture 10 and 20 ## [Passed]
## Notes: CustomJS [$pickleTSCustomStatements.CustomStatement1] succeeded. = ok
## Execution Method: AutoWeb
Given I find element "[ByTag]h1" and capture 33 ## [Failed]
## Notes: CustomJS [$pickleTSCustomStatements.CustomStatement2] failed. = {success: false, message:'Broken'}
## Execution Method: AutoWeb

Dynamic Data (Variables)

No variables declared.

Custom JS Statement Errors

I find element "(.*)" and capture (*.) :: Calling [$pickleTSCustomStatements.CustomStatement3]
parsing "^\s*(?:Then|When|Given|And|But|then|when|given|and|but)\s+I find element "(.*)" and capture (*.)" - Quantifier {x,y} following nothing.

You will notice that the last section of the report highlights any issues it found when executing custom statements:

Custom JS Statement Errors

I find element “(.*)” and capture (*.) :: Calling [$pickleTSCustomStatements.CustomStatement3] parsing “^\s*(?:Then|When|Given|And|But|then|when|given|and|but)\s+I find element ”(.*)“ and capture (*.)” - Quantifier {x,y} following nothing.

  • wiki/pickle/supported_statements/javascript.txt
  • Last modified: 28/07/2019 09:36
  • by ThinkingEngine