Extensions

Extensions allow the user to create reusable reusable custom code. This is similar to using Custom JS, however extensions can be created one time and then be reused across your organization with a simple mapping. There are two types of extensions:

  1. Internal Extensions
  2. External Extensions 

Internal Extensions allow the user to create and host code within our system that can be reused throughout the account. We support the following languages: NodeJS 10, Python 3.7, and Go 1.11/Go1.13. In addition, you can include libraries to fully extend the possibilities of development. We host this code using the Google Cloud's Functions Service. We take all of the deployment and integration work out so the user only needs to understand how to write the code. NOTE: Internal Extensions are limited to the capabilities of Google's Cloud Functions for things like maximum payload, execution length, and so on. 

Great use cases for Internal Extensions include: 

  • Accessing external system to create a valid Order Number
  • Generating random data of a specific format (names, dates, etc)

External Extensions easily allow the user to set up an action to trigger an externally hosted API. Like Internal Extensions, these can be triggered either before or after an action takes place.

Great use cases for External Extensions include:

  • Triggering a function outside the scope of a website such as submitting an order from a POS machine
  • Managing usernames and passwords so you don't need to store them within our system.

 

To Create or Modify Extensions

1. Go to the user profile dropdown menu.

2. Click on Extension Management 

mceclip0.png

 

To Create an Internal Extension

1. Click on the Create Extension button. By default, we provide an external extension "toLowerCase" This example is shown for the purpose of updating all inputs to lower case.  Notice the specific format required that includes: "updates", "action", "attributes", "value".mceclip1.png

2. The Function to Execute defaults to helloWorld but is just the starting point for the program to run. This can be updated if desired.mceclip2.png

3. Update the code to perform any action desired. In the example below, you may update the package.json for a Node program and similar for Go or Python. Input and response interfaces can be found below in this documentation.

4. Update the Name of the extension. Only AlphaNumeric characters are allowed.mceclip10.png

5. Then select the Privacy of the extension being created.  This can be Private (only for the creator) or for the entire Team, accessible across projects.

6. Click Create Extension.  

7. Once created, the newly created extension will appear here on the main Extensions page.mceclip11.png

 

Testing your Extensions

Clicking on the extension will bring you to a page where you can test it out. You will want to add various inputs to the extensions to make sure it works in the Action Types (Inputs, Clicks, etc) that you desire.  The Run Parameters Body examples and supported fields can be found below. mceclip12.png

1. Click Run.

2. Output will be returned: mceclip13.png

 

To Create an External Extension

1. Click on Create External Extension button. The following will display:

mceclip1.png

2. Input the Name of your extension. This must be AlphaNumeric

3. Input the POST Endpoint where you API can be reached. This endpoint must follow identical guidelines for input and output parameters as Internal Extensions.

4. Click Save.

5. External Extensions can be tested in the same way as Internal Extensions.

 

Mapping Extensions

Once the extensions is created, it must be mapped to an action to be used.

1. From the test case details page, expand the action then click on the (+) sign.

2. Click on Map Extensions.

mceclip1.png

There are 2 types of mappings and both may be used on the same action:

   1: Prehook, which occurs before the action. If you want to override an input value, the Prehook must be used.

   2: Posthook, which occurs after the action. If you want to collect data that may appear such as randomly generated data, the Posthook must be used.

mceclip3.png

3. In this example, selecting Prehook brings the user to the Map Extensions window. See below: 

mceclip2.png

Note: Recall Creating an Extension allows the user to create a Privacy level of the extension.  Here we are using the Private available extensions.

4. Select the Extension to map.  In this example, we are using the RandomWord extension.

mceclip4.png

5. Click Submit.

6. The Extension = RandomWord has now been mapped to the action. 

mceclip5.png

 

To Use/Map an Extension during Architect Test Case Creation

1. Launch Architect via New Test Case creation.

2. Once Architect has been launched,  click on the + icon to open Architect Advanced functionality.

3. Click on the Extensions flag. See below:mceclip6.png

Extensions will open, guiding the user to Select the icon next to the appropriate action. mceclip7.png

Once selected, choose the extension from the dropdown menu.  In this example, we are choosing the RandomWord extension. 

mceclip6.png

Click Add button.

Once test creation is complete, click Save in Architect to save your test case.

Once all data has processed, the user is returned to the Test Details page and will see the extension = RandomWord has been mapped to the action.

 

Extension Requests 

Below are sample .json objects that may be passed into the Extension with these particular Action Types. In addition to the current action information, previous action data will also be sent so that multi-step information can be processed within the extension. An array called previousSteps will be included into the request and will contain objects identical to the sample actions below. 

These can be used in Run Parameters Body for testing your extensions:

 

Request for Input Action

{ 
"previousSteps": [
{
"path": "",
"optional": false,
"action": actionObjectAsBelow,
"output": outputObjectAsBelow
},
{
"path": "",
"optional": false,
"action": actionObjectAsBelow,
"output": outputObjectAsBelow
},
],
"step": {
"path": "",
"optional": false,
"output": {
"result": null,
"elementResult": null,
"baseFileName": "3 _chrome_new_1533082145693_X2LT2UKABZQ1B3J",
"verificationResults": [],
"foundUrl": null,
"postScreenshot": null,
"preScreenshot": null,
"displayScreenshotPath": null
  },
"action": {
"id": "1533082145693_X2LT2UKABZQ1B3J",
"type": "INPUT",
"value": "marbles < fze - date > mints"
}
}
}

 

Request for Click Action

{ 
"step": {
"path": "",
"optional": false,
"action": {
"id": "1533082139889_YPPDQ6J0A6JEIC6",
"type": "CLICK"
},
"output": {
"result": null,
"elementResult": null,
"baseFileName": "2 _chrome_new_1533082139889_YPPDQ6J0A6JEIC6",
"verificationResults": [],
"displayScreenshotPath": null,
"foundUrl": null,
"postScreenshot": null,
"preScreenshot": null
}
}
}

 

Request for Page Init Action

{ 
"step": {
"path": "",
"optional": false,
"action": {
"pageTitle": "",
"id": "1533082131294 _33Z3UHK98EX2CN8",
"type": "PAGE_INIT",
"url": "https://www.google.com/"
},
"output": {
"result": null,
"elementResult": null,
"foundUrl": null,
"postScreenshot": null,
"preScreenshot": null,
"baseFileName": "0_chrome_new_1533082131294_33Z3UHK98EX2CN8",
"verificationResults": [],
"displayScreenshotPath": null
}
}
}

 

Request for Resize Action

{ 
"step": {
"path":"" ,
"optional": false,
"output": {
"result": null,
"elementResult": null,
"displayScreenshotPath": null,
"verificationResults": [],
"postScreenshot": null,
"preScreenshot": null,
"baseFileName": "1_chrome_new_1533082134164_QAYUGEY0MJTFNUC",
"foundUrl": null
},
"action": {
"windowsHeight": 712,
"windowsWidth": 1535,
"id": "1533082134164_QAYUGEY0MJTFNUC",
"type": "RESIZE"
}
}
}

 

Request for Wait Action

{ 
"step": {
"path": "",
"optional": false,
"output": {
"result": null,
"elementResult": null,
"displayScreenshotPath": null,
"foundUrl": null,
"postScreenshot": null,
"preScreenshot": null,
"baseFileName": "1_chrome_new_1588950647647_4NYWNJ58YQXOW59",
"verificationResults": []
},
"action": {
"id": "1588950647647_4NYWNJ58YQXOW59",
"time": 4000,
"type": "WAIT"
}
}
}

 

Extensions Supported Fields

The attributes under "action" in the input can vary depending on the type of action occurring. The following is a list of attributes currently supported, depending on the type of attribute. For specific questions, please reach our to support. 

  • value
  • elementCode
  • transitionQualifier
  • promptValue
  • text
  • fileUrl
  • selectorAttribute
  • windowWidth
  • time
  • fileName
  • selectorAttributeValue
  • windowHeight
  • url
  • dropTargetEventX
  • selector
  • seleniumMethod
  • alertText
  • dropTargetEventY
  • pageTitle
  • cookieName
  • newPopup
  • dtype
  • evarName
  • cookieValue
  • hasValue
  • targetSelectors
  • evarValue
  • eventOffsetX
  • selection
  • target
  • refActionId
  • eventOffsetY
  • eventX
  • step
  • refVerifyField
  • selectText
  • eventY
  • scrollTop
  • projectVariableSaveAttribute
  • foundText
  • mouseX
  • scrollLeft
  • projectVariableSaveValue
  • fileLocation
  • mouseY
  • currentMethod
  • projectVariableSaveName
 
  • failOnInvisible
  • userCode
  • projectVariableLoadName
 
  • forceClickCoordinates
  • keyCode
  • projectVariableLoadOperation
 
  • onClickAttr
  • key
  • projectVariableLoadAttribute
 
  • attributeType
  • navigationType
  • promptMessage
 

 

Extension Responses

For Prehooks where you want to set a value before the action takes place, your response can look like the following. Note that the formatting must match exactly.

Sample Input Action Response

{ 
"updates": {
"action": {
"attributes": {
"value": "new value to set"
}
}
}

 

Sample Wait Action Response

Here is an example modifying the wait time for a Wait action. This response will modify the wait time to 9 seconds.

 

{
"updates": {
"action": {
"attributes": {
"time": 9000
}
}
}
}

 

For Posthooks, you may want to set a pass or a fail for the action based on what occurred with this, or previous actions. The response from your extension should look something like this. The status may be "pass" or "fail". If "fail", an additional message may be used for display to the web application upon a failure.

{
"updates": {
"stepResult": {
"status": "fail",
"message": "Because the extension said so"
}
}
}

A failed action due to an extension will appear like this in the slider view:

mceclip0.png