JavaScript Transactions
Synthetic web transactions are performed by injecting and invoking custom JavaScript when the web page loads. Once the JavaScript is injected into the DOM (Document Object Model) it's invoked with the page load count and any other arguments required to perform the transaction. The below flow demonstrates what happens when the web browser is instantiated and invokes the custom JavaScript.
This document provides a basic overview of using JavaScript to perform DOM automations and will walk you through developing your first transaction script. Starting with a basic login page, the script will populate input values and submit the form by triggering a button click event. This is a modular example with each section adding new functionality to demonstrate how to implement and use the different features.
Webpage Automations
There are many documents, tutorials and examples of using JavaScript to perform web page automations. This involves manipulating the DOM and most of this information can be applied when developing your own synthetic user transactions.
When a page is loaded into the web browser, it becomes a document object and is the entry point into the web page's content. Using JavaScript and the document object, you can access any element on the page with standard DOM methods to set input values and trigger events such as clicking a link or submit button. To populate input values and trigger events you must find the element within the DOM by id, name, tag name, class name, CSS selectors or HTML object collections. Open a web browser and use the developer tools (F12) if you are unsure of the id, tag or class name of the element you want to find.
For this example to work correctly, the Web Browser version must set to any version greater than 7.
The below example login form will be used to demonstrate the different techniques and ways to automate a user login.
1. Save the below html to a file named login.html in the same directory as DomMan.exe.
<!DOCTYPE html>
<html>
<head></head>
<body>
<form action="login.html">
<input name="username" type="text"/>
<input name="password" type="password"/>
<button id="login">Login</button>
</form>
</body>
</html>
The next file we need to create is the JavaScript file that will perform the transaction.
2. Create a new file named login.js in the same directory as DomMan.exe.
The script is invoked with a page load count argument (args) so it knows what block of code to execute. The args value only contains the page load count as no custom arguments will be defined. If custom arguments are defined, they are comma separated so you can split the string into an array to retrieve the values.
3. Add the below JavaScript to the beginning of login.js.
// Variable to store the page load count.
var count = args;
The next thing we want to do is create variables to store the username and password. These values can be changed as this is only an example and the login account doesn't actually exist.
4. Add the below JavaScript to the end of login.js.
// Variables to store the username and password.
var username = "example";
var password = "password";
We now have to find the username and password input fields to populate them with the values defined above.
The below example finds all elements with the tag name input and updates the values.
5. Add the below JavaScript to the end of login.js.
// Set the input values if this is the first page load.
if (count == 0) {
// Gets all elements in the document with the tag name input.
var inputs = document.getElementsByTagName("input");
// Set the username input value.
inputs[0].value = username;
// Set the password input value.
inputs[1].value = password;
}
The input elements have now been updated with the username and password so if you were to run the transaction it would look like the below screenshot.
PostBack Data
When the the login button is clicked, the form-data is sent to the page defined in the form action (login.html) and the JavaScript is injected and invoked on that page once it has loaded. The hidden div element WebBrowserPostBack is also injected on every page load to share data between pages. Update the innerHTML of the WebBrowserPostBack element and the on the next page load it will be returned and can be read using the innerHTML.
To create a custom welcome page for the user we will update the innerHTML of the WebBrowserPostBack element with the username value.
6. Add the below JavaScript to the end of login.js.
// Update the WebBrowserPostBack innerHTML if this is the first page load.
if (count == 0) {
// Get the WebBrowserPostBack div element.
var post = document.getElementById('WebBrowserPostBack');
// Update the WebBrowserPostBack innerHTML with the username.
post.innerHTML = username;
}
Writing Text Files
Not only can data be shared between pages, it can also be written to a text file. The below example will create or append the file login.log with the date/time and username.
7. Add the below JavaScript to the end of login.js.
// Create a textarea element to write a text file.
if (count == 0) {
var file = document.createElement("textarea");
// Set the textarea id.
file.setAttribute("id", "WebBrowserFileWriter");
// Path of the log file to write.
file.setAttribute("path", "login.log");
// Set the style so the element is not displayed.
file.setAttribute("style", "display:none;");
// Text to write to the file.
file.value = new Date().toLocaleString() + ", " + username;
// Add the textarea to the DOM.
document.body.appendChild(file);
}
Page Tracking
If we don't track the page load and trigger the button click event, it could end up in a infinite loop with the form being submitted endlessly. To prevent an infinite loop, use the same condition as above to only trigger the button click event if it's the first page load.
8. Add the below JavaScript to the end of login.js.
// Trigger the button click event if this is the first page load.
if (count == 0) {
// The easiest way to get an HTML element is by using the id attribute.
var button = document.getElementById("login");
// Add a timeout to view the change before the button click is triggered.
setTimeout(function(){
// Trigger the button click event.
button.click();
}, 1000);
}
Since we only have logic to handle the initial page load, when we trigger the button click event the input values will be lost and nothing would appear to happen. To display a custom welcome message after the login button has been clicked, add the code below to update the document body innerHTML.
9. Add the below JavaScript to the end of login.js.
// Display a welcome message if the page count is 1.
if (count == 1) {
// Get the WebBrowserPostBack div element.
var post = document.getElementById('WebBrowserPostBack');
// Update the document body to display the custom welcome message.
document.body.innerHTML = "<h2>Welcome " + post.innerHTML + "</h2>";
}
Running Transactions
The first time you launch DOM Manipulator it will prompt you to create an application key password to encrypt the RSA public/private key pair file. This is not required to run the example as the files are not encrypted.
Transactions are configured and run from the Settings tab.
Enter the following configuration information for the example transaction. All files should be saved in the same directory as DomMan.exe.
Name: Login Example
Location: login.html
File: login.js
The Settings tab should look similar to the screenshot below.
Click the save image to save the configuration for later use. | |
Click the preview image to preview the JavaScript before running the transaction. |
On the Settings tab, click the run image to execute the transaction. |
Example Files
Below is the source code for all of the files required to run the example transaction. The JavaScript has been slightly modified from the examples above to remove duplicate statements. This example provides an introduction into creating JavaScript transactions and doesn't contain any error checking or handling.
All files should be saved in the same directory as DomMan.exe
login.dom
<settings>
<name>login example</name>
<location>login.html</location>
<file>login.js</file>
</settings>
login.html
<!DOCTYPE html>
<html>
<head></head>
<body>
<form action="login.html">
<input name="username" type="text"/>
<input name="password" type="password"/>
<button id="login">Login</button>
</form>
</body>
</html>
login.js
// Variable to store the page load count.
var count = args;
// Variables to store the username and password.
var username = "example";
var password = "password";
// Get the WebBrowserPostBack div element.
var post = document.getElementById('WebBrowserPostBack');
// Set the input values if this is the first page load.
if (count == 0) {
// Gets all elements in the document with the tag name input.
var inputs = document.getElementsByTagName("input");
// Set the username input value.
inputs[0].value = username;
// Set the password input value.
inputs[1].value = password;
// Update the WebBrowserPostBack innerHTML with the username.
post.innerHTML = username;
// Create a textarea element to write a text file.
var file = document.createElement("textarea");
// Set the textarea id.
file.setAttribute("id", "WebBrowserFileWriter");
// Path of the log file to write.
file.setAttribute("path", "login.log");
// Set the style so the element is not displayed.
file.setAttribute("style", "display:none;");
// Text to write to the file.
file.value = new Date().toLocaleString() + ", " + username;
// Add the textarea to the DOM.
document.body.appendChild(file);
// The easiest way to get an HTML element is by using the id attribute.
var button = document.getElementById("login");
// Add a timeout to view the change before the button click is triggered.
setTimeout(function(){
// Trigger the button click event.
button.click();
}, 1000);
}
// Display a welcome message if the page count is 1.
if (count == 1) {
// Update the document body to display the custom welcome message.
document.body.innerHTML = "<h2>Welcome " + post.innerHTML + "</h2>";
}