diff --git a/composer.lock b/composer.lock
index 725d8b5bb020ab4fb6380cd86d224c7ca9b27802..58be85866c8ec563983f6a0ee924d25738a240e0 100644
--- a/composer.lock
+++ b/composer.lock
@@ -2004,7 +2004,7 @@
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/6bfcdcfe0aab6c11dcccfbd28dea01a592afd5b3",
+                "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/6196fdb001faf681f92db2ae10abafb5815affde",
                 "reference": "47bb3388cfeae41a38087ac8465a7d08fa92ea2e",
                 "shasum": ""
             },
@@ -2642,6 +2642,67 @@
             ],
             "time": "2015-10-07 11:40:41"
         },
+        {
+            "name": "jcalderonzumba/mink-phantomjs-driver",
+            "version": "dev-master",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/jcalderonzumba/MinkPhantomJSDriver.git",
+                "reference": "10d7c48c9a4129463052321b52450d98983c4332"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/jcalderonzumba/MinkPhantomJSDriver/zipball/10d7c48c9a4129463052321b52450d98983c4332",
+                "reference": "10d7c48c9a4129463052321b52450d98983c4332",
+                "shasum": ""
+            },
+            "require": {
+                "behat/mink": "~1.6",
+                "jcalderonzumba/gastonjs": "~1.0",
+                "php": ">=5.4",
+                "twig/twig": "~1.8"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~4.6",
+                "silex/silex": "~1.2",
+                "symfony/css-selector": "~2.1",
+                "symfony/phpunit-bridge": "~2.7",
+                "symfony/process": "~2.3"
+            },
+            "type": "mink-driver",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "0.4.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Zumba\\Mink\\Driver\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Juan Francisco Calderón Zumba",
+                    "email": "juanfcz@gmail.com",
+                    "homepage": "http://github.com/jcalderonzumba"
+                }
+            ],
+            "description": "PhantomJS driver for Mink framework",
+            "homepage": "http://mink.behat.org/",
+            "keywords": [
+                "ajax",
+                "browser",
+                "headless",
+                "javascript",
+                "phantomjs",
+                "testing"
+            ],
+            "time": "2015-10-05 18:24:44"
+        },
         {
             "name": "mikey179/vfsStream",
             "version": "v1.6.0",
@@ -3730,6 +3791,7 @@
         "behat/mink": 0,
         "behat/mink-goutte-driver": 0,
         "jcalderonzumba/gastonjs": 20,
+        "jcalderonzumba/mink-phantomjs-driver": 20,
         "mikey179/vfsstream": 0,
         "phpunit/phpunit": 0,
         "symfony/css-selector": 0
diff --git a/core/composer.json b/core/composer.json
index 4d08cca71482ea06b4926aa370c459be31bf2ecc..fd33b45b7d1094ff27eac8c2e91c510f0d1aabe4 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -35,6 +35,7 @@
     "behat/mink": "~1.6",
     "behat/mink-goutte-driver": "~1.2",
     "jcalderonzumba/gastonjs": "^1.1@dev",
+    "jcalderonzumba/mink-phantomjs-driver": "dev-master#10d7c48c9a4129463052321b52450d98983c4332",
     "mikey179/vfsStream": "~1.2",
     "phpunit/phpunit": "~4.8",
     "symfony/css-selector": "2.7.*"
diff --git a/core/lib/Drupal/Core/Composer/Composer.php b/core/lib/Drupal/Core/Composer/Composer.php
index 112913d385f51d2e3ed621600393aba39eaefbde..50e694256f9361a613967141fa4c35fe0190d0aa 100644
--- a/core/lib/Drupal/Core/Composer/Composer.php
+++ b/core/lib/Drupal/Core/Composer/Composer.php
@@ -31,9 +31,8 @@ class Composer {
     'fabpot/goutte' => ['Goutte/Tests'],
     'guzzlehttp/promises' => ['tests'],
     'guzzlehttp/psr7' => ['tests'],
-    'jcalderonzumba/gastonjs' => ['docs'],
-    'jcalderonzumba/gastonjs' => ['examples'],
-    'jcalderonzumba/gastonjs' => ['tests'],
+    'jcalderonzumba/gastonjs' => ['docs', 'examples', 'tests'],
+    'jcalderonzumba/mink-phantomjs-driver' => ['tests'],
     'masterminds/html5' => ['test'],
     'mikey179/vfsStream' => ['src/test'],
     'phpdocumentor/reflection-docblock' => ['tests'],
diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php
index b948ef6a81b46357d72ae61d29037b5fd67d9644..030a0de768aaf8b3ee5e11b22cc34faa49e16141 100644
--- a/vendor/composer/autoload_psr4.php
+++ b/vendor/composer/autoload_psr4.php
@@ -6,6 +6,7 @@
 $baseDir = dirname($vendorDir);
 
 return array(
+    'Zumba\\Mink\\Driver\\' => array($vendorDir . '/jcalderonzumba/mink-phantomjs-driver/src'),
     'Zumba\\GastonJS\\' => array($vendorDir . '/jcalderonzumba/gastonjs/src'),
     'Zend\\Stdlib\\' => array($vendorDir . '/zendframework/zend-stdlib/src'),
     'Zend\\Hydrator\\' => array($vendorDir . '/zendframework/zend-hydrator/src'),
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index e7564c9c9eecb1039ca4620730270f3e937f0be1..af7346c27d1b199550db0c28c687aa238485db3b 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -107,7 +107,7 @@
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/6bfcdcfe0aab6c11dcccfbd28dea01a592afd5b3",
+            "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/6196fdb001faf681f92db2ae10abafb5815affde",
             "reference": "47bb3388cfeae41a38087ac8465a7d08fa92ea2e",
             "shasum": ""
         },
@@ -3816,5 +3816,68 @@
             "headless",
             "phantomjs"
         ]
+    },
+    {
+        "name": "jcalderonzumba/mink-phantomjs-driver",
+        "version": "dev-master",
+        "version_normalized": "9999999-dev",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/jcalderonzumba/MinkPhantomJSDriver.git",
+            "reference": "10d7c48c9a4129463052321b52450d98983c4332"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/jcalderonzumba/MinkPhantomJSDriver/zipball/10d7c48c9a4129463052321b52450d98983c4332",
+            "reference": "10d7c48c9a4129463052321b52450d98983c4332",
+            "shasum": ""
+        },
+        "require": {
+            "behat/mink": "~1.6",
+            "jcalderonzumba/gastonjs": "~1.0",
+            "php": ">=5.4",
+            "twig/twig": "~1.8"
+        },
+        "require-dev": {
+            "phpunit/phpunit": "~4.6",
+            "silex/silex": "~1.2",
+            "symfony/css-selector": "~2.1",
+            "symfony/phpunit-bridge": "~2.7",
+            "symfony/process": "~2.3"
+        },
+        "time": "2015-10-05 18:24:44",
+        "type": "mink-driver",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "0.4.x-dev"
+            }
+        },
+        "installation-source": "source",
+        "autoload": {
+            "psr-4": {
+                "Zumba\\Mink\\Driver\\": "src"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Juan Francisco Calderón Zumba",
+                "email": "juanfcz@gmail.com",
+                "homepage": "http://github.com/jcalderonzumba"
+            }
+        ],
+        "description": "PhantomJS driver for Mink framework",
+        "homepage": "http://mink.behat.org/",
+        "keywords": [
+            "ajax",
+            "browser",
+            "headless",
+            "javascript",
+            "phantomjs",
+            "testing"
+        ]
     }
 ]
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/.travis.yml b/vendor/jcalderonzumba/mink-phantomjs-driver/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0dd8e587b31a66078c415f4ce5424c4158c1ab4a
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/.travis.yml
@@ -0,0 +1,40 @@
+language: php
+
+php:
+  - 5.4
+  - 5.5
+  - 5.6
+  - 7.0
+  - hhvm
+
+matrix:
+  fast_finish: true
+  include:
+    - php: 5.4
+      env: COMPOSER_FLAGS='--prefer-lowest --prefer-stable' SYMFONY_DEPRECATIONS_HELPER=weak
+    - php: 5.6
+      env: DEPENDENCIES=dev
+  allow_failures:
+    - php: 7.0
+    - php: hhvm
+
+cache:
+  directories:
+    - $HOME/.composer/cache/files
+
+before_install:
+  - composer self-update
+  - if [ "$DEPENDENCIES" = "dev" ]; then perl -pi -e 's/^}$/,"minimum-stability":"dev"}/' composer.json; fi;
+
+install:
+  - composer update $COMPOSER_FLAGS
+
+before_script:
+  - mkdir -p /tmp/jcalderonzumba/phantomjs
+
+script:
+  - bin/run-tests.sh
+
+after_script:
+  - ps axo pid,command | grep phantomjs | grep -v grep | awk '{print $1}' | xargs -I {} kill {}
+  - ps axo pid,command | grep php | grep -v grep | awk '{print $1}' | xargs -I {} kill {}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/CHANGELOG-0.2.md b/vendor/jcalderonzumba/mink-phantomjs-driver/CHANGELOG-0.2.md
new file mode 100644
index 0000000000000000000000000000000000000000..e7482b297e984516977ca8d1de28e7650f78aa8a
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/CHANGELOG-0.2.md
@@ -0,0 +1,7 @@
+CHANGELOG for 0.2.x
+===================
+This changelog references the relevant changes (bug and security fixes) done in 0.2 minor versions.
+
+* 0.2.3
+
+  * bug #1 set_url_blacklist was not working properly (thanks to reporter)
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/LICENSE b/vendor/jcalderonzumba/mink-phantomjs-driver/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..7ba018acd071864e41f4ee88f799ada6bfb7aa6c
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Juan Francisco Calderón Zumba
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/README.md b/vendor/jcalderonzumba/mink-phantomjs-driver/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..54a433b11a3a6bccf8b50c6eb058d1aec588ab96
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/README.md
@@ -0,0 +1,61 @@
+Mink PhantomJS Driver
+===========================
+[![Build Status](https://travis-ci.org/jcalderonzumba/MinkPhantomJSDriver.svg?branch=master)](https://travis-ci.org/jcalderonzumba/MinkPhantomJSDriver)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/jcalderonzumba/MinkPhantomJSDriver/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/jcalderonzumba/MinkPhantomJSDriver/?branch=master)
+[![Latest Stable Version](https://poser.pugx.org/jcalderonzumba/mink-phantomjs-driver/v/stable)](https://packagist.org/packages/jcalderonzumba/mink-phantomjs-driver)
+[![Total Downloads](https://poser.pugx.org/jcalderonzumba/mink-phantomjs-driver/downloads)](https://packagist.org/packages/jcalderonzumba/mink-phantomjs-driver)
+
+Installation & Compatibility
+----------------------------
+You need a working installation of [PhantomJS](http://phantomjs.org/download.html)
+
+This driver is tested using PhantomJS 1.9.8 but it should work with 1.9.X or latest 2.0.X versions
+
+This driver supports **PHP 5.4 or greater**, there is NO support for PHP 5.3
+
+Use [Composer](https://getcomposer.org/) to install all required PHP dependencies:
+
+```bash
+$ composer require --dev behat/mink jcalderonzumba/mink-phantomjs-driver
+```
+
+How to use
+-------------
+Extension configuration (for the moment NONE).
+```yml
+default:
+  extensions:
+    Zumba\PhantomJSExtension:
+```
+Driver specific configuration:
+```yml
+Behat\MinkExtension:
+phantomjs:
+    phantom_server: "http://localhost:8510/api"
+    template_cache: "/tmp/pjsdrivercache/phantomjs"
+```
+PhantomJS browser start:
+```bash
+phantomjs --ssl-protocol=any --ignore-ssl-errors=true vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768 2>&1 >> /tmp/gastonjs.log &
+```
+
+FAQ
+---------
+
+1. Is this a selenium based driver?:
+
+  **NO**, it has nothing to do with Selenium it's inspired on [Poltergeist](https://github.com/teampoltergeist/poltergeist)
+
+2. What features does this driver implements?
+  
+  **ALL** of the features defined in Mink DriverInterface. maximizeWindow is the only one not implemented since is a headless browser it does not make sense to implement it.
+
+3. Do i need to modify my selenium based tests?
+
+  If you only use the standard behat driver defined methods then NO, you just have to change your default javascript driver.
+  
+
+Copyright
+---------
+
+Copyright (c) 2015 Juan Francisco Calderon Zumba <juanfcz@gmail.com>
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/bin/run-tests.sh b/vendor/jcalderonzumba/mink-phantomjs-driver/bin/run-tests.sh
new file mode 100644
index 0000000000000000000000000000000000000000..60bd21941571055ab16f14c8afab52943fc84450
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/bin/run-tests.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+set -e
+
+start_browser_api(){
+  CURRENT_DIR=$(pwd)
+  LOCAL_PHANTOMJS="${CURRENT_DIR}/bin/phantomjs"
+  if [ -f ${LOCAL_PHANTOMJS} ]; then
+    ${LOCAL_PHANTOMJS} --ssl-protocol=any --ignore-ssl-errors=true vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768 2>&1 &
+  else
+    phantomjs --ssl-protocol=any --ignore-ssl-errors=true vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768 2>&1 >> /dev/null &
+  fi
+  sleep 2
+}
+
+stop_services(){
+  ps axo pid,command | grep phantomjs | grep -v grep | awk '{print $1}' | xargs -I {} kill {}
+  ps axo pid,command | grep php | grep -v grep | grep -v phpstorm | awk '{print $1}' | xargs -I {} kill {}
+  sleep 2
+}
+
+star_local_browser(){
+  CURRENT_DIR=$(pwd)
+  cd ${CURRENT_DIR}/vendor/behat/mink/driver-testsuite/web-fixtures
+  if [ "$TRAVIS" = true ]; then
+    echo "Starting webserver fox fixtures...."
+    ~/.phpenv/versions/5.6/bin/php -S 127.0.0.1:6789 > /dev/null 2>&1 &
+  else
+    php -S 127.0.0.1:6789 2>&1 >> /dev/null &
+  fi
+  sleep 2
+}
+
+mkdir -p /tmp/jcalderonzumba/phantomjs
+stop_services
+start_browser_api
+star_local_browser
+cd ${CURRENT_DIR}
+${CURRENT_DIR}/bin/phpunit --configuration integration_tests.xml
+stop_services
+start_browser_api
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/composer.json b/vendor/jcalderonzumba/mink-phantomjs-driver/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..31b4f57a49bd60651f341633b4a43a99dadc03cd
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/composer.json
@@ -0,0 +1,53 @@
+{
+  "name": "jcalderonzumba/mink-phantomjs-driver",
+  "description": "PhantomJS driver for Mink framework",
+  "keywords": [
+    "phantomjs",
+    "headless",
+    "javascript",
+    "ajax",
+    "testing",
+    "browser"
+  ],
+  "homepage": "http://mink.behat.org/",
+  "type": "mink-driver",
+  "license": "MIT",
+  "authors": [
+    {
+      "name": "Juan Francisco Calderón Zumba",
+      "email": "juanfcz@gmail.com",
+      "homepage": "http://github.com/jcalderonzumba"
+    }
+  ],
+  "require": {
+    "php": ">=5.4",
+    "behat/mink": "~1.6",
+    "twig/twig": "~1.8",
+    "jcalderonzumba/gastonjs": "~1.0"
+  },
+  "require-dev": {
+    "symfony/process": "~2.3",
+    "symfony/phpunit-bridge": "~2.7",
+    "symfony/css-selector": "~2.1",
+    "phpunit/phpunit": "~4.6",
+    "silex/silex": "~1.2"
+  },
+  "config": {
+    "bin-dir": "bin"
+  },
+  "autoload": {
+    "psr-4": {
+      "Zumba\\Mink\\Driver\\": "src"
+    }
+  },
+  "autoload-dev": {
+    "psr-4": {
+      "Behat\\Mink\\Tests\\Driver\\": "tests/integration"
+    }
+  },
+  "extra": {
+    "branch-alias": {
+      "dev-master": "0.4.x-dev"
+    }
+  }
+}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/integration_tests.xml b/vendor/jcalderonzumba/mink-phantomjs-driver/integration_tests.xml
new file mode 100644
index 0000000000000000000000000000000000000000..739fc365a9c2e696020ff694e22e51b30042b9de
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/integration_tests.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit colors="true" bootstrap="./tests/integration/bootstrap.php" stopOnFailure="true">
+    <testsuites>
+        <testsuite name="PhantomJS Driver test suite">
+            <directory>tests/integration</directory>
+            <file>vendor/behat/mink/driver-testsuite/tests/Basic/BasicAuthTest.php</file>
+            <file>vendor/behat/mink/driver-testsuite/tests/Basic/ContentTest.php</file>
+            <file>vendor/behat/mink/driver-testsuite/tests/Basic/CookieTest.php</file>
+            <file>vendor/behat/mink/driver-testsuite/tests/Basic/ErrorHandlingTest.php</file>
+            <file>vendor/behat/mink/driver-testsuite/tests/Basic/IFrameTest.php</file>
+            <file>vendor/behat/mink/driver-testsuite/tests/Basic/ScreenshotTest.php</file>
+            <file>vendor/behat/mink/driver-testsuite/tests/Basic/TraversingTest.php</file>
+            <file>vendor/behat/mink/driver-testsuite/tests/Basic/VisibilityTest.php</file>
+            <directory>vendor/behat/mink/driver-testsuite/tests/Form</directory>
+            <directory>vendor/behat/mink/driver-testsuite/tests/Js</directory>
+            <!-- The following have been disabled and their respective equals added to Custom driver tests -->
+            <!--<directory>vendor/behat/mink/driver-testsuite/tests/Css</directory>-->
+            <!--<file>vendor/behat/mink/driver-testsuite/tests/Basic/StatusCodeTest.php</file>-->
+            <!--<file>vendor/behat/mink/driver-testsuite/tests/Basic/HeaderTest.php</file>-->
+            <!--<file>vendor/behat/mink/driver-testsuite/tests/Basic/NavigationTest.php</file>-->
+        </testsuite>
+    </testsuites>
+
+    <php>
+        <var name="driver_config_factory" value="Behat\Mink\Tests\Driver\PhantomJSConfig::getInstance"/>
+        <server name="WEB_FIXTURES_HOST" value="http://127.0.0.1:6789"/>
+        <!-- where driver will connect to -->
+        <server name="DRIVER_URL" value="http://127.0.0.1:8510/"/>
+        <server name="TEMPLATE_CACHE_DIR" value="/tmp/jcalderonzumba/phantomjs"/>
+    </php>
+
+    <filter>
+        <whitelist>
+            <directory>./src/Behat/Mink/Driver</directory>
+        </whitelist>
+    </filter>
+</phpunit>
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/BasePhantomJSDriver.php b/vendor/jcalderonzumba/mink-phantomjs-driver/src/BasePhantomJSDriver.php
new file mode 100644
index 0000000000000000000000000000000000000000..d962ff526d0e67375dffc0b8f8fafdcecfb6fc8c
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/BasePhantomJSDriver.php
@@ -0,0 +1,109 @@
+<?php
+
+namespace Zumba\Mink\Driver;
+
+use Behat\Mink\Driver\CoreDriver;
+use Behat\Mink\Exception\DriverException;
+use Behat\Mink\Session;
+use Zumba\GastonJS\Browser\Browser;
+
+/**
+ * Class BasePhantomJSDriver
+ * @package Zumba\Mink\Driver
+ */
+class BasePhantomJSDriver extends CoreDriver {
+
+  /** @var  Session */
+  protected $session;
+  /** @var  Browser */
+  protected $browser;
+  /** @var  string */
+  protected $phantomHost;
+  /** @var  \Twig_Loader_Filesystem */
+  protected $templateLoader;
+  /** @var  \Twig_Environment */
+  protected $templateEnv;
+
+  /**
+   * Instantiates the driver
+   * @param string $phantomHost browser "api" oriented host
+   * @param string $templateCache where we are going to store the templates cache
+   */
+  public function __construct($phantomHost, $templateCache = null) {
+    $this->phantomHost = $phantomHost;
+    $this->browser = new Browser($phantomHost);
+    $this->templateLoader = new \Twig_Loader_Filesystem(realpath(__DIR__ . '/Resources/Script'));
+    $this->templateEnv = new \Twig_Environment($this->templateLoader, array('cache' => $this->templateCacheSetup($templateCache), 'strict_variables' => true));
+  }
+
+  /**
+   * Sets up the cache template location for the scripts we are going to create with the driver
+   * @param $templateCache
+   * @return string
+   * @throws DriverException
+   */
+  protected function templateCacheSetup($templateCache) {
+    $cacheDir = $templateCache;
+    if ($templateCache === null) {
+      $cacheDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "jcalderonzumba" . DIRECTORY_SEPARATOR . "phantomjs";
+      if (!file_exists($cacheDir)) {
+        mkdir($cacheDir, 0777, true);
+      }
+    }
+
+    if (!file_exists($cacheDir)) {
+      throw new DriverException("Template cache $cacheDir directory does not exist");
+    }
+    return $cacheDir;
+  }
+
+  /**
+   * Helper to find a node element given an xpath
+   * @param string $xpath
+   * @param int    $max
+   * @returns int
+   * @throws DriverException
+   */
+  protected function findElement($xpath, $max = 1) {
+    $elements = $this->browser->find("xpath", $xpath);
+    if (!isset($elements["page_id"]) || !isset($elements["ids"]) || count($elements["ids"]) !== $max) {
+      throw new DriverException("Failed to get elements with given $xpath");
+    }
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   * @param Session $session
+   */
+  public function setSession(Session $session) {
+    $this->session = $session;
+  }
+
+  /**
+   * @return Browser
+   */
+  public function getBrowser() {
+    return $this->browser;
+  }
+
+  /**
+   * @return \Twig_Environment
+   */
+  public function getTemplateEnv() {
+    return $this->templateEnv;
+  }
+
+  /**
+   * Returns a javascript script via twig template engine
+   * @param $templateName
+   * @param $viewData
+   * @return string
+   */
+  public function javascriptTemplateRender($templateName, $viewData) {
+    /** @var $templateEngine \Twig_Environment */
+    $templateEngine = $this->getTemplateEnv();
+    return $templateEngine->render($templateName, $viewData);
+  }
+
+}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/CookieTrait.php b/vendor/jcalderonzumba/mink-phantomjs-driver/src/CookieTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..327b94885d15cead5d1f51e8adc97335e6dbe854
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/CookieTrait.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Zumba\Mink\Driver;
+
+use Zumba\GastonJS\Cookie;
+
+/**
+ * Trait CookieTrait
+ * @package Zumba\Mink\Driver
+ */
+trait CookieTrait {
+
+  /**
+   * Sets a cookie on the browser, if null value then delete it
+   * @param string $name
+   * @param string $value
+   */
+  public function setCookie($name, $value = null) {
+    if ($value === null) {
+      $this->browser->removeCookie($name);
+    }
+    //TODO: set the cookie with domain, not with url, meaning www.aaa.com or .aaa.com
+    if ($value !== null) {
+      $urlData = parse_url($this->getCurrentUrl());
+      $cookie = array("name" => $name, "value" => $value, "domain" => $urlData["host"]);
+      $this->browser->setCookie($cookie);
+    }
+  }
+
+  /**
+   * Gets a cookie by its name if exists, else it will return null
+   * @param string $name
+   * @return string
+   */
+  public function getCookie($name) {
+    $cookies = $this->browser->cookies();
+    foreach ($cookies as $cookie) {
+      if ($cookie instanceof Cookie && strcmp($cookie->getName(), $name) === 0) {
+        return $cookie->getValue();
+      }
+    }
+    return null;
+  }
+
+}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/FormManipulationTrait.php b/vendor/jcalderonzumba/mink-phantomjs-driver/src/FormManipulationTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..5a94fc7629084d3c642922ffe63f5bd987501f48
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/FormManipulationTrait.php
@@ -0,0 +1,168 @@
+<?php
+
+namespace Zumba\Mink\Driver;
+
+use Behat\Mink\Exception\DriverException;
+
+/**
+ * Trait FormManipulationTrait
+ * @package Zumba\Mink\Driver
+ */
+trait FormManipulationTrait {
+
+
+  /**
+   * Returns the value of a given xpath element
+   * @param string $xpath
+   * @return string
+   * @throws DriverException
+   */
+  public function getValue($xpath) {
+    $this->findElement($xpath, 1);
+    $javascript = $this->javascriptTemplateRender("get_value.js.twig", array("xpath" => $xpath));
+    return $this->browser->evaluate($javascript);
+  }
+
+  /**
+   * @param string $xpath
+   * @param string $value
+   * @throws DriverException
+   */
+  public function setValue($xpath, $value) {
+    $this->findElement($xpath, 1);
+    //This stuff is BECAUSE the way the driver works for setting values when being checkboxes, radios, etc.
+    if (is_bool($value)) {
+      $value = $this->boolToString($value);
+    }
+
+    $javascript = $this->javascriptTemplateRender("set_value.js.twig", array("xpath" => $xpath, "value" => json_encode($value)));
+    $this->browser->evaluate($javascript);
+  }
+
+
+  /**
+   * Submits a form given an xpath selector
+   * @param string $xpath
+   * @throws DriverException
+   */
+  public function submitForm($xpath) {
+    $element = $this->findElement($xpath, 1);
+    $tagName = $this->browser->tagName($element["page_id"], $element["ids"][0]);
+    if (strcmp(strtolower($tagName), "form") !== 0) {
+      throw new DriverException("Can not submit something that is not a form");
+    }
+    $this->browser->trigger($element["page_id"], $element["ids"][0], "submit");
+  }
+
+  /**
+   * Helper method needed for twig and javascript stuff
+   * @param $boolValue
+   * @return string
+   */
+  protected function boolToString($boolValue) {
+    if ($boolValue === true) {
+      return "1";
+    }
+    return "0";
+  }
+
+  /**
+   * Selects an option
+   * @param string $xpath
+   * @param string $value
+   * @param bool   $multiple
+   * @return bool
+   * @throws DriverException
+   */
+  public function selectOption($xpath, $value, $multiple = false) {
+    $element = $this->findElement($xpath, 1);
+    $tagName = strtolower($this->browser->tagName($element["page_id"], $element["ids"][0]));
+    $attributes = $this->browser->attributes($element["page_id"], $element["ids"][0]);
+
+    if (!in_array($tagName, array("input", "select"))) {
+      throw new DriverException(sprintf('Impossible to select an option on the element with XPath "%s" as it is not a select or radio input', $xpath));
+    }
+
+    if ($tagName === "input" && $attributes["type"] != "radio") {
+      throw new DriverException(sprintf('Impossible to select an option on the element with XPath "%s" as it is not a select or radio input', $xpath));
+    }
+
+    return $this->browser->selectOption($element["page_id"], $element["ids"][0], $value, $multiple);
+  }
+
+  /**
+   * Check control over an input element of radio or checkbox type
+   * @param $xpath
+   * @return bool
+   * @throws DriverException
+   */
+  protected function inputCheckableControl($xpath) {
+    $element = $this->findElement($xpath, 1);
+    $tagName = strtolower($this->browser->tagName($element["page_id"], $element["ids"][0]));
+    $attributes = $this->browser->attributes($element["page_id"], $element["ids"][0]);
+    if ($tagName != "input") {
+      throw new DriverException("Can not check when the element is not of the input type");
+    }
+    if (!in_array($attributes["type"], array("checkbox", "radio"))) {
+      throw new DriverException("Can not check when the element is not checkbox or radio");
+    }
+    return true;
+  }
+
+  /**
+   * We click on the checkbox or radio when possible and needed
+   * @param string $xpath
+   * @throws DriverException
+   */
+  public function check($xpath) {
+    $this->inputCheckableControl($xpath);
+    $javascript = $this->javascriptTemplateRender("check_element.js.twig", array("xpath" => $xpath, "check" => "true"));
+    $this->browser->evaluate($javascript);
+  }
+
+  /**
+   * We click on the checkbox or radio when possible and needed
+   * @param string $xpath
+   * @throws DriverException
+   */
+  public function uncheck($xpath) {
+    $this->inputCheckableControl($xpath);
+    $javascript = $this->javascriptTemplateRender("check_element.js.twig", array("xpath" => $xpath, "check" => "false"));
+    $this->browser->evaluate($javascript);
+  }
+
+  /**
+   * Checks if the radio or checkbox is checked
+   * @param string $xpath
+   * @return bool
+   * @throws DriverException
+   */
+  public function isChecked($xpath) {
+    $this->findElement($xpath, 1);
+    $javascript = $this->javascriptTemplateRender("is_checked.js.twig", array("xpath" => $xpath));
+    $checked = $this->browser->evaluate($javascript);
+
+    if ($checked === null) {
+      throw new DriverException("Can not check when the element is not checkbox or radio");
+    }
+
+    return $checked;
+  }
+
+  /**
+   * Checks if the option is selected or not
+   * @param string $xpath
+   * @return bool
+   * @throws DriverException
+   */
+  public function isSelected($xpath) {
+    $elements = $this->findElement($xpath, 1);
+    $javascript = $this->javascriptTemplateRender("is_selected.js.twig", array("xpath" => $xpath));
+    $tagName = $this->browser->tagName($elements["page_id"], $elements["ids"][0]);
+    if (strcmp(strtolower($tagName), "option") !== 0) {
+      throw new DriverException("Can not assert on element that is not an option");
+    }
+
+    return $this->browser->evaluate($javascript);
+  }
+}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/HeadersTrait.php b/vendor/jcalderonzumba/mink-phantomjs-driver/src/HeadersTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d6865aca4a1be7fe375146137191a758ef3aeff
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/HeadersTrait.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Zumba\Mink\Driver;
+
+/**
+ * Class HeadersTrait
+ * @package Zumba\Mink\Driver
+ */
+trait HeadersTrait {
+
+  /**
+   * Gets the current request response headers
+   * Should be called only after a request, other calls are undefined behaviour
+   * @return array
+   */
+  public function getResponseHeaders() {
+    return $this->browser->responseHeaders();
+  }
+
+  /**
+   * Current request status code response
+   * @return int
+   */
+  public function getStatusCode() {
+    return $this->browser->getStatusCode();
+  }
+
+  /**
+   * The name say its all
+   * @param string $name
+   * @param string $value
+   */
+  public function setRequestHeader($name, $value) {
+    $header = array();
+    $header[$name] = $value;
+    //TODO: as a limitation of the driver it self, we will send permanent for the moment
+    $this->browser->addHeader($header, true);
+  }
+
+}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/JavascriptTrait.php b/vendor/jcalderonzumba/mink-phantomjs-driver/src/JavascriptTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5b7d630475760154b987ea5b21c0cad9eb50d32
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/JavascriptTrait.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Zumba\Mink\Driver;
+
+use Behat\Mink\Exception\DriverException;
+
+/**
+ * Class JavascriptTrait
+ * @package Zumba\Mink\Driver
+ */
+trait JavascriptTrait {
+
+  /**
+   * Executes a script on the browser
+   * @param string $script
+   */
+  public function executeScript($script) {
+    $this->browser->execute($script);
+  }
+
+  /**
+   * Evaluates a script and returns the result
+   * @param string $script
+   * @return mixed
+   */
+  public function evaluateScript($script) {
+    return $this->browser->evaluate($script);
+  }
+
+  /**
+   * Waits some time or until JS condition turns true.
+   *
+   * @param integer $timeout timeout in milliseconds
+   * @param string  $condition JS condition
+   * @return boolean
+   * @throws DriverException                  When the operation cannot be done
+   */
+  public function wait($timeout, $condition) {
+    $start = microtime(true);
+    $end = $start + $timeout / 1000.0;
+    do {
+      $result = $this->browser->evaluate($condition);
+      usleep(100000);
+    } while (microtime(true) < $end && !$result);
+
+    return (bool)$result;
+  }
+
+}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/KeyboardTrait.php b/vendor/jcalderonzumba/mink-phantomjs-driver/src/KeyboardTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..2b0c96d2006e9b14be420018bc4cee225346348f
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/KeyboardTrait.php
@@ -0,0 +1,95 @@
+<?php
+
+namespace Zumba\Mink\Driver;
+
+use Behat\Mink\Exception\DriverException;
+
+/**
+ * Class KeyboardTrait
+ * @package Zumba\Mink\Driver
+ */
+trait KeyboardTrait {
+
+  /**
+   * Does some normalization for the char we want to do keyboard events with.
+   * @param $char
+   * @throws DriverException
+   * @return string
+   */
+  protected function normalizeCharForKeyEvent($char) {
+    if (!is_int($char) && !is_string($char)) {
+      throw new DriverException("Unsupported key type, can only be integer or string");
+    }
+
+    if (is_string($char) && strlen($char) !== 1) {
+      throw new DriverException("Key can only have ONE character");
+    }
+
+    $key = $char;
+    if (is_int($char)) {
+      $key = chr($char);
+    }
+    return $key;
+  }
+
+  /**
+   * Does some control and normalization for the key event modifier
+   * @param $modifier
+   * @return string
+   * @throws DriverException
+   */
+  protected function keyEventModifierControl($modifier) {
+    if ($modifier === null) {
+      $modifier = "none";
+    }
+
+    if (!in_array($modifier, array("none", "alt", "ctrl", "shift", "meta"))) {
+      throw new DriverException("Unsupported key modifier $modifier");
+    }
+    return $modifier;
+  }
+
+  /**
+   * Send a key-down event to the browser element
+   * @param        $xpath
+   * @param        $char
+   * @param string $modifier
+   * @throws DriverException
+   */
+  public function keyDown($xpath, $char, $modifier = null) {
+    $element = $this->findElement($xpath, 1);
+    $key = $this->normalizeCharForKeyEvent($char);
+    $modifier = $this->keyEventModifierControl($modifier);
+    return $this->browser->keyEvent($element["page_id"], $element["ids"][0], "keydown", $key, $modifier);
+  }
+
+  /**
+   * @param string $xpath
+   * @param string $char
+   * @param string $modifier
+   * @throws DriverException
+   */
+  public function keyPress($xpath, $char, $modifier = null) {
+    $element = $this->findElement($xpath, 1);
+    $key = $this->normalizeCharForKeyEvent($char);
+    $modifier = $this->keyEventModifierControl($modifier);
+    return $this->browser->keyEvent($element["page_id"], $element["ids"][0], "keypress", $key, $modifier);
+  }
+
+  /**
+   * Pressed up specific keyboard key.
+   *
+   * @param string         $xpath
+   * @param string|integer $char could be either char ('b') or char-code (98)
+   * @param string         $modifier keyboard modifier (could be 'ctrl', 'alt', 'shift' or 'meta')
+   *
+   * @throws DriverException                  When the operation cannot be done
+   */
+  public function keyUp($xpath, $char, $modifier = null) {
+    $this->findElement($xpath, 1);
+    $element = $this->findElement($xpath, 1);
+    $key = $this->normalizeCharForKeyEvent($char);
+    $modifier = $this->keyEventModifierControl($modifier);
+    return $this->browser->keyEvent($element["page_id"], $element["ids"][0], "keyup", $key, $modifier);
+  }
+}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/MouseTrait.php b/vendor/jcalderonzumba/mink-phantomjs-driver/src/MouseTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..c7cd2ebbcad171f11d64256d46e0f3023dc676b6
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/MouseTrait.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Zumba\Mink\Driver;
+
+use Behat\Mink\Exception\DriverException;
+
+/**
+ * Class MouseTrait
+ * @package Zumba\Mink\Driver
+ */
+trait MouseTrait {
+
+  /**
+   * Generates a mouseover event on the given element by xpath
+   * @param string $xpath
+   * @throws DriverException
+   */
+  public function mouseOver($xpath) {
+    $element = $this->findElement($xpath, 1);
+    $this->browser->hover($element["page_id"], $element["ids"][0]);
+  }
+
+  /**
+   * Clicks if possible on an element given by xpath
+   * @param string $xpath
+   * @return mixed
+   * @throws DriverException
+   */
+  public function click($xpath) {
+    $elements = $this->findElement($xpath, 1);
+    $this->browser->click($elements["page_id"], $elements["ids"][0]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  /**
+   * Double click on element found via xpath
+   * @param string $xpath
+   * @throws DriverException
+   */
+  public function doubleClick($xpath) {
+    $elements = $this->findElement($xpath, 1);
+    $this->browser->doubleClick($elements["page_id"], $elements["ids"][0]);
+  }
+
+  /**
+   * Right click on element found via xpath
+   * @param string $xpath
+   * @throws DriverException
+   */
+  public function rightClick($xpath) {
+    $elements = $this->findElement($xpath, 1);
+    $this->browser->rightClick($elements["page_id"], $elements["ids"][0]);
+  }
+
+}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/NavigationTrait.php b/vendor/jcalderonzumba/mink-phantomjs-driver/src/NavigationTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..88ca4293454e45a5263c466c2aae1013f18adfaf
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/NavigationTrait.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Zumba\Mink\Driver;
+
+/**
+ * Trait NavigationTrait
+ * @package Zumba\Mink\Driver
+ */
+trait NavigationTrait {
+  /**
+   * Visits a given url
+   * @param string $url
+   */
+  public function visit($url) {
+    $this->browser->visit($url);
+  }
+
+  /**
+   * Gets the current url if any
+   * @return string
+   */
+  public function getCurrentUrl() {
+    return $this->browser->currentUrl();
+  }
+
+
+  /**
+   * Reloads the page if possible
+   */
+  public function reload() {
+    $this->browser->reload();
+  }
+
+  /**
+   * Goes forward if possible
+   */
+  public function forward() {
+    $this->browser->goForward();
+  }
+
+  /**
+   * Goes back if possible
+   */
+  public function back() {
+    $this->browser->goBack();
+  }
+
+
+}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/PageContentTrait.php b/vendor/jcalderonzumba/mink-phantomjs-driver/src/PageContentTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..7759a0fd79f91a42fb1c3012861caabb6c266774
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/PageContentTrait.php
@@ -0,0 +1,72 @@
+<?php
+
+namespace Zumba\Mink\Driver;
+
+use Behat\Mink\Exception\DriverException;
+
+/**
+ * Class PageContentTrait
+ * @package Zumba\Mink\Driver
+ */
+trait PageContentTrait {
+
+  /**
+   * @return string
+   */
+  public function getContent() {
+    return $this->browser->getBody();
+  }
+
+  /**
+   * Given xpath, will try to get ALL the text, visible and not visible from such xpath
+   * @param string $xpath
+   * @return string
+   * @throws DriverException
+   */
+  public function getText($xpath) {
+    $elements = $this->findElement($xpath, 1);
+    //allText works only with ONE element so it will be the first one and also returns new lines that we will remove
+    $text = $this->browser->allText($elements["page_id"], $elements["ids"][0]);
+    $text = trim(str_replace(array("\r", "\r\n", "\n"), ' ', $text));
+    $text = preg_replace('/ {2,}/', ' ', $text);
+    return $text;
+  }
+
+  /**
+   * Returns the inner html of a given xpath
+   * @param string $xpath
+   * @return string
+   * @throws DriverException
+   */
+  public function getHtml($xpath) {
+    $elements = $this->findElement($xpath, 1);
+    //allText works only with ONE element so it will be the first one
+    return $this->browser->allHtml($elements["page_id"], $elements["ids"][0], "inner");
+  }
+
+  /**
+   * Gets the outer html of a given xpath
+   * @param string $xpath
+   * @return string
+   * @throws DriverException
+   */
+  public function getOuterHtml($xpath) {
+    $elements = $this->findElement($xpath, 1);
+    //allText works only with ONE element so it will be the first one
+    return $this->browser->allHtml($elements["page_id"], $elements["ids"][0], "outer");
+  }
+
+  /**
+   * Returns the binary representation of the current page we are in
+   * @throws DriverException
+   * @return string
+   */
+  public function getScreenshot() {
+    $options = array("full" => true, "selector" => null);
+    $b64ScreenShot = $this->browser->renderBase64("JPEG", $options);
+    if (($binaryScreenShot = base64_decode($b64ScreenShot, true)) === false) {
+      throw new DriverException("There was a problem while doing the screenshot of the current page");
+    }
+    return $binaryScreenShot;
+  }
+}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/PhantomJSDriver.php b/vendor/jcalderonzumba/mink-phantomjs-driver/src/PhantomJSDriver.php
new file mode 100644
index 0000000000000000000000000000000000000000..ac251707dba2eca72fd977d743ab7c9487e5faf2
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/PhantomJSDriver.php
@@ -0,0 +1,164 @@
+<?php
+
+namespace Zumba\Mink\Driver;
+
+use Behat\Mink\Element\NodeElement;
+use Behat\Mink\Exception\DriverException;
+
+/**
+ * Class PhantomJSDriver
+ * @package Behat\Mink\Driver
+ */
+class PhantomJSDriver extends BasePhantomJSDriver {
+
+  use SessionTrait;
+  use NavigationTrait;
+  use CookieTrait;
+  use HeadersTrait;
+  use JavascriptTrait;
+  use MouseTrait;
+  use PageContentTrait;
+  use KeyboardTrait;
+  use FormManipulationTrait;
+  use WindowTrait;
+
+  /**
+   * Sets the basic auth user and password
+   * @param string $user
+   * @param string $password
+   */
+  public function setBasicAuth($user, $password) {
+    $this->browser->setHttpAuth($user, $password);
+  }
+
+  /**
+   * Gets the tag name of a given xpath
+   * @param string $xpath
+   * @return string
+   * @throws DriverException
+   */
+  public function getTagName($xpath) {
+    $elements = $this->findElement($xpath, 1);
+    return $this->browser->tagName($elements["page_id"], $elements["ids"][0]);
+  }
+
+  /**
+   * Gets the attribute value of a given element and name
+   * @param string $xpath
+   * @param string $name
+   * @return string
+   * @throws DriverException
+   */
+  public function getAttribute($xpath, $name) {
+    $elements = $this->findElement($xpath, 1);
+    return $this->browser->attribute($elements["page_id"], $elements["ids"][0], $name);
+  }
+
+  /**
+   * Check if element given by xpath is visible or not
+   * @param string $xpath
+   * @return bool
+   * @throws DriverException
+   */
+  public function isVisible($xpath) {
+    $elements = $this->findElement($xpath, 1);
+    return $this->browser->isVisible($elements["page_id"], $elements["ids"][0]);
+  }
+
+  /**
+   * Drags one element to another
+   * @param string $sourceXpath
+   * @param string $destinationXpath
+   * @throws DriverException
+   */
+  public function dragTo($sourceXpath, $destinationXpath) {
+    $sourceElement = $this->findElement($sourceXpath, 1);
+    $destinationElement = $this->findElement($destinationXpath, 1);
+    $this->browser->drag($sourceElement["page_id"], $sourceElement["ids"][0], $destinationElement["ids"][0]);
+  }
+
+  /**
+   * Upload a file to the browser
+   * @param string $xpath
+   * @param string $path
+   * @throws DriverException
+   */
+  public function attachFile($xpath, $path) {
+    if (!file_exists($path)) {
+      throw new DriverException("Wow there the file does not exist, you can not upload it");
+    }
+
+    if (($realPath = realpath($path)) === false) {
+      throw new DriverException("Wow there the file does not exist, you can not upload it");
+    }
+
+    $element = $this->findElement($xpath, 1);
+    $tagName = $this->getTagName($xpath);
+    if ($tagName != "input") {
+      throw new DriverException("The element is not an input element, you can not attach a file to it");
+    }
+
+    $attributes = $this->getBrowser()->attributes($element["page_id"], $element["ids"][0]);
+    if (!isset($attributes["type"]) || $attributes["type"] != "file") {
+      throw new DriverException("The element is not an input file type element, you can not attach a file to it");
+    }
+
+    $this->browser->selectFile($element["page_id"], $element["ids"][0], $realPath);
+  }
+
+  /**
+   * Puts the browser control inside the IFRAME
+   * You own the control, make sure to go back to the parent calling this method with null
+   * @param string $name
+   */
+  public function switchToIFrame($name = null) {
+    //TODO: check response of the calls
+    if ($name === null) {
+      $this->browser->popFrame();
+      return;
+    } else {
+      $this->browser->pushFrame($name);
+    }
+  }
+
+  /**
+   * Focus on an element
+   * @param string $xpath
+   * @throws DriverException
+   */
+  public function focus($xpath) {
+    $element = $this->findElement($xpath, 1);
+    $this->browser->trigger($element["page_id"], $element["ids"][0], "focus");
+  }
+
+  /**
+   * Blur on element
+   * @param string $xpath
+   * @throws DriverException
+   */
+  public function blur($xpath) {
+    $element = $this->findElement($xpath, 1);
+    $this->browser->trigger($element["page_id"], $element["ids"][0], "blur");
+  }
+
+  /**
+   * Finds elements with specified XPath query.
+   * @param string $xpath
+   * @return NodeElement[]
+   * @throws DriverException                  When the operation cannot be done
+   */
+  public function find($xpath) {
+    $elements = $this->browser->find("xpath", $xpath);
+    $nodeElements = array();
+
+    if (!isset($elements["ids"])) {
+      return null;
+    }
+
+    foreach ($elements["ids"] as $i => $elementId) {
+      $nodeElements[] = new NodeElement(sprintf('(%s)[%d]', $xpath, $i + 1), $this->session);
+    }
+    return $nodeElements;
+  }
+
+}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/check_element.js.twig b/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/check_element.js.twig
new file mode 100644
index 0000000000000000000000000000000000000000..f3372ba7f41b8eb1e3206c8bd3371eaa0ff2885a
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/check_element.js.twig
@@ -0,0 +1,35 @@
+{% autoescape 'js' %}
+(function (xpath, check) {
+  function getPolterNode(xpath) {
+    var polterAgent = window.__poltergeist;
+    var ids = polterAgent.find("xpath", xpath, document);
+    return polterAgent.get(ids[0]);
+  }
+
+  var pNode = getPolterNode(xpath);
+
+  if (check && pNode.element.checked) {
+    //requested to check the element and is already check, do nothing.
+    return true;
+  }
+
+  if (!check && pNode.element.checked == false) {
+    //move along nothing to be done
+    return true;
+  }
+
+  if (check && pNode.element.checked == false) {
+    //we have to check the element, we will do so by triggering a click event so all change listeners are aware.
+    pNode.trigger("click");
+    pNode.element.checked = true;
+  }
+
+  if (!check && pNode.element.checked) {
+    //move along nothing to be done
+    pNode.trigger("click");
+    pNode.element.checked = false;
+    return true;
+  }
+  return false;
+}('{{xpath}}', {{check}}));
+{% endautoescape %}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/execute_script.js.twig b/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/execute_script.js.twig
new file mode 100644
index 0000000000000000000000000000000000000000..791276c51e3a335b34fd6ddddee60016d3af399a
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/execute_script.js.twig
@@ -0,0 +1,3 @@
+{% autoescape false %}
+  {{ script }};
+{% endautoescape %}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/get_value.js.twig b/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/get_value.js.twig
new file mode 100644
index 0000000000000000000000000000000000000000..8e040f8546c804c5f55cf06fc33e857765c42b76
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/get_value.js.twig
@@ -0,0 +1,63 @@
+{% autoescape 'js' %}
+(function (xpath) {
+  function getElement(xpath) {
+    var polterAgent = window.__poltergeist;
+    var ids = polterAgent.find("xpath", xpath, document);
+    var polterNode = polterAgent.get(ids[0]);
+    return polterNode.element;
+  }
+
+  function inputRadioGetValue(element){
+    var value = null;
+    var name = element.getAttribute('name');
+    if (!name){
+      return null;
+    }
+    var fields = window.document.getElementsByName(name);
+    var i;
+    var l = fields.length;
+    for (i = 0; i < l; i++) {
+      var field = fields.item(i);
+      if (field.form === element.form && field.checked) {
+        return field.value;
+      }
+    }
+    return null;
+  }
+
+  var node = getElement(xpath);
+  var tagName = node.tagName.toLowerCase();
+  var value = null;
+  if (tagName == "input") {
+    var type = node.type.toLowerCase();
+    if (type == "checkbox") {
+      value = node.checked ? node.value : null;
+    } else if (type == "radio") {
+      value = inputRadioGetValue(node);
+    } else {
+      value = node.value;
+    }
+  } else if (tagName == "textarea") {
+    value = node.value;
+  } else if (tagName == "select") {
+    if (node.multiple) {
+      value = [];
+      for (var i = 0; i < node.options.length; i++) {
+        if (node.options[i].selected) {
+          value.push(node.options[i].value);
+        }
+      }
+    } else {
+      var idx = node.selectedIndex;
+      if (idx >= 0) {
+        value = node.options.item(idx).value;
+      } else {
+        value = null;
+      }
+    }
+  } else {
+    value = node.value;
+  }
+  return value;
+}('{{ xpath }}'));
+{% endautoescape %}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/is_checked.js.twig b/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/is_checked.js.twig
new file mode 100644
index 0000000000000000000000000000000000000000..6b14cad6ad54795ca253b61baafaebd308c5636e
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/is_checked.js.twig
@@ -0,0 +1,31 @@
+{% autoescape 'js' %}
+(function (xpath) {
+  function getElement(xpath, within) {
+    var result;
+    if (within === null || within === undefined) {
+      within = document;
+    }
+    result = document.evaluate(xpath, within, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    if (result.snapshotLength !== 1) {
+      return null;
+    }
+    return result.snapshotItem(0);
+  }
+
+  var node = getElement(xpath);
+
+  if (node === null) {
+    return null;
+  }
+
+  if(node.tagName.toLowerCase() != "input"){
+    return null;
+  }
+
+  if(node.type.toLowerCase() != "checkbox" && node.type.toLowerCase() != "radio"){
+    return null;
+  }
+
+  return node.checked;
+}('{{ xpath }}'));
+{% endautoescape %}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/is_selected.js.twig b/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/is_selected.js.twig
new file mode 100644
index 0000000000000000000000000000000000000000..a3a18d307b9e1a39eba163c989440d6563885ddd
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/is_selected.js.twig
@@ -0,0 +1,16 @@
+{% autoescape 'js' %}
+(function (xpath) {
+  function getElement(xpath) {
+    var polterAgent = window.__poltergeist;
+    var ids = polterAgent.find("xpath", xpath, document);
+    var polterNode = polterAgent.get(ids[0]);
+    return polterNode.element;
+  }
+
+  var node = getElement(xpath);
+  if(typeof node.selected == "undefined"){
+    return null;
+  }
+  return node.selected;
+}('{{xpath}}'));
+{% endautoescape %}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/set_value.js.twig b/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/set_value.js.twig
new file mode 100644
index 0000000000000000000000000000000000000000..605aec37a7fa2747c60075c19a023e0bd003fa0b
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/set_value.js.twig
@@ -0,0 +1,213 @@
+{% autoescape 'js' %}
+(function (xpath, value) {
+  function getElement(xpath, within) {
+    var result;
+    if (within === null || within === undefined) {
+      within = document;
+    }
+    result = document.evaluate(xpath, within, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    if (result.snapshotLength !== 1) {
+      return null;
+    }
+    return result.snapshotItem(0);
+  }
+
+  function isInput(element) {
+    if (element === null || element === undefined) {
+      return false;
+    }
+    return (element.tagName.toLowerCase() == "input");
+  }
+
+  function isTextArea(element) {
+    if (element === null || element === undefined) {
+      return false;
+    }
+    return (element.tagName.toLowerCase() == "textarea");
+  }
+
+  function isSelect(element) {
+    if (element === null || element === undefined) {
+      return false;
+    }
+    return (element.tagName.toLowerCase() == "select");
+  }
+
+  function deselectAllOptions(element) {
+    var i, l = element.options.length;
+    for (i = 0; i < l; i++) {
+      element.options[i].selected = false;
+    }
+  }
+
+  function xpathStringLiteral(s) {
+    if (s.indexOf('"') === -1)
+      return '"' + s + '"';
+    if (s.indexOf("'") === -1)
+      return "'" + s + "'";
+    return 'concat("' + s.replace(/"/g, '",\'"\',"') + '")';
+  }
+
+  function clickOnElement(element) {
+    // create a mouse click event
+    var event = document.createEvent('MouseEvents');
+    event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+
+    // send click to element
+    element.dispatchEvent(event);
+
+    //After dispatching the event let's wait for 2 seconds at least...
+    return setTimeout(function () {
+    }, 2);
+  }
+
+  function dispatchChange(element) {
+    var tagName =element.tagName.toLowerCase();
+    var elementType = element.getAttribute("type");
+    if (tagName != "option" || (tagName == "input" && elementType == "radio")){
+      return true;
+    }
+    //Force the change when element is option
+    var event;
+    event = document.createEvent('HTMLEvents');
+    event.initEvent('change', true, false);
+    element.dispatchEvent(event);
+    return true;
+  }
+
+  function selectOptionOnElement(element, option, multiple) {
+    var polterAgent = window.__poltergeist;
+    var escapedOption = xpathStringLiteral(option);
+    // The value of an option is the normalized version of its text when it has no value attribute
+    var optionQuery = ".//option[@value = " + escapedOption + " or (not(@value) and normalize-space(.) = " + escapedOption + ")]";
+    var ids = polterAgent.find("xpath", optionQuery, element);
+    var polterNode = polterAgent.get(ids[0]);
+    var optionElement = polterNode.element;
+
+    if (multiple || !element.multiple) {
+      if (!optionElement.selected) {
+        clickOnElement(optionElement);
+        optionElement.selected = true;
+      }
+      return dispatchChange(optionElement);
+    }
+
+    deselectAllOptions(element);
+    clickOnElement(optionElement);
+    optionElement.selected = true;
+    return dispatchChange(optionElement);
+  }
+
+  function selectSetValue(element, value) {
+    var option;
+    if ((Array.isArray && Array.isArray(value)) || (value instanceof Array)) {
+      deselectAllOptions(element);
+      for (option in value) {
+        if (value.hasOwnProperty(option)) {
+          selectOptionOnElement(element, value[option], true);
+        }
+      }
+      return true;
+    }
+
+    selectOptionOnElement(element, value, false);
+    return true;
+  }
+
+  function selectRadioValue(element, value) {
+    if (element.value === value) {
+      clickOnElement(element);
+      element.checked=true;
+      dispatchChange(element);
+      return true;
+    }
+
+    var formElements = element.form.elements;
+    var name = element.getAttribute("name");
+    var radioElement, i;
+
+    if (!name) {
+      return null;
+    }
+
+    for (i = 0; i < formElements.length; i++) {
+      radioElement = formElements[i];
+      if (radioElement.tagName.toLowerCase() == 'input' && radioElement.type.toLowerCase() == 'radio' && radioElement.name === name) {
+        if (value === radioElement.value) {
+          clickOnElement(radioElement);
+          radioElement.checked=true;
+          dispatchChange(radioElement);
+          return true;
+        }
+      }
+    }
+
+    return null;
+  }
+
+  function inputSetValue(element, value, elementXpath) {
+    var allowedTypes = ['submit', 'image', 'button', 'reset'];
+    var elementType = element.type.toLowerCase();
+    var textLikeInputType = ['file', 'text', 'password', 'url', 'email', 'search', 'number', 'tel', 'range', 'date', 'month', 'week', 'time', 'datetime', 'color', 'datetime-local'];
+
+    if (allowedTypes.indexOf(elementType) !== -1) {
+      return null;
+    }
+
+    if (elementType == "checkbox") {
+      var booleanValue = false;
+      if (value == "1" || value == 1) {
+        booleanValue = true;
+      } else if (value == "0" || value == 0) {
+        booleanValue = false;
+      }
+      if ((element.checked && !booleanValue) || (!element.checked && booleanValue)) {
+        clickOnElement(element);
+        dispatchChange(element);
+      }
+      return true;
+    }
+
+    if (elementType == "radio") {
+      return selectRadioValue(element, value);
+    }
+
+    if (textLikeInputType.indexOf(elementType) !== -1) {
+      return textAreaSetValue(elementXpath, value);
+    }
+
+    //No support for the moment for file stuff or other input types
+    return null;
+
+  }
+
+  function textAreaSetValue(elementXpath, value) {
+    var polterAgent = window.__poltergeist;
+    var ids = polterAgent.find("xpath", elementXpath, document);
+    var polterNode = polterAgent.get(ids[0]);
+    polterNode.set(value);
+    return true;
+  }
+
+  var node = getElement(xpath);
+  if (node === null) {
+    return null;
+  }
+
+  if (isSelect(node)) {
+    return selectSetValue(node, value);
+  }
+
+  if (isInput(node)) {
+    return inputSetValue(node, value, xpath);
+  }
+
+  if (isTextArea(node)) {
+    return textAreaSetValue(xpath, value);
+  }
+
+  //for the moment everything else also to textArea stuff
+  return textAreaSetValue(xpath, value);
+
+}('{{xpath}}', JSON.parse('{{ value }}')));
+{% endautoescape %}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/SessionTrait.php b/vendor/jcalderonzumba/mink-phantomjs-driver/src/SessionTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..6443dffac7eeb7adb4f5f60bf7b41a60570d3eb5
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/SessionTrait.php
@@ -0,0 +1,50 @@
+<?php
+
+
+namespace Zumba\Mink\Driver;
+
+/**
+ * Trait SessionTrait
+ * @package Zumba\Mink\Driver
+ */
+trait SessionTrait {
+
+  /** @var  bool */
+  protected $started;
+
+  /**
+   * Starts a session to be used by the driver client
+   */
+  public function start() {
+    $this->started = true;
+  }
+
+  /**
+   * Tells if the session is started or not
+   * @return bool
+   */
+  public function isStarted() {
+    return $this->started;
+  }
+
+  /**
+   * Stops the session completely, clean slate for the browser
+   * @return bool
+   */
+  public function stop() {
+    //Since we are using a remote browser "API", stopping is just like resetting, say good bye to cookies
+    //TODO: In the future we may want to control a start / stop of the remove browser
+    return $this->reset();
+  }
+
+  /**
+   * Clears the cookies in the browser, all of them
+   * @return bool
+   */
+  public function reset() {
+    $this->getBrowser()->clearCookies();
+    $this->getBrowser()->reset();
+    $this->started = false;
+    return true;
+  }
+}
diff --git a/vendor/jcalderonzumba/mink-phantomjs-driver/src/WindowTrait.php b/vendor/jcalderonzumba/mink-phantomjs-driver/src/WindowTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..92fc6ee3ad61593c47a76438d946c567d597f5c8
--- /dev/null
+++ b/vendor/jcalderonzumba/mink-phantomjs-driver/src/WindowTrait.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace Zumba\Mink\Driver;
+
+use Behat\Mink\Exception\DriverException;
+
+/**
+ * Class WindowTrait
+ * @package Zumba\Mink\Driver
+ */
+trait WindowTrait {
+  /**
+   * Returns the current page window name
+   * @return string
+   */
+  public function getWindowName() {
+    return $this->browser->windowName();
+  }
+
+  /**
+   * Return all the window handles currently present in phantomjs
+   * @return array
+   */
+  public function getWindowNames() {
+    return $this->browser->windowHandles();
+  }
+
+  /**
+   * Switches to window by name if possible
+   * @param $name
+   * @throws DriverException
+   */
+  public function switchToWindow($name = null) {
+    $handles = $this->browser->windowHandles();
+    if ($name === null) {
+      //null means back to the main window
+      return $this->browser->switchToWindow($handles[0]);
+    }
+
+    $windowHandle = $this->browser->windowHandle($name);
+    if (!empty($windowHandle)) {
+      $this->browser->switchToWindow($windowHandle);
+    } else {
+      throw new DriverException("Could not find window handle by a given window name: $name");
+    }
+
+  }
+
+  /**
+   * Resizing a window with specified size
+   * @param int    $width
+   * @param int    $height
+   * @param string $name
+   * @throws DriverException
+   */
+  public function resizeWindow($width, $height, $name = null) {
+    if ($name !== null) {
+      //TODO: add this on the phantomjs stuff
+      throw new DriverException("Resizing other window than the main one is not supported yet");
+    }
+    $this->browser->resize($width, $height);
+  }
+
+}