This artifact consists of:
The page Getting started describes how to run a quick experiment to check if everything works as it should.
The page Usage instructions describes how to use AjaxRacer.
The page Install instructions describes how to install AjaxRacer on a fresh Ubuntu 14.04.5 machine (i.e., how to derive the virtual machine that has already been prepared).
1The username and password of the virtual machine is "ajaxracer".
The reader may choose to use the pre-configured virtual machine, or follow the install instructions. To use the pre-configured virtual machine
vm.ova, open VirtualBox and import
vm.ova via "Import Appliance..." in the File menu.
We recommend using the following VirtualBox settings for the virtual machine:
AjaxRacer has been installed in the directory
~/ajaxracer/ in the virtual machine. The usage instructions on this page are relative to this directory. Hence, start by opening a terminal and stepping into this directory:
Run AjaxRacer on one of the tests too check that AjaxRacer and its dependencies have been installed correctly by issuing following command (this will take a few minutes):
./ajaxracer.js --run-id test --url test/ajax_nondeterministic_ui/index.html
Then run the following command to serve the report using a local HTTP server (note that this command will build the web site, which takes a few minutes):
npm run report
Just getting started? Check Getting started.
Consider the web page in the directory
test/ajax_nondeterministic_ui/ (see on GitHub). This example illustrates the essence of an observable AJAX race. AjaxRacer can be applied to this page by issuing the following command:
./ajaxracer.js --run-id test --url test/ajax_nondeterministic_ui/index.html
The argument passed to the
--run-id option is simply an identifier for the run. It merely specifies which directory that should be used for the output and does not need to be unique. In this case, the result of the run is stored in the
The URL is automatically converted to http://localhost:8080/test/ajax_nondeterministic_ui/index.html as the path points to a test on the disk (AjaxRacer starts an HTTP server on port 8080 on its own).
By default, AjaxRacer uses a headless instance of Google Chrome. This can be circumvented by passing the flag
--no-headless. This is mostly intended for testing purposes, though.
When executing the
./ajaxracer.js command, the following happens:
Phase 1 of AjaxRacer is run (described in ) using the script in
This script starts a proxy server on port 8081 (using
instrumentation_server/proxy.py). The actual instrumentation is carried out by
When the proxy server has been started, the web page is loaded in Google Chrome using the Protractor testing framework (using
src/utils/protractor.js). The interaction with the web page is carried out by the Protractor test script
driver/spec.js. This script waits for the web application to load, and then sends a message to the web application that will generate a trace for every event handler. This is carried out by the analysis that is injected into the web application by the instrumentation. The key components responsible for generating the traces are
Finally, the results are stored by
driver/spec.js to the disk.
Phase 2 of AjaxRacer is run using the script in
This script will analyze the traces from Phase 1 to find "potentially AJAX conflicting pairs of user event handlers". For each such pair, the script runs the given pair of user event handlers in "synchronous" mode and "adverse" mode . This involves starting a proxy server and loading the web application in the browser using the Protractor testing framework, similar to the way Phase 1 works.
Unlike in Phase 1, though, the Protractor test script
driver/spec.js will cause
src/analysis/modes/synchronous-mode-execution.js to run in the browser.
The results of the run can be viewed in the browser by issuing the command
npm run report. This command will compile the TypeScript source files in the
Note that it is only necessary to run this command once: if AjaxRacer is applied to a website after this command is run, the results will automatically become available at http://localhost:3000/, if the page is reloaded.
The generated report should look similar to the one that was automatically generated for the experiments from . This report is available at http://www.brics.dk/experiments/.
The experiments from  can be run by issuing the following command (note that this takes several hours):
This script is essentially just a wrapper around
./ajaxracer.js. For example, to run the experiments for the web page "Customize your MacBook" on https://www.apple.com/, one can issue one of the following commands:
./ajaxracer.js --run-id apple-customize-macbook --url "https://www.apple.com/shop/buy-mac/macbook?product=MNYF2LL/A&step=config"
./run-experiments.js --filter apple-customize-macbook
Note that AjaxRacer runs on the live versions of the web pages from . As a consequence, it will not necessarily be possible to reproduce the results if some of these web pages change. As of June 2018, some web pages have been redesigned (e.g., https://www.chevronwithtechron.com/station used to look like this, http://www.fanniemae.com/portal/jsp/search.html used to look like this) and others have been updated in a way that affects the results (e.g., the tabs on https://www.apple.com/accessibility/iphone no longer use AJAX but instead redirect the user to a different web page).
AjaxRacer comes with a set of tests in the
test/ directory. These tests can be run using the following command (this indirectly invokes the script
To run only tests that matches "ajax_nondeterministic_ui/", one can issue the following command:
npm test -- --filter "ajax_nondeterministic_ui/"
The traces that result from executing the tests will be output to the
out/ directory, and will be compared to the expected traces, which are stored in
./debug.sh is useful for debugging. It automatically starts the proxy server and launches Google Chrome with proper flags for using the proxy server to automatically instrument whatever website is visited.
This way it is possible to debug errors in the instrumentation and the dynamic analysis using the developer toolbar in the browser.
Instructions for installing AjaxRacer and its dependencies are available in the
INSTALL.md from the GitHub repository. This page repeats these instructions for the reader's convenience.
The following install instructions have been tested on Ubuntu 14.04.5, and can be used to derive the virtual machine that has been included with the AjaxRacer artifact.
sudo apt update sudo apt install curl git graphviz
Install Node.js and the NPM package manager
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install -y nodejs
Install Node.js v8.9.4 using the NPM package n
sudo npm install -g n sudo n 8.9.4
Verify that the Node.js v8.9.4 is installed by running
Install the following NPM packages
sudo npm install -g http-server lite-server @firstname.lastname@example.org
Install Google Chrome from https://www.google.com/chrome.
Install Protractor using NPM
sudo npm install -g email@example.com sudo webdriver-manager update
Install mitmproxy v0.17:
sudo apt install python-pip python-dev libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev zlib1g-dev sudo pip install -U pip sudo pip install mitmproxy==0.17
Troubleshooting: If the last command fails with an error, try to reinstall Python 2.7 (this should remove some packages that will be installed with mitmproxy):
sudo apt remove python-2.7 sudo apt install python-2.7
It may be necessary to run
sudo apt-get install ubuntu-desktop to prevent a blank screen after rebooting.
Install the mitmproxy certificate (needed for AjaxRacer to work with web applications that use SSL):
mitmdump -p 8080.
Open http://mitm.it/ in Google Chrome by issuing the following command after closing all instances of Google Chrome:
google-chrome-stable http://mitm.it/ --proxy-server="127.0.0.1:8080"
Download the mitmproxy certificate
mitmproxy-ca-cert.pem for Ubuntu by clicking on the button "Other".
Install the mitmproxy certificate: Open chrome://settings/certificates in Google Chrome, click on "Authorities", and import the certificate
mitmproxy-ca-cert.pem. In addition, issue the following commands.
sudo cp ~/Downloads/mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/mitmproxy-ca-cert.crt sudo update-ca-certificates
Test that the mitmproxy certificate is installed correctly by running the following command.
google-chrome-stable https://github.com/cs-au-dk/ajaxracer --proxy-server="127.0.0.1:8080"
If mitmproxy has not been setup properly, Google Chrome will show a warning saying "Your connection is not private".
Issue the following commands to install AjaxRacer.
git clone https://github.com/cs-au-dk/ajaxracer.git cd ajaxracer npm install (cd report/; npm install)
See Getting started.