ソースを参照

Merge pull request #204 from gempesaw/action-chains-experiment

Implement action chains
Daniel Gempesaw 10 年 前
コミット
3892c4d920

+ 396 - 0
lib/Selenium/ActionChains.pm

@@ -0,0 +1,396 @@
+package Selenium::ActionChains;
+
+# ABSTRACT: Action chains for Selenium::Remote::Driver
+use Moo;
+
+has 'driver' => (
+    is => 'ro',
+);
+
+has 'actions' => (
+    is => 'lazy',
+    builder => sub { [] },
+    clearer => 1,
+);
+
+sub perform {
+    my $self = shift;
+    foreach my $action (@{$self->actions}) {
+        $action->();
+    }
+}
+
+sub click {
+    my $self = shift;
+    my $element = shift;
+    if ($element) {
+       $self->move_to_element($element);
+    }
+    # left click
+    push @{$self->actions}, sub { $self->driver->click('LEFT') };
+    $self;
+}
+
+sub click_and_hold {
+    my $self = shift;
+    my $element = shift;
+    if ($element) {
+       $self->move_to_element($element);
+    }
+    push @{$self->actions}, sub { $self->driver->button_down };
+    $self;
+}
+
+sub context_click {
+    my $self = shift;
+    my $element = shift;
+    if ($element) {
+       $self->move_to_element($element);
+    }
+    # right click
+    push @{$self->actions}, sub { $self->driver->click('RIGHT') };
+    $self;
+}
+
+
+sub double_click {
+    my $self = shift;
+    my $element = shift;
+    if ($element) {
+       $self->move_to_element($element);
+    }
+    push @{$self->actions}, sub { $self->driver->double_click };
+    $self;
+}
+
+sub release {
+    my $self = shift;
+    my $element = shift;
+    if ($element) {
+       $self->move_to_element($element);
+    }
+    push @{$self->actions}, sub { $self->driver->button_up };
+    $self;
+}
+
+sub drag_and_drop {
+    my $self = shift;
+    my ($source,$target) = @_;
+    $self->click_and_hold($source);
+    $self->release($target);
+    $self;
+}
+
+sub drag_and_drop_by_offset {
+    my $self = shift;
+    my ($source,$xoffset,$yoffset) = @_;
+    $self->click_and_hold($source);
+    $self->move_by_offset($xoffset,$yoffset);
+    $self->release($source);
+    $self;
+}
+
+sub move_to_element {
+    my $self    = shift;
+    my $element = shift;
+    push @{ $self->actions },
+      sub { $self->driver->move_to( element => $element ) };
+    $self;
+}
+
+sub move_by_offset {
+    my $self = shift;
+    my ( $xoffset, $yoffset ) = @_;
+    push @{ $self->actions }, sub {
+        $self->driver->move_to( xoffset => $xoffset, yoffset => $yoffset );
+    };
+    $self;
+}
+
+sub move_to_element_with_offset {
+    my $self = shift;
+    my ( $element, $xoffset, $yoffset ) = @_;
+    push @{ $self->actions }, sub {
+        $self->driver->move_to( element => $element, xoffset => $xoffset,
+            yoffset => $yoffset );
+    };
+    $self;
+}
+
+sub key_down {
+    my $self = shift;
+    my ($value ,$element) = @_;
+    if (defined($element)) {
+        $self->click($element);
+    }
+    push @{ $self->actions }, sub { $self->driver->send_keys_to_active_element(@$value) };
+    $self;
+}
+
+sub key_up {
+    my $self = shift;
+    my ($value ,$element) = @_;
+    if (defined($element)) {
+        $self->click($element);
+    }
+    push @{ $self->actions }, sub { $self->driver->send_keys_to_active_element(@$value) };
+    $self;
+}
+
+sub send_keys {
+    my $self = shift;
+    my $keys = shift;
+    push @{ $self->actions} , sub { $self->driver->get_active_element->send_keys($keys) };
+    $self;
+}
+
+sub send_keys_to_element {
+    my $self = shift;
+    my ($element,$keys) = @_;
+    push @{ $self->actions }, sub { $element->send_keys($keys) };
+    $self;
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 SYNOPSIS
+
+    use Selenium::Remote::Driver;
+    use Selenium::ActionChains;
+
+    my $driver = Selenium::Remote::Driver->new;
+    my $action_chains = Selenium::ActionChains->new(driver => $driver);
+
+    $driver->get("http://www.some.web/site");
+    my $elt_1 = $driver->find_element("//*[\@id='someid']");
+    my $elt_2 = $driver->find_element("//*[\@id='someotherid']");
+    $action_chains->send_keys_to_element($elt_1)->click($elt_2)->perform;
+
+=head1 DESCRIPTION
+
+This module implements ActionChains for Selenium, which is a way of automating
+low level interactions like mouse movements, mouse button actions , key presses and
+context menu interactions.
+The code was inspired by the L<Python implementation|http://selenium.googlecode.com/svn/trunk/docs/api/py/_modules/selenium/webdriver/common/action_chains.html#ActionChains>.
+
+
+=head1 DRAG AND DROP IS NOT WORKING !
+
+The implementation contains a drag_and_drop function, but due to Selenium limitations, it is L<not working|https://code.google.com/p/selenium/issues/detail?id=3604>.
+
+Nevertheless, we decided to implement the function, because eventually one day it will work.
+
+In the meantime, there are workarounds that can be used to simulate drag and drop, like L<this StackOverflow post|http://stackoverflow.com/questions/29381233/how-to-simulate-html5-drag-and-drop-in-selenium-webdriver-in-python>.
+
+=head1 FUNCTIONS
+
+=head2 new
+
+Creates a new ActionChains object. Requires a Selenium::Remote::Driver as a mandatory parameter:
+
+    my $driver = Selenium::Remote::Driver->new;
+    my $action_chains = Selenium::ActionChains->new(driver => $driver);
+
+=head2 perform
+
+Performs all the actions stored in the ActionChains object in the order they were called:
+
+    Args: None
+
+    Usage:
+        my $action_chains = Selenium::ActionChains->new(driver => $driver);
+        # assuming that $some_element and $other_element are valid
+        # Selenium::Remote::WebElement objects
+        $action_chains->click($some_element);
+        $action_chains->move_to_element($other_element);
+        $action_chains->click($other_element);
+        # click some_element, move to other_element, then click other_element
+        $action_chains->perform;
+
+
+
+=head2 click
+
+Clicks an element. If none specified, clicks on current mouse position.
+
+    Args: A Selenium::Remote::WebElement object
+
+    Usage:
+        my $element = $driver->find_element("//div[\@id='some_id']");
+        $action_chains->click($element);
+
+
+=head2 click_and_hold
+
+Holds down the left mouse button on an element. If none specified, clicks on current
+mouse position.
+
+    Args: A Selenium::Remote::WebElement object
+
+    Usage:
+        my $element = $driver->find_element("//div[\@id='some_id']");
+        $action_chains->click_and_hold($element);
+
+=head2 context_click
+
+Right clicks an element. If none specified, right clicks on current mouse
+position.
+
+    Args: A Selenium::Remote::WebElement object
+
+    Usage:
+        my $element = $driver->find_element("//div[\@id='some_id']");
+        $action_chains->context_click($element);
+
+
+
+=head2 double_click
+
+Double clicks an element. If none specified, double clicks on current mouse
+position.
+
+    Args: A Selenium::Remote::WebElement object
+
+    Usage:
+        my $element = $driver->find_element("//div[\@id='some_id']");
+        $action_chains->double_click($element);
+
+=head2 drag_and_drop - NOT WORKING
+
+Holds down the left mouse button on the source element, then moves to the target
+element and releases the mouse button. IT IS NOT WORKING DUE TO CURRENT SELENIUM
+LIMITATIONS.
+
+    Args:
+       A source Selenium::Remote::WebElement object
+       A target Selenium::Remote::WebElement object
+
+    Usage:
+        my $src_element = $driver->find_element("//*[\@class='foo']");
+        my $tgt_element = $driver->find_element("//*[\@class='bar']");
+        $action_chains->drag_and_drop($src_element,$tgt_element);
+
+=head2 drag_and_drop_by_offset - NOT WORKING
+
+Holds down the left mouse button on the source element, then moves to the offset
+specified and releases the mouse button. IT IS NOT WORKING DUE TO CURRENT SELENIUM
+LIMITATIONS.
+
+    Args:
+       A source Selenium::Remote::WebElement object
+       An integer X offset
+       An integer Y offset
+
+    Usage:
+        my $src_element = $driver->find_element("//*[\@class='foo']");
+        my $xoffset = 10;
+        my $yoffset = 10;
+        $action_chains->drag_and_drop($src_element,$xoffset,$yoffset);
+
+
+=head2 key_down
+
+Sends key presses only, without releasing them.
+Should be used only with modifier keys (Control, Alt, Shift)
+
+    Args:
+        An array ref to keys to send. Use the KEY constant from Selenium::Remote::WDKeys
+        The element to send keys to. If none, sends keys to the current focused element
+
+    Usage:
+        use Selenium::Remote::WDKeys 'KEYS';
+        $action_chains->key_down( [ KEYS->{'alt'} ] );
+
+
+=head2 key_up
+
+Releases a mofifier key.
+
+    Args:
+        An array ref to keys to send. Use the KEY constant from Selenium::Remote::WDKeys
+        The element to send keys to. If none, sends keys to the current focused element
+
+    Usage:
+        use Selenium::Remote::WDKeys 'KEYS';
+        my $element = $driver->find_element('foo','id');
+        $action_chains->key_up( [ KEYS->{'alt'} ],$element);
+
+
+=head2 move_by_offset
+
+Moves the mouse to an offset from current mouse position.
+
+    Args:
+        An integer X offset
+        An integer Y offset
+
+    Usage:
+        $action_chains->move_by_offset(10,100);
+
+=head2 move_to_element
+
+Moves the mouse to the middle of an element
+
+    Args:
+        A Selenium::Remote::WebElement to move to
+
+    Usage:
+        my $element = $driver->find_element('foo','id');
+        $action_chains->move_to_element($element);
+
+
+
+=head2 move_to_element_with_offset
+
+Moves the mouse by an offset of the specified element.
+Offsets are relative to the top-left corner of the element
+
+    Args:
+        A Selenium::Remote::WebElement
+        An integer X offset
+        An integer Y offset
+
+    Usage:
+        my $element = $driver->find_element('foo','id');
+        $action_chains->move_to_element_with_offset($element,10,10);
+
+
+=head2 release
+
+Releases a held mouse_button
+
+    Args:
+        A Selenium::Remote::WebElement, the element to mouse up
+
+    Usage:
+        my $element = $driver->find_element('foo','id');
+        $action_chains->release($element);
+
+=head2 send_keys
+
+Sends keys to the currently focused element
+
+    Args:
+        The keys to send
+
+    Usage:
+        $action_chains->send_keys('abcd');
+
+=head2 send_keys_to_element
+
+Sends keys to an element
+
+    Args:
+        A Selenium::Remote::WebElement
+        The keys to send
+
+    Usage:
+        my $element = $driver->find_element('foo','id');
+        $action_chains->send_keys_to_element($element,'abcd');
+
+
+=cut

+ 48 - 0
t/11-action-chains.t

@@ -0,0 +1,48 @@
+use strict;
+use warnings;
+
+use JSON;
+use Test::More;
+use Test::Selenium::Remote::Driver;
+use Selenium::ActionChains;
+use Selenium::Remote::WDKeys 'KEYS';
+
+use FindBin;
+use lib $FindBin::Bin . '/lib';
+use TestHarness;
+
+my $harness = TestHarness->new(
+    this_file => $FindBin::Script
+);
+my %selenium_args = %{ $harness->base_caps };
+{
+    my $driver = Test::Selenium::Remote::Driver->new(%selenium_args);
+    my $action_chains = Selenium::ActionChains->new( driver => $driver );
+
+    $driver->get('https://www.google.com');
+    my $input_text = $driver->find_element("//input[\@type='text']");
+
+    # type text to search on Google and press 'Enter'
+    $action_chains->send_keys_to_element( $input_text, "test" )
+      ->key_down( [ KEYS->{'enter'} ] )->key_up( [ KEYS->{'enter'} ] )
+      ->perform;
+    $driver->find_elements_ok( "//*[\@class='hdtb-mitem']",
+        "We found Google's navbar" );
+    $driver->quit;
+}
+
+{
+    my $driver = Test::Selenium::Remote::Driver->new(%selenium_args);
+    my $action_chains = Selenium::ActionChains->new( driver => $driver );
+
+    $driver->get("http://medialize.github.io/jQuery-contextMenu/demo.html");
+    my $right_click_zone =
+      $driver->find_element("//*[contains(text(),'right click me')]");
+    $action_chains->context_click($right_click_zone)->perform;
+    $driver->find_element("//*[text()='Paste']")
+      ->is_displayed_ok("The menu is correctly displayed on right click");
+    $driver->quit;
+}
+
+
+done_testing;

+ 46 - 0
t/mock-recordings/11-action-chains-mock-MSWin32.json

@@ -0,0 +1,46 @@
+{
+   "POST session {\"desiredCapabilities\":{\"acceptSslCerts\":true,\"browserName\":\"firefox\",\"javascriptEnabled\":false,\"platform\":\"ANY\",\"version\":null}}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:30 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 581\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:40 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":null,\"sessionId\":\"10f77902-a32f-4438-950d-29f64f0b9d0f\",\"hCode\":1004900685,\"value\":{\"applicationCacheEnabled\":true,\"rotatable\":false,\"handlesAlerts\":true,\"databaseEnabled\":true,\"version\":\"27.0.1\",\"platform\":\"WINDOWS\",\"browserConnectionEnabled\":true,\"nativeEvents\":false,\"acceptSslCerts\":true,\"webdriver.remote.sessionid\":\"10f77902-a32f-4438-950d-29f64f0b9d0f\",\"webStorageEnabled\":true,\"locationContextEnabled\":true,\"browserName\":\"firefox\",\"takesScreenshot\":true,\"javascriptEnabled\":true,\"cssSelectorsEnabled\":true},\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n",
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:42 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 580\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:45 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":null,\"sessionId\":\"afba4697-fecf-4405-b7e6-094b50b6817b\",\"hCode\":284820248,\"value\":{\"applicationCacheEnabled\":true,\"rotatable\":false,\"handlesAlerts\":true,\"databaseEnabled\":true,\"version\":\"27.0.1\",\"platform\":\"WINDOWS\",\"browserConnectionEnabled\":true,\"nativeEvents\":false,\"acceptSslCerts\":true,\"webdriver.remote.sessionid\":\"afba4697-fecf-4405-b7e6-094b50b6817b\",\"webStorageEnabled\":true,\"locationContextEnabled\":true,\"browserName\":\"firefox\",\"takesScreenshot\":true,\"javascriptEnabled\":true,\"cssSelectorsEnabled\":true},\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ],
+   "POST session/10f77902-a32f-4438-950d-29f64f0b9d0f/elements {\"using\":\"xpath\",\"value\":\"//*[@class='hdtb-mitem']\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:41 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 156\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:42 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"10f77902-a32f-4438-950d-29f64f0b9d0f\",\"hCode\":826539780,\"value\":[],\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ],
+   "GET session/afba4697-fecf-4405-b7e6-094b50b6817b/element/1/displayed {}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:48 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 157\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:48 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"afba4697-fecf-4405-b7e6-094b50b6817b\",\"hCode\":65530616,\"value\":true,\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ],
+   "POST session/afba4697-fecf-4405-b7e6-094b50b6817b/moveto {\"element\":\"0\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:48 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:48 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"afba4697-fecf-4405-b7e6-094b50b6817b\",\"hCode\":1650602365,\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ],
+   "POST session/10f77902-a32f-4438-950d-29f64f0b9d0f/element {\"using\":\"xpath\",\"value\":\"//input[@type='text']\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:41 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 170\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:41 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"10f77902-a32f-4438-950d-29f64f0b9d0f\",\"hCode\":2036970995,\"value\":{\"ELEMENT\":\"0\"},\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ],
+   "DELETE session/10f77902-a32f-4438-950d-29f64f0b9d0f {}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:42 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:42 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"10f77902-a32f-4438-950d-29f64f0b9d0f\",\"hCode\":1361847628,\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ],
+   "POST session/afba4697-fecf-4405-b7e6-094b50b6817b/element {\"using\":\"xpath\",\"value\":\"//*[contains(text(),'right click me')]\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:48 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 170\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:48 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"afba4697-fecf-4405-b7e6-094b50b6817b\",\"hCode\":1735026461,\"value\":{\"ELEMENT\":\"0\"},\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ],
+   "DELETE session/afba4697-fecf-4405-b7e6-094b50b6817b {}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:48 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:48 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"afba4697-fecf-4405-b7e6-094b50b6817b\",\"hCode\":1701199990,\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ],
+   "POST session/afba4697-fecf-4405-b7e6-094b50b6817b/click {\"button\":2}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:48 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 158\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:48 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"afba4697-fecf-4405-b7e6-094b50b6817b\",\"hCode\":337250944,\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ],
+   "POST session/10f77902-a32f-4438-950d-29f64f0b9d0f/url {\"url\":\"https://www.google.com\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:40 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:41 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"10f77902-a32f-4438-950d-29f64f0b9d0f\",\"hCode\":1079278796,\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ],
+   "POST session/afba4697-fecf-4405-b7e6-094b50b6817b/element {\"using\":\"xpath\",\"value\":\"//*[text()='Paste']\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:48 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 169\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:48 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"afba4697-fecf-4405-b7e6-094b50b6817b\",\"hCode\":920587161,\"value\":{\"ELEMENT\":\"1\"},\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ],
+   "POST session/10f77902-a32f-4438-950d-29f64f0b9d0f/element/0/value {\"value\":[\"test\"]}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:41 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:41 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"10f77902-a32f-4438-950d-29f64f0b9d0f\",\"hCode\":1072790976,\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ],
+   "POST session/afba4697-fecf-4405-b7e6-094b50b6817b/url {\"url\":\"http://medialize.github.io/jQuery-contextMenu/demo.html\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:45 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 158\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:48 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"afba4697-fecf-4405-b7e6-094b50b6817b\",\"hCode\":550257166,\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ],
+   "POST session/10f77902-a32f-4438-950d-29f64f0b9d0f/keys {\"value\":[\"\"]}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:41 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:41 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"10f77902-a32f-4438-950d-29f64f0b9d0f\",\"hCode\":1917995955,\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n",
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sun, 17 May 2015 00:19:41 GMT\nServer: Jetty/5.1.x (Windows 7/6.1 amd64 java/1.8.0_31\nContent-Length: 158\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sun, 17 May 2015 00:19:41 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"state\":\"success\",\"sessionId\":\"10f77902-a32f-4438-950d-29f64f0b9d0f\",\"hCode\":317953629,\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"status\":0}\n"
+   ]
+}

+ 46 - 0
t/mock-recordings/11-action-chains-mock-darwin.json

@@ -0,0 +1,46 @@
+{
+   "GET session/84387d94-f675-407a-a1fb-1ffde8d5666c/element/1/displayed {}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:12 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:12 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"84387d94-f675-407a-a1fb-1ffde8d5666c\",\"status\":0,\"state\":\"success\",\"value\":true,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1792702889}\n"
+   ],
+   "POST session {\"desiredCapabilities\":{\"acceptSslCerts\":true,\"browserName\":\"firefox\",\"javascriptEnabled\":false,\"platform\":\"ANY\",\"version\":null}}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:05 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 544\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:07 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"8581995e-44ff-4f9a-a077-3788f39e6ff8\",\"status\":0,\"state\":null,\"value\":{\"platform\":\"MAC\",\"javascriptEnabled\":true,\"acceptSslCerts\":true,\"browserName\":\"firefox\",\"rotatable\":false,\"locationContextEnabled\":true,\"webdriver.remote.sessionid\":\"8581995e-44ff-4f9a-a077-3788f39e6ff8\",\"version\":\"36.0.4\",\"databaseEnabled\":true,\"cssSelectorsEnabled\":true,\"handlesAlerts\":true,\"webStorageEnabled\":true,\"nativeEvents\":false,\"applicationCacheEnabled\":true,\"takesScreenshot\":true},\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":966892248}\n",
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:09 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 544\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:11 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"84387d94-f675-407a-a1fb-1ffde8d5666c\",\"status\":0,\"state\":null,\"value\":{\"platform\":\"MAC\",\"javascriptEnabled\":true,\"acceptSslCerts\":true,\"browserName\":\"firefox\",\"rotatable\":false,\"locationContextEnabled\":true,\"webdriver.remote.sessionid\":\"84387d94-f675-407a-a1fb-1ffde8d5666c\",\"version\":\"36.0.4\",\"databaseEnabled\":true,\"cssSelectorsEnabled\":true,\"handlesAlerts\":true,\"webStorageEnabled\":true,\"nativeEvents\":false,\"applicationCacheEnabled\":true,\"takesScreenshot\":true},\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":640374985}\n"
+   ],
+   "POST session/84387d94-f675-407a-a1fb-1ffde8d5666c/moveto {\"element\":\"0\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:12 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 158\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:12 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"84387d94-f675-407a-a1fb-1ffde8d5666c\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":776319264}\n"
+   ],
+   "POST session/8581995e-44ff-4f9a-a077-3788f39e6ff8/element {\"using\":\"xpath\",\"value\":\"//input[@type='text']\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:08 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 169\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:09 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"8581995e-44ff-4f9a-a077-3788f39e6ff8\",\"status\":0,\"state\":\"success\",\"value\":{\"ELEMENT\":\"0\"},\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":216810905}\n"
+   ],
+   "POST session/8581995e-44ff-4f9a-a077-3788f39e6ff8/element/0/value {\"value\":[\"test\"]}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:09 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:09 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"8581995e-44ff-4f9a-a077-3788f39e6ff8\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1563200034}\n"
+   ],
+   "POST session/8581995e-44ff-4f9a-a077-3788f39e6ff8/elements {\"using\":\"xpath\",\"value\":\"//*[@class='hdtb-mitem']\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:09 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 157\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:09 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"8581995e-44ff-4f9a-a077-3788f39e6ff8\",\"status\":0,\"state\":\"success\",\"value\":[],\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1544679395}\n"
+   ],
+   "DELETE session/8581995e-44ff-4f9a-a077-3788f39e6ff8 {}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:09 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 158\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:09 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"8581995e-44ff-4f9a-a077-3788f39e6ff8\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":670443577}\n"
+   ],
+   "POST session/8581995e-44ff-4f9a-a077-3788f39e6ff8/url {\"url\":\"https://www.google.com\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:07 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:08 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"8581995e-44ff-4f9a-a077-3788f39e6ff8\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1448893803}\n"
+   ],
+   "POST session/84387d94-f675-407a-a1fb-1ffde8d5666c/element {\"using\":\"xpath\",\"value\":\"//*[contains(text(),'right click me')]\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:12 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 169\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:12 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"84387d94-f675-407a-a1fb-1ffde8d5666c\",\"status\":0,\"state\":\"success\",\"value\":{\"ELEMENT\":\"0\"},\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":753180193}\n"
+   ],
+   "POST session/84387d94-f675-407a-a1fb-1ffde8d5666c/url {\"url\":\"http://medialize.github.io/jQuery-contextMenu/demo.html\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:11 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 158\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:12 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"84387d94-f675-407a-a1fb-1ffde8d5666c\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":234318942}\n"
+   ],
+   "POST session/84387d94-f675-407a-a1fb-1ffde8d5666c/click {\"button\":2}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:12 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:12 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"84387d94-f675-407a-a1fb-1ffde8d5666c\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1290489623}\n"
+   ],
+   "POST session/84387d94-f675-407a-a1fb-1ffde8d5666c/element {\"using\":\"xpath\",\"value\":\"//*[text()='Paste']\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:12 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 170\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:12 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"84387d94-f675-407a-a1fb-1ffde8d5666c\",\"status\":0,\"state\":\"success\",\"value\":{\"ELEMENT\":\"1\"},\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1355338077}\n"
+   ],
+   "DELETE session/84387d94-f675-407a-a1fb-1ffde8d5666c {}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:12 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 158\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:12 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"84387d94-f675-407a-a1fb-1ffde8d5666c\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":365077409}\n"
+   ],
+   "POST session/8581995e-44ff-4f9a-a077-3788f39e6ff8/keys {\"value\":[\"\"]}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:09 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:09 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"8581995e-44ff-4f9a-a077-3788f39e6ff8\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1533862104}\n",
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Sat, 16 May 2015 23:41:09 GMT\nServer: Jetty/5.1.x (Mac OS X/10.10.3 x86_64 java/1.7.0_67\nContent-Length: 158\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Sat, 16 May 2015 23:41:09 GMT\nClient-Peer: ::1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"8581995e-44ff-4f9a-a077-3788f39e6ff8\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":634949849}\n"
+   ]
+}

+ 46 - 0
t/mock-recordings/11-action-chains-mock-linux.json

@@ -0,0 +1,46 @@
+{
+   "POST session/3931ba86-e2dc-4dcb-b0b8-ff2974c59db8/url {\"url\":\"https://www.google.com\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:17 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 157\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:18 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"3931ba86-e2dc-4dcb-b0b8-ff2974c59db8\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":23829224}\n"
+   ],
+   "POST session/3931ba86-e2dc-4dcb-b0b8-ff2974c59db8/elements {\"using\":\"xpath\",\"value\":\"//*[@class='hdtb-mitem']\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:18 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 157\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:18 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"3931ba86-e2dc-4dcb-b0b8-ff2974c59db8\",\"status\":0,\"state\":\"success\",\"value\":[],\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1717827636}\n"
+   ],
+   "POST session {\"desiredCapabilities\":{\"acceptSslCerts\":true,\"browserName\":\"firefox\",\"javascriptEnabled\":false,\"platform\":\"ANY\",\"version\":null}}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:16 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 547\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:17 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"3931ba86-e2dc-4dcb-b0b8-ff2974c59db8\",\"status\":0,\"state\":null,\"value\":{\"platform\":\"LINUX\",\"javascriptEnabled\":true,\"acceptSslCerts\":true,\"browserName\":\"firefox\",\"rotatable\":false,\"locationContextEnabled\":true,\"webdriver.remote.sessionid\":\"3931ba86-e2dc-4dcb-b0b8-ff2974c59db8\",\"version\":\"37.0.2\",\"databaseEnabled\":true,\"cssSelectorsEnabled\":true,\"handlesAlerts\":true,\"webStorageEnabled\":true,\"nativeEvents\":false,\"applicationCacheEnabled\":true,\"takesScreenshot\":true},\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1923882051}\n",
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:18 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 546\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:20 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"22a948eb-4101-45dd-92a5-7181b7b03240\",\"status\":0,\"state\":null,\"value\":{\"platform\":\"LINUX\",\"javascriptEnabled\":true,\"acceptSslCerts\":true,\"browserName\":\"firefox\",\"rotatable\":false,\"locationContextEnabled\":true,\"webdriver.remote.sessionid\":\"22a948eb-4101-45dd-92a5-7181b7b03240\",\"version\":\"37.0.2\",\"databaseEnabled\":true,\"cssSelectorsEnabled\":true,\"handlesAlerts\":true,\"webStorageEnabled\":true,\"nativeEvents\":false,\"applicationCacheEnabled\":true,\"takesScreenshot\":true},\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":898359747}\n"
+   ],
+   "POST session/22a948eb-4101-45dd-92a5-7181b7b03240/url {\"url\":\"http://medialize.github.io/jQuery-contextMenu/demo.html\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:20 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 158\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:21 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"22a948eb-4101-45dd-92a5-7181b7b03240\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":169615849}\n"
+   ],
+   "POST session/22a948eb-4101-45dd-92a5-7181b7b03240/click {\"button\":2}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:21 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:21 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"22a948eb-4101-45dd-92a5-7181b7b03240\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1285538535}\n"
+   ],
+   "POST session/22a948eb-4101-45dd-92a5-7181b7b03240/moveto {\"element\":\"0\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:21 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 158\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:21 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"22a948eb-4101-45dd-92a5-7181b7b03240\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":612866572}\n"
+   ],
+   "DELETE session/22a948eb-4101-45dd-92a5-7181b7b03240 {}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:22 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:22 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"22a948eb-4101-45dd-92a5-7181b7b03240\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":2134262868}\n"
+   ],
+   "POST session/3931ba86-e2dc-4dcb-b0b8-ff2974c59db8/keys {\"value\":[\"\"]}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:18 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:18 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"3931ba86-e2dc-4dcb-b0b8-ff2974c59db8\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1952000828}\n",
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:18 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 158\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:18 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"3931ba86-e2dc-4dcb-b0b8-ff2974c59db8\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":916855601}\n"
+   ],
+   "POST session/22a948eb-4101-45dd-92a5-7181b7b03240/element {\"using\":\"xpath\",\"value\":\"//*[contains(text(),'right click me')]\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:21 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 169\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:21 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"22a948eb-4101-45dd-92a5-7181b7b03240\",\"status\":0,\"state\":\"success\",\"value\":{\"ELEMENT\":\"0\"},\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":500426191}\n"
+   ],
+   "POST session/3931ba86-e2dc-4dcb-b0b8-ff2974c59db8/element/0/value {\"value\":[\"test\"]}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:18 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:18 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"3931ba86-e2dc-4dcb-b0b8-ff2974c59db8\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1498447564}\n"
+   ],
+   "GET session/22a948eb-4101-45dd-92a5-7181b7b03240/element/1/displayed {}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:22 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:22 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"22a948eb-4101-45dd-92a5-7181b7b03240\",\"status\":0,\"state\":\"success\",\"value\":true,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1325008783}\n"
+   ],
+   "DELETE session/3931ba86-e2dc-4dcb-b0b8-ff2974c59db8 {}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:18 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 159\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:18 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"3931ba86-e2dc-4dcb-b0b8-ff2974c59db8\",\"status\":0,\"state\":\"success\",\"value\":null,\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1760992235}\n"
+   ],
+   "POST session/3931ba86-e2dc-4dcb-b0b8-ff2974c59db8/element {\"using\":\"xpath\",\"value\":\"//input[@type='text']\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:18 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 170\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:18 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"3931ba86-e2dc-4dcb-b0b8-ff2974c59db8\",\"status\":0,\"state\":\"success\",\"value\":{\"ELEMENT\":\"0\"},\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":1026878616}\n"
+   ],
+   "POST session/22a948eb-4101-45dd-92a5-7181b7b03240/element {\"using\":\"xpath\",\"value\":\"//*[text()='Paste']\"}" : [
+      "HTTP/1.1 200 OK\nCache-Control: no-cache\nCache-Control: no-cache\nConnection: close\nDate: Wed, 13 May 2015 13:41:21 GMT\nServer: Jetty/5.1.x (Linux/3.13.0-52-generic amd64 java/1.7.0_79\nContent-Length: 170\nContent-Type: application/json; charset=utf-8\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\nClient-Date: Wed, 13 May 2015 13:41:22 GMT\nClient-Peer: 127.0.0.1:4444\nClient-Response-Num: 1\n\n{\"sessionId\":\"22a948eb-4101-45dd-92a5-7181b7b03240\",\"status\":0,\"state\":\"success\",\"value\":{\"ELEMENT\":\"1\"},\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":2003185629}\n"
+   ]
+}