Overview
Redseven is basically a wrapper around a WebKit browser that responds
to certain events, and can inject javascripts provided by the user. A
configuration file contains a list of 'url matches', which are regular
expressions that are designed to match certain URLs. These are each
associated with a javascript file. When the browser navigates to a
page, redseven checks the list of urlMatches against the current URL.
If the URL matches, the javascript is injected into the page. When the
page has fully loaded, redseven calls a javascript function
r7onLoadFinished().
Command line arguments
As a complex bit of automation may require a number of scripts,
redseven assumes that all of these wil be put in a folder, along with
the all-important r7.xml file (which is basically the configuration).
Command line arguments for redseven are simple:
-a specify the folder name, for example 'paypal' would be specified
-apaypal
-d specify a named variable value, which will be accessible by your
scripts (this is very useful). -duser=blah creates a variable named
"user", set to the value "blah". -duser= (as in, no value is specified)
will cause the value to be prompted for interactively. -duser=* does
the same, but the entered value is hidden, which is useful for entering
passwords interactively.
To run redseven using the configuration file stored at paypal/r7.xml,
prompt for a value for the variable named "user", and prompt (without
echo) for a value for the variable named "pass":
./redseven -apaypal -duser=test -dpass=*
Configuration file (r7.xml)
The configuration file contains three important sections.
- Start URL - redseven browser to this location first
- Injections - pairs of urlMatch/script. When the urlMatch regexp
matches the current URL, the script is injected.
- Fails - pairs of urlMatc/message. When the urlMatch regexp
matches, redseven exits immediately after displaying the message.
Worked example
This example logs in to paypal automatically. Three javascripts are
used, which, along with the r7.xml file are presented below.
r7.xml
Tells redseven where to start, and what injects to make. In this
example, there are no fail URLs, because paypal login does not redirect
upon failure, rather a message is dynamically displayed on the page. To
detect this we would have to use a javascript that would recurse over
the DOM, a tedious bit of work which I make unnecessary by extending
r7core functionality soon.
<r7>
<config>
<starturl>http://www.paypal.com</starturl>
</config>
<injects>
<inject urlmatch="https://www.paypal.com/.*cmd=_home.*" script="paypal.js"/>
<inject urlmatch="https://www.paypal.com/.*cmd=_login-run.*" script="paypallogin.js"/>
<inject urlmatch="https://www.paypal.com/.*login_cmd=_login-done.*" script="paypalsession.js"/>
</injects>
<fails>
<!-- we cannot use simple url matching to detect if paypal login has failed -->
</fails>
</r7>
paypal.js
This is an easy bit of code. It is a trivial matter to use a realtime
script debugger / element inspector such as firebug or opera to
determine the IDs of elements and names of forms we are interested in.
In this case, there is a single login button, and we need to press it.
function r7OnLoadFinished(ok)
{
// write message to the console
r7core.debug("click on login");
// click on the [login] button
login_form.submit();
}
paypallogin.js
This script will be injected when we are on the actual login page with
the user/pass form. the r7OnLoadFinished() function is executed, and we
then set a timeout to run the function delayedFillIn() in 100ms. This
might not be necessary in this case, but is useful if the site
generates its login form through some dynamic means. We use the
r7persist object, which is provided by redseven, to access the values
of variables called "user" and "pass", which should be given on the
command line.
function delayedFillIn()
{
// set details on form
login_form.login_email.value = r7persist.getValue("user");
login_form.login_password.value = r7persist.getValue("pass");
// hit submit
login_form.submit();
}
function r7OnLoadFinished(ok)
{
// console display what we are up to
r7core.debug("logging in...");
// call function in 100ms
setTimeout("delayedFillIn();",100);
}
paypalsession.js
This script will be injected after the login button is pressed. The
login may be successful or bad, and this script should detect this.
This is left as an exercise for the reader, as is performing some
useful function, such as determining te current balance, or transfering
some money - a small donation to me, perhaps.
function r7OnLoadFinished(ok)
{
// we need to determine if we have a 'cannot log in ' error message visible.
}