ActivIT Automatron  (beta v0.1) user manual

What is ActivIT Automatron?

ActivIT Automatron is a Google Chrome browser plugin, a scripting tool for internet browsing automation. By executing instructions contained in a javascript "TRON" file it automatically browses the web, clicks on links, fills out forms, etc.

Its main advantage over other web automation/testing tools such as Selenium is its simplicity, ease of installation and use. Unlike many others, this tool allows you to store variables, use conditions, execute procedures and has an AJAX support. It only requires minimal programming skills to get it running.

We presume you are familiar with the basics of JavaScript if you want to use the plugin.

ActivIT Automatron can be used as a tool for web developers to test the funcionality of websites or for anyone else who needs to automate recurring "tasks" in the browser. The plugin can be used for whatever the user comes up with. If you are going to use this plugin, we presume that you are familiar with the basics of JavaScript.

Usage

Automatron needs a "TRON" file with instructions to run. If you already have such file, you can upload it by clicking on the plugin icon. In the plugin window click on the "Upload TRON file" and select the file you want to run.

- Please note that after you enable the plugin, it will not work with already opened tabs - you need to open new tab! -

After the file has been uploaded the "Start", "Stop" and "Pause" buttons can be used to control the execution of script.

The "Forced delay" checkbox delays the execution of each instruction by 1 second.

The "Animate instructions" checkbox displays an additional mouse cursor that shows which DOM element is being affected by the instruction that is currently being executed.

Press F12 and click on the Automatron tab to see the log.

In order to display log records press F12 and switch to the Automatron tab in the window that pops up. Here are the logging messages of TRON execution displayed. A button for filtering the log records is located on the right side. The buttons "Start", "Stop" and "Pause" are available here too, with addition of few features like "copy to clipboard" or "scroll to bottom".

Structure of TRON file

A valid TRON file must contain at least a main function, the name of which cannot be changed: function tron_main(step) {}.

The "step" parameter contains the current step in the TRON file that is going to be executed. After each page load the step is automatically incremented and the current step of TRON script is executed. Initial step is always 0 and should contain tron_visit() instruction.

The body of the main function (or procedure) contains "instructions" or "helper functions" that will interact with DOM elements of loaded page. Instructions are commands for interacting with DOM elements, like click on button, write to textfield, or calling a procedure. Helper functions allow you to use conditions or store variables during run of TRON.

The TRON script is always executed after the $(document).ready() event. Since step is incremented after every page load, one step must contain only one instruction that is causing a page load (eg. click on a link, form submission) and that instruction should be the last in the step.

The step of TRON execution is incremented after each page load.

Automatron also allows you to define so called "procedures" - useful for executing subroutine tasks multiple times without writing the same code twice. Procedures have the same structure as main function and are defined in the same file. They can be called from the main function or another procedure. Read more about using procedures.

Here's an example TRON file you can use while creating your own script:

// Declare your constants here (these variables are reseted after every pageload)
var WEBSITE_URL = 'http://www.yourwebsite.com';

/**
 * Main function, executed after start of TRON. Please DO NOT change the name of this function.
 */
function tron_main(step) {

  // Step is incremented after every page load
  switch (step) {

    // First step executed after start of TRON is 0.
    // Allways should contain tron_visit() instruction with TRON's initial url location.
    case 0:

      tron_visit(WEBSITE_URL);
      break;

    case 1:

      // ...YOUR INSTRUCTIONS HERE...
      break;

    case 2:

      // ...YOUR INSTRUCTIONS HERE...
      break;

    // Last step should allways contains tron_end() to terminate run of TRON
    case 3:

      tron_end('Last step!');
      break;

    // This should not be executed if everything is allright.
    default:
      tron_end('Seems like step order is corrupted or tron_end() is missing in last executed step!');
  }
}

Instructions

Instructions are primary functions of the Automatron plugin and majority of them simulates an user action, eg. click, checkbox tick, etc. Some instructions are used for controlling script execution, eg. pause, stop or procedure call. All the user action simulating instructions have an optional delay parameter that specifies time in seconds that will delay execution of the instruction. Please note that a new page load triggering instruction should be the last and the only one in a step. It is not possible for example to click at the two menu items simultaneously in a single step/pageload.

List of instructions:

tron_visit(url) Loads a page with a specified absolute URL in the currently opened browser tab.

tron_click(selector, delay) Executes a click on the specified DOM element.

tron_fill(selector, value, delay) Fills in the specified form input or text area with the given value.

tron_select(selector, value, delay) Selects the specified option from the select element.

tron_check(selector, delay) Ticks the specified checkbox.

tron_uncheck(selector, delay) Unticks the specified checkbox.

tron_after(selector, event, callback, delay) Executes given callback function after the specified "event" has occured on the specified DOM element. Used primarily for setting listener to an AJAX action. Currently, only the value "appears" is supported for the event parameter.

tron_execute(procedurename, params) Executes specified procedure. It can be called from main function or other procedures. It is also possible to pass an object with custom parameters as a second parameter of tron_execute function. Note that this instruction allways increments step and should be also used as the last one in a step, even if the called procedure does not contains any page load triggering instructions.

tron_return() Stops the execution of the currently executed procedure and continues with the execution of the next step in a main function or previous procedure, from which the procedure was called.

tron_interrupt(logmessage) Pauses the TRON file execution. The execution can be resumed by manually clicking at a "Resume" button.

tron_end(logmessage) Stops the TRON script execution. Every TRON execution should end with this instruction, otherwise you will have to stop the execution manually by clicking at a "Stop" button.

Helper functions

In some cases, you need to store a persistent variable that will be accesible during the whole run of script. Or you may need to use conditions and alter the execution of the script based on the content of the current page, the existence of a specific DOM element or a URL query param, etc.

This should be done by the "helper functions". For maintaining full functionality of the plugin, these helper functions, eg. if(_tron_exists('#login'))), should always be used for making a conditions instead of classic javascript conditions, eg. if($('#login').length).

Always use Automatron's helper functions (eg. if(_tron_exists('#login'))) instead of classic javascript conditions (eg. if($('#login').length)).

List of helper functions:

_tron_content(selector) (string) Returns the HTML content of the specified DOM element.

_tron_contains(selector, value) (boolean) Checks whether the specified DOM element contains the given value. Returns TRUE if it does, FALSE otherwise.

_tron_value(selector) (mixed) Returns the value attribute of the specified form element.

_tron_exists(selector) (boolean) Returns TRUE if the loaded page contains at least one DOM element that matches the selector.

_tron_variable(varname, value) (-/mixed) Persistently stores the variable if the "value" parameter is specified, otherwise returns the value of specified stored variable.

_tron_log(logtype, logmessage) (-) Records a log message with arbitrary type that will be displayed in Automatron log.

Instructions and helper functions parameters

url (string) Absolute URL of a page that is to be opened (including http(s)://)

selector (string) jQuery selector of a DOM element on which the instruction or helper function is to be executed.

value (mixed) Value to be used for a instruction or helper function.

delay (int) Optional parameter. Time (in seconds) which delays the execution of a given function. In case "Forced delay" is active, 1 second will be added to the time specified by this parameter.

event (string) Specifies the event on the occurence of which the callback of the tron_before() instruction will be executed. Currently, only the value "appears" is supported.

callback (function) Function to be executed after the specified "event" occured on a given DOM element.

procedurename (string) The name of a procedure that will be executed from the one that is currently being executed.

params (object) Optional parameter. An object containing arbitrary values that will be passed as a parameter for the helper function.

(string) logtype Log message type, arbitrary value. Reserved values are "step", "intention", "notfound", "multiplefound".

logmessage (string) Arbitrary message that will be recored to the log.

Use cases

Basic use:

One TRON step stands for a single page load. The current TRON step is automatically incremented after every page load. That is the reason why each step should contain only one (and last) instruction causing a new page load (e.g. click on link), but can have multiple "non-redirecting" instructions (e.g. fill in textbox, check checkbox...). In order for the TRON to stop execution correctly, the last step should contain the tron_end() instruction.

In the example below the second step specifies a delay of one second passed as the third parameter to the tron_fill() command. All three instructions in step 3 will follow each another with a delay of one second.

function tron_main(step) {

  switch (step) {

    /* Step 0: should allways contain a tron_visit() instructions. */
    case 0:

      tron_visit('http://www.example.com');
      break;


    /* Step 1: click at login button */
    case 1:

      tron_click('#login-button');
      break;

    /* Step 2: fill username and password, then submit login form. */
    case 2:

      tron_fill('#login-form input.username', 'admin', 1);
      tron_fill('#login-form input.password', 'password123', 1);
      tron_click('#login-form input[type="submit"]', 1);
      break;

    /* Step 3: end run of TRON properly */
    case 3:

      tron_end('End of TRON, we should be logged in').
      break;

    /* This should never be triggered */
    default:
      tron_end('Seems like step order is corrupted or tron_end() is missing!');

  }
}

The use of conditions

In the following example, we presume we do not know whether the user will be logged in or not. If the user is not logged in we will log user in, otherwise we skip the login process and go directly to step 3. The conditions are used in the first and the third step.

function tron_main(step) {

  switch (step) {

    /* Step 0: should allways contain a redirect to TRON's starting page */
    case 0:

      tron_visit('http://www.example.com');
      break;


    /* Step 1: check if we are loggen in. If not, log user in, else go to step 3. */
    case 1:

      // if #logout button exists we are logged in
      if(_tron_exists('#logout')) {

        // go to step 3
        tron_goto(3);

      // if we are not logged in
      } else {

        // click at login button
        tron_click('#login-button');
      }

      break;

    /* Step 2: fill username and password, then submit and log user in. */
    case 2:

      tron_fill('#login-form input.username', 'admin');
      tron_fill('#login-form input.password', 'password123');
      tron_click('#login-form input[type="submit"]');
      break;

    /* Step 3: check if we are really logged in and eterminate run of TRON properly */
    case 3:

      // if #username element exists and contains 'admin'
      if(_tron_contains('#username', 'admin')) {

        tron_end('End of TRON, we are be definitely logged in!');
      } else {

        tron_end('End of TRON, we are not logged in. Something went wrong!');
      }

      break;

    /* This should never be triggered */
    default:
      tron_end('Seems like step order is corrupted or tron_end() is missing!');

  }
}

The use of procedures

If there is repetitive code in some parts of our TRON script or you want to split the file into multiple logical chunks, "procedures" are exactly what we need. A procedure can be run using the tron_execute(procedure, params) instruction. In order to end the execution of a procedure you can use the tron_return() instruction. That will tell the Automatron to continue with the execution of the previous function from which our procedure was called.

In the following example, we try to login a user using the tron_login procedure. In case the first user fails to log in, we will use the credentials of another user using the same procedure.

function tron_main(step) {

  switch (step) {

    case 0:

      tron_visit('http://www.example.com');
      break;

    /* Step: 1: Try to log first user in */
    case 1:

      // log first user in using procedure
      tron_execute('tron_login', {
        username:'user1',
        password:'password123'
      });

      break;

    /* Step 2: Check if we are logged in. If not, try to log second user in, otherwise terminate TRON. */
    case 2:

      // logout button exists so we are logged in
      if(_tron_exists('#logout')) {

        // end of execution
        tron_end('We are logged in as user1!');

      // logging was unsuccesfull, try to log second user in
      } else {

        // log second user in using the same procedure
        tron_execute('tron_login', {
          username:'user2',
          password:'password456'
        });
      }

      break;

    /* Step 3: terminate run of TRON properly if not terminated yet */
    case 3:

      if(_tron_exists('#logout')) {
        tron_end('End of TRON, we are logged in as user2!');
      } else {
        tron_end('End of TRON, none of the users was loggen in!');
      }

      break;

    /* This should never be triggered */
    default:
      tron_end('Seems like step order is corrupted or tron_end() is missing!');

  }
}

The tron_login() procedure and the use of parameters (located in the same file as the main function):

/**
 * This procedure will try to log user in with given username and password
 */
function tron_login(step, params) {

  switch (step) {

    case 0:

      tron_click('#login-button');
      break;

    case 1:

      tron_fill('#login-form input.username', params.username);
      tron_fill('#login-form input.password', params.password);
      tron_click('#login-form input[type="submit"]');
      break;

    case 3:

      // Log the result of this login attempt
      if(_tron_contains('#username', 'admin')) {
        tron_log('We are sucessfuly logged in!');
      } else {
        tron_log('We are not logged in. Something went wrong!');
      }

      // end of procedure and return to the main function
      tron_return();

      break;
    }
}

Storing and reading variables

Sometimes you need to store or modify a persistent variable that will be accessible in later TRON steps. You can use helper function _tron_variable(varname, value) for this. If you specify the second "value" parameter, it will store or modify the value of the specified variable, otherwise it will return the value of specified variable.

The following example reads and store the name of logged in user, that wil be later used for text input in a contact form.

function tron_main(step) {

  switch (step) {

    case 0:

      tron_visit('http://www.example.com');
      break;

    case 1:

      // store the usernname of logged in user
      var name = _tron_content('span#logged-user');
      _tron_variable('username', name);

      // go to contact page
      tron_click('#navigation a[href="contact"]');

      break;

    case 2:

      // read username variable and fill the value to an input of a contact form
      var name =  _tron_variable('username');
      tron_fill('#contact-form input.name', name);

      // submit form
      tron_click('#contact-form input[type="submit"]');

      break

    /* End of TRON */
    case 3:

      tron_end('Variables works!');
      break;

    /* This should never be triggered */
    default:
      tron_end('Seems like step order is corrupted or tron_end() is missing!');

  }
}

Javascript and AJAX

Sometimes, for example a click on a button can initiate an AJAX callback or JavaScript code that alters the DOM structure in some way. In such case, we may want to execute next instruction/s only after the callback is done.

The first method is the use of delay in the following instruction. This will cause the instruction to wait for a specified amount of time while the DOM structure is being altered. In some cases, however, it is not a good approach to wait for an already specified amount of time while the DOM is being altered or AJAX response callback being executed. Therefore, the second option is to use the instruction tron_after(), which executes the callback that contains another instructions only after the occurence of an event on the specified DOM element (the current version only supports the "appears" parameter).

The following example ticks an AJAX checkbox in a form and the AJAX callback appends a new textfield into the form. The textfield is then filled out and the form is submitted.

function tron_main(step) {

  switch (step) {

    case 0:

      tron_visit('http://www.example.com');
      break;

    /* After checking checkbox wait for AJAX response and then fill appended text input */
    case 1:

      // check the checkbox
      tron_check('#ajax-form input[type="checkbox]');

      // wait and execute next instructions only after text input appears in a form
      tron_after('#ajax-form input[type="text"]', 'appears', function() {

        // fill text input and submit form
        tron_fill('#ajax-form input[type="text"]', 'Hello, this is Automatron!');
        tron_click('#ajax-form input[type="submit"]');
      });

      break;

    case 2:

      tron_end('Ajax form works well!');
      break;

    default:
      tron_end('Seems like step order is corrupted or tron_end() is missing!');

  }
}