The service that runs Recorded Login and Custom User Behavior recordings is called Trails. If you for some reason need to modify your .trail files containing your recordings, please refer to this documentation.
For most use cases, you will not need to refer to this documentation to troubleshoot or solve any issues you might experience while setting up your Recorded Login. For a general introduction and troubleshooting tips to this functionality, please refer to this article instead.
BackgroundTrails is a way for Detectify to reach different states of a web application. This can be anything from authenticating (logging in), to adding an item to an e-commerce shopping cart. The entire service is based around a JSON specification containing various actions. An action could be, "move the mouse cursor", "click on an element" or "enter some text in an input/textarea".
By performing these events, various requests will be made. These requests are recorded for future use. Any cookie being set will be used elsewhere later when performing crawling and security testing.
DescriptionThe data format is a JSON document containing two arrays of actions. The actions define how we are to interact with the site. The first set of arrays is called the
"Commands"-node. Everything defined therein will run the first time the trail is executed. The second node is called
"SanityChecks". Like with
"Commands", this node contain a set of actions. The difference is that
"SanityChecks" will run after all
"Commands" are done (and Detectify have reached the assumed state), and then once more per minute indefinitely. The reason for this behavior is to validate that we are still authenticated or otherwise have reached the correct state in the application. If any assertion fail, then we assume the state is lost from
"Commands", and the entire process will restart and
"Commands" will run again in an attempt to regain the state.
The entire document should be considered a checklist. On the first execution all action nodes stored in
"Commands" will be executed. A failure to execute an action (or if an assertion fails) will terminate the chain of commands and the trail should be considered failed. If all
"Commands" execute successfully the trail is working. When the trail reaches a working state the
"SanityChecks" will run sequentially in a similar manner as of
"Commands". If the
"SanityChecks" fail (either by a failed action or by assertion), the entire chain of
"Commands" will have to re-run to reach the same initial state again. The
"SanityChecks" should run in a loop to constantly verify that the correct states are reached.
// Run this to reach a given state (i.e, authenticate as a user)
"Target": "Welcome admin!",
// Will run sequentially in a loop once per minute, if the assertion fails re-run "Commands"
"Target": "Welcome admin!",
ActionsHere is the list of supported actions.
|Selenium||1.0||click||Element||N/A||Performs a click operation.|
|Selenium||1.0||clickAndWait||Element||N/A||Performs a click operation and waits for a new page to load.|
|Selenium||1.0||open||URL||N/A||Opens a page using a URL.|
|Selenium||1.0||type||Element||Text||Enters text in an input.|
|Selenium||1.0||verifyElementPresent/assertElementPresent||Element||N/A||Use this command when you must test for the presence of a specific UI element, rather than its content. This verification does not check the text, only the HTML tag. One common use is to check for the presence of an image.|
|Selenium||1.0||verifyText/assertText||Element||Text||Use verifyText when both the text and its UI element must be tested. verifyText must use a locator. If you choose an XPath or DOM locator, you can verify that specific text appears at a specific location on the page relative to other UI components on the page.|
|Selenium||1.0||verifyTextPresent/assertTextPresent||Text||N/A||The command verifyTextPresent is used to verify specific text exists somewhere on the page. It takes a single argument–the text pattern to be verified.|
|Selenium||1.0||verifyTitle/assertTitle||Text||N/A||Verifies an expected page title.|
|Selenium||1.0||verifyURL/assertURL||Text||N/A||Verifies an expected page URL.|
|Selenium||1.0||waitForElementPresent||Element||N/A||Pauses execution until an expected UI element, as defined by its HTML tag, is present on the page.|
|Selenium||1.0||waitForPageToLoad||Integer||N/A||Pauses execution until an expected new page loads. Called automatically when clickAndWait is used. The target is a timeout in milliseconds.|
Detectify defined UserActions:
|UserAction||1.0||blur||Element||Element||N/A||User loses focus on element / input. If we fail to find the Element in Target, use the Element in Value.|
|UserAction||1.0||focus||Element||Element||N/A||User gains focus on element / input. If we fail to find the Element in Target, use the Element in Value.|
|UserAction||1.0||input||Element||Element||N/A||This more or less will do element.value = x. After updating the element value we will dispatch "change"-event. If we fail to find the Element in Target, use the Element in Value.|
|UserAction||1.0||keyDown||Element||Element||keyCode, key, code, [text]||User pressed a sigle key. Simulates a key-down event with the Target Element in focus. On failure tries the Element specified in Value.|
|UserAction||1.0||keyPress||Element||Element||keyCode, key, code, [text]||Simulates a keystroke with the Target Element in focus. On failure tries the Element specified in Value. The only practical difference between KeyDown and KeyPress is that KeyPress relays the character resulting from a keypress, and is only called if there is one.|
|UserAction||1.0||keyUp||Element||Element||keyCode, key, code, [text]||User stopped pressing single key. Simulates a key-up event with the Target Element in focus. On failure tries the Element specified in Value.|
|UserAction||1.0||mouseClick||Element||Element||N/A||Clicks on an element (similar to Selenium 1.0 click). The Target will be the element we wish to click on. If this fails we will click on the element specified in Value.|
|UserAction||1.0||mouseDown||Element||Element||N/A||Pushes down the mouse on the Element specified in Target. If no element could be found in Target, use the Element specified in Value.|
|UserAction||1.0||mouseUp||Element||Element||N/A||Releases the mouse button on the Element specified in Target. If no element could be found in Target, use the Element specified in Value.|
|UserAction||1.0||type||Element||Text||Element||Enters text in an input. This command is very similar to Selenium.type but adds support for multiple elements|
|UserAction||1.0||reload/refresh||N/A||N/A||N/A||Trigger a refresh of the page.|
|UserAction||1.0||reloadNoCache/refreshNoCache||N/A||N/A||N/A||Trigger a hard refresh of the page (disregarding any cached content).|
|UserAction||1.0||scroll||Integer||Integer||N/A||Trigger a scroll event. The Target-property is the X coordinate, the Value-property is the Y-coordinate. All UserActions will issue a scroll call first, before the actual action is executed. To try this in Chrome, run: |
|UserAction||1.0||setViewport/setSize||Integer||Integer||N/A||Changes the size of the viewport. The Target-attribute is the width. The Value-attribute is the height.|
|UserAction||1.0||waitForElementPresent||Element||Integer||N/A||Pauses execution until an expected UI element, as defined by its HTML tag, is present on the page. Times out after the given value is reached.|
|UserAction||1.0||tabFocus||Text||N/A||N/A||The Target-attributes defines which tab to focus on. The very first tab will have the ID "A". Any new tab or window will be called "B", "C", etc... If any tab (such as tab "B") is closed, Detectify will be unable to access tab B and the action will fail. The sequence of ID's will contiune indefinitely and no ID's will be reused.|
|UserAction||1.0||verifyTabCount/assertTabCount||Integer||N/A||N/A||Validates that the amount of tabs/windows open correspond to the expected value|
Detectify defined Helper actions:
|Helper||1.0||sleep||Integer||N/A||Sleeps for the Target-amount milliseconds.|
Detectify specified Extractors:
|Extractor||1.0||cookie||Text||N/A||Extracts the specified cookie to use in other services.|
|Extractor||1.0||cookies||N/A||N/A||Extracts all observed cookies for all origins to use in other services (i.e, Crawler and Scanner).|
|Extractor||1.0||requestHeader||Integer||N/A||Extracts the specified request header. This header will then be set in all future requests issued by other services (i.e, Crawler and Scanner).|
|Extractor||1.0||links||Element||N/A||Extracts all links under the specified element. If no element is specified, all links on the page will be extracted.|
|Extractor||1.0||screenshot||N/A||N/A||Takes a screenshot.|
|Extractor||1.0||url||N/A||N/A||Extracts the current URL we're visiting. The next time we run the same trail, we will start from the extracted URL (however a Selenium open command will navigate away again).|
Note: These will polyfill the specified function group at the point where the command is executed. This means that page navigation might invalidate earlier polyfills. Can only be added manually to the trail and will never be set via the Chrome plugin.
|Polyfill||1.0||credentials||N/A||N/A||Polyfills navigator.credentials.store and navigator.credentials.get|
|URL|| Can be a relative or absolute URL.|
|Element|| Any kind of selector to specify an element to focus on. Here is more information on what a selector is.|
|Text|| A snippet of text to search for or to fill in. If the Text is used as a |
Target it will support globbing.
|Integer|| A positive number.|
The difference between a command and its AndWait alternative is that the regular command (e.g. click) will do the action and continue with the following command as fast as it can, while the AndWait alternative (e.g. clickAndWait) tells the interpreter to wait for the page to load after the action has been executed.
The "AndWait" commands
The AndWait alternative is always used when the action causes the browser to navigate to another page or reload the present one.
Be aware, if you use an AndWait command for an action that does not trigger a navigation/refresh, your test will fail. This happens because the interpreter will reach the AndWait’s timeout without seeing any navigation (or page refresh) being made, causing the interpreter to raise a timeout exception.
For many Selenium commands, a target is required. This target identifies an element in the content of the web application, and consists of the location strategy followed by the location in the format locatorType=location.