Issue #2433009 by hussainweb, grom358, neclimdul, daffie, larowlan, alexpott, pcambra, benjy, jibran, phenaproxima, moshe weitzman, nick_schuch: Add Mink, with Goutte driver, to core
parent
3eafd2d1dc
commit
ddbb2c7999
|
@ -27,7 +27,10 @@
|
|||
"zendframework/zend-feed": "2.3.*",
|
||||
"mikey179/vfsStream": "1.*",
|
||||
"stack/builder": "1.0.*",
|
||||
"egulias/email-validator": "1.2.*"
|
||||
"egulias/email-validator": "1.2.*",
|
||||
"behat/mink": "~1.6",
|
||||
"behat/mink-goutte-driver": "~1.1",
|
||||
"fabpot/goutte": "dev-master"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
@ -4,8 +4,170 @@
|
|||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "c977649e8e1a8b93301fa83283672a06",
|
||||
"hash": "71958cc676a2780e738e9a7d95a3b78b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "behat/mink",
|
||||
"version": "v1.6.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/minkphp/Mink.git",
|
||||
"reference": "8b68523a339ec991bcd638b39dc8f04f808da88a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/minkphp/Mink/zipball/8b68523a339ec991bcd638b39dc8f04f808da88a",
|
||||
"reference": "8b68523a339ec991bcd638b39dc8f04f808da88a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.1",
|
||||
"symfony/css-selector": "~2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)",
|
||||
"behat/mink-goutte-driver": "fast headless driver for any app without JS emulation",
|
||||
"behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)",
|
||||
"behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.6.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Behat\\Mink\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Konstantin Kudryashov",
|
||||
"email": "ever.zet@gmail.com",
|
||||
"homepage": "http://everzet.com"
|
||||
}
|
||||
],
|
||||
"description": "Browser controller/emulator abstraction for PHP",
|
||||
"homepage": "http://mink.behat.org/",
|
||||
"keywords": [
|
||||
"browser",
|
||||
"testing",
|
||||
"web"
|
||||
],
|
||||
"time": "2015-02-04 17:02:06"
|
||||
},
|
||||
{
|
||||
"name": "behat/mink-browserkit-driver",
|
||||
"version": "v1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/minkphp/MinkBrowserKitDriver.git",
|
||||
"reference": "aed8f4a596b79014a75254c3e337511c33e38cbd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/aed8f4a596b79014a75254c3e337511c33e38cbd",
|
||||
"reference": "aed8f4a596b79014a75254c3e337511c33e38cbd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"behat/mink": "~1.6@dev",
|
||||
"php": ">=5.3.1",
|
||||
"symfony/browser-kit": "~2.0",
|
||||
"symfony/dom-crawler": "~2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"silex/silex": "~1.2"
|
||||
},
|
||||
"type": "mink-driver",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Behat\\Mink\\Driver": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Konstantin Kudryashov",
|
||||
"email": "ever.zet@gmail.com",
|
||||
"homepage": "http://everzet.com"
|
||||
}
|
||||
],
|
||||
"description": "Symfony2 BrowserKit driver for Mink framework",
|
||||
"homepage": "http://mink.behat.org/",
|
||||
"keywords": [
|
||||
"Mink",
|
||||
"Symfony2",
|
||||
"browser",
|
||||
"testing"
|
||||
],
|
||||
"time": "2014-09-26 11:35:19"
|
||||
},
|
||||
{
|
||||
"name": "behat/mink-goutte-driver",
|
||||
"version": "v1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/minkphp/MinkGoutteDriver.git",
|
||||
"reference": "2bf327b4166694ecaa8ae7f956cb6ae252ecf03e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/2bf327b4166694ecaa8ae7f956cb6ae252ecf03e",
|
||||
"reference": "2bf327b4166694ecaa8ae7f956cb6ae252ecf03e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"behat/mink": "~1.6@dev",
|
||||
"behat/mink-browserkit-driver": "~1.2@dev",
|
||||
"fabpot/goutte": "~1.0.4|~2.0",
|
||||
"php": ">=5.3.1"
|
||||
},
|
||||
"type": "mink-driver",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Behat\\Mink\\Driver": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Konstantin Kudryashov",
|
||||
"email": "ever.zet@gmail.com",
|
||||
"homepage": "http://everzet.com"
|
||||
}
|
||||
],
|
||||
"description": "Goutte driver for Mink framework",
|
||||
"homepage": "http://mink.behat.org/",
|
||||
"keywords": [
|
||||
"browser",
|
||||
"goutte",
|
||||
"headless",
|
||||
"testing"
|
||||
],
|
||||
"time": "2014-10-09 09:21:12"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
"version": "v1.2.1",
|
||||
|
@ -570,6 +732,55 @@
|
|||
],
|
||||
"time": "2014-11-06 08:59:44"
|
||||
},
|
||||
{
|
||||
"name": "fabpot/goutte",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/FriendsOfPHP/Goutte.git",
|
||||
"reference": "65ab61eae03d670b93a9044ad2328eb81aa1bde5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/65ab61eae03d670b93a9044ad2328eb81aa1bde5",
|
||||
"reference": "65ab61eae03d670b93a9044ad2328eb81aa1bde5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/guzzle": ">=4,<6",
|
||||
"php": ">=5.4.0",
|
||||
"symfony/browser-kit": "~2.1",
|
||||
"symfony/css-selector": "~2.1",
|
||||
"symfony/dom-crawler": "~2.1"
|
||||
},
|
||||
"type": "application",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Goutte\\": "Goutte"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "A simple PHP Web Scraper",
|
||||
"homepage": "https://github.com/FriendsOfPHP/Goutte",
|
||||
"keywords": [
|
||||
"scraper"
|
||||
],
|
||||
"time": "2014-11-28 09:48:17"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "5.0.3",
|
||||
|
@ -1693,6 +1904,61 @@
|
|||
],
|
||||
"time": "2014-10-20 20:55:17"
|
||||
},
|
||||
{
|
||||
"name": "symfony/browser-kit",
|
||||
"version": "v2.6.4",
|
||||
"target-dir": "Symfony/Component/BrowserKit",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/BrowserKit.git",
|
||||
"reference": "2ecec44ed5047020c65dd6e4a4b2f3cf13ae3c04"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/BrowserKit/zipball/2ecec44ed5047020c65dd6e4a4b2f3cf13ae3c04",
|
||||
"reference": "2ecec44ed5047020c65dd6e4a4b2f3cf13ae3c04",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"symfony/dom-crawler": "~2.0,>=2.0.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/css-selector": "~2.0,>=2.0.5",
|
||||
"symfony/process": "~2.0,>=2.0.5"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/process": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\BrowserKit\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Symfony BrowserKit Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-01-03 08:01:59"
|
||||
},
|
||||
{
|
||||
"name": "symfony/class-loader",
|
||||
"version": "v2.6.4",
|
||||
|
@ -1914,6 +2180,59 @@
|
|||
"homepage": "http://symfony.com",
|
||||
"time": "2015-01-25 04:39:26"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dom-crawler",
|
||||
"version": "v2.6.4",
|
||||
"target-dir": "Symfony/Component/DomCrawler",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/DomCrawler.git",
|
||||
"reference": "26a9eb302decd828990e1015afaa11b78b016073"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/DomCrawler/zipball/26a9eb302decd828990e1015afaa11b78b016073",
|
||||
"reference": "26a9eb302decd828990e1015afaa11b78b016073",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/css-selector": "~2.3"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/css-selector": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\DomCrawler\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Symfony DomCrawler Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-01-03 08:01:59"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v2.6.4",
|
||||
|
@ -2651,7 +2970,9 @@
|
|||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {
|
||||
"fabpot/goutte": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
vendor
|
||||
composer.lock
|
||||
/phpunit.xml
|
|
@ -0,0 +1,20 @@
|
|||
language: php
|
||||
|
||||
php: [5.3, 5.4, 5.5, 5.6, hhvm]
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- php: 5.5
|
||||
env: SYMFONY_VERSION='2.3.*'
|
||||
- php: 5.5
|
||||
env: SYMFONY_VERSION='2.5.*@dev'
|
||||
|
||||
before_script:
|
||||
- sh -c 'if [ "$SYMFONY_VERSION" != "" ]; then composer require -n --no-update symfony/symfony=$SYMFONY_VERSION; fi;'
|
||||
- composer install -n --prefer-source
|
||||
|
||||
script: phpunit -v --coverage-clover=coverage.clover
|
||||
|
||||
after_script:
|
||||
- wget https://scrutinizer-ci.com/ocular.phar
|
||||
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover
|
|
@ -0,0 +1,33 @@
|
|||
1.2.0 / 2014-09-26
|
||||
==================
|
||||
|
||||
BC break:
|
||||
|
||||
* Changed the behavior of `getValue` for checkboxes according to the BC break in Mink 1.6
|
||||
|
||||
New features:
|
||||
|
||||
* Implemented `getOuterHtml`
|
||||
* Added the support of manipulating forms without submit buttons
|
||||
* Added support of any request headers instead of supporting only a few hardcoded ones
|
||||
* Added support of any BrowserKit client using `filterResponse` when using BrowserKit 2.3+
|
||||
* Added the support of reset buttons
|
||||
* Implemented `submitForm`
|
||||
* Implemented `isSelected`
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* Fixed the support of options without value attribute in `isSelected` and `getValue`
|
||||
* Added the support of radio buttons in `isChecked`
|
||||
* Fixed the submission of empty textarea fields
|
||||
* Refactored the handling of request headers to ensure they are reset when resetting the driver
|
||||
* Fixed the handling of buttons to submit only for submit buttons rather than all buttons
|
||||
* Fixed the code to throw exceptions rather than triggering a fatal error for invalid usages of the driver
|
||||
* Fixed the removal of cookies
|
||||
* Fixed the submission of form fields with same name and without id
|
||||
* Fixed `getAttribute` to return `null` for missing attributes rather than an empty string
|
||||
|
||||
Testing:
|
||||
|
||||
* Updated the testsuite to use the new Mink 1.6 driver testsuite
|
||||
* Added testing on HHVM
|
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2012-2013 Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
|
||||
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.
|
|
@ -0,0 +1,54 @@
|
|||
Mink BrowserKit Driver
|
||||
======================
|
||||
|
||||
[](https://packagist.org/packages/behat/mink-browserkit-driver)
|
||||
[](https://packagist.org/packages/behat/mink-browserkit-driver)
|
||||
[](https://packagist.org/packages/behat/mink-browserkit-driver)
|
||||
[](https://travis-ci.org/Behat/MinkBrowserKitDriver)
|
||||
[](https://scrutinizer-ci.com/g/Behat/MinkBrowserKitDriver/)
|
||||
[](https://scrutinizer-ci.com/g/Behat/MinkBrowserKitDriver/)
|
||||
[](https://packagist.org/packages/behat/mink-browserkit-driver)
|
||||
|
||||
Usage Example
|
||||
-------------
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Behat\Mink\Mink,
|
||||
Behat\Mink\Session,
|
||||
Behat\Mink\Driver\BrowserKitDriver;
|
||||
|
||||
use Symfony\Component\HttpKernel\Client;
|
||||
|
||||
$app = require_once(__DIR__.'/app.php'); // Silex app
|
||||
|
||||
$mink = new Mink(array(
|
||||
'silex' => new Session(new BrowserKitDriver(new Client($app))),
|
||||
));
|
||||
|
||||
$mink->getSession('silex')->getPage()->findLink('Chat')->click();
|
||||
```
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
``` json
|
||||
{
|
||||
"require": {
|
||||
"behat/mink": "~1.5",
|
||||
"behat/mink-browserkit-driver": "~1.1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
``` bash
|
||||
$> curl -sS https://getcomposer.org/installer | php
|
||||
$> php composer.phar install
|
||||
```
|
||||
|
||||
Maintainers
|
||||
-----------
|
||||
|
||||
* Konstantin Kudryashov [everzet](http://github.com/everzet)
|
||||
* Other [awesome developers](https://github.com/Behat/MinkBrowserKitDriver/graphs/contributors)
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"name": "behat/mink-browserkit-driver",
|
||||
"description": "Symfony2 BrowserKit driver for Mink framework",
|
||||
"keywords": ["Symfony2", "Mink", "testing", "browser"],
|
||||
"homepage": "http://mink.behat.org/",
|
||||
"type": "mink-driver",
|
||||
"license": "MIT",
|
||||
|
||||
"authors": [
|
||||
{
|
||||
"name": "Konstantin Kudryashov",
|
||||
"email": "ever.zet@gmail.com",
|
||||
"homepage": "http://everzet.com"
|
||||
}
|
||||
],
|
||||
|
||||
"require": {
|
||||
"php": ">=5.3.1",
|
||||
"behat/mink": "~1.6@dev",
|
||||
"symfony/browser-kit": "~2.0",
|
||||
"symfony/dom-crawler": "~2.0"
|
||||
},
|
||||
|
||||
"require-dev": {
|
||||
"silex/silex": "~1.2"
|
||||
},
|
||||
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Behat\\Mink\\Driver": "src/"
|
||||
}
|
||||
},
|
||||
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Behat\\Mink\\Tests\\Driver\\": "tests"
|
||||
}
|
||||
},
|
||||
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.2.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit colors="true" bootstrap="vendor/behat/mink/driver-testsuite/bootstrap.php">
|
||||
<php>
|
||||
<var name="driver_config_factory" value="Behat\Mink\Tests\Driver\BrowserKitConfig::getInstance" />
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Driver test suite">
|
||||
<directory>tests</directory>
|
||||
<directory>vendor/behat/mink/driver-testsuite/tests/Basic</directory>
|
||||
<directory>vendor/behat/mink/driver-testsuite/tests/Form</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./src/Behat/Mink/Driver</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
949
core/vendor/behat/mink-browserkit-driver/src/Behat/Mink/Driver/BrowserKitDriver.php
vendored
Normal file
949
core/vendor/behat/mink-browserkit-driver/src/Behat/Mink/Driver/BrowserKitDriver.php
vendored
Normal file
|
@ -0,0 +1,949 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat\Mink.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Mink\Driver;
|
||||
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Behat\Mink\Exception\DriverException;
|
||||
use Behat\Mink\Exception\UnsupportedDriverActionException;
|
||||
use Behat\Mink\Session;
|
||||
use Symfony\Component\BrowserKit\Client;
|
||||
use Symfony\Component\BrowserKit\Cookie;
|
||||
use Symfony\Component\BrowserKit\Request;
|
||||
use Symfony\Component\BrowserKit\Response;
|
||||
use Symfony\Component\DomCrawler\Crawler;
|
||||
use Symfony\Component\DomCrawler\Field\ChoiceFormField;
|
||||
use Symfony\Component\DomCrawler\Field\FileFormField;
|
||||
use Symfony\Component\DomCrawler\Field\FormField;
|
||||
use Symfony\Component\DomCrawler\Field\InputFormField;
|
||||
use Symfony\Component\DomCrawler\Field\TextareaFormField;
|
||||
use Symfony\Component\DomCrawler\Form;
|
||||
use Symfony\Component\HttpFoundation\Request as HttpFoundationRequest;
|
||||
use Symfony\Component\HttpFoundation\Response as HttpFoundationResponse;
|
||||
use Symfony\Component\HttpKernel\Client as HttpKernelClient;
|
||||
|
||||
/**
|
||||
* Symfony2 BrowserKit driver.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class BrowserKitDriver extends CoreDriver
|
||||
{
|
||||
private $session;
|
||||
private $client;
|
||||
|
||||
/**
|
||||
* @var Form[]
|
||||
*/
|
||||
private $forms = array();
|
||||
private $serverParameters = array();
|
||||
private $started = false;
|
||||
private $removeScriptFromUrl = false;
|
||||
private $removeHostFromUrl = false;
|
||||
|
||||
/**
|
||||
* Initializes BrowserKit driver.
|
||||
*
|
||||
* @param Client $client BrowserKit client instance
|
||||
* @param string|null $baseUrl Base URL for HttpKernel clients
|
||||
*/
|
||||
public function __construct(Client $client, $baseUrl = null)
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->client->followRedirects(true);
|
||||
|
||||
if ($baseUrl !== null && $client instanceof HttpKernelClient) {
|
||||
$client->setServerParameter('SCRIPT_FILENAME', parse_url($baseUrl, PHP_URL_PATH));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns BrowserKit HTTP client instance.
|
||||
*
|
||||
* @return Client
|
||||
*/
|
||||
public function getClient()
|
||||
{
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setSession(Session $session)
|
||||
{
|
||||
$this->session = $session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells driver to remove hostname from URL.
|
||||
*
|
||||
* @param Boolean $remove
|
||||
*
|
||||
* @deprecated Deprecated as of 1.2, to be removed in 2.0. Pass the base url in the constructor instead.
|
||||
*/
|
||||
public function setRemoveHostFromUrl($remove = true)
|
||||
{
|
||||
trigger_error(
|
||||
'setRemoveHostFromUrl() is deprecated as of 1.2 and will be removed in 2.0. Pass the base url in the constructor instead.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
$this->removeHostFromUrl = (bool) $remove;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells driver to remove script name from URL.
|
||||
*
|
||||
* @param Boolean $remove
|
||||
*
|
||||
* @deprecated Deprecated as of 1.2, to be removed in 2.0. Pass the base url in the constructor instead.
|
||||
*/
|
||||
public function setRemoveScriptFromUrl($remove = true)
|
||||
{
|
||||
trigger_error(
|
||||
'setRemoveScriptFromUrl() is deprecated as of 1.2 and will be removed in 2.0. Pass the base url in the constructor instead.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
$this->removeScriptFromUrl = (bool) $remove;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
$this->started = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isStarted()
|
||||
{
|
||||
return $this->started;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function stop()
|
||||
{
|
||||
$this->reset();
|
||||
$this->started = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
// Restarting the client resets the cookies and the history
|
||||
$this->client->restart();
|
||||
$this->forms = array();
|
||||
$this->serverParameters = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function visit($url)
|
||||
{
|
||||
$this->client->request('GET', $this->prepareUrl($url), array(), array(), $this->serverParameters);
|
||||
$this->forms = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCurrentUrl()
|
||||
{
|
||||
if (method_exists($this->client, 'getInternalRequest')) {
|
||||
$request = $this->client->getInternalRequest();
|
||||
} else {
|
||||
// BC layer for BrowserKit 2.2.x and older
|
||||
$request = $this->client->getRequest();
|
||||
|
||||
if (null !== $request && !$request instanceof Request && !$request instanceof HttpFoundationRequest) {
|
||||
throw new DriverException(sprintf(
|
||||
'The BrowserKit client returned an unsupported request implementation: %s. Please upgrade your BrowserKit package to 2.3 or newer.',
|
||||
get_class($request)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if ($request === null) {
|
||||
throw new DriverException('Unable to access the request before visiting a page');
|
||||
}
|
||||
|
||||
return $request->getUri();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reload()
|
||||
{
|
||||
$this->client->reload();
|
||||
$this->forms = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function forward()
|
||||
{
|
||||
$this->client->forward();
|
||||
$this->forms = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function back()
|
||||
{
|
||||
$this->client->back();
|
||||
$this->forms = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setBasicAuth($user, $password)
|
||||
{
|
||||
if (false === $user) {
|
||||
unset($this->serverParameters['PHP_AUTH_USER'], $this->serverParameters['PHP_AUTH_PW']);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->serverParameters['PHP_AUTH_USER'] = $user;
|
||||
$this->serverParameters['PHP_AUTH_PW'] = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setRequestHeader($name, $value)
|
||||
{
|
||||
$contentHeaders = array('CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true);
|
||||
$name = str_replace('-', '_', strtoupper($name));
|
||||
|
||||
// CONTENT_* are not prefixed with HTTP_ in PHP when building $_SERVER
|
||||
if (!isset($contentHeaders[$name])) {
|
||||
$name = 'HTTP_' . $name;
|
||||
}
|
||||
|
||||
$this->serverParameters[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResponseHeaders()
|
||||
{
|
||||
return $this->getResponse()->getHeaders();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setCookie($name, $value = null)
|
||||
{
|
||||
if (null === $value) {
|
||||
$this->deleteCookie($name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$jar = $this->client->getCookieJar();
|
||||
$jar->set(new Cookie($name, $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a cookie by name.
|
||||
*
|
||||
* @param string $name Cookie name.
|
||||
*/
|
||||
private function deleteCookie($name)
|
||||
{
|
||||
$path = $this->getCookiePath();
|
||||
$jar = $this->client->getCookieJar();
|
||||
|
||||
do {
|
||||
if (null !== $jar->get($name, $path)) {
|
||||
$jar->expire($name, $path);
|
||||
}
|
||||
|
||||
$path = preg_replace('/.$/', '', $path);
|
||||
} while ($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current cookie path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getCookiePath()
|
||||
{
|
||||
$path = dirname(parse_url($this->getCurrentUrl(), PHP_URL_PATH));
|
||||
|
||||
if ('\\' === DIRECTORY_SEPARATOR) {
|
||||
$path = str_replace('\\', '/', $path);
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCookie($name)
|
||||
{
|
||||
// Note that the following doesn't work well because
|
||||
// Symfony\Component\BrowserKit\CookieJar stores cookies by name,
|
||||
// path, AND domain and if you don't fill them all in correctly then
|
||||
// you won't get the value that you're expecting.
|
||||
//
|
||||
// $jar = $this->client->getCookieJar();
|
||||
//
|
||||
// if (null !== $cookie = $jar->get($name)) {
|
||||
// return $cookie->getValue();
|
||||
// }
|
||||
|
||||
$allValues = $this->client->getCookieJar()->allValues($this->getCurrentUrl());
|
||||
|
||||
if (isset($allValues[$name])) {
|
||||
return $allValues[$name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->getResponse()->getStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
return $this->getResponse()->getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function find($xpath)
|
||||
{
|
||||
$nodes = $this->getCrawler()->filterXPath($xpath);
|
||||
|
||||
$elements = array();
|
||||
foreach ($nodes as $i => $node) {
|
||||
$elements[] = new NodeElement(sprintf('(%s)[%d]', $xpath, $i + 1), $this->session);
|
||||
}
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTagName($xpath)
|
||||
{
|
||||
return $this->getCrawlerNode($this->getFilteredCrawler($xpath))->nodeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getText($xpath)
|
||||
{
|
||||
$text = $this->getFilteredCrawler($xpath)->text();
|
||||
$text = str_replace("\n", ' ', $text);
|
||||
$text = preg_replace('/ {2,}/', ' ', $text);
|
||||
|
||||
return trim($text);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHtml($xpath)
|
||||
{
|
||||
// cut the tag itself (making innerHTML out of outerHTML)
|
||||
return preg_replace('/^\<[^\>]+\>|\<[^\>]+\>$/', '', $this->getOuterHtml($xpath));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOuterHtml($xpath)
|
||||
{
|
||||
$node = $this->getCrawlerNode($this->getFilteredCrawler($xpath));
|
||||
|
||||
return $node->ownerDocument->saveXML($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAttribute($xpath, $name)
|
||||
{
|
||||
$node = $this->getFilteredCrawler($xpath);
|
||||
|
||||
if ($this->getCrawlerNode($node)->hasAttribute($name)) {
|
||||
return $node->attr($name);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getValue($xpath)
|
||||
{
|
||||
if (in_array($this->getAttribute($xpath, 'type'), array('submit', 'image', 'button'))) {
|
||||
return $this->getAttribute($xpath, 'value');
|
||||
}
|
||||
|
||||
$node = $this->getCrawlerNode($this->getFilteredCrawler($xpath));
|
||||
|
||||
if ('option' === $node->tagName) {
|
||||
return $this->getOptionValue($node);
|
||||
}
|
||||
|
||||
try {
|
||||
$field = $this->getFormField($xpath);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return $this->getAttribute($xpath, 'value');
|
||||
}
|
||||
|
||||
return $field->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setValue($xpath, $value)
|
||||
{
|
||||
$this->getFormField($xpath)->setValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function check($xpath)
|
||||
{
|
||||
$this->getCheckboxField($xpath)->tick();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function uncheck($xpath)
|
||||
{
|
||||
$this->getCheckboxField($xpath)->untick();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function selectOption($xpath, $value, $multiple = false)
|
||||
{
|
||||
$field = $this->getFormField($xpath);
|
||||
|
||||
if (!$field instanceof ChoiceFormField) {
|
||||
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 ($multiple) {
|
||||
$oldValue = (array) $field->getValue();
|
||||
$oldValue[] = $value;
|
||||
$value = $oldValue;
|
||||
}
|
||||
|
||||
$field->select($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isSelected($xpath)
|
||||
{
|
||||
$optionValue = $this->getOptionValue($this->getCrawlerNode($this->getFilteredCrawler($xpath)));
|
||||
$selectField = $this->getFormField('(' . $xpath . ')/ancestor-or-self::*[local-name()="select"]');
|
||||
$selectValue = $selectField->getValue();
|
||||
|
||||
return is_array($selectValue) ? in_array($optionValue, $selectValue) : $optionValue == $selectValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function click($xpath)
|
||||
{
|
||||
$node = $this->getFilteredCrawler($xpath);
|
||||
$crawlerNode = $this->getCrawlerNode($node);
|
||||
$tagName = $crawlerNode->nodeName;
|
||||
|
||||
if ('a' === $tagName) {
|
||||
$this->client->click($node->link());
|
||||
$this->forms = array();
|
||||
} elseif ($this->canSubmitForm($crawlerNode)) {
|
||||
$this->submit($node->form());
|
||||
} elseif ($this->canResetForm($crawlerNode)) {
|
||||
$this->resetForm($crawlerNode);
|
||||
} else {
|
||||
$message = sprintf('%%s supports clicking on links and buttons only. But "%s" provided', $tagName);
|
||||
|
||||
throw new UnsupportedDriverActionException($message, $this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isChecked($xpath)
|
||||
{
|
||||
$field = $this->getFormField($xpath);
|
||||
|
||||
if (!$field instanceof ChoiceFormField || 'select' === $field->getType()) {
|
||||
throw new DriverException(sprintf('Impossible to get the checked state of the element with XPath "%s" as it is not a checkbox or radio input', $xpath));
|
||||
}
|
||||
|
||||
if ('checkbox' === $field->getType()) {
|
||||
return $field->hasValue();
|
||||
}
|
||||
|
||||
$radio = $this->getCrawlerNode($this->getFilteredCrawler($xpath));
|
||||
|
||||
return $radio->getAttribute('value') === $field->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function attachFile($xpath, $path)
|
||||
{
|
||||
$field = $this->getFormField($xpath);
|
||||
|
||||
if (!$field instanceof FileFormField) {
|
||||
throw new DriverException(sprintf('Impossible to attach a file on the element with XPath "%s" as it is not a file input', $xpath));
|
||||
}
|
||||
|
||||
$field->upload($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm($xpath)
|
||||
{
|
||||
$crawler = $this->getFilteredCrawler($xpath);
|
||||
|
||||
$this->submit($crawler->form());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Response
|
||||
*
|
||||
* @throws DriverException If there is not response yet
|
||||
*/
|
||||
protected function getResponse()
|
||||
{
|
||||
if (!method_exists($this->client, 'getInternalResponse')) {
|
||||
$implementationResponse = $this->client->getResponse();
|
||||
|
||||
if (null === $implementationResponse) {
|
||||
throw new DriverException('Unable to access the response before visiting a page');
|
||||
}
|
||||
|
||||
return $this->convertImplementationResponse($implementationResponse);
|
||||
}
|
||||
|
||||
$response = $this->client->getInternalResponse();
|
||||
|
||||
if (null === $response) {
|
||||
throw new DriverException('Unable to access the response before visiting a page');
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the BrowserKit Response for legacy BrowserKit versions.
|
||||
*
|
||||
* Before 2.3.0, there was no Client::getInternalResponse method, and the
|
||||
* return value of Client::getResponse can be anything when the implementation
|
||||
* uses Client::filterResponse because of a bad choice done in BrowserKit and
|
||||
* kept for BC reasons (the Client::getInternalResponse method has been added
|
||||
* to solve it).
|
||||
*
|
||||
* This implementation supports client which don't rely Client::filterResponse
|
||||
* and clients which use an HttpFoundation Response (like the HttpKernel client).
|
||||
*
|
||||
* @param object $response the response specific to the BrowserKit implementation
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @throws DriverException If the response cannot be converted to a BrowserKit response
|
||||
*/
|
||||
private function convertImplementationResponse($response)
|
||||
{
|
||||
if ($response instanceof Response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
// due to a bug, the HttpKernel client implementation returns the HttpFoundation response
|
||||
// The conversion logic is copied from Symfony\Component\HttpKernel\Client::filterResponse
|
||||
if ($response instanceof HttpFoundationResponse) {
|
||||
$headers = $response->headers->all();
|
||||
if ($response->headers->getCookies()) {
|
||||
$cookies = array();
|
||||
foreach ($response->headers->getCookies() as $cookie) {
|
||||
$cookies[] = new Cookie(
|
||||
$cookie->getName(),
|
||||
$cookie->getValue(),
|
||||
$cookie->getExpiresTime(),
|
||||
$cookie->getPath(),
|
||||
$cookie->getDomain(),
|
||||
$cookie->isSecure(),
|
||||
$cookie->isHttpOnly()
|
||||
);
|
||||
}
|
||||
$headers['Set-Cookie'] = $cookies;
|
||||
}
|
||||
|
||||
// this is needed to support StreamedResponse
|
||||
ob_start();
|
||||
$response->sendContent();
|
||||
$content = ob_get_clean();
|
||||
|
||||
return new Response($content, $response->getStatusCode(), $headers);
|
||||
}
|
||||
|
||||
throw new DriverException(sprintf(
|
||||
'The BrowserKit client returned an unsupported response implementation: %s. Please upgrade your BrowserKit package to 2.3 or newer.',
|
||||
get_class($response)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares URL for visiting.
|
||||
* Removes "*.php/" from urls and then passes it to BrowserKitDriver::visit().
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function prepareUrl($url)
|
||||
{
|
||||
$replacement = ($this->removeHostFromUrl ? '' : '$1') . ($this->removeScriptFromUrl ? '' : '$2');
|
||||
|
||||
return preg_replace('#(https?\://[^/]+)(/[^/\.]+\.php)?#', $replacement, $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns form field from XPath query.
|
||||
*
|
||||
* @param string $xpath
|
||||
*
|
||||
* @return FormField
|
||||
*
|
||||
* @throws DriverException
|
||||
*/
|
||||
protected function getFormField($xpath)
|
||||
{
|
||||
$fieldNode = $this->getCrawlerNode($this->getFilteredCrawler($xpath));
|
||||
$fieldName = str_replace('[]', '', $fieldNode->getAttribute('name'));
|
||||
|
||||
$formNode = $this->getFormNode($fieldNode);
|
||||
$formId = $this->getFormNodeId($formNode);
|
||||
|
||||
if (!isset($this->forms[$formId])) {
|
||||
$this->forms[$formId] = new Form($formNode, $this->getCurrentUrl());
|
||||
}
|
||||
|
||||
if (is_array($this->forms[$formId][$fieldName])) {
|
||||
return $this->forms[$formId][$fieldName][$this->getFieldPosition($fieldNode)];
|
||||
}
|
||||
|
||||
return $this->forms[$formId][$fieldName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the checkbox field from xpath query, ensuring it is valid.
|
||||
*
|
||||
* @param string $xpath
|
||||
*
|
||||
* @return ChoiceFormField
|
||||
*
|
||||
* @throws DriverException when the field is not a checkbox
|
||||
*/
|
||||
private function getCheckboxField($xpath)
|
||||
{
|
||||
$field = $this->getFormField($xpath);
|
||||
|
||||
if (!$field instanceof ChoiceFormField) {
|
||||
throw new DriverException(sprintf('Impossible to check the element with XPath "%s" as it is not a checkbox', $xpath));
|
||||
}
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $element
|
||||
*
|
||||
* @return \DOMElement
|
||||
*
|
||||
* @throws DriverException if the form node cannot be found
|
||||
*/
|
||||
private function getFormNode(\DOMElement $element)
|
||||
{
|
||||
if ($element->hasAttribute('form')) {
|
||||
$formId = $element->getAttribute('form');
|
||||
$formNode = $element->ownerDocument->getElementById($formId);
|
||||
|
||||
if (null === $formNode || 'form' !== $formNode->nodeName) {
|
||||
throw new DriverException(sprintf('The selected node has an invalid form attribute (%s).', $formId));
|
||||
}
|
||||
|
||||
return $formNode;
|
||||
}
|
||||
|
||||
$formNode = $element;
|
||||
|
||||
do {
|
||||
// use the ancestor form element
|
||||
if (null === $formNode = $formNode->parentNode) {
|
||||
throw new DriverException('The selected node does not have a form ancestor.');
|
||||
}
|
||||
} while ('form' !== $formNode->nodeName);
|
||||
|
||||
return $formNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the position of the field node among elements with the same name
|
||||
*
|
||||
* BrowserKit uses the field name as index to find the field in its Form object.
|
||||
* When multiple fields have the same name (checkboxes for instance), it will return
|
||||
* an array of elements in the order they appear in the DOM.
|
||||
*
|
||||
* @param \DOMElement $fieldNode
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
private function getFieldPosition(\DOMElement $fieldNode)
|
||||
{
|
||||
$elements = $this->getCrawler()->filterXPath('//*[@name=\''.$fieldNode->getAttribute('name').'\']');
|
||||
|
||||
if (count($elements) > 1) {
|
||||
// more than one element contains this name !
|
||||
// so we need to find the position of $fieldNode
|
||||
foreach ($elements as $key => $element) {
|
||||
/** @var \DOMElement $element */
|
||||
if ($element->getNodePath() === $fieldNode->getNodePath()) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function submit(Form $form)
|
||||
{
|
||||
$formId = $this->getFormNodeId($form->getFormNode());
|
||||
|
||||
if (isset($this->forms[$formId])) {
|
||||
$this->mergeForms($form, $this->forms[$formId]);
|
||||
}
|
||||
|
||||
// remove empty file fields from request
|
||||
foreach ($form->getFiles() as $name => $field) {
|
||||
if (empty($field['name']) && empty($field['tmp_name'])) {
|
||||
$form->remove($name);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($form->all() as $field) {
|
||||
// Add a fix for https://github.com/symfony/symfony/pull/10733 to support Symfony versions which are not fixed
|
||||
if ($field instanceof TextareaFormField && null === $field->getValue()) {
|
||||
$field->setValue('');
|
||||
}
|
||||
}
|
||||
|
||||
$this->client->submit($form);
|
||||
|
||||
$this->forms = array();
|
||||
}
|
||||
|
||||
private function resetForm(\DOMElement $fieldNode)
|
||||
{
|
||||
$formNode = $this->getFormNode($fieldNode);
|
||||
$formId = $this->getFormNodeId($formNode);
|
||||
unset($this->forms[$formId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a node can submit a form.
|
||||
*
|
||||
* @param \DOMElement $node Node.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function canSubmitForm(\DOMElement $node)
|
||||
{
|
||||
$type = $node->hasAttribute('type') ? $node->getAttribute('type') : null;
|
||||
|
||||
if ('input' == $node->nodeName && in_array($type, array('submit', 'image'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return 'button' == $node->nodeName && (null === $type || 'submit' == $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a node can reset a form.
|
||||
*
|
||||
* @param \DOMElement $node Node.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function canResetForm(\DOMElement $node)
|
||||
{
|
||||
$type = $node->hasAttribute('type') ? $node->getAttribute('type') : null;
|
||||
|
||||
return in_array($node->nodeName, array('input', 'button')) && 'reset' == $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns form node unique identifier.
|
||||
*
|
||||
* @param \DOMElement $form
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getFormNodeId(\DOMElement $form)
|
||||
{
|
||||
return md5($form->getLineNo() . $form->getNodePath() . $form->nodeValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of an option element
|
||||
*
|
||||
* @param \DOMElement $option
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @see \Symfony\Component\DomCrawler\Field\ChoiceFormField::buildOptionValue
|
||||
*/
|
||||
private function getOptionValue(\DOMElement $option)
|
||||
{
|
||||
if ($option->hasAttribute('value')) {
|
||||
return $option->getAttribute('value');
|
||||
}
|
||||
|
||||
if (!empty($option->nodeValue)) {
|
||||
return $option->nodeValue;
|
||||
}
|
||||
|
||||
return '1'; // DomCrawler uses 1 by default if there is no text in the option
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges second form values into first one.
|
||||
*
|
||||
* @param Form $to merging target
|
||||
* @param Form $from merging source
|
||||
*/
|
||||
private function mergeForms(Form $to, Form $from)
|
||||
{
|
||||
foreach ($from->all() as $name => $field) {
|
||||
$fieldReflection = new \ReflectionObject($field);
|
||||
$nodeReflection = $fieldReflection->getProperty('node');
|
||||
$valueReflection = $fieldReflection->getProperty('value');
|
||||
|
||||
$nodeReflection->setAccessible(true);
|
||||
$valueReflection->setAccessible(true);
|
||||
|
||||
if (!($field instanceof InputFormField && in_array(
|
||||
$nodeReflection->getValue($field)->getAttribute('type'),
|
||||
array('submit', 'button', 'image')
|
||||
))) {
|
||||
$valueReflection->setValue($to[$name], $valueReflection->getValue($field));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns DOMElement from crawler instance.
|
||||
*
|
||||
* @param Crawler $crawler
|
||||
*
|
||||
* @return \DOMElement
|
||||
*
|
||||
* @throws DriverException when the node does not exist
|
||||
*/
|
||||
private function getCrawlerNode(Crawler $crawler)
|
||||
{
|
||||
$crawler->rewind();
|
||||
$node = $crawler->current();
|
||||
|
||||
if (null !== $node) {
|
||||
return $node;
|
||||
}
|
||||
|
||||
throw new DriverException('The element does not exist');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a crawler filtered for the given XPath, requiring at least 1 result.
|
||||
*
|
||||
* @param string $xpath
|
||||
*
|
||||
* @return Crawler
|
||||
*
|
||||
* @throws DriverException when no matching elements are found
|
||||
*/
|
||||
private function getFilteredCrawler($xpath)
|
||||
{
|
||||
if (!count($crawler = $this->getCrawler()->filterXPath($xpath))) {
|
||||
throw new DriverException(sprintf('There is no element matching XPath "%s"', $xpath));
|
||||
}
|
||||
|
||||
return $crawler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns crawler instance (got from client).
|
||||
*
|
||||
* @return Crawler
|
||||
*
|
||||
* @throws DriverException
|
||||
*/
|
||||
private function getCrawler()
|
||||
{
|
||||
$crawler = $this->client->getCrawler();
|
||||
|
||||
if (null === $crawler) {
|
||||
throw new DriverException('Unable to access the response content before visiting a page');
|
||||
}
|
||||
|
||||
return $crawler;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver;
|
||||
|
||||
use Behat\Mink\Driver\BrowserKitDriver;
|
||||
use Symfony\Component\HttpKernel\Client;
|
||||
|
||||
class BrowserKitConfig extends AbstractConfig
|
||||
{
|
||||
public static function getInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createDriver()
|
||||
{
|
||||
$client = new Client(require(__DIR__.'/app.php'));
|
||||
|
||||
return new BrowserKitDriver($client);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWebFixturesUrl()
|
||||
{
|
||||
return 'http://localhost';
|
||||
}
|
||||
|
||||
protected function supportsJs()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Custom;
|
||||
|
||||
use Behat\Mink\Driver\BrowserKitDriver;
|
||||
use Behat\Mink\Session;
|
||||
use Symfony\Component\HttpKernel\Client;
|
||||
|
||||
/**
|
||||
* @group functional
|
||||
*/
|
||||
class BaseUrlTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testBaseUrl()
|
||||
{
|
||||
$client = new Client(require(__DIR__.'/../app.php'));
|
||||
$driver = new BrowserKitDriver($client, 'http://localhost/foo/');
|
||||
$session = new Session($driver);
|
||||
|
||||
$session->visit('http://localhost/foo/index.html');
|
||||
$this->assertEquals(200, $session->getStatusCode());
|
||||
$this->assertEquals('http://localhost/foo/index.html', $session->getCurrentUrl());
|
||||
}
|
||||
}
|
181
core/vendor/behat/mink-browserkit-driver/tests/Custom/ErrorHandlingTest.php
vendored
Normal file
181
core/vendor/behat/mink-browserkit-driver/tests/Custom/ErrorHandlingTest.php
vendored
Normal file
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Custom;
|
||||
|
||||
use Behat\Mink\Driver\BrowserKitDriver;
|
||||
use Symfony\Component\BrowserKit\Client;
|
||||
use Symfony\Component\BrowserKit\Response;
|
||||
|
||||
class ErrorHandlingTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var TestClient
|
||||
*/
|
||||
private $client;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->client = new TestClient();
|
||||
}
|
||||
|
||||
public function testGetClient()
|
||||
{
|
||||
$this->assertSame($this->client, $this->getDriver()->getClient());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Behat\Mink\Exception\DriverException
|
||||
* @expectedExceptionMessage Unable to access the response before visiting a page
|
||||
*/
|
||||
public function testGetResponseHeaderWithoutVisit()
|
||||
{
|
||||
$this->getDriver()->getResponseHeaders();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Behat\Mink\Exception\DriverException
|
||||
* @expectedExceptionMessage Unable to access the response content before visiting a page
|
||||
*/
|
||||
public function testFindWithoutVisit()
|
||||
{
|
||||
$this->getDriver()->find('//html');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Behat\Mink\Exception\DriverException
|
||||
* @expectedExceptionMessage Unable to access the request before visiting a page
|
||||
*/
|
||||
public function testGetCurrentUrlWithoutVisit()
|
||||
{
|
||||
$this->getDriver()->getCurrentUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Behat\Mink\Exception\DriverException
|
||||
* @expectedExceptionMessage The selected node has an invalid form attribute (foo)
|
||||
*/
|
||||
public function testNotMatchingHtml5FormId()
|
||||
{
|
||||
$html = <<<'HTML'
|
||||
<html>
|
||||
<body>
|
||||
<form id="test">
|
||||
<input name="test" value="foo" form="foo">
|
||||
<input type="submit">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
|
||||
$this->client->setNextResponse(new Response($html));
|
||||
|
||||
$driver = $this->getDriver();
|
||||
$driver->visit('/index.php');
|
||||
$driver->setValue('//input[./@name="test"]', 'bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Behat\Mink\Exception\DriverException
|
||||
* @expectedExceptionMessage The selected node has an invalid form attribute (foo)
|
||||
*/
|
||||
public function testInvalidHtml5FormId()
|
||||
{
|
||||
$html = <<<'HTML'
|
||||
<html>
|
||||
<body>
|
||||
<form id="test">
|
||||
<input name="test" value="foo" form="foo">
|
||||
<input type="submit">
|
||||
</form>
|
||||
<div id="foo"></div>
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
|
||||
$this->client->setNextResponse(new Response($html));
|
||||
|
||||
$driver = $this->getDriver();
|
||||
$driver->visit('/index.php');
|
||||
$driver->setValue('//input[./@name="test"]', 'bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Behat\Mink\Exception\DriverException
|
||||
* @expectedExceptionMessage The selected node does not have a form ancestor.
|
||||
*/
|
||||
public function testManipulateInputWithoutForm()
|
||||
{
|
||||
$html = <<<'HTML'
|
||||
<html>
|
||||
<body>
|
||||
<form id="test">
|
||||
<input type="submit">
|
||||
</form>
|
||||
<div id="foo">
|
||||
<input name="test" value="foo">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
|
||||
$this->client->setNextResponse(new Response($html));
|
||||
|
||||
$driver = $this->getDriver();
|
||||
$driver->visit('/index.php');
|
||||
$driver->setValue('//input[./@name="test"]', 'bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Behat\Mink\Exception\DriverException
|
||||
* @expectedExceptionMessage Behat\Mink\Driver\BrowserKitDriver supports clicking on links and buttons only. But "div" provided
|
||||
*/
|
||||
public function testClickOnUnsupportedElement()
|
||||
{
|
||||
$html = <<<'HTML'
|
||||
<html>
|
||||
<body>
|
||||
<div></div>
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
|
||||
$this->client->setNextResponse(new Response($html));
|
||||
|
||||
$driver = $this->getDriver();
|
||||
$driver->visit('/index.php');
|
||||
$driver->click('//div');
|
||||
}
|
||||
|
||||
private function getDriver()
|
||||
{
|
||||
return new BrowserKitDriver($this->client);
|
||||
}
|
||||
}
|
||||
|
||||
class TestClient extends Client
|
||||
{
|
||||
protected $nextResponse = null;
|
||||
protected $nextScript = null;
|
||||
|
||||
public function setNextResponse(Response $response)
|
||||
{
|
||||
$this->nextResponse = $response;
|
||||
}
|
||||
|
||||
public function setNextScript($script)
|
||||
{
|
||||
$this->nextScript = $script;
|
||||
}
|
||||
|
||||
protected function doRequest($request)
|
||||
{
|
||||
if (null === $this->nextResponse) {
|
||||
return new Response();
|
||||
}
|
||||
|
||||
$response = $this->nextResponse;
|
||||
$this->nextResponse = null;
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace app;
|
||||
|
||||
$app = new \Silex\Application();
|
||||
$app->register(new \Silex\Provider\SessionServiceProvider());
|
||||
|
||||
$def = realpath(__DIR__.'/../vendor/behat/mink/driver-testsuite/web-fixtures');
|
||||
$ovr = realpath(__DIR__.'/web-fixtures');
|
||||
$cbk = function ($file) use ($app, $def, $ovr) {
|
||||
$file = str_replace('.file', '.php', $file);
|
||||
$path = file_exists($ovr.'/'.$file) ? $ovr.'/'.$file : $def.'/'.$file;
|
||||
$resp = null;
|
||||
|
||||
ob_start();
|
||||
include($path);
|
||||
$content = ob_get_clean();
|
||||
|
||||
if ($resp) {
|
||||
if ('' === $resp->getContent()) {
|
||||
$resp->setContent($content);
|
||||
}
|
||||
|
||||
return $resp;
|
||||
}
|
||||
|
||||
return $content;
|
||||
};
|
||||
|
||||
$app->get('/{file}', $cbk)->assert('file', '.*');
|
||||
$app->post('/{file}', $cbk)->assert('file', '.*');
|
||||
|
||||
$app['debug'] = true;
|
||||
$app['exception_handler']->disable();
|
||||
$app['session.test'] = true;
|
||||
|
||||
return $app;
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
$resp = new Symfony\Component\HttpFoundation\Response('Sorry, page not found', 404);
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
$resp = new Symfony\Component\HttpFoundation\Response('Sorry, a server error happened', 500);
|
32
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/advanced_form_post.php
vendored
Normal file
32
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/advanced_form_post.php
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
|
||||
<head>
|
||||
<title>Advanced form save</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
error_reporting(0);
|
||||
|
||||
$request = $app['request'];
|
||||
$POST = $request->request->all();
|
||||
$FILES = $request->files->all();
|
||||
|
||||
if (isset($POST['select_multiple_numbers']) && false !== strpos($POST['select_multiple_numbers'][0], ',')) {
|
||||
$POST['select_multiple_numbers'] = explode(',', $POST['select_multiple_numbers'][0]);
|
||||
}
|
||||
|
||||
// checkbox can have any value and will be successful in case "on"
|
||||
// http://www.w3.org/TR/html401/interact/forms.html#checkbox
|
||||
$POST['agreement'] = isset($POST['agreement']) ? 'on' : 'off';
|
||||
ksort($POST);
|
||||
echo str_replace('>', '', var_export($POST, true)) . "\n";
|
||||
if (isset($FILES['about']) && file_exists($FILES['about']->getPathname())) {
|
||||
echo $FILES['about']->getClientOriginalName() . "\n";
|
||||
echo file_get_contents($FILES['about']->getPathname());
|
||||
} else {
|
||||
echo "no file";
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
$SERVER = $app['request']->server->all();
|
||||
|
||||
$username = isset($SERVER['PHP_AUTH_USER']) ? $SERVER['PHP_AUTH_USER'] : false;
|
||||
$password = isset($SERVER['PHP_AUTH_PW']) ? $SERVER['PHP_AUTH_PW'] : false;
|
||||
|
||||
if ($username == 'mink-user' && $password == 'mink-password') {
|
||||
echo 'is authenticated';
|
||||
} else {
|
||||
$resp = new \Symfony\Component\HttpFoundation\Response();
|
||||
$resp->setStatusCode(401);
|
||||
$resp->headers->set('WWW-Authenticate', 'Basic realm="Mink Testing Area"');
|
||||
|
||||
echo 'is not authenticated';
|
||||
}
|
14
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/basic_form_post.php
vendored
Normal file
14
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/basic_form_post.php
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
|
||||
<head>
|
||||
<title>Basic Form Saving</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Anket for <?php echo $app['request']->request->get('first_name') ?></h1>
|
||||
|
||||
<span id="first">Firstname: <?php echo $app['request']->request->get('first_name') ?></span>
|
||||
<span id="last">Lastname: <?php echo $app['request']->request->get('last_name') ?></span>
|
||||
</body>
|
||||
</html>
|
23
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/basic_get_form.php
vendored
Normal file
23
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/basic_get_form.php
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
|
||||
<head>
|
||||
<title>Basic Get Form</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Basic Get Form Page</h1>
|
||||
|
||||
<div id="serach">
|
||||
<?php
|
||||
$GET = $app['request']->query->all();
|
||||
echo isset($GET['q']) && $GET['q'] ? $GET['q'] : 'No search query'
|
||||
?>
|
||||
</div>
|
||||
|
||||
<form>
|
||||
<input name="q" value="" type="text" />
|
||||
|
||||
<input type="submit" value="Find" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
17
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/cookie_page1.php
vendored
Normal file
17
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/cookie_page1.php
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
$resp = new Symfony\Component\HttpFoundation\Response();
|
||||
$cook = new Symfony\Component\HttpFoundation\Cookie('srvr_cookie', 'srv_var_is_set', 0, '/');
|
||||
$resp->headers->setCookie($cook);
|
||||
?>
|
||||
<!doctype html public "-//w3c//dtd xhtml 1.1//en" "http://www.w3.org/tr/xhtml11/dtd/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
|
||||
<head>
|
||||
<title>basic form</title>
|
||||
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
|
||||
<script>
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
basic page with cookie set from server side
|
||||
</body>
|
||||
</html>
|
14
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/cookie_page2.php
vendored
Normal file
14
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/cookie_page2.php
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
|
||||
<head>
|
||||
<title>Basic Form</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
<script>
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
Previous cookie: <?php
|
||||
echo $app['request']->cookies->has('srvr_cookie') ? $app['request']->cookies->get('srvr_cookie') : 'NO';
|
||||
?>
|
||||
</body>
|
||||
</html>
|
20
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/cookie_page3.php
vendored
Normal file
20
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/cookie_page3.php
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
$hasCookie = $app['request']->cookies->has('foo');
|
||||
$resp = new Symfony\Component\HttpFoundation\Response();
|
||||
$cook = new Symfony\Component\HttpFoundation\Cookie('foo', 'bar');
|
||||
$resp->headers->setCookie($cook);
|
||||
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
|
||||
<head>
|
||||
<title>HttpOnly Cookie Test</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
<script>
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="cookie-status">Has Cookie: <?php echo json_encode($hasCookie) ?></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
|
||||
<head>
|
||||
<title>Headers page</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<?php print_r($app['request']->server->all()); ?>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<?php
|
||||
if ('1' === $app['request']->query->get('p')) {
|
||||
echo '<a href="/issue130.php?p=2">Go to 2</a>';
|
||||
} else {
|
||||
echo '<strong>'.$app['request']->headers->get('referer').'</strong>';
|
||||
}
|
||||
?>
|
||||
</body>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<?php if ($app['request']->isMethod('POST')) {
|
||||
$resp = new Symfony\Component\HttpFoundation\Response();
|
||||
$cook = new Symfony\Component\HttpFoundation\Cookie('tc', $app['request']->request->get('cookie_value'));
|
||||
$resp->headers->setCookie($cook);
|
||||
} elseif ($app['request']->query->has('show_value')) {
|
||||
echo $app['request']->cookies->get('tc');
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<form method="post">
|
||||
<input name="cookie_value">
|
||||
<input type="submit" value="Set cookie">
|
||||
</form>
|
||||
</body>
|
25
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/print_cookies.php
vendored
Normal file
25
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/print_cookies.php
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
|
||||
<head>
|
||||
<title>Cookies page</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
$cookies = $app['request']->cookies->all();
|
||||
unset($cookies['MOCKSESSID']);
|
||||
|
||||
if (isset($cookies['srvr_cookie'])) {
|
||||
$srvrCookie = $cookies['srvr_cookie'];
|
||||
unset($cookies['srvr_cookie']);
|
||||
$cookies['_SESS'] = '';
|
||||
$cookies['srvr_cookie'] = $srvrCookie;
|
||||
}
|
||||
|
||||
foreach ($cookies as $name => $val) {
|
||||
$cookies[$name] = (string)$val;
|
||||
}
|
||||
echo str_replace(array('>'), '', var_export($cookies, true));
|
||||
?>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
$resp = new Symfony\Component\HttpFoundation\RedirectResponse('/redirect_destination.html');
|
15
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/response_headers.php
vendored
Normal file
15
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/response_headers.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
$resp = new Symfony\Component\HttpFoundation\Response();
|
||||
$resp->headers->set('X-Mink-Test', 'response-headers');
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Response headers</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Response headers</h1>
|
||||
</body>
|
||||
</html>
|
||||
|
19
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/session_test.php
vendored
Normal file
19
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/session_test.php
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
$session = $app['request']->getSession();
|
||||
|
||||
if ($app['request']->query->has('login')) {
|
||||
$session->migrate();
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
|
||||
<head>
|
||||
<title>Session Test</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
<script>
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="session-id"><?php echo $session->getId() ?></div>
|
||||
</body>
|
||||
</html>
|
18
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/sub-folder/cookie_page1.php
vendored
Normal file
18
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/sub-folder/cookie_page1.php
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
$requestUri = $app['request']->server->get('REQUEST_URI');
|
||||
$resp = new Symfony\Component\HttpFoundation\Response();
|
||||
$cook = new Symfony\Component\HttpFoundation\Cookie('srvr_cookie', 'srv_var_is_set_sub_folder', 0, dirname($requestUri));
|
||||
$resp->headers->setCookie($cook);
|
||||
?>
|
||||
<!doctype html public "-//w3c//dtd xhtml 1.1//en" "http://www.w3.org/tr/xhtml11/dtd/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
|
||||
<head>
|
||||
<title>basic form</title>
|
||||
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
|
||||
<script>
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
basic page with cookie set from server side
|
||||
</body>
|
||||
</html>
|
18
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/sub-folder/cookie_page2.php
vendored
Normal file
18
core/vendor/behat/mink-browserkit-driver/tests/web-fixtures/sub-folder/cookie_page2.php
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
|
||||
<head>
|
||||
<title>Basic Form</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
<script>
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
Previous cookie: <?php
|
||||
if ($app['request']->cookies->has('srvr_cookie')) {
|
||||
echo $app['request']->cookies->get('srvr_cookie');
|
||||
} else {
|
||||
echo 'NO';
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,4 @@
|
|||
vendor
|
||||
composer.phar
|
||||
composer.lock
|
||||
phpunit.xml
|
|
@ -0,0 +1,19 @@
|
|||
language: php
|
||||
|
||||
php: [5.3, 5.4, 5.5, 5.6, hhvm]
|
||||
|
||||
before_script:
|
||||
- export WEB_FIXTURES_HOST=http://localhost
|
||||
|
||||
- composer install --dev --prefer-source
|
||||
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install -y --force-yes apache2 libapache2-mod-php5
|
||||
- sudo sed -i -e "s,/var/www,$(pwd)/vendor/behat/mink/driver-testsuite/web-fixtures,g" /etc/apache2/sites-available/default
|
||||
- sudo /etc/init.d/apache2 restart
|
||||
|
||||
script: phpunit -v --coverage-clover=coverage.clover
|
||||
|
||||
after_script:
|
||||
- wget https://scrutinizer-ci.com/ocular.phar
|
||||
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover
|
|
@ -0,0 +1,20 @@
|
|||
1.1.0 / 2014-10-09
|
||||
==================
|
||||
|
||||
The driver now relies on BrowserKitDriver 1.2.x, so all changes of this driver are relevant.
|
||||
The changes below only describe the changes related to GoutteDriver specifically.
|
||||
|
||||
New features:
|
||||
|
||||
* Added the possibility to use a normal Goutte client instead of requiring to use an extended one
|
||||
* Added the support of Goutte 2.0 as well
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* Fixed the support of disabling basic auth
|
||||
* Fixed the resetting of the driver to reset the basic auth
|
||||
|
||||
Testing:
|
||||
|
||||
* Updated the testsuite to use the new Mink 1.6 driver testsuite
|
||||
* Added testing on HHVM
|
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2012-2013 Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
|
||||
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.
|
|
@ -0,0 +1,53 @@
|
|||
Mink Goutte Driver
|
||||
==================
|
||||
|
||||
[](https://packagist.org/packages/behat/mink-goutte-driver)
|
||||
[](https://packagist.org/packages/behat/mink-goutte-driver)
|
||||
[](https://packagist.org/packages/behat/mink-goutte-driver)
|
||||
[](https://travis-ci.org/Behat/MinkGoutteDriver)
|
||||
[](https://scrutinizer-ci.com/g/Behat/MinkGoutteDriver/)
|
||||
[](https://scrutinizer-ci.com/g/Behat/MinkGoutteDriver/)
|
||||
[](https://packagist.org/packages/behat/mink-goutte-driver)
|
||||
|
||||
Usage Example
|
||||
-------------
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Behat\Mink\Mink,
|
||||
Behat\Mink\Session,
|
||||
Behat\Mink\Driver\GoutteDriver,
|
||||
Behat\Mink\Driver\Goutte\Client as GoutteClient;
|
||||
|
||||
$startUrl = 'http://example.com';
|
||||
|
||||
$mink = new Mink(array(
|
||||
'goutte' => new Session(new GoutteDriver(new GoutteClient($startUrl))),
|
||||
));
|
||||
|
||||
$mink->getSession('goutte')->getPage()->findLink('Chat')->click();
|
||||
```
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
``` json
|
||||
{
|
||||
"require": {
|
||||
"behat/mink": "~1.5",
|
||||
"behat/mink-goutte-driver": "~1.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
``` bash
|
||||
$> curl -sS https://getcomposer.org/installer | php
|
||||
$> php composer.phar install
|
||||
```
|
||||
|
||||
Maintainers
|
||||
-----------
|
||||
|
||||
* Konstantin Kudryashov [everzet](http://github.com/everzet)
|
||||
* Other [awesome developers](https://github.com/Behat/MinkGoutteDriver/graphs/contributors)
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"name": "behat/mink-goutte-driver",
|
||||
"description": "Goutte driver for Mink framework",
|
||||
"keywords": ["goutte", "headless", "testing", "browser"],
|
||||
"homepage": "http://mink.behat.org/",
|
||||
"type": "mink-driver",
|
||||
"license": "MIT",
|
||||
|
||||
"authors": [
|
||||
{
|
||||
"name": "Konstantin Kudryashov",
|
||||
"email": "ever.zet@gmail.com",
|
||||
"homepage": "http://everzet.com"
|
||||
}
|
||||
],
|
||||
|
||||
"require": {
|
||||
"php": ">=5.3.1",
|
||||
"behat/mink": "~1.6@dev",
|
||||
"behat/mink-browserkit-driver": "~1.2@dev",
|
||||
"fabpot/goutte": "~1.0.4|~2.0"
|
||||
},
|
||||
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Behat\\Mink\\Driver": "src/"
|
||||
}
|
||||
},
|
||||
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Behat\\Mink\\Tests\\Driver\\": "tests"
|
||||
}
|
||||
},
|
||||
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit colors="true" bootstrap="vendor/behat/mink/driver-testsuite/bootstrap.php">
|
||||
<testsuites>
|
||||
<testsuite name="Driver test suite">
|
||||
<directory>tests</directory>
|
||||
<directory>vendor/behat/mink/driver-testsuite/tests/Basic</directory>
|
||||
<directory>vendor/behat/mink/driver-testsuite/tests/Form</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<php>
|
||||
<var name="driver_config_factory" value="Behat\Mink\Tests\Driver\GoutteConfig::getInstance" />
|
||||
|
||||
<!--server name="WEB_FIXTURES_HOST" value="http://test.mink.dev" /-->
|
||||
</php>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./src/Behat/Mink/Driver</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
43
core/vendor/behat/mink-goutte-driver/src/Behat/Mink/Driver/Goutte/Client.php
vendored
Normal file
43
core/vendor/behat/mink-goutte-driver/src/Behat/Mink/Driver/Goutte/Client.php
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat\Mink.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Mink\Driver\Goutte;
|
||||
|
||||
use Goutte\Client as BaseClient;
|
||||
use Symfony\Component\BrowserKit\Response;
|
||||
|
||||
/**
|
||||
* Client overrides to support Mink functionality.
|
||||
*/
|
||||
class Client extends BaseClient
|
||||
{
|
||||
/**
|
||||
* Reads response meta tags to guess content-type charset.
|
||||
*
|
||||
* @param Response $response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
protected function filterResponse($response)
|
||||
{
|
||||
$contentType = $response->getHeader('Content-Type');
|
||||
|
||||
if (!$contentType || false === strpos($contentType, 'charset=')) {
|
||||
if (preg_match('/\<meta[^\>]+charset *= *["\']?([a-zA-Z\-0-9]+)/i', $response->getContent(), $matches)) {
|
||||
$headers = $response->getHeaders();
|
||||
$headers['Content-Type'] = $contentType.';charset='.$matches[1];
|
||||
|
||||
$response = new Response($response->getContent(), $response->getStatus(), $headers);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::filterResponse($response);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat\Mink.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Mink\Driver;
|
||||
|
||||
use Behat\Mink\Driver\Goutte\Client as ExtendedClient;
|
||||
use Goutte\Client;
|
||||
|
||||
/**
|
||||
* Goutte driver.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class GoutteDriver extends BrowserKitDriver
|
||||
{
|
||||
/**
|
||||
* Initializes Goutte driver.
|
||||
*
|
||||
* @param Client $client Goutte client instance
|
||||
*/
|
||||
public function __construct(Client $client = null)
|
||||
{
|
||||
parent::__construct($client ?: new ExtendedClient());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setBasicAuth($user, $password)
|
||||
{
|
||||
if (false === $user) {
|
||||
$this->getClient()->resetAuth();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->getClient()->setAuth($user, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Goutte client.
|
||||
*
|
||||
* The method is overwritten only to provide the appropriate return type hint.
|
||||
*
|
||||
* @return Client
|
||||
*/
|
||||
public function getClient()
|
||||
{
|
||||
return parent::getClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
parent::reset();
|
||||
$this->getClient()->resetAuth();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareUrl($url)
|
||||
{
|
||||
return $url;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Custom;
|
||||
|
||||
use Behat\Mink\Driver\GoutteDriver;
|
||||
|
||||
class InstantiationTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testInstantiateWithClient()
|
||||
{
|
||||
$client = $this->getMockBuilder('Goutte\Client')->disableOriginalConstructor()->getMock();
|
||||
$client->expects($this->once())
|
||||
->method('followRedirects')
|
||||
->with(true);
|
||||
|
||||
$driver = new GoutteDriver($client);
|
||||
|
||||
$this->assertSame($client, $driver->getClient());
|
||||
}
|
||||
|
||||
public function testInstantiateWithoutClient()
|
||||
{
|
||||
$driver = new GoutteDriver();
|
||||
|
||||
$this->assertInstanceOf('Behat\Mink\Driver\Goutte\Client', $driver->getClient());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver;
|
||||
|
||||
use Behat\Mink\Driver\GoutteDriver;
|
||||
|
||||
class GoutteConfig extends AbstractConfig
|
||||
{
|
||||
public static function getInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createDriver()
|
||||
{
|
||||
return new GoutteDriver();
|
||||
}
|
||||
|
||||
protected function supportsJs()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
*.tgz
|
||||
*.phar
|
||||
phpunit.xml
|
||||
composer.lock
|
||||
vendor
|
|
@ -0,0 +1,17 @@
|
|||
language: php
|
||||
|
||||
sudo: false
|
||||
|
||||
php: [5.3, 5.4, 5.5, 5.6, hhvm]
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.composer/cache
|
||||
|
||||
install:
|
||||
- composer install
|
||||
|
||||
script: phpunit -v --coverage-clover=coverage.clover
|
||||
|
||||
after_script:
|
||||
- wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover coverage.clover
|
|
@ -0,0 +1,255 @@
|
|||
1.6.1 / 2015-02-04
|
||||
==================
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* Added a check for empty path in `WebAssert::cleanUrl()`
|
||||
|
||||
Driver testsuite:
|
||||
|
||||
* Added an extra test to ensure the right behavior for traversal
|
||||
|
||||
Misc:
|
||||
|
||||
* Changed the description in the composer.json
|
||||
* Switched the repository structure to use PSR-4
|
||||
* Updated URLs for the move to the new Github organization
|
||||
|
||||
1.6.0 / 2014-09-26
|
||||
==================
|
||||
|
||||
* [BC break] Changed the named selector to prefer exact matches over partial matches
|
||||
* [BC break] Changed `NodeElement::getValue` for checkboxes to return the value rather than the checked state (use `isChecked` for that)
|
||||
* Fixed the XPath prefixing when searching inside an existing element
|
||||
* Refactored the driver testsuite entirely and expand it to cover drivers entirely (covering many more cases for consistency)
|
||||
* Changed `NodeElement::setValue` to support any fields rather than only input elements
|
||||
* Removed the wrapping of any driver-level exception in a MinkException on invalid usage as it was making the code too complex
|
||||
* Fixed the matching of the input type in the named selector to be case insensitive according to the HTML spec
|
||||
* Introduced `Behat\Mink\Selector\Xpath\Escaper` to allow reusing the XPath escaping
|
||||
* Deprecated `Element::getSession`. Code needing the session should get it from outside rather than the element
|
||||
* Changed ElementNotFoundException to extend from ExpectationException
|
||||
* Added `Element::getOuterHtml` to get the HTML code of the element including itself
|
||||
* Fixed the name selectors to match on the `placeholder` only for textual inputs
|
||||
* Enforced consistent behavior for drivers on 4xx and 5xx response to return the response rather than throwing an exception
|
||||
* Added `Element::waitFor` to allow retrying some code until it succeeds or the timeout is reached
|
||||
* Added `Element::isValid` to check whether an element still exists in the page
|
||||
* Made `Session::executeScript` compatible across drivers by ensuring they all support the same syntaxes for the JS expression
|
||||
* Made `Session::evaluateScript` compatible across drivers by ensuring they all support the same syntaxes for the JS expression
|
||||
* Removed `hasClass` from `DocumentElement` (instead of triggering a fatal error)
|
||||
* Added testing on HHVM to ensure consistency
|
||||
* Fixed `NodeElement::getTagName` to ensure that the tag name is lowercase for all drivers
|
||||
* Fixed `Element::hasAttribute` to ensure it supports attributes with an empty value
|
||||
* Fixed the `field` selector to avoid matching inputs with the type `submit` or `reset`
|
||||
* Changed the button XPath selection to accept `reset` buttons as well
|
||||
* Changed `Session::wait` to return the condition value rather than nothing
|
||||
* Added `Session::getWindowName` and `Session::getWindowNames` to get the name of the current and of all windows
|
||||
* Added `Session::maximizeWindow` to maximize the window
|
||||
* Added `NodeElement::isSelected` to check whether an `<option>` is selected
|
||||
* Added `NodeElement::submitForm` to allow submitting a form without using a button
|
||||
* Added assertions about the value of an attribute
|
||||
* Added the anchor in the assertion on the URL in `WebAssert`
|
||||
|
||||
1.5.0 / 2013-04-14
|
||||
==================
|
||||
|
||||
* Add `CoreDriver` to simplify future drivers improvements
|
||||
* Add `Mink::isSessionStarted()` method
|
||||
* Fix multibite string `preg_replace` bugs
|
||||
* Fix handling of whitespaces in `WebAssert::pageText...()` methods
|
||||
|
||||
1.4.3 / 2013-03-02
|
||||
==================
|
||||
|
||||
* Bump dependencies constraints
|
||||
|
||||
1.4.2 / 2013-02-13
|
||||
==================
|
||||
|
||||
* Fix wrong test case to ensure that core drivers work as expected
|
||||
|
||||
1.4.1 / 2013-02-10
|
||||
==================
|
||||
|
||||
* Update dependencies
|
||||
* Add ElementException to element actions
|
||||
* Rel attribute support for named selectors
|
||||
* Add hasClass() helper to traversable elements
|
||||
* Add getScreenshot() method to session
|
||||
* Name attr support in named selector for button
|
||||
* Fix for bunch of bugs
|
||||
|
||||
1.4.0 / 2012-05-40
|
||||
==================
|
||||
|
||||
* New `Session::selectWindow()` and `Session::selectIFrame()` methods
|
||||
* New built-in `WebAssert` class
|
||||
* Fixed DocBlocks (autocompletion in any IDE now should just work)
|
||||
* Moved Behat-related code into `Behat\MinkExtension`
|
||||
* Removed PHPUnit test case class
|
||||
* Updated composer dependencies to not require custom repository anymore
|
||||
* All drivers moved into separate packages
|
||||
|
||||
1.3.3 / 2012-03-23
|
||||
==================
|
||||
|
||||
* Prevent exceptions in `__toString()`
|
||||
* Added couple of useful step definitions for Behat
|
||||
* Fixed issues #168, #211, #212, #208
|
||||
* Lot of small bug fixes and improvements
|
||||
* Fixed dependencies and composer installation routine
|
||||
|
||||
1.3.2 / 2011-12-21
|
||||
==================
|
||||
|
||||
* Fixed webdriver registration in MinkContext
|
||||
|
||||
1.3.1 / 2011-12-21
|
||||
==================
|
||||
|
||||
* Fixed Composer package
|
||||
|
||||
1.3.0 / 2011-12-21
|
||||
==================
|
||||
|
||||
* Brand new Selenium2Driver (webdriver session)
|
||||
* Multiselect bugfixes
|
||||
* ZombieDriver back in the business
|
||||
* Composer now manages dependencies
|
||||
* Some MinkContext steps got fixes
|
||||
* Lots of bug fixes and cleanup
|
||||
|
||||
1.2.0 / 2011-11-04
|
||||
==================
|
||||
|
||||
* Brand new SeleniumDriver (thanks @alexandresalome)
|
||||
* Multiselect support (multiple options selection), including new Behat steps
|
||||
* Ability to select option by it's text (in addition to value)
|
||||
* ZombieDriver updates
|
||||
* Use SuiteHooks to populate parameters (no need to call parent __construct anymore)
|
||||
* Updated Goutte and all vendors
|
||||
* Lot of bugfixes and new tests
|
||||
|
||||
1.1.1 / 2011-08-12
|
||||
==================
|
||||
|
||||
* Fixed Zombie.js server termination on Linux
|
||||
* Fixed base_url usage for external URLs
|
||||
|
||||
1.1.0 / 2011-08-08
|
||||
==================
|
||||
|
||||
* Added Zombie.js driver (thanks @b00giZm)
|
||||
* Added pt translation (thanks Daniel Gomes)
|
||||
* Refactored MinkContext and MinkTestCase
|
||||
|
||||
1.0.3 / 2011-08-02
|
||||
==================
|
||||
|
||||
* File uploads for empty fields fixed (GoutteDriver)
|
||||
* Lazy sessions restart
|
||||
* `show_tmp_dir` option in MinkContext
|
||||
* Updated to stable Symfony2 components
|
||||
* SahiClient connection limit bumped to 60 seconds
|
||||
* Dutch language support
|
||||
|
||||
1.0.2 / 2011-07-22
|
||||
==================
|
||||
|
||||
* ElementHtmlException fixed (thanks @Stof)
|
||||
|
||||
1.0.1 / 2011-07-21
|
||||
==================
|
||||
|
||||
* Fixed buggy assertions in MinkContext
|
||||
|
||||
1.0.0 / 2011-07-20
|
||||
==================
|
||||
|
||||
* Added missing tests for almost everything
|
||||
* Hude speedup for SahiDriver
|
||||
* Support for Behat 2.0 contexts
|
||||
* Bundled PHPUnit TestCase
|
||||
* Deep element traversing
|
||||
* Correct behavior of getText() method
|
||||
* New getHtml() method
|
||||
* Basic HTTP auth support
|
||||
* Soft and hard session resetting
|
||||
* Cookies management
|
||||
* Browser history interactions (reload(), back(), forward())
|
||||
* Weaverryan'd exception messages
|
||||
* Huge amount of bugfixes and small additions
|
||||
|
||||
0.3.2 / 2011-06-20
|
||||
==================
|
||||
|
||||
* Fixed file uploads in Goutte driver
|
||||
* Fixed setting of long texts into fields
|
||||
* Added getPlainText() (returns text without tags and whitespaces) method to the element's API
|
||||
* Start_url is now optional parameter
|
||||
* Default session (if needed) name now need to be always specified by hands with setDefaultSessionName()
|
||||
* default_driver => default_session
|
||||
* Updated Symfony Components
|
||||
|
||||
0.3.1 / 2011-05-17
|
||||
==================
|
||||
|
||||
* Small SahiClient update (it generates SID now if no provided)
|
||||
* setActiveSessionName => setDefaultSessionName method rename
|
||||
|
||||
0.3.0 / 2011-05-17
|
||||
==================
|
||||
|
||||
* Rewritten from scratch Mink drivers handler. Now it's sessions handler. And Mink now
|
||||
sessions-centric tool. See examples in readme. Much cleaner API now.
|
||||
|
||||
0.2.4 / 2011-05-12
|
||||
==================
|
||||
|
||||
* Fixed wrong url locator function
|
||||
* Fixed wrong regex in `should see` step
|
||||
* Fixed delimiters use in `should see` step
|
||||
* Added url-match step for checking urls against regex
|
||||
|
||||
0.2.3 / 2011-05-01
|
||||
==================
|
||||
|
||||
* Updated SahiClient with new version, which is faster and cleaner with it's exceptions
|
||||
|
||||
0.2.2 / 2011-05-01
|
||||
==================
|
||||
|
||||
* Ability to use already started browser as SahiDriver aim
|
||||
* Added japanese translation for bundled steps (thanks @hidenorigoto)
|
||||
* 10 seconds limit for browser connection in SahiDriver
|
||||
|
||||
0.2.1 / 2011-04-21
|
||||
==================
|
||||
|
||||
* Fixed some bundled step definitions
|
||||
|
||||
0.2.0 / 2011-04-21
|
||||
==================
|
||||
|
||||
* Additional step definitions
|
||||
* Support for extended drivers configuration through behat.yml environment parameters
|
||||
* Lots of new named selectors
|
||||
* Bug fixes
|
||||
* Small improvements
|
||||
|
||||
0.1.2 / 2011-04-08
|
||||
==================
|
||||
|
||||
* Fixed Sahi url escaping
|
||||
|
||||
0.1.1 / 2011-04-06
|
||||
==================
|
||||
|
||||
* Fixed should/should_not steps
|
||||
* Added spanish translation
|
||||
* Fixed forms to use <base> element
|
||||
* Fixed small UnsupportedByDriverException issue
|
||||
|
||||
0.1.0 / 2011-04-04
|
||||
==================
|
||||
|
||||
* Initial release
|
|
@ -0,0 +1,22 @@
|
|||
# Contributing
|
||||
Mink is an open source, community-driven project. If you'd like to contribute, feel free to do this, but remember to follow these few simple rules:
|
||||
|
||||
## Submitting an issues
|
||||
- __Driver-related__ issues must be reported in the corresponding driver repository
|
||||
- A reproducible example is required for every bug report, otherwise it will most probably be __closed without warning__
|
||||
- If you are going to make a big, substantial change, let's discuss it first
|
||||
|
||||
## Working with Pull Requests
|
||||
1. Create your feature addition or a bug fix branch based on `master` branch in your repository's fork.
|
||||
2. Make necessary changes, but __don't mix__ code reformatting with code changes on topic.
|
||||
3. Add tests for those changes (please look into `tests/` folder for some examples). This is important so we don't break it in a future version unintentionally.
|
||||
4. Commit your code, but do not mess with `CHANGES.md`.
|
||||
5. Squash your commits by topic to preserve a clean and readable log.
|
||||
6. Create Pull Request.
|
||||
|
||||
# Running tests
|
||||
Make sure that you don't break anything with your changes by running:
|
||||
|
||||
```bash
|
||||
$> phpunit
|
||||
```
|
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2011-2013 Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
|
||||
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.
|
|
@ -0,0 +1,74 @@
|
|||
Mink
|
||||
====
|
||||
[](https://packagist.org/packages/behat/mink)
|
||||
[](https://packagist.org/packages/behat/mink)
|
||||
[](https://packagist.org/packages/behat/mink)
|
||||
[](https://scrutinizer-ci.com/g/minkphp/Mink/?branch=master)
|
||||
[](https://scrutinizer-ci.com/g/minkphp/Mink/)
|
||||
[](https://travis-ci.org/minkphp/Mink)
|
||||
[](https://insight.sensiolabs.com/projects/5bb8fab0-978f-428a-ae23-44ee4e129fbc)
|
||||
[](https://packagist.org/packages/behat/mink)
|
||||
|
||||
|
||||
Useful Links
|
||||
------------
|
||||
|
||||
- The main website with documentation is at [http://mink.behat.org](http://mink.behat.org)
|
||||
- Official Google Group is at [http://groups.google.com/group/behat](http://groups.google.com/group/behat)
|
||||
- IRC channel on [#freenode](http://freenode.net/) is `#behat`
|
||||
- [Note on Patches/Pull Requests](CONTRIBUTING.md)
|
||||
|
||||
Usage Example
|
||||
-------------
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Behat\Mink\Mink,
|
||||
Behat\Mink\Session,
|
||||
Behat\Mink\Driver\GoutteDriver,
|
||||
Behat\Mink\Driver\Goutte\Client as GoutteClient;
|
||||
|
||||
$startUrl = 'http://example.com';
|
||||
|
||||
// init Mink and register sessions
|
||||
$mink = new Mink(array(
|
||||
'goutte1' => new Session(new GoutteDriver(new GoutteClient())),
|
||||
'goutte2' => new Session(new GoutteDriver(new GoutteClient())),
|
||||
'custom' => new Session(new MyCustomDriver($startUrl))
|
||||
));
|
||||
|
||||
// set the default session name
|
||||
$mink->setDefaultSessionName('goutte2');
|
||||
|
||||
// visit a page
|
||||
$mink->getSession()->visit($startUrl);
|
||||
|
||||
// call to getSession() without argument will always return a default session if has one (goutte2 here)
|
||||
$mink->getSession()->getPage()->findLink('Downloads')->click();
|
||||
echo $mink->getSession()->getPage()->getContent();
|
||||
|
||||
// call to getSession() with argument will return session by its name
|
||||
$mink->getSession('custom')->getPage()->findLink('Downloads')->click();
|
||||
echo $mink->getSession('custom')->getPage()->getContent();
|
||||
|
||||
// this all is done to make possible mixing sessions
|
||||
$mink->getSession('goutte1')->getPage()->findLink('Chat')->click();
|
||||
$mink->getSession('goutte2')->getPage()->findLink('Chat')->click();
|
||||
```
|
||||
|
||||
Install Dependencies
|
||||
--------------------
|
||||
|
||||
``` bash
|
||||
$> curl -sS https://getcomposer.org/installer | php
|
||||
$> php composer.phar install
|
||||
```
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Konstantin Kudryashov [everzet](https://github.com/everzet) [lead developer]
|
||||
* Christophe Coevoet [stof](https://github.com/stof) [lead developer]
|
||||
* Alexander Obuhovich [aik099](https://github.com/aik099) [lead developer]
|
||||
* Other [awesome developers](https://github.com/minkphp/Mink/graphs/contributors)
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"name": "behat/mink",
|
||||
"description": "Browser controller/emulator abstraction for PHP",
|
||||
"keywords": ["web", "testing", "browser"],
|
||||
"homepage": "http://mink.behat.org/",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
|
||||
"authors": [
|
||||
{
|
||||
"name": "Konstantin Kudryashov",
|
||||
"email": "ever.zet@gmail.com",
|
||||
"homepage": "http://everzet.com"
|
||||
}
|
||||
],
|
||||
|
||||
"require": {
|
||||
"php": ">=5.3.1",
|
||||
"symfony/css-selector": "~2.0"
|
||||
},
|
||||
|
||||
"suggest": {
|
||||
"behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)",
|
||||
"behat/mink-goutte-driver": "fast headless driver for any app without JS emulation",
|
||||
"behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)",
|
||||
"behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)"
|
||||
},
|
||||
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Behat\\Mink\\": "src/"
|
||||
}
|
||||
},
|
||||
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Behat\\Mink\\Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.6.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
Mink Driver testsuite
|
||||
=====================
|
||||
|
||||
This is the common testsuite for Mink drivers to ensure consistency among implementations.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
The testsuite of a driver should be based as follow:
|
||||
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
"behat/mink": "~1.6@dev"
|
||||
},
|
||||
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Acme\\MyDriver\\Tests\\": "tests"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```xml
|
||||
<!-- phpunit.xml.dist -->
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit colors="true" bootstrap="vendor/behat/mink/driver-testsuite/bootstrap.php">
|
||||
<php>
|
||||
<var name="driver_config_factory" value="Acme\MyDriver\Tests\Config::getInstance" />
|
||||
|
||||
<server name="WEB_FIXTURES_HOST" value="http://test.mink.dev" />
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Functional tests">
|
||||
<directory>vendor/behat/mink/driver-testsuite/tests</directory>
|
||||
</testsuite>
|
||||
<!-- if needed to add more tests -->
|
||||
<testsuite name="Driver tests">
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
```
|
||||
|
||||
Then create the driver config for the testsuite:
|
||||
|
||||
```php
|
||||
// tests/Config.php
|
||||
|
||||
namespace Acme\MyDriver\Tests;
|
||||
|
||||
use Behat\Mink\Tests\Driver\AbstractConfig;
|
||||
|
||||
class Config extends AbstractConfig
|
||||
{
|
||||
/**
|
||||
* Creates an instance of the config.
|
||||
*
|
||||
* This is the callable registered as a php variable in the phpunit.xml config file.
|
||||
* It could be outside the class but this is convenient.
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates driver instance.
|
||||
*
|
||||
* @return \Behat\Mink\Driver\DriverInterface
|
||||
*/
|
||||
public function createDriver()
|
||||
{
|
||||
return new \Acme\MyDriver\MyDriver();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Some other methods are available in the AbstractConfig which can be overwritten to adapt the testsuite to
|
||||
the needs of the driver (skipping some tests for instance).
|
||||
|
||||
Adding Driver-specific Tests
|
||||
----------------------------
|
||||
|
||||
When adding extra test cases specific to the driver, either use your own namespace or put them in the
|
||||
``Behat\Mink\Tests\Driver\Custom`` subnamespace to ensure that you will not create conflicts with test cases
|
||||
added in the driver testsuite in the future.
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
$file = __DIR__.'/../../../autoload.php';
|
||||
|
||||
if (!file_exists($file)) {
|
||||
echo PHP_EOL.'The Mink driver testsuite expects Mink to be installed as a composer dependency of your project'.PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/** @var \Composer\Autoload\ClassLoader $loader */
|
||||
$loader = require $file;
|
||||
|
||||
$loader->addPsr4('Behat\Mink\Tests\Driver\\', __DIR__.'/tests');
|
||||
|
||||
// Clean the global variables
|
||||
unset($file);
|
||||
unset($loader);
|
||||
|
||||
// Check the definition of the driverLoaderFactory
|
||||
|
||||
if (!isset($GLOBALS['driver_config_factory'])) {
|
||||
echo PHP_EOL.'The "driver_config_factory" global variable must be set.'.PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
if (!is_callable($GLOBALS['driver_config_factory'])) {
|
||||
echo PHP_EOL.'The "driver_config_factory" global variable must be a callable.'.PHP_EOL;
|
||||
exit(1);
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver;
|
||||
|
||||
use Behat\Mink\Driver\DriverInterface;
|
||||
|
||||
abstract class AbstractConfig
|
||||
{
|
||||
/**
|
||||
* Creates driver instance.
|
||||
*
|
||||
* @return DriverInterface
|
||||
*/
|
||||
abstract public function createDriver();
|
||||
|
||||
/**
|
||||
* Map remote file path.
|
||||
*
|
||||
* @param string $file File path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function mapRemoteFilePath($file)
|
||||
{
|
||||
if (!isset($_SERVER['TEST_MACHINE_BASE_PATH']) || !isset($_SERVER['DRIVER_MACHINE_BASE_PATH'])) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
$pattern = '/^'.preg_quote($_SERVER['TEST_MACHINE_BASE_PATH'], '/').'/';
|
||||
$basePath = $_SERVER['DRIVER_MACHINE_BASE_PATH'];
|
||||
|
||||
return preg_replace($pattern, $basePath, $file, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base url to the fixture folder
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getWebFixturesUrl()
|
||||
{
|
||||
return $_SERVER['WEB_FIXTURES_HOST'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $testCase The name of the TestCase class
|
||||
* @param string $test The name of the test method
|
||||
*
|
||||
* @return string|null A message explaining why the test should be skipped, or null to run the test.
|
||||
*/
|
||||
public function skipMessage($testCase, $test)
|
||||
{
|
||||
if (!$this->supportsCss() && 0 === strpos($testCase, 'Behat\Mink\Tests\Driver\Css\\')) {
|
||||
return 'This driver does not support CSS.';
|
||||
}
|
||||
|
||||
if (!$this->supportsJs() && 0 === strpos($testCase, 'Behat\Mink\Tests\Driver\Js\\')) {
|
||||
return 'This driver does not support JavaScript.';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the JS tests should run or no.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function supportsJs()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the CSS tests should run or no.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function supportsCss()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Basic;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class BasicAuthTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider setBasicAuthDataProvider
|
||||
*/
|
||||
public function testSetBasicAuth($user, $pass, $pageText)
|
||||
{
|
||||
$session = $this->getSession();
|
||||
|
||||
$session->setBasicAuth($user, $pass);
|
||||
|
||||
$session->visit($this->pathTo('/basic_auth.php'));
|
||||
|
||||
$this->assertContains($pageText, $session->getPage()->getContent());
|
||||
}
|
||||
|
||||
public function setBasicAuthDataProvider()
|
||||
{
|
||||
return array(
|
||||
array('mink-user', 'mink-password', 'is authenticated'),
|
||||
array('', '', 'is not authenticated'),
|
||||
);
|
||||
}
|
||||
|
||||
public function testResetBasicAuth()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
|
||||
$session->setBasicAuth('mink-user', 'mink-password');
|
||||
|
||||
$session->visit($this->pathTo('/basic_auth.php'));
|
||||
|
||||
$this->assertContains('is authenticated', $session->getPage()->getContent());
|
||||
|
||||
$session->setBasicAuth(false);
|
||||
|
||||
$session->visit($this->pathTo('/headers.php'));
|
||||
|
||||
$this->assertNotContains('PHP_AUTH_USER', $session->getPage()->getContent());
|
||||
}
|
||||
|
||||
public function testResetWithBasicAuth()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
|
||||
$session->setBasicAuth('mink-user', 'mink-password');
|
||||
|
||||
$session->visit($this->pathTo('/basic_auth.php'));
|
||||
|
||||
$this->assertContains('is authenticated', $session->getPage()->getContent());
|
||||
|
||||
$session->reset();
|
||||
|
||||
$session->visit($this->pathTo('/headers.php'));
|
||||
|
||||
$this->assertNotContains('PHP_AUTH_USER', $session->getPage()->getContent());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Basic;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class ContentTest extends TestCase
|
||||
{
|
||||
public function testOuterHtml()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$element = $this->getAssertSession()->elementExists('css', '.travers');
|
||||
|
||||
$this->assertEquals(
|
||||
"<div class=\"travers\">\n <div class=\"sub\">el1</div>\n".
|
||||
" <div class=\"sub\">el2</div>\n <div class=\"sub\">\n".
|
||||
" <a href=\"some_url\">some <strong>deep</strong> url</a>\n".
|
||||
" </div>\n </div>",
|
||||
$element->getOuterHtml()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAttributeDataProvider
|
||||
*/
|
||||
public function testGetAttribute($attributeName, $attributeValue)
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$element = $this->getSession()->getPage()->findById('attr-elem['.$attributeName.']');
|
||||
|
||||
$this->assertNotNull($element);
|
||||
$this->assertSame($attributeValue, $element->getAttribute($attributeName));
|
||||
}
|
||||
|
||||
public function getAttributeDataProvider()
|
||||
{
|
||||
return array(
|
||||
array('with-value', 'some-value'),
|
||||
array('without-value', ''),
|
||||
array('with-empty-value', ''),
|
||||
array('with-missing', null),
|
||||
);
|
||||
}
|
||||
|
||||
public function testJson()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/json.php'));
|
||||
$this->assertContains(
|
||||
'{"key1":"val1","key2":234,"key3":[1,2,3]}',
|
||||
$this->getSession()->getPage()->getContent()
|
||||
);
|
||||
}
|
||||
|
||||
public function testHtmlDecodingNotPerformed()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
$webAssert = $this->getAssertSession();
|
||||
$session->visit($this->pathTo('/html_decoding.html'));
|
||||
$page = $session->getPage();
|
||||
|
||||
$span = $webAssert->elementExists('css', 'span');
|
||||
$input = $webAssert->elementExists('css', 'input');
|
||||
|
||||
$expectedHtml = '<span custom-attr="&">some text</span>';
|
||||
$this->assertContains($expectedHtml, $page->getHtml(), '.innerHTML is returned as-is');
|
||||
$this->assertContains($expectedHtml, $page->getContent(), '.outerHTML is returned as-is');
|
||||
|
||||
$this->assertEquals('&', $span->getAttribute('custom-attr'), '.getAttribute value is decoded');
|
||||
$this->assertEquals('&', $input->getAttribute('value'), '.getAttribute value is decoded');
|
||||
$this->assertEquals('&', $input->getValue(), 'node value is decoded');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Basic;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class CookieTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* test cookie decoding
|
||||
* @group issue140
|
||||
*/
|
||||
public function testIssue140()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/issue140.php'));
|
||||
|
||||
$this->getSession()->getPage()->fillField('cookie_value', 'some:value;');
|
||||
$this->getSession()->getPage()->pressButton('Set cookie');
|
||||
|
||||
$this->getSession()->visit($this->pathTo('/issue140.php?show_value'));
|
||||
$this->assertEquals('some:value;', $this->getSession()->getCookie('tc'));
|
||||
$this->assertEquals('some:value;', $this->getSession()->getPage()->getText());
|
||||
}
|
||||
|
||||
public function testCookie()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/cookie_page2.php'));
|
||||
$this->assertContains('Previous cookie: NO', $this->getSession()->getPage()->getText());
|
||||
$this->assertNull($this->getSession()->getCookie('srvr_cookie'));
|
||||
|
||||
$this->getSession()->setCookie('srvr_cookie', 'client cookie set');
|
||||
$this->getSession()->reload();
|
||||
$this->assertContains('Previous cookie: client cookie set', $this->getSession()->getPage()->getText());
|
||||
$this->assertEquals('client cookie set', $this->getSession()->getCookie('srvr_cookie'));
|
||||
|
||||
$this->getSession()->setCookie('srvr_cookie', null);
|
||||
$this->getSession()->reload();
|
||||
$this->assertContains('Previous cookie: NO', $this->getSession()->getPage()->getText());
|
||||
|
||||
$this->getSession()->visit($this->pathTo('/cookie_page1.php'));
|
||||
$this->getSession()->visit($this->pathTo('/cookie_page2.php'));
|
||||
|
||||
$this->assertContains('Previous cookie: srv_var_is_set', $this->getSession()->getPage()->getText());
|
||||
$this->getSession()->setCookie('srvr_cookie', null);
|
||||
$this->getSession()->reload();
|
||||
$this->assertContains('Previous cookie: NO', $this->getSession()->getPage()->getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider cookieWithPathsDataProvider
|
||||
*/
|
||||
public function testCookieWithPaths($cookieRemovalMode)
|
||||
{
|
||||
// start clean
|
||||
$session = $this->getSession();
|
||||
$session->visit($this->pathTo('/sub-folder/cookie_page2.php'));
|
||||
$this->assertContains('Previous cookie: NO', $session->getPage()->getText());
|
||||
|
||||
// cookie from root path is accessible in sub-folder
|
||||
$session->visit($this->pathTo('/cookie_page1.php'));
|
||||
$session->visit($this->pathTo('/sub-folder/cookie_page2.php'));
|
||||
$this->assertContains('Previous cookie: srv_var_is_set', $session->getPage()->getText());
|
||||
|
||||
// cookie from sub-folder overrides cookie from root path
|
||||
$session->visit($this->pathTo('/sub-folder/cookie_page1.php'));
|
||||
$session->visit($this->pathTo('/sub-folder/cookie_page2.php'));
|
||||
$this->assertContains('Previous cookie: srv_var_is_set_sub_folder', $session->getPage()->getText());
|
||||
|
||||
if ($cookieRemovalMode == 'session_reset') {
|
||||
$session->reset();
|
||||
} elseif ($cookieRemovalMode == 'cookie_delete') {
|
||||
$session->setCookie('srvr_cookie', null);
|
||||
}
|
||||
|
||||
// cookie is removed from all paths
|
||||
$session->visit($this->pathTo('/sub-folder/cookie_page2.php'));
|
||||
$this->assertContains('Previous cookie: NO', $session->getPage()->getText());
|
||||
}
|
||||
|
||||
public function cookieWithPathsDataProvider()
|
||||
{
|
||||
return array(
|
||||
array('session_reset'),
|
||||
array('cookie_delete'),
|
||||
);
|
||||
}
|
||||
|
||||
public function testReset()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/cookie_page1.php'));
|
||||
$this->getSession()->visit($this->pathTo('/cookie_page2.php'));
|
||||
$this->assertContains('Previous cookie: srv_var_is_set', $this->getSession()->getPage()->getText());
|
||||
|
||||
$this->getSession()->reset();
|
||||
$this->getSession()->visit($this->pathTo('/cookie_page2.php'));
|
||||
|
||||
$this->assertContains('Previous cookie: NO', $this->getSession()->getPage()->getText());
|
||||
|
||||
$this->getSession()->setCookie('srvr_cookie', 'test_cookie');
|
||||
$this->getSession()->visit($this->pathTo('/cookie_page2.php'));
|
||||
$this->assertContains('Previous cookie: test_cookie', $this->getSession()->getPage()->getText());
|
||||
$this->getSession()->reset();
|
||||
$this->getSession()->visit($this->pathTo('/cookie_page2.php'));
|
||||
$this->assertContains('Previous cookie: NO', $this->getSession()->getPage()->getText());
|
||||
|
||||
$this->getSession()->setCookie('client_cookie1', 'some_val');
|
||||
$this->getSession()->setCookie('client_cookie2', 123);
|
||||
$this->getSession()->visit($this->pathTo('/session_test.php'));
|
||||
$this->getSession()->visit($this->pathTo('/cookie_page1.php'));
|
||||
|
||||
$this->getSession()->visit($this->pathTo('/print_cookies.php'));
|
||||
$this->assertContains(
|
||||
"'client_cookie1' = 'some_val'",
|
||||
$this->getSession()->getPage()->getText()
|
||||
);
|
||||
$this->assertContains(
|
||||
"'client_cookie2' = '123'",
|
||||
$this->getSession()->getPage()->getText()
|
||||
);
|
||||
$this->assertContains(
|
||||
"_SESS' = ",
|
||||
$this->getSession()->getPage()->getText()
|
||||
);
|
||||
$this->assertContains(
|
||||
" 'srvr_cookie' = 'srv_var_is_set'",
|
||||
$this->getSession()->getPage()->getText()
|
||||
);
|
||||
|
||||
$this->getSession()->reset();
|
||||
$this->getSession()->visit($this->pathTo('/print_cookies.php'));
|
||||
$this->assertContains('array ( )', $this->getSession()->getPage()->getText());
|
||||
}
|
||||
|
||||
public function testHttpOnlyCookieIsDeleted()
|
||||
{
|
||||
$this->getSession()->restart();
|
||||
$this->getSession()->visit($this->pathTo('/cookie_page3.php'));
|
||||
$this->assertEquals('Has Cookie: false', $this->findById('cookie-status')->getText());
|
||||
|
||||
$this->getSession()->reload();
|
||||
$this->assertEquals('Has Cookie: true', $this->findById('cookie-status')->getText());
|
||||
|
||||
$this->getSession()->restart();
|
||||
$this->getSession()->visit($this->pathTo('/cookie_page3.php'));
|
||||
$this->assertEquals('Has Cookie: false', $this->findById('cookie-status')->getText());
|
||||
}
|
||||
|
||||
public function testSessionPersistsBetweenRequests()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/session_test.php'));
|
||||
$webAssert = $this->getAssertSession();
|
||||
$node = $webAssert->elementExists('css', '#session-id');
|
||||
$sessionId = $node->getText();
|
||||
|
||||
$this->getSession()->visit($this->pathTo('/session_test.php'));
|
||||
$node = $webAssert->elementExists('css', '#session-id');
|
||||
$this->assertEquals($sessionId, $node->getText());
|
||||
|
||||
$this->getSession()->visit($this->pathTo('/session_test.php?login'));
|
||||
$node = $webAssert->elementExists('css', '#session-id');
|
||||
$this->assertNotEquals($sessionId, $newSessionId = $node->getText());
|
||||
|
||||
$this->getSession()->visit($this->pathTo('/session_test.php'));
|
||||
$node = $webAssert->elementExists('css', '#session-id');
|
||||
$this->assertEquals($newSessionId, $node->getText());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,262 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Basic;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class ErrorHandlingTest extends TestCase
|
||||
{
|
||||
const NOT_FOUND_XPATH = '//html/./invalid';
|
||||
|
||||
const NOT_FOUND_EXCEPTION = 'Exception';
|
||||
|
||||
const INVALID_EXCEPTION = 'Exception';
|
||||
|
||||
public function testVisitErrorPage()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/500.php'));
|
||||
|
||||
$this->assertContains(
|
||||
'Sorry, a server error happened',
|
||||
$this->getSession()->getPage()->getContent(),
|
||||
'Drivers allow loading pages with a 500 status code'
|
||||
);
|
||||
}
|
||||
|
||||
public function testCheckInvalidElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
$element = $this->findById('user-name');
|
||||
|
||||
$this->setExpectedException(self::INVALID_EXCEPTION);
|
||||
$this->getSession()->getDriver()->check($element->getXpath());
|
||||
}
|
||||
|
||||
public function testCheckNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->check(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testUncheckInvalidElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
$element = $this->findById('user-name');
|
||||
|
||||
$this->setExpectedException(self::INVALID_EXCEPTION);
|
||||
$this->getSession()->getDriver()->uncheck($element->getXpath());
|
||||
}
|
||||
|
||||
public function testUncheckNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->uncheck(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testSelectOptionInvalidElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
$element = $this->findById('user-name');
|
||||
|
||||
$this->setExpectedException(self::INVALID_EXCEPTION);
|
||||
$this->getSession()->getDriver()->selectOption($element->getXpath(), 'test');
|
||||
}
|
||||
|
||||
public function testSelectOptionNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->selectOption(self::NOT_FOUND_XPATH, 'test');
|
||||
}
|
||||
|
||||
public function testAttachFileInvalidElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
$element = $this->findById('user-name');
|
||||
|
||||
$this->setExpectedException(self::INVALID_EXCEPTION);
|
||||
$this->getSession()->getDriver()->attachFile($element->getXpath(), __FILE__);
|
||||
}
|
||||
|
||||
public function testAttachFileNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->attachFile(self::NOT_FOUND_XPATH, __FILE__);
|
||||
}
|
||||
|
||||
public function testSubmitFormInvalidElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
$element = $this->findById('core');
|
||||
|
||||
$this->setExpectedException(self::INVALID_EXCEPTION);
|
||||
$this->getSession()->getDriver()->submitForm($element->getXpath());
|
||||
}
|
||||
|
||||
public function testSubmitFormNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->submitForm(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testGetTagNameNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->getTagName(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testGetTextNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->getText(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testGetHtmlNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->getHtml(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testGetOuterHtmlNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->getOuterHtml(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testGetValueNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->getValue(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testSetValueNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->setValue(self::NOT_FOUND_XPATH, 'test');
|
||||
}
|
||||
|
||||
public function testIsSelectedNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->isSelected(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testIsCheckedNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->isChecked(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testIsVisibleNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->isVisible(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testClickNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->click(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testDoubleClickNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->doubleClick(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testRightClickNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->rightClick(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testGetAttributeNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->getAttribute(self::NOT_FOUND_XPATH, 'id');
|
||||
}
|
||||
|
||||
public function testMouseOverNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->mouseOver(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testFocusNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->focus(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testBlurNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->blur(self::NOT_FOUND_XPATH);
|
||||
}
|
||||
|
||||
public function testKeyPressNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->keyPress(self::NOT_FOUND_XPATH, 'a');
|
||||
}
|
||||
|
||||
public function testKeyDownNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->keyDown(self::NOT_FOUND_XPATH, 'a');
|
||||
}
|
||||
|
||||
public function testKeyUpNotFoundElement()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->setExpectedException(self::NOT_FOUND_EXCEPTION);
|
||||
$this->getSession()->getDriver()->keyUp(self::NOT_FOUND_XPATH, 'a');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Basic;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class HeaderTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* test referrer
|
||||
* @group issue130
|
||||
*/
|
||||
public function testIssue130()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/issue130.php?p=1'));
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$page->clickLink('Go to 2');
|
||||
$this->assertEquals($this->pathTo('/issue130.php?p=1'), $page->getText());
|
||||
}
|
||||
|
||||
public function testHeaders()
|
||||
{
|
||||
$this->getSession()->setRequestHeader('Accept-Language', 'fr');
|
||||
$this->getSession()->visit($this->pathTo('/headers.php'));
|
||||
|
||||
$this->assertContains('[HTTP_ACCEPT_LANGUAGE] => fr', $this->getSession()->getPage()->getContent());
|
||||
}
|
||||
|
||||
public function testSetUserAgent()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
|
||||
$session->setRequestHeader('user-agent', 'foo bar');
|
||||
$session->visit($this->pathTo('/headers.php'));
|
||||
$this->assertContains('[HTTP_USER_AGENT] => foo bar', $session->getPage()->getContent());
|
||||
}
|
||||
|
||||
public function testResetHeaders()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
|
||||
$session->setRequestHeader('X-Mink-Test', 'test');
|
||||
$session->visit($this->pathTo('/headers.php'));
|
||||
|
||||
$this->assertContains(
|
||||
'[HTTP_X_MINK_TEST] => test',
|
||||
$session->getPage()->getContent(),
|
||||
'The custom header should be sent',
|
||||
true
|
||||
);
|
||||
|
||||
$session->reset();
|
||||
$session->visit($this->pathTo('/headers.php'));
|
||||
|
||||
$this->assertNotContains(
|
||||
'[HTTP_X_MINK_TEST] => test',
|
||||
$session->getPage()->getContent(),
|
||||
'The custom header should not be sent after resetting',
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
public function testResponseHeaders()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/response_headers.php'));
|
||||
|
||||
$headers = $this->getSession()->getResponseHeaders();
|
||||
|
||||
$lowercasedHeaders = array();
|
||||
foreach ($headers as $name => $value) {
|
||||
$lowercasedHeaders[str_replace('_', '-', strtolower($name))] = $value;
|
||||
}
|
||||
|
||||
$this->assertArrayHasKey('x-mink-test', $lowercasedHeaders);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Basic;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class IFrameTest extends TestCase
|
||||
{
|
||||
public function testIFrame()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/iframe.html'));
|
||||
$webAssert = $this->getAssertSession();
|
||||
|
||||
$el = $webAssert->elementExists('css', '#text');
|
||||
$this->assertSame('Main window div text', $el->getText());
|
||||
|
||||
$this->getSession()->switchToIFrame('subframe');
|
||||
|
||||
$el = $webAssert->elementExists('css', '#text');
|
||||
$this->assertSame('iFrame div text', $el->getText());
|
||||
|
||||
$this->getSession()->switchToIFrame();
|
||||
|
||||
$el = $webAssert->elementExists('css', '#text');
|
||||
$this->assertSame('Main window div text', $el->getText());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Basic;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class NavigationTest extends TestCase
|
||||
{
|
||||
public function testRedirect()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/redirector.php'));
|
||||
$this->assertEquals($this->pathTo('/redirect_destination.html'), $this->getSession()->getCurrentUrl());
|
||||
}
|
||||
|
||||
public function testPageControlls()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/randomizer.php'));
|
||||
$number1 = $this->getSession()->getPage()->find('css', '#number')->getText();
|
||||
|
||||
$this->getSession()->reload();
|
||||
$number2 = $this->getSession()->getPage()->find('css', '#number')->getText();
|
||||
|
||||
$this->assertNotEquals($number1, $number2);
|
||||
|
||||
$this->getSession()->visit($this->pathTo('/links.html'));
|
||||
$this->getSession()->getPage()->clickLink('Random number page');
|
||||
|
||||
$this->assertEquals($this->pathTo('/randomizer.php'), $this->getSession()->getCurrentUrl());
|
||||
|
||||
$this->getSession()->back();
|
||||
$this->assertEquals($this->pathTo('/links.html'), $this->getSession()->getCurrentUrl());
|
||||
|
||||
$this->getSession()->forward();
|
||||
$this->assertEquals($this->pathTo('/randomizer.php'), $this->getSession()->getCurrentUrl());
|
||||
}
|
||||
|
||||
public function testLinks()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/links.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
$link = $page->findLink('Redirect me to');
|
||||
|
||||
$this->assertNotNull($link);
|
||||
$this->assertRegExp('/redirector\.php$/', $link->getAttribute('href'));
|
||||
$link->click();
|
||||
|
||||
$this->assertEquals($this->pathTo('/redirect_destination.html'), $this->getSession()->getCurrentUrl());
|
||||
|
||||
$this->getSession()->visit($this->pathTo('/links.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
$link = $page->findLink('basic form image');
|
||||
|
||||
$this->assertNotNull($link);
|
||||
$this->assertRegExp('/basic_form\.html$/', $link->getAttribute('href'));
|
||||
$link->click();
|
||||
|
||||
$this->assertEquals($this->pathTo('/basic_form.html'), $this->getSession()->getCurrentUrl());
|
||||
|
||||
$this->getSession()->visit($this->pathTo('/links.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
$link = $page->findLink("Link with a ");
|
||||
|
||||
$this->assertNotNull($link);
|
||||
$this->assertRegExp('/links\.html\?quoted$/', $link->getAttribute('href'));
|
||||
$link->click();
|
||||
|
||||
$this->assertEquals($this->pathTo('/links.html?quoted'), $this->getSession()->getCurrentUrl());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Basic;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class ScreenshotTest extends TestCase
|
||||
{
|
||||
public function testScreenshot()
|
||||
{
|
||||
if (!extension_loaded('gd')) {
|
||||
$this->markTestSkipped('Testing screenshots requires the GD extension');
|
||||
}
|
||||
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$screenShot = $this->getSession()->getScreenshot();
|
||||
|
||||
$this->assertInternalType('string', $screenShot);
|
||||
$this->assertFalse(base64_decode($screenShot, true), 'The returned screenshot should not be base64-encoded');
|
||||
|
||||
$img = imagecreatefromstring($screenShot);
|
||||
|
||||
if (false === $img) {
|
||||
$this->fail('The screenshot should be a valid image');
|
||||
}
|
||||
|
||||
imagedestroy($img);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Basic;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class StatusCodeTest extends TestCase
|
||||
{
|
||||
public function testStatuses()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->assertEquals(200, $this->getSession()->getStatusCode());
|
||||
$this->assertEquals($this->pathTo('/index.html'), $this->getSession()->getCurrentUrl());
|
||||
|
||||
$this->getSession()->visit($this->pathTo('/404.php'));
|
||||
|
||||
$this->assertEquals($this->pathTo('/404.php'), $this->getSession()->getCurrentUrl());
|
||||
$this->assertEquals(404, $this->getSession()->getStatusCode());
|
||||
$this->assertEquals('Sorry, page not found', $this->getSession()->getPage()->getContent());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Basic;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class TraversingTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* find by label
|
||||
* @group issue211
|
||||
*/
|
||||
public function testIssue211()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/issue211.html'));
|
||||
$field = $this->getSession()->getPage()->findField('Téléphone');
|
||||
|
||||
$this->assertNotNull($field);
|
||||
}
|
||||
|
||||
public function testElementsTraversing()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$this->assertNotNull($page->find('css', 'h1'));
|
||||
$this->assertEquals('Extremely useless page', $page->find('css', 'h1')->getText());
|
||||
$this->assertEquals('h1', $page->find('css', 'h1')->getTagName());
|
||||
|
||||
$this->assertNotNull($page->find('xpath', '//div/strong[3]'));
|
||||
$this->assertEquals('pariatur', $page->find('xpath', '//div/strong[3]')->getText());
|
||||
$this->assertEquals('super-duper', $page->find('xpath', '//div/strong[3]')->getAttribute('class'));
|
||||
$this->assertTrue($page->find('xpath', '//div/strong[3]')->hasAttribute('class'));
|
||||
|
||||
$this->assertNotNull($page->find('xpath', '//div/strong[2]'));
|
||||
$this->assertEquals('veniam', $page->find('xpath', '//div/strong[2]')->getText());
|
||||
$this->assertEquals('strong', $page->find('xpath', '//div/strong[2]')->getTagName());
|
||||
$this->assertNull($page->find('xpath', '//div/strong[2]')->getAttribute('class'));
|
||||
$this->assertFalse($page->find('xpath', '//div/strong[2]')->hasAttribute('class'));
|
||||
|
||||
$strongs = $page->findAll('css', 'div#core > strong');
|
||||
$this->assertCount(3, $strongs);
|
||||
$this->assertEquals('Lorem', $strongs[0]->getText());
|
||||
$this->assertEquals('pariatur', $strongs[2]->getText());
|
||||
|
||||
$element = $page->find('css', '#some-element');
|
||||
|
||||
$this->assertEquals('some very interesting text', $element->getText());
|
||||
$this->assertEquals(
|
||||
"\n some <div>very\n </div>\n".
|
||||
"<em>interesting</em> text\n ",
|
||||
$element->getHtml()
|
||||
);
|
||||
|
||||
$this->assertTrue($element->hasAttribute('data-href'));
|
||||
$this->assertFalse($element->hasAttribute('data-url'));
|
||||
$this->assertEquals('http://mink.behat.org', $element->getAttribute('data-href'));
|
||||
$this->assertNull($element->getAttribute('data-url'));
|
||||
$this->assertEquals('div', $element->getTagName());
|
||||
}
|
||||
|
||||
public function testVeryDeepElementsTraversing()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$footer = $page->find('css', 'footer');
|
||||
$this->assertNotNull($footer);
|
||||
|
||||
$searchForm = $footer->find('css', 'form#search-form');
|
||||
$this->assertNotNull($searchForm);
|
||||
$this->assertEquals('search-form', $searchForm->getAttribute('id'));
|
||||
|
||||
$searchInput = $searchForm->findField('Search site...');
|
||||
$this->assertNotNull($searchInput);
|
||||
$this->assertEquals('text', $searchInput->getAttribute('type'));
|
||||
|
||||
$searchInput = $searchForm->findField('Search site...');
|
||||
$this->assertNotNull($searchInput);
|
||||
$this->assertEquals('text', $searchInput->getAttribute('type'));
|
||||
|
||||
$profileForm = $footer->find('css', '#profile');
|
||||
$this->assertNotNull($profileForm);
|
||||
|
||||
$profileFormDiv = $profileForm->find('css', 'div');
|
||||
$this->assertNotNull($profileFormDiv);
|
||||
|
||||
$profileFormDivLabel = $profileFormDiv->find('css', 'label');
|
||||
$this->assertNotNull($profileFormDivLabel);
|
||||
|
||||
$profileFormDivParent = $profileFormDivLabel->getParent();
|
||||
$this->assertNotNull($profileFormDivParent);
|
||||
|
||||
$profileFormDivParent = $profileFormDivLabel->getParent();
|
||||
$this->assertEquals('something', $profileFormDivParent->getAttribute('data-custom'));
|
||||
|
||||
$profileFormInput = $profileFormDivLabel->findField('user-name');
|
||||
$this->assertNotNull($profileFormInput);
|
||||
$this->assertEquals('username', $profileFormInput->getAttribute('name'));
|
||||
}
|
||||
|
||||
public function testDeepTraversing()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$traversDiv = $this->getSession()->getPage()->findAll('css', 'div.travers');
|
||||
|
||||
$this->assertCount(1, $traversDiv);
|
||||
$traversDiv = $traversDiv[0];
|
||||
|
||||
$subDivs = $traversDiv->findAll('css', 'div.sub');
|
||||
$this->assertCount(3, $subDivs);
|
||||
|
||||
$this->assertTrue($subDivs[2]->hasLink('some deep url'));
|
||||
$this->assertFalse($subDivs[2]->hasLink('come deep url'));
|
||||
$subUrl = $subDivs[2]->findLink('some deep url');
|
||||
$this->assertNotNull($subUrl);
|
||||
|
||||
$this->assertRegExp('/some_url$/', $subUrl->getAttribute('href'));
|
||||
$this->assertEquals('some deep url', $subUrl->getText());
|
||||
$this->assertEquals('some <strong>deep</strong> url', $subUrl->getHtml());
|
||||
|
||||
$this->assertTrue($subUrl->has('css', 'strong'));
|
||||
$this->assertFalse($subUrl->has('css', 'em'));
|
||||
$this->assertEquals('deep', $subUrl->find('css', 'strong')->getText());
|
||||
}
|
||||
|
||||
public function testFindingChild()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$form = $this->getSession()->getPage()->find('css', 'footer form');
|
||||
$this->assertNotNull($form);
|
||||
|
||||
$this->assertCount(1, $form->findAll('css', 'input'), 'Elements are searched only in the element, not in all previous matches');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Basic;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class VisibilityTest extends TestCase
|
||||
{
|
||||
public function testVisibility()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/js_test.html'));
|
||||
$webAssert = $this->getAssertSession();
|
||||
|
||||
$clicker = $webAssert->elementExists('css', '.elements div#clicker');
|
||||
$invisible = $webAssert->elementExists('css', '#invisible');
|
||||
|
||||
$this->assertFalse($invisible->isVisible());
|
||||
$this->assertTrue($clicker->isVisible());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Css;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class HoverTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @group mouse-events
|
||||
*/
|
||||
public function testMouseOverHover()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/css_mouse_events.html'));
|
||||
|
||||
$this->findById('reset-square')->mouseOver();
|
||||
$this->assertActionSquareHeight(100);
|
||||
|
||||
$this->findById('action-square')->mouseOver();
|
||||
$this->assertActionSquareHeight(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group mouse-events
|
||||
* @depends testMouseOverHover
|
||||
*/
|
||||
public function testClickHover()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/css_mouse_events.html'));
|
||||
|
||||
$this->findById('reset-square')->mouseOver();
|
||||
$this->assertActionSquareHeight(100);
|
||||
|
||||
$this->findById('action-square')->click();
|
||||
$this->assertActionSquareHeight(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group mouse-events
|
||||
* @depends testMouseOverHover
|
||||
*/
|
||||
public function testDoubleClickHover()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/css_mouse_events.html'));
|
||||
|
||||
$this->findById('reset-square')->mouseOver();
|
||||
$this->assertActionSquareHeight(100);
|
||||
|
||||
$this->findById('action-square')->doubleClick();
|
||||
$this->assertActionSquareHeight(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group mouse-events
|
||||
* @depends testMouseOverHover
|
||||
*/
|
||||
public function testRightClickHover()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/css_mouse_events.html'));
|
||||
|
||||
$this->findById('reset-square')->mouseOver();
|
||||
$this->assertActionSquareHeight(100);
|
||||
|
||||
$this->findById('action-square')->rightClick();
|
||||
$this->assertActionSquareHeight(200);
|
||||
}
|
||||
|
||||
private function assertActionSquareHeight($expected)
|
||||
{
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
$this->getSession()->evaluateScript("return window.$('#action-square').height();"),
|
||||
'Mouse is located over the object when mouse-related action is performed'
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Form;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class CheckboxTest extends TestCase
|
||||
{
|
||||
public function testManipulate()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('advanced_form.html'));
|
||||
|
||||
$checkbox = $this->getAssertSession()->fieldExists('agreement');
|
||||
|
||||
$this->assertNull($checkbox->getValue());
|
||||
$this->assertFalse($checkbox->isChecked());
|
||||
|
||||
$checkbox->check();
|
||||
|
||||
$this->assertEquals('yes', $checkbox->getValue());
|
||||
$this->assertTrue($checkbox->isChecked());
|
||||
|
||||
$checkbox->uncheck();
|
||||
|
||||
$this->assertNull($checkbox->getValue());
|
||||
$this->assertFalse($checkbox->isChecked());
|
||||
}
|
||||
|
||||
public function testSetValue()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('advanced_form.html'));
|
||||
|
||||
$checkbox = $this->getAssertSession()->fieldExists('agreement');
|
||||
|
||||
$this->assertNull($checkbox->getValue());
|
||||
$this->assertFalse($checkbox->isChecked());
|
||||
|
||||
$checkbox->setValue(true);
|
||||
|
||||
$this->assertEquals('yes', $checkbox->getValue());
|
||||
$this->assertTrue($checkbox->isChecked());
|
||||
|
||||
$checkbox->setValue(false);
|
||||
|
||||
$this->assertNull($checkbox->getValue());
|
||||
$this->assertFalse($checkbox->isChecked());
|
||||
}
|
||||
|
||||
public function testCheckboxMultiple()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/multicheckbox_form.html'));
|
||||
$webAssert = $this->getAssertSession();
|
||||
|
||||
$this->assertEquals('Multicheckbox Test', $webAssert->elementExists('css', 'h1')->getText());
|
||||
|
||||
$updateMail = $webAssert->elementExists('css', '[name="mail_types[]"][value="update"]');
|
||||
$spamMail = $webAssert->elementExists('css', '[name="mail_types[]"][value="spam"]');
|
||||
|
||||
$this->assertEquals('update', $updateMail->getValue());
|
||||
$this->assertNull($spamMail->getValue());
|
||||
|
||||
$this->assertTrue($updateMail->isChecked());
|
||||
$this->assertFalse($spamMail->isChecked());
|
||||
|
||||
$updateMail->uncheck();
|
||||
$this->assertFalse($updateMail->isChecked());
|
||||
$this->assertFalse($spamMail->isChecked());
|
||||
|
||||
$spamMail->check();
|
||||
$this->assertFalse($updateMail->isChecked());
|
||||
$this->assertTrue($spamMail->isChecked());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,312 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Form;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class GeneralTest extends TestCase
|
||||
{
|
||||
// test multiple submit buttons
|
||||
public function testIssue212()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
|
||||
$session->visit($this->pathTo('/issue212.html'));
|
||||
|
||||
$field = $this->findById('poney-button');
|
||||
$this->assertEquals('poney', $field->getValue());
|
||||
}
|
||||
|
||||
public function testBasicForm()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/basic_form.html'));
|
||||
|
||||
$webAssert = $this->getAssertSession();
|
||||
$page = $this->getSession()->getPage();
|
||||
$this->assertEquals('Basic Form Page', $webAssert->elementExists('css', 'h1')->getText());
|
||||
|
||||
$firstname = $webAssert->fieldExists('first_name');
|
||||
$lastname = $webAssert->fieldExists('lastn');
|
||||
|
||||
$this->assertEquals('Firstname', $firstname->getValue());
|
||||
$this->assertEquals('Lastname', $lastname->getValue());
|
||||
|
||||
$firstname->setValue('Konstantin');
|
||||
$page->fillField('last_name', 'Kudryashov');
|
||||
|
||||
$this->assertEquals('Konstantin', $firstname->getValue());
|
||||
$this->assertEquals('Kudryashov', $lastname->getValue());
|
||||
|
||||
$page->findButton('Reset')->click();
|
||||
|
||||
$this->assertEquals('Firstname', $firstname->getValue());
|
||||
$this->assertEquals('Lastname', $lastname->getValue());
|
||||
|
||||
$firstname->setValue('Konstantin');
|
||||
$page->fillField('last_name', 'Kudryashov');
|
||||
|
||||
$page->findButton('Save')->click();
|
||||
|
||||
if ($this->safePageWait(5000, 'document.getElementById("first") !== null')) {
|
||||
$this->assertEquals('Anket for Konstantin', $webAssert->elementExists('css', 'h1')->getText());
|
||||
$this->assertEquals('Firstname: Konstantin', $webAssert->elementExists('css', '#first')->getText());
|
||||
$this->assertEquals('Lastname: Kudryashov', $webAssert->elementExists('css', '#last')->getText());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider formSubmitWaysDataProvider
|
||||
*/
|
||||
public function testFormSubmitWays($submitVia)
|
||||
{
|
||||
$session = $this->getSession();
|
||||
$session->visit($this->pathTo('/basic_form.html'));
|
||||
$page = $session->getPage();
|
||||
$webAssert = $this->getAssertSession();
|
||||
|
||||
$firstname = $webAssert->fieldExists('first_name');
|
||||
$firstname->setValue('Konstantin');
|
||||
|
||||
$page->findButton($submitVia)->click();
|
||||
|
||||
if ($this->safePageWait(5000, 'document.getElementById("first") !== null')) {
|
||||
$this->assertEquals('Firstname: Konstantin', $webAssert->elementExists('css', '#first')->getText());
|
||||
} else {
|
||||
$this->fail('Form was never submitted');
|
||||
}
|
||||
}
|
||||
|
||||
public function formSubmitWaysDataProvider()
|
||||
{
|
||||
return array(
|
||||
array('Save'),
|
||||
array('input-type-image'),
|
||||
array('button-without-type'),
|
||||
array('button-type-submit'),
|
||||
);
|
||||
}
|
||||
|
||||
public function testFormSubmit()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
$session->visit($this->pathTo('/basic_form.html'));
|
||||
|
||||
$webAssert = $this->getAssertSession();
|
||||
$webAssert->fieldExists('first_name')->setValue('Konstantin');
|
||||
|
||||
$webAssert->elementExists('xpath', 'descendant-or-self::form[1]')->submit();
|
||||
|
||||
if ($this->safePageWait(5000, 'document.getElementById("first") !== null')) {
|
||||
$this->assertEquals('Firstname: Konstantin', $webAssert->elementExists('css', '#first')->getText());
|
||||
};
|
||||
}
|
||||
|
||||
public function testFormSubmitWithoutButton()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
$session->visit($this->pathTo('/form_without_button.html'));
|
||||
|
||||
$webAssert = $this->getAssertSession();
|
||||
$webAssert->fieldExists('first_name')->setValue('Konstantin');
|
||||
|
||||
$webAssert->elementExists('xpath', 'descendant-or-self::form[1]')->submit();
|
||||
|
||||
if ($this->safePageWait(5000, 'document.getElementById("first") !== null')) {
|
||||
$this->assertEquals('Firstname: Konstantin', $webAssert->elementExists('css', '#first')->getText());
|
||||
};
|
||||
}
|
||||
|
||||
public function testBasicGetForm()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/basic_get_form.php'));
|
||||
$webAssert = $this->getAssertSession();
|
||||
|
||||
$page = $this->getSession()->getPage();
|
||||
$this->assertEquals('Basic Get Form Page', $webAssert->elementExists('css', 'h1')->getText());
|
||||
|
||||
$search = $webAssert->fieldExists('q');
|
||||
$search->setValue('some#query');
|
||||
$page->pressButton('Find');
|
||||
|
||||
$div = $webAssert->elementExists('css', 'div');
|
||||
$this->assertEquals('some#query', $div->getText());
|
||||
}
|
||||
|
||||
public function testAdvancedForm()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/advanced_form.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$page->fillField('first_name', 'ever');
|
||||
$page->fillField('last_name', 'zet');
|
||||
|
||||
$page->pressButton('Register');
|
||||
|
||||
$this->assertContains('no file', $page->getContent());
|
||||
|
||||
$this->getSession()->visit($this->pathTo('/advanced_form.html'));
|
||||
|
||||
$webAssert = $this->getAssertSession();
|
||||
$page = $this->getSession()->getPage();
|
||||
$this->assertEquals('ADvanced Form Page', $webAssert->elementExists('css', 'h1')->getText());
|
||||
|
||||
$firstname = $webAssert->fieldExists('first_name');
|
||||
$lastname = $webAssert->fieldExists('lastn');
|
||||
$email = $webAssert->fieldExists('Your email:');
|
||||
$select = $webAssert->fieldExists('select_number');
|
||||
$sex = $webAssert->fieldExists('sex');
|
||||
$maillist = $webAssert->fieldExists('mail_list');
|
||||
$agreement = $webAssert->fieldExists('agreement');
|
||||
$notes = $webAssert->fieldExists('notes');
|
||||
$about = $webAssert->fieldExists('about');
|
||||
|
||||
$this->assertEquals('Firstname', $firstname->getValue());
|
||||
$this->assertEquals('Lastname', $lastname->getValue());
|
||||
$this->assertEquals('your@email.com', $email->getValue());
|
||||
$this->assertEquals('20', $select->getValue());
|
||||
$this->assertEquals('w', $sex->getValue());
|
||||
$this->assertEquals('original notes', $notes->getValue());
|
||||
|
||||
$this->assertEquals('on', $maillist->getValue());
|
||||
$this->assertNull($agreement->getValue());
|
||||
|
||||
$this->assertTrue($maillist->isChecked());
|
||||
$this->assertFalse($agreement->isChecked());
|
||||
|
||||
$agreement->check();
|
||||
$this->assertTrue($agreement->isChecked());
|
||||
|
||||
$maillist->uncheck();
|
||||
$this->assertFalse($maillist->isChecked());
|
||||
|
||||
$select->selectOption('thirty');
|
||||
$this->assertEquals('30', $select->getValue());
|
||||
|
||||
$sex->selectOption('m');
|
||||
$this->assertEquals('m', $sex->getValue());
|
||||
|
||||
$notes->setValue('new notes');
|
||||
$this->assertEquals('new notes', $notes->getValue());
|
||||
|
||||
$about->attachFile($this->mapRemoteFilePath(__DIR__.'/../../web-fixtures/some_file.txt'));
|
||||
|
||||
$button = $page->findButton('Register');
|
||||
$this->assertNotNull($button);
|
||||
|
||||
$page->fillField('first_name', 'Foo "item"');
|
||||
$page->fillField('last_name', 'Bar');
|
||||
$page->fillField('Your email:', 'ever.zet@gmail.com');
|
||||
|
||||
$this->assertEquals('Foo "item"', $firstname->getValue());
|
||||
$this->assertEquals('Bar', $lastname->getValue());
|
||||
|
||||
$button->press();
|
||||
|
||||
if ($this->safePageWait(5000, 'document.getElementsByTagName("title") !== null')) {
|
||||
$out = <<<OUT
|
||||
array (
|
||||
'agreement' = 'on',
|
||||
'email' = 'ever.zet@gmail.com',
|
||||
'first_name' = 'Foo "item"',
|
||||
'last_name' = 'Bar',
|
||||
'notes' = 'new notes',
|
||||
'select_number' = '30',
|
||||
'sex' = 'm',
|
||||
'submit' = 'Register',
|
||||
)
|
||||
some_file.txt
|
||||
1 uploaded file
|
||||
OUT;
|
||||
$this->assertContains($out, $page->getContent());
|
||||
}
|
||||
}
|
||||
|
||||
public function testMultiInput()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/multi_input_form.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
$webAssert = $this->getAssertSession();
|
||||
$this->assertEquals('Multi input Test', $webAssert->elementExists('css', 'h1')->getText());
|
||||
|
||||
$first = $webAssert->fieldExists('First');
|
||||
$second = $webAssert->fieldExists('Second');
|
||||
$third = $webAssert->fieldExists('Third');
|
||||
|
||||
$this->assertEquals('tag1', $first->getValue());
|
||||
$this->assertSame('tag2', $second->getValue());
|
||||
$this->assertEquals('tag1', $third->getValue());
|
||||
|
||||
$first->setValue('tag2');
|
||||
$this->assertEquals('tag2', $first->getValue());
|
||||
$this->assertSame('tag2', $second->getValue());
|
||||
$this->assertEquals('tag1', $third->getValue());
|
||||
|
||||
$second->setValue('one');
|
||||
|
||||
$this->assertEquals('tag2', $first->getValue());
|
||||
$this->assertSame('one', $second->getValue());
|
||||
|
||||
$third->setValue('tag3');
|
||||
|
||||
$this->assertEquals('tag2', $first->getValue());
|
||||
$this->assertSame('one', $second->getValue());
|
||||
$this->assertEquals('tag3', $third->getValue());
|
||||
|
||||
$button = $page->findButton('Register');
|
||||
$this->assertNotNull($button);
|
||||
$button->press();
|
||||
|
||||
$space = ' ';
|
||||
$out = <<<OUT
|
||||
'tags' =$space
|
||||
array (
|
||||
0 = 'tag2',
|
||||
1 = 'one',
|
||||
2 = 'tag3',
|
||||
),
|
||||
OUT;
|
||||
$this->assertContains($out, $page->getContent());
|
||||
}
|
||||
|
||||
public function testAdvancedFormSecondSubmit()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/advanced_form.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$button = $page->findButton('Login');
|
||||
$this->assertNotNull($button);
|
||||
$button->press();
|
||||
|
||||
$toSearch = array(
|
||||
"'agreement' = 'off',",
|
||||
"'submit' = 'Login',",
|
||||
'no file',
|
||||
);
|
||||
|
||||
$pageContent = $page->getContent();
|
||||
|
||||
foreach ($toSearch as $searchString) {
|
||||
$this->assertContains($searchString, $pageContent);
|
||||
}
|
||||
}
|
||||
|
||||
public function testSubmitEmptyTextarea()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/empty_textarea.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$page->pressButton('Save');
|
||||
|
||||
$toSearch = array(
|
||||
"'textarea' = '',",
|
||||
"'submit' = 'Save',",
|
||||
'no file',
|
||||
);
|
||||
|
||||
$pageContent = $page->getContent();
|
||||
|
||||
foreach ($toSearch as $searchString) {
|
||||
$this->assertContains($searchString, $pageContent);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Form;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class Html5Test extends TestCase
|
||||
{
|
||||
public function testHtml5FormInputAttribute()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/html5_form.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
$webAssert = $this->getAssertSession();
|
||||
|
||||
$firstName = $webAssert->fieldExists('first_name');
|
||||
$lastName = $webAssert->fieldExists('last_name');
|
||||
|
||||
$this->assertEquals('not set', $lastName->getValue());
|
||||
$firstName->setValue('John');
|
||||
$lastName->setValue('Doe');
|
||||
|
||||
$this->assertEquals('Doe', $lastName->getValue());
|
||||
|
||||
$page->pressButton('Submit in form');
|
||||
|
||||
if ($this->safePageWait(5000, 'document.getElementsByTagName("title") !== null')) {
|
||||
$out = <<<OUT
|
||||
'first_name' = 'John',
|
||||
'last_name' = 'Doe',
|
||||
OUT;
|
||||
$this->assertContains($out, $page->getContent());
|
||||
$this->assertNotContains('other_field', $page->getContent());
|
||||
}
|
||||
}
|
||||
|
||||
public function testHtml5FormRadioAttribute()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('html5_radio.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$radio = $this->findById('sex_f');
|
||||
$otherRadio = $this->findById('sex_invalid');
|
||||
|
||||
$this->assertEquals('f', $radio->getValue());
|
||||
$this->assertEquals('invalid', $otherRadio->getValue());
|
||||
|
||||
$radio->selectOption('m');
|
||||
|
||||
$this->assertEquals('m', $radio->getValue());
|
||||
$this->assertEquals('invalid', $otherRadio->getValue());
|
||||
|
||||
$page->pressButton('Submit in form');
|
||||
|
||||
$out = <<<OUT
|
||||
'sex' = 'm',
|
||||
OUT;
|
||||
$this->assertContains($out, $page->getContent());
|
||||
}
|
||||
|
||||
public function testHtml5FormButtonAttribute()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/html5_form.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
$webAssert = $this->getAssertSession();
|
||||
|
||||
$firstName = $webAssert->fieldExists('first_name');
|
||||
$lastName = $webAssert->fieldExists('last_name');
|
||||
|
||||
$firstName->setValue('John');
|
||||
$lastName->setValue('Doe');
|
||||
|
||||
$page->pressButton('Submit outside form');
|
||||
|
||||
if ($this->safePageWait(5000, 'document.getElementsByTagName("title") !== null')) {
|
||||
$out = <<<OUT
|
||||
'first_name' = 'John',
|
||||
'last_name' = 'Doe',
|
||||
'submit_button' = 'test',
|
||||
OUT;
|
||||
$this->assertContains($out, $page->getContent());
|
||||
}
|
||||
}
|
||||
|
||||
public function testHtml5FormOutside()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/html5_form.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$page->fillField('other_field', 'hello');
|
||||
|
||||
$page->pressButton('Submit separate form');
|
||||
|
||||
if ($this->safePageWait(5000, 'document.getElementsByTagName("title") !== null')) {
|
||||
$out = <<<OUT
|
||||
'other_field' = 'hello',
|
||||
OUT;
|
||||
$this->assertContains($out, $page->getContent());
|
||||
$this->assertNotContains('first_name', $page->getContent());
|
||||
}
|
||||
}
|
||||
|
||||
public function testHtml5Types()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('html5_types.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$page->fillField('url', 'http://mink.behat.org/');
|
||||
$page->fillField('email', 'mink@example.org');
|
||||
$page->fillField('number', '6');
|
||||
$page->fillField('search', 'mink');
|
||||
$page->fillField('date', '2014-05-19');
|
||||
$page->fillField('color', '#ff00aa');
|
||||
|
||||
$page->pressButton('Submit');
|
||||
|
||||
$out = <<<OUT
|
||||
'color' = '#ff00aa',
|
||||
'date' = '2014-05-19',
|
||||
'email' = 'mink@example.org',
|
||||
'number' = '6',
|
||||
'search' = 'mink',
|
||||
'submit_button' = 'Submit',
|
||||
'url' = 'http://mink.behat.org/',
|
||||
OUT;
|
||||
|
||||
$this->assertContains($out, $page->getContent());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Form;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class RadioTest extends TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('radio.html'));
|
||||
}
|
||||
|
||||
public function testIsChecked()
|
||||
{
|
||||
$option = $this->findById('first');
|
||||
$option2 = $this->findById('second');
|
||||
|
||||
$this->assertTrue($option->isChecked());
|
||||
$this->assertFalse($option2->isChecked());
|
||||
|
||||
$option2->selectOption('updated');
|
||||
|
||||
$this->assertFalse($option->isChecked());
|
||||
$this->assertTrue($option2->isChecked());
|
||||
}
|
||||
|
||||
public function testSelectOption()
|
||||
{
|
||||
$option = $this->findById('first');
|
||||
|
||||
$this->assertEquals('set', $option->getValue());
|
||||
|
||||
$option->selectOption('updated');
|
||||
|
||||
$this->assertEquals('updated', $option->getValue());
|
||||
|
||||
$option->selectOption('set');
|
||||
|
||||
$this->assertEquals('set', $option->getValue());
|
||||
}
|
||||
|
||||
public function testSetValue()
|
||||
{
|
||||
$option = $this->findById('first');
|
||||
|
||||
$this->assertEquals('set', $option->getValue());
|
||||
|
||||
$option->setValue('updated');
|
||||
|
||||
$this->assertEquals('updated', $option->getValue());
|
||||
$this->assertFalse($option->isChecked());
|
||||
}
|
||||
|
||||
public function testSameNameInMultipleForms()
|
||||
{
|
||||
$option1 = $this->findById('reused_form1');
|
||||
$option2 = $this->findById('reused_form2');
|
||||
|
||||
$this->assertEquals('test2', $option1->getValue());
|
||||
$this->assertEquals('test3', $option2->getValue());
|
||||
|
||||
$option1->selectOption('test');
|
||||
|
||||
$this->assertEquals('test', $option1->getValue());
|
||||
$this->assertEquals('test3', $option2->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/Behat/MinkSahiDriver/issues/32
|
||||
*/
|
||||
public function testSetValueXPathEscaping()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
$session->visit($this->pathTo('/advanced_form.html'));
|
||||
$page = $session->getPage();
|
||||
|
||||
$sex = $page->find('xpath', '//*[@name = "sex"]'."\n|\n".'//*[@id = "sex"]');
|
||||
$this->assertNotNull($sex, 'xpath with line ending works');
|
||||
|
||||
$sex->setValue('m');
|
||||
$this->assertEquals('m', $sex->getValue(), 'no double xpath escaping during radio button value change');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Form;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class SelectTest extends TestCase
|
||||
{
|
||||
public function testMultiselect()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/multiselect_form.html'));
|
||||
$webAssert = $this->getAssertSession();
|
||||
$page = $this->getSession()->getPage();
|
||||
$this->assertEquals('Multiselect Test', $webAssert->elementExists('css', 'h1')->getText());
|
||||
|
||||
$select = $webAssert->fieldExists('select_number');
|
||||
$multiSelect = $webAssert->fieldExists('select_multiple_numbers[]');
|
||||
$secondMultiSelect = $webAssert->fieldExists('select_multiple_values[]');
|
||||
|
||||
$this->assertEquals('20', $select->getValue());
|
||||
$this->assertSame(array(), $multiSelect->getValue());
|
||||
$this->assertSame(array('2', '3'), $secondMultiSelect->getValue());
|
||||
|
||||
$select->selectOption('thirty');
|
||||
$this->assertEquals('30', $select->getValue());
|
||||
|
||||
$multiSelect->selectOption('one', true);
|
||||
|
||||
$this->assertSame(array('1'), $multiSelect->getValue());
|
||||
|
||||
$multiSelect->selectOption('three', true);
|
||||
|
||||
$this->assertEquals(array('1', '3'), $multiSelect->getValue());
|
||||
|
||||
$secondMultiSelect->selectOption('two');
|
||||
$this->assertSame(array('2'), $secondMultiSelect->getValue());
|
||||
|
||||
$button = $page->findButton('Register');
|
||||
$this->assertNotNull($button);
|
||||
$button->press();
|
||||
|
||||
$space = ' ';
|
||||
$out = <<<OUT
|
||||
'agreement' = 'off',
|
||||
'select_multiple_numbers' =$space
|
||||
array (
|
||||
0 = '1',
|
||||
1 = '3',
|
||||
),
|
||||
'select_multiple_values' =$space
|
||||
array (
|
||||
0 = '2',
|
||||
),
|
||||
'select_number' = '30',
|
||||
OUT;
|
||||
$this->assertContains($out, $page->getContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider testElementSelectedStateCheckDataProvider
|
||||
*/
|
||||
public function testElementSelectedStateCheck($selectName, $optionValue, $optionText)
|
||||
{
|
||||
$session = $this->getSession();
|
||||
$webAssert = $this->getAssertSession();
|
||||
$session->visit($this->pathTo('/multiselect_form.html'));
|
||||
$select = $webAssert->fieldExists($selectName);
|
||||
|
||||
$optionValueEscaped = $session->getSelectorsHandler()->xpathLiteral($optionValue);
|
||||
$option = $webAssert->elementExists('named', array('option', $optionValueEscaped));
|
||||
|
||||
$this->assertFalse($option->isSelected());
|
||||
$select->selectOption($optionText);
|
||||
$this->assertTrue($option->isSelected());
|
||||
}
|
||||
|
||||
public function testElementSelectedStateCheckDataProvider()
|
||||
{
|
||||
return array(
|
||||
array('select_number', '30', 'thirty'),
|
||||
array('select_multiple_numbers[]', '2', 'two'),
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetValueSingleSelect()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
$session->visit($this->pathTo('/multiselect_form.html'));
|
||||
$select = $this->getAssertSession()->fieldExists('select_number');
|
||||
|
||||
$select->setValue('10');
|
||||
$this->assertEquals('10', $select->getValue());
|
||||
}
|
||||
|
||||
public function testSetValueMultiSelect()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
$session->visit($this->pathTo('/multiselect_form.html'));
|
||||
$select = $this->getAssertSession()->fieldExists('select_multiple_values[]');
|
||||
|
||||
$select->setValue(array('1', '2'));
|
||||
$this->assertEquals(array('1', '2'), $select->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/Behat/Mink/issues/193
|
||||
*/
|
||||
public function testOptionWithoutValue()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
$session->visit($this->pathTo('/issue193.html'));
|
||||
|
||||
$session->getPage()->selectFieldOption('options-without-values', 'Two');
|
||||
$this->assertEquals('Two', $this->findById('options-without-values')->getValue());
|
||||
|
||||
$this->assertTrue($this->findById('two')->isSelected());
|
||||
$this->assertFalse($this->findById('one')->isSelected());
|
||||
|
||||
$session->getPage()->selectFieldOption('options-with-values', 'two');
|
||||
$this->assertEquals('two', $this->findById('options-with-values')->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/Behat/Mink/issues/131
|
||||
*/
|
||||
public function testAccentuatedOption()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/issue131.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$page->selectFieldOption('foobar', 'Gimme some accentués characters');
|
||||
|
||||
$this->assertEquals('1', $page->findField('foobar')->getValue());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Js;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class ChangeEventTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* 'change' event should be fired after selecting an <option> in a <select>
|
||||
*
|
||||
* TODO check whether this test is redundant with other change event tests.
|
||||
*/
|
||||
public function testIssue255()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
$session->visit($this->pathTo('/issue255.html'));
|
||||
|
||||
$session->getPage()->selectFieldOption('foo_select', 'Option 3');
|
||||
|
||||
$session->wait(2000, '$("#output_foo_select").text() != ""');
|
||||
$this->assertEquals('onChangeSelect', $session->getPage()->find('css', '#output_foo_select')->getText());
|
||||
}
|
||||
|
||||
public function testIssue178()
|
||||
{
|
||||
$session = $this->getSession();
|
||||
$session->visit($this->pathTo('/issue178.html'));
|
||||
|
||||
$this->findById('source')->setValue('foo');
|
||||
$this->assertEquals('foo', $this->findById('target')->getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider setValueChangeEventDataProvider
|
||||
* @group change-event-detector
|
||||
*/
|
||||
public function testSetValueChangeEvent($elementId, $valueForEmpty, $valueForFilled = '')
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/element_change_detector.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$input = $this->findById($elementId);
|
||||
$this->assertNull($page->findById($elementId.'-result'));
|
||||
|
||||
// Verify setting value, when control is initially empty.
|
||||
$input->setValue($valueForEmpty);
|
||||
$this->assertElementChangeCount($elementId, 'initial value setting triggers change event');
|
||||
|
||||
if ($valueForFilled) {
|
||||
// Verify setting value, when control already has a value.
|
||||
$this->findById('results')->click();
|
||||
$input->setValue($valueForFilled);
|
||||
$this->assertElementChangeCount($elementId, 'value change triggers change event');
|
||||
}
|
||||
}
|
||||
|
||||
public function setValueChangeEventDataProvider()
|
||||
{
|
||||
return array(
|
||||
'input default' => array('the-input-default', 'from empty', 'from existing'),
|
||||
'input text' => array('the-input-text', 'from empty', 'from existing'),
|
||||
'input email' => array('the-email', 'from empty', 'from existing'),
|
||||
'textarea' => array('the-textarea', 'from empty', 'from existing'),
|
||||
'file' => array('the-file', 'from empty', 'from existing'),
|
||||
'select' => array('the-select', '30'),
|
||||
'radio' => array('the-radio-m', 'm'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider selectOptionChangeEventDataProvider
|
||||
* @group change-event-detector
|
||||
*/
|
||||
public function testSelectOptionChangeEvent($elementId, $elementValue)
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/element_change_detector.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$input = $this->findById($elementId);
|
||||
$this->assertNull($page->findById($elementId.'-result'));
|
||||
|
||||
$input->selectOption($elementValue);
|
||||
$this->assertElementChangeCount($elementId);
|
||||
}
|
||||
|
||||
public function selectOptionChangeEventDataProvider()
|
||||
{
|
||||
return array(
|
||||
'select' => array('the-select', '30'),
|
||||
'radio' => array('the-radio-m', 'm'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider checkboxTestWayDataProvider
|
||||
* @group change-event-detector
|
||||
*/
|
||||
public function testCheckChangeEvent($useSetValue)
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/element_change_detector.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$checkbox = $this->findById('the-unchecked-checkbox');
|
||||
$this->assertNull($page->findById('the-unchecked-checkbox-result'));
|
||||
|
||||
if ($useSetValue) {
|
||||
$checkbox->setValue(true);
|
||||
} else {
|
||||
$checkbox->check();
|
||||
}
|
||||
|
||||
$this->assertElementChangeCount('the-unchecked-checkbox');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider checkboxTestWayDataProvider
|
||||
* @group change-event-detector
|
||||
*/
|
||||
public function testUncheckChangeEvent($useSetValue)
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/element_change_detector.html'));
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$checkbox = $this->findById('the-checked-checkbox');
|
||||
$this->assertNull($page->findById('the-checked-checkbox-result'));
|
||||
|
||||
if ($useSetValue) {
|
||||
$checkbox->setValue(false);
|
||||
} else {
|
||||
$checkbox->uncheck();
|
||||
}
|
||||
|
||||
$this->assertElementChangeCount('the-checked-checkbox');
|
||||
}
|
||||
|
||||
public function checkboxTestWayDataProvider()
|
||||
{
|
||||
return array(
|
||||
array(true),
|
||||
array(false),
|
||||
);
|
||||
}
|
||||
|
||||
private function assertElementChangeCount($elementId, $message = '')
|
||||
{
|
||||
$counterElement = $this->getSession()->getPage()->findById($elementId.'-result');
|
||||
$actualCount = null === $counterElement ? 0 : $counterElement->getText();
|
||||
|
||||
$this->assertEquals('1', $actualCount, $message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Js;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class EventsTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @group mouse-events
|
||||
*/
|
||||
public function testClick()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/js_test.html'));
|
||||
$clicker = $this->getAssertSession()->elementExists('css', '.elements div#clicker');
|
||||
$this->assertEquals('not clicked', $clicker->getText());
|
||||
|
||||
$clicker->click();
|
||||
$this->assertEquals('single clicked', $clicker->getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group mouse-events
|
||||
*/
|
||||
public function testDoubleClick()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/js_test.html'));
|
||||
$clicker = $this->getAssertSession()->elementExists('css', '.elements div#clicker');
|
||||
$this->assertEquals('not clicked', $clicker->getText());
|
||||
|
||||
$clicker->doubleClick();
|
||||
$this->assertEquals('double clicked', $clicker->getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group mouse-events
|
||||
*/
|
||||
public function testRightClick()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/js_test.html'));
|
||||
$clicker = $this->getAssertSession()->elementExists('css', '.elements div#clicker');
|
||||
$this->assertEquals('not clicked', $clicker->getText());
|
||||
|
||||
$clicker->rightClick();
|
||||
$this->assertEquals('right clicked', $clicker->getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group mouse-events
|
||||
*/
|
||||
public function testFocus()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/js_test.html'));
|
||||
$focusBlurDetector = $this->getAssertSession()->elementExists('css', '.elements input#focus-blur-detector');
|
||||
$this->assertEquals('no action detected', $focusBlurDetector->getValue());
|
||||
|
||||
$focusBlurDetector->focus();
|
||||
$this->assertEquals('focused', $focusBlurDetector->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group mouse-events
|
||||
* @depends testFocus
|
||||
*/
|
||||
public function testBlur()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/js_test.html'));
|
||||
$focusBlurDetector = $this->getAssertSession()->elementExists('css', '.elements input#focus-blur-detector');
|
||||
$this->assertEquals('no action detected', $focusBlurDetector->getValue());
|
||||
|
||||
$focusBlurDetector->blur();
|
||||
$this->assertEquals('blured', $focusBlurDetector->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group mouse-events
|
||||
*/
|
||||
public function testMouseOver()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/js_test.html'));
|
||||
$mouseOverDetector = $this->getAssertSession()->elementExists('css', '.elements div#mouseover-detector');
|
||||
$this->assertEquals('no mouse action detected', $mouseOverDetector->getText());
|
||||
|
||||
$mouseOverDetector->mouseOver();
|
||||
$this->assertEquals('mouse overed', $mouseOverDetector->getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideKeyboardEventsModifiers
|
||||
*/
|
||||
public function testKeyboardEvents($modifier, $eventProperties)
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/js_test.html'));
|
||||
$webAssert = $this->getAssertSession();
|
||||
|
||||
$input1 = $webAssert->elementExists('css', '.elements input.input.first');
|
||||
$input2 = $webAssert->elementExists('css', '.elements input.input.second');
|
||||
$input3 = $webAssert->elementExists('css', '.elements input.input.third');
|
||||
$event = $webAssert->elementExists('css', '.elements .text-event');
|
||||
|
||||
$input1->keyDown('u', $modifier);
|
||||
$this->assertEquals('key downed:'.$eventProperties, $event->getText());
|
||||
|
||||
$input2->keyPress('r', $modifier);
|
||||
$this->assertEquals('key pressed:114 / '.$eventProperties, $event->getText());
|
||||
|
||||
$input3->keyUp(78, $modifier);
|
||||
$this->assertEquals('key upped:78 / '.$eventProperties, $event->getText());
|
||||
}
|
||||
|
||||
public function provideKeyboardEventsModifiers()
|
||||
{
|
||||
return array(
|
||||
'none' => array(null, '0 / 0 / 0 / 0'),
|
||||
'alt' => array('alt', '1 / 0 / 0 / 0'),
|
||||
// jQuery considers ctrl as being a metaKey in the normalized event
|
||||
'ctrl' => array('ctrl', '0 / 1 / 0 / 1'),
|
||||
'shift' => array('shift', '0 / 0 / 1 / 0'),
|
||||
'meta' => array('meta', '0 / 0 / 0 / 1'),
|
||||
);
|
||||
}
|
||||
}
|
85
core/vendor/behat/mink/driver-testsuite/tests/Js/JavascriptEvaluationTest.php
vendored
Normal file
85
core/vendor/behat/mink/driver-testsuite/tests/Js/JavascriptEvaluationTest.php
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Js;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class JavascriptEvaluationTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Tests, that `wait` method returns check result after exit.
|
||||
*/
|
||||
public function testWaitReturnValue()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/js_test.html'));
|
||||
|
||||
$found = $this->getSession()->wait(5000, '$("#draggable").length == 1');
|
||||
$this->assertTrue($found);
|
||||
}
|
||||
|
||||
public function testWait()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/js_test.html'));
|
||||
|
||||
$waitable = $this->findById('waitable');
|
||||
|
||||
$waitable->click();
|
||||
$this->getSession()->wait(3000, '$("#waitable").has("div").length > 0');
|
||||
$this->assertEquals('arrived', $this->getSession()->getPage()->find('css', '#waitable > div')->getText());
|
||||
|
||||
$waitable->click();
|
||||
$this->getSession()->wait(3000, 'false');
|
||||
$this->assertEquals('timeout', $this->getSession()->getPage()->find('css', '#waitable > div')->getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideExecutedScript
|
||||
*/
|
||||
public function testExecuteScript($script)
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->getSession()->executeScript($script);
|
||||
|
||||
sleep(1);
|
||||
|
||||
$heading = $this->getAssertSession()->elementExists('css', 'h1');
|
||||
$this->assertEquals('Hello world', $heading->getText());
|
||||
}
|
||||
|
||||
public function provideExecutedScript()
|
||||
{
|
||||
return array(
|
||||
array('document.querySelector("h1").textContent = "Hello world"'),
|
||||
array('document.querySelector("h1").textContent = "Hello world";'),
|
||||
array('function () {document.querySelector("h1").textContent = "Hello world";}()'),
|
||||
array('function () {document.querySelector("h1").textContent = "Hello world";}();'),
|
||||
array('(function () {document.querySelector("h1").textContent = "Hello world";})()'),
|
||||
array('(function () {document.querySelector("h1").textContent = "Hello world";})();'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideEvaluatedScript
|
||||
*/
|
||||
public function testEvaluateJavascript($script)
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
|
||||
$this->assertSame(2, $this->getSession()->evaluateScript($script));
|
||||
}
|
||||
|
||||
public function provideEvaluatedScript()
|
||||
{
|
||||
return array(
|
||||
array('1 + 1'),
|
||||
array('1 + 1;'),
|
||||
array('return 1 + 1'),
|
||||
array('return 1 + 1;'),
|
||||
array('function () {return 1+1;}()'),
|
||||
array('(function () {return 1+1;})()'),
|
||||
array('return function () { return 1+1;}()'),
|
||||
array('return (function () {return 1+1;})()'),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Js;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class JavascriptTest extends TestCase
|
||||
{
|
||||
public function testAriaRoles()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/aria_roles.html'));
|
||||
|
||||
$this->getSession()->wait(5000, '$("#hidden-element").is(":visible") === false');
|
||||
$this->getSession()->getPage()->pressButton('Toggle');
|
||||
$this->getSession()->wait(5000, '$("#hidden-element").is(":visible") === true');
|
||||
|
||||
$this->getSession()->getPage()->clickLink('Go to Index');
|
||||
$this->assertEquals($this->pathTo('/index.html'), $this->getSession()->getCurrentUrl());
|
||||
}
|
||||
|
||||
public function testDragDrop()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/js_test.html'));
|
||||
$webAssert = $this->getAssertSession();
|
||||
|
||||
$draggable = $webAssert->elementExists('css', '#draggable');
|
||||
$droppable = $webAssert->elementExists('css', '#droppable');
|
||||
|
||||
$draggable->dragTo($droppable);
|
||||
$this->assertEquals('Dropped!', $droppable->find('css', 'p')->getText());
|
||||
}
|
||||
|
||||
// test accentuated char in button
|
||||
public function testIssue225()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/issue225.html'));
|
||||
$this->getSession()->getPage()->pressButton('Créer un compte');
|
||||
$this->getSession()->wait(5000, '$("#panel").text() != ""');
|
||||
|
||||
$this->assertContains('OH AIH!', $this->getSession()->getPage()->getText());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver\Js;
|
||||
|
||||
use Behat\Mink\Tests\Driver\TestCase;
|
||||
|
||||
class WindowTest extends TestCase
|
||||
{
|
||||
public function testWindow()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/window.html'));
|
||||
$session = $this->getSession();
|
||||
$page = $session->getPage();
|
||||
$webAssert = $this->getAssertSession();
|
||||
|
||||
$page->clickLink('Popup #1');
|
||||
$session->switchToWindow(null);
|
||||
|
||||
$page->clickLink('Popup #2');
|
||||
$session->switchToWindow(null);
|
||||
|
||||
$el = $webAssert->elementExists('css', '#text');
|
||||
$this->assertSame('Main window div text', $el->getText());
|
||||
|
||||
$session->switchToWindow('popup_1');
|
||||
$el = $webAssert->elementExists('css', '#text');
|
||||
$this->assertSame('Popup#1 div text', $el->getText());
|
||||
|
||||
$session->switchToWindow('popup_2');
|
||||
$el = $webAssert->elementExists('css', '#text');
|
||||
$this->assertSame('Popup#2 div text', $el->getText());
|
||||
|
||||
$session->switchToWindow(null);
|
||||
$el = $webAssert->elementExists('css', '#text');
|
||||
$this->assertSame('Main window div text', $el->getText());
|
||||
}
|
||||
|
||||
public function testGetWindowNames()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/window.html'));
|
||||
$session = $this->getSession();
|
||||
$page = $session->getPage();
|
||||
|
||||
$windowName = $this->getSession()->getWindowName();
|
||||
|
||||
$this->assertNotNull($windowName);
|
||||
|
||||
$page->clickLink('Popup #1');
|
||||
$page->clickLink('Popup #2');
|
||||
|
||||
$windowNames = $this->getSession()->getWindowNames();
|
||||
|
||||
$this->assertNotNull($windowNames[0]);
|
||||
$this->assertNotNull($windowNames[1]);
|
||||
$this->assertNotNull($windowNames[2]);
|
||||
}
|
||||
|
||||
public function testResizeWindow()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
$session = $this->getSession();
|
||||
|
||||
$session->resizeWindow(400, 300);
|
||||
$session->wait(1000, 'false');
|
||||
|
||||
$script = "return Math.abs(window.outerHeight - 300) <= 100 && Math.abs(window.outerWidth - 400) <= 100;";
|
||||
|
||||
$this->assertTrue($session->evaluateScript($script));
|
||||
}
|
||||
|
||||
public function testWindowMaximize()
|
||||
{
|
||||
$this->getSession()->visit($this->pathTo('/index.html'));
|
||||
$session = $this->getSession();
|
||||
|
||||
$session->maximizeWindow();
|
||||
$session->wait(1000, 'false');
|
||||
|
||||
$script = "return Math.abs(screen.availHeight - window.outerHeight) <= 100;";
|
||||
|
||||
$this->assertTrue($session->evaluateScript($script));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
<?php
|
||||
|
||||
namespace Behat\Mink\Tests\Driver;
|
||||
|
||||
use Behat\Mink\Exception\UnsupportedDriverActionException;
|
||||
use Behat\Mink\Mink;
|
||||
use Behat\Mink\Session;
|
||||
use Behat\Mink\WebAssert;
|
||||
|
||||
abstract class TestCase extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Mink session manager.
|
||||
*
|
||||
* @var Mink
|
||||
*/
|
||||
private static $mink;
|
||||
|
||||
/**
|
||||
* @var AbstractConfig
|
||||
*/
|
||||
private static $config;
|
||||
|
||||
/**
|
||||
* Initializes the test case
|
||||
*/
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (null === self::$mink) {
|
||||
$session = new Session(self::getConfig()->createDriver());
|
||||
self::$mink = new Mink(array('sess' => $session));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AbstractConfig
|
||||
*
|
||||
* @throws \UnexpectedValueException if the global driver_config_factory returns an invalid object
|
||||
*/
|
||||
private static function getConfig()
|
||||
{
|
||||
if (null === self::$config) {
|
||||
self::$config = call_user_func($GLOBALS['driver_config_factory']);
|
||||
|
||||
if (!self::$config instanceof AbstractConfig) {
|
||||
throw new \UnexpectedValueException('The "driver_config_factory" global variable must return a \Behat\Mink\Tests\Driver\AbstractConfig.');
|
||||
}
|
||||
}
|
||||
|
||||
return self::$config;
|
||||
}
|
||||
|
||||
protected function checkRequirements()
|
||||
{
|
||||
if (null !== $message = self::getConfig()->skipMessage(get_class($this), $this->getName(false))) {
|
||||
$this->markTestSkipped($message);
|
||||
}
|
||||
|
||||
parent::checkRequirements();
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
if (null !== self::$mink) {
|
||||
self::$mink->resetSessions();
|
||||
}
|
||||
}
|
||||
|
||||
protected function onNotSuccessfulTest(\Exception $e)
|
||||
{
|
||||
if ($e instanceof UnsupportedDriverActionException) {
|
||||
$this->markTestSkipped($e->getMessage());
|
||||
}
|
||||
|
||||
parent::onNotSuccessfulTest($e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns session.
|
||||
*
|
||||
* @return Session
|
||||
*/
|
||||
protected function getSession()
|
||||
{
|
||||
return self::$mink->getSession('sess');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns assert session.
|
||||
*
|
||||
* @return WebAssert
|
||||
*/
|
||||
protected function getAssertSession()
|
||||
{
|
||||
return self::$mink->assertSession('sess');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement
|
||||
*/
|
||||
protected function findById($id)
|
||||
{
|
||||
$id = $this->getSession()->getSelectorsHandler()->xpathLiteral($id);
|
||||
|
||||
return $this->getAssertSession()->elementExists('named', array('id', $id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Map remote file path.
|
||||
*
|
||||
* @param string $file File path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function mapRemoteFilePath($file)
|
||||
{
|
||||
$realPath = realpath($file);
|
||||
|
||||
if (false !== $realPath) {
|
||||
$file = $realPath;
|
||||
}
|
||||
|
||||
return self::getConfig()->mapRemoteFilePath($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function pathTo($path)
|
||||
{
|
||||
return rtrim(self::getConfig()->getWebFixturesUrl(), '/').'/'.ltrim($path, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for a condition to be true, considering than it is successful for drivers not supporting wait()
|
||||
*
|
||||
* @param int $time
|
||||
* @param string $condition A JS condition to evaluate
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @see \Behat\Mink\Session::wait()
|
||||
*/
|
||||
protected function safePageWait($time, $condition)
|
||||
{
|
||||
try {
|
||||
return $this->getSession()->wait($time, $condition);
|
||||
} catch (UnsupportedDriverActionException $e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
<?php header("HTTP/1.0 404 Not Found") ?>
|
||||
Sorry, page not found
|
|
@ -0,0 +1,2 @@
|
|||
<?php header("HTTP/1.0 500 Server Error") ?>
|
||||
Sorry, a server error happened
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ADvanced Form</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ADvanced Form Page</h1>
|
||||
|
||||
<form method="POST" enctype="multipart/form-data" action="advanced_form_post.php">
|
||||
<input name="first_name" value="Firstname" type="text" />
|
||||
<input id="lastn" name="last_name" value="Lastname" type="text" />
|
||||
<label for="email">
|
||||
Your email:
|
||||
<input type="email" id="email" name="email" value="your@email.com" />
|
||||
</label>
|
||||
|
||||
<select name="select_number">
|
||||
<option value="10">ten</option>
|
||||
<option selected="selected" value="20">twenty</option>
|
||||
<option value="30">thirty</option>
|
||||
</select>
|
||||
|
||||
<label>
|
||||
<span><input type="radio" name="sex" value="m" /> m</span>
|
||||
<span><input type="radio" name="sex" value="w" checked="checked" /> w</span>
|
||||
</label>
|
||||
|
||||
<input type="checkbox" name="mail_list" checked="checked" value="on"/>
|
||||
<input type="checkbox" name="agreement" value="yes"/>
|
||||
|
||||
<textarea name="notes">original notes</textarea>
|
||||
|
||||
<input type="file" name="about" />
|
||||
|
||||
<input type="submit" name="submit" value="Register" />
|
||||
<input type="submit" name="submit" value="Login" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Advanced form save</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
error_reporting(0);
|
||||
|
||||
if (isset($_POST['select_multiple_numbers']) && false !== strpos($_POST['select_multiple_numbers'][0], ',')) {
|
||||
$_POST['select_multiple_numbers'] = explode(',', $_POST['select_multiple_numbers'][0]);
|
||||
}
|
||||
|
||||
$_POST['agreement'] = isset($_POST['agreement']) ? 'on' : 'off';
|
||||
ksort($_POST);
|
||||
echo str_replace('>', '', var_export($_POST, true)) . "\n";
|
||||
if (isset($_FILES['about']) && file_exists($_FILES['about']['tmp_name'])) {
|
||||
echo $_FILES['about']['name'] . "\n";
|
||||
echo file_get_contents($_FILES['about']['tmp_name']);
|
||||
} else {
|
||||
echo "no file";
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ARIA roles test</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
This page tests selected ARIA roles<br />
|
||||
(see <a href="http://www.w3.org/TR/wai-aria/">http://www.w3.org/TR/wai-aria/</a>)
|
||||
|
||||
<div id="hidden-element-toggle-button" role="button">Toggle</div>
|
||||
<div id="hidden-element" style="display:none;">This content's visibility is changed by clicking the Toggle Button.</div>
|
||||
|
||||
<!-- This link is created programmatically -->
|
||||
<div id="link-element"></div>
|
||||
|
||||
<script language="javascript" type="text/javascript" src="js/jquery-1.6.2-min.js"></script>
|
||||
<script language="javascript" type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('#hidden-element-toggle-button').click(function() {
|
||||
$('#hidden-element').toggle();
|
||||
});
|
||||
|
||||
$('#link-element').attr('role', 'link').text('Go to Index').click(function() {
|
||||
window.location.href = 'index.html';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
$username = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : false;
|
||||
$password = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : false;
|
||||
|
||||
if ($username == 'mink-user' && $password == 'mink-password') {
|
||||
echo 'is authenticated';
|
||||
} else {
|
||||
header('WWW-Authenticate: Basic realm="Mink Testing Area"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
|
||||
echo 'is not authenticated';
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Basic Form</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Basic Form Page</h1>
|
||||
|
||||
<form method="POST" action="basic_form_post.php">
|
||||
<input name="first_name" value="Firstname" type="text" />
|
||||
<input id="lastn" name="last_name" value="Lastname" type="text" />
|
||||
|
||||
<input type="reset" id="Reset" />
|
||||
|
||||
<input type="submit" id="Save" />
|
||||
<input type="image" id="input-type-image"/>
|
||||
<button>button-without-type</button>
|
||||
<button type="submit">button-type-submit</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Basic Form Saving</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Anket for <?php echo $_POST['first_name'] ?></h1>
|
||||
|
||||
<span id="first">Firstname: <?php echo $_POST['first_name'] ?></span>
|
||||
<span id="last">Lastname: <?php echo $_POST['last_name'] ?></span>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Basic Get Form</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Basic Get Form Page</h1>
|
||||
|
||||
<div id="serach">
|
||||
<?php echo isset($_GET['q']) && $_GET['q'] ? $_GET['q'] : 'No search query' ?>
|
||||
</div>
|
||||
|
||||
<form>
|
||||
<input name="q" value="" type="text" />
|
||||
|
||||
<input type="submit" value="Find" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
if (!isset($cookieAtRootPath)) {
|
||||
$cookieAtRootPath = true;
|
||||
}
|
||||
|
||||
if (!isset($cookieValue)) {
|
||||
$cookieValue = 'srv_var_is_set';
|
||||
}
|
||||
|
||||
setcookie('srvr_cookie', $cookieValue, null, $cookieAtRootPath ? '/' : null);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Basic Form</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Basic Page With Cookie Set from Server Side
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Basic Form</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Previous cookie: <?php echo isset($_COOKIE['srvr_cookie']) ? $_COOKIE['srvr_cookie'] : 'NO'; ?>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
$hasCookie = isset($_COOKIE['foo']);
|
||||
setcookie('foo', 'bar', 0, '/', null, false, true);
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>HttpOnly Cookie Test</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="cookie-status">Has Cookie: <?php echo json_encode($hasCookie) ?></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>CSS Mouse Events Testing</title>
|
||||
<style type="text/css">
|
||||
.squares div {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border: 1px solid black;
|
||||
margin-right: 4px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.squares div:hover {
|
||||
height: 200px;
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script language="javascript" type="text/javascript" src="js/jquery-1.6.2-min.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="squares">
|
||||
<div id="reset-square">reset</div>
|
||||
<div id="action-square">mouse action</div>
|
||||
</div>
|
||||
<script>
|
||||
$('#action-square').bind('contextmenu', function (e) {
|
||||
// Prevent opening the context menu on right click as the browser might consider the
|
||||
// mouse is in the context menu rather than hovering the element
|
||||
e.preventDefault();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
65
core/vendor/behat/mink/driver-testsuite/web-fixtures/element_change_detector.html
vendored
Normal file
65
core/vendor/behat/mink/driver-testsuite/web-fixtures/element_change_detector.html
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ADvanced Form</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
<script src="js/jquery-1.6.2-min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ADvanced Form Page</h1>
|
||||
|
||||
<form method="POST" enctype="multipart/form-data" action="advanced_form_post.php">
|
||||
<input id="the-input-default" value="" />
|
||||
<input type="text" id="the-input-text" value="" />
|
||||
<input type="email" id="the-email" value="" />
|
||||
|
||||
<select id="the-select">
|
||||
<option value="10">ten</option>
|
||||
<option value="20" selected="selected">twenty</option>
|
||||
<option value="30">thirty</option>
|
||||
</select>
|
||||
|
||||
<label>
|
||||
<span><input type="radio" name="sex" id="the-radio-m" value="m" /> m</span>
|
||||
<span><input type="radio" name="sex" id="the-radio-w" value="w" checked="checked" /> w</span>
|
||||
</label>
|
||||
|
||||
<input type="checkbox" id="the-checked-checkbox" value="cb-val" checked/>
|
||||
<input type="checkbox" id="the-unchecked-checkbox" value="cb-val"/>
|
||||
|
||||
<textarea id="the-textarea"></textarea>
|
||||
|
||||
<input type="file" id="the-file" />
|
||||
</form>
|
||||
|
||||
<ul id="results" style="border: 1px solid red;">
|
||||
<li>for easy element location</li>
|
||||
</ul>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
var $change_registry = {},
|
||||
$results = $('#results');
|
||||
|
||||
$(':input').change(function ($e) {
|
||||
var $result_id = this.id + '-result';
|
||||
|
||||
if (!$change_registry[this.id]) {
|
||||
$change_registry[this.id] = 1;
|
||||
$results.append('<li id="' + $result_id + '"></li>');
|
||||
}
|
||||
else {
|
||||
$change_registry[this.id]++;
|
||||
}
|
||||
|
||||
$('#' + $result_id).text($change_registry[this.id]);
|
||||
});
|
||||
|
||||
$results.click(function () {
|
||||
$results.empty();
|
||||
$change_registry = {};
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Empty textarea submission</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Empty textarea submission</h1>
|
||||
<form method="POST" action="advanced_form_post.php">
|
||||
<textarea name="textarea"></textarea>
|
||||
<input type="submit" name="submit" value="Save" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
13
core/vendor/behat/mink/driver-testsuite/web-fixtures/form_without_button.html
vendored
Normal file
13
core/vendor/behat/mink/driver-testsuite/web-fixtures/form_without_button.html
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Form submission without button test</title>
|
||||
</head>
|
||||
<body>
|
||||
<form action="basic_form_post.php" method="POST">
|
||||
<input name="first_name" type="text" value="not set">
|
||||
<input name="last_name" type="text" value="not set">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Headers page</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<?php print_r($_SERVER); ?>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>HTML5 form attribute test</title>
|
||||
</head>
|
||||
<body>
|
||||
<form action="advanced_form_post.php" method="POST" id="test-form">
|
||||
<input name="first_name" type="text" value="not set">
|
||||
<input name="other_field" type="text" value="not submitted" form="another">
|
||||
<input type="submit" value="Submit separate form" form="another">
|
||||
<input type="submit" value="Submit in form">
|
||||
</form>
|
||||
<input name="last_name" type="text" form="test-form" value="not set">
|
||||
<button type="submit" form="test-form" name="submit_button" value="test">Submit outside form</button>
|
||||
<form id="another" method="post" action="advanced_form_post.php"></form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>HTML5 form attribute test</title>
|
||||
</head>
|
||||
<body>
|
||||
<form action="advanced_form_post.php" method="POST" id="test-form">
|
||||
<input name="sex" type="radio" value="m" id="sex_m">
|
||||
<input name="sex" type="radio" value="invalid" form="another" id="sex_invalid" checked="checked">
|
||||
<input type="submit" value="Submit in form">
|
||||
</form>
|
||||
<input name="sex" type="radio" form="test-form" value="f" id="sex_f" checked="checked">
|
||||
<form id="another" method="post" action="advanced_form_post.php"></form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>HTML5 form attribute test</title>
|
||||
</head>
|
||||
<body>
|
||||
<form action="advanced_form_post.php" method="POST">
|
||||
<input name="url" type="url">
|
||||
<input name="email" type="email">
|
||||
<input name="number" type="number">
|
||||
<input name="search" type="search">
|
||||
<input name="color" type="color">
|
||||
<input name="date" type="date">
|
||||
<input type="submit" name="submit_button" value="Submit">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>HTML Decoding Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<span custom-attr="&">some text</span>
|
||||
|
||||
<form method="post" action="index.html">
|
||||
<input value="&"/>
|
||||
|
||||
<input type="submit" value="Send"/>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<iframe src="iframe_inner.html" name="subframe"></iframe>
|
||||
|
||||
<div id="text">
|
||||
Main window div text
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<div id="text">
|
||||
iFrame div text
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,51 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Index page</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Extremely useless page</h1>
|
||||
<div id="core">
|
||||
<strong>Lorem</strong> ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim <strong>veniam</strong>, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla <strong class="super-duper">pariatur</strong>. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
|
||||
<div id="some-element" data-href="http://mink.behat.org">
|
||||
some <div>very
|
||||
</div>
|
||||
<em>interesting</em> text
|
||||
</div>
|
||||
|
||||
<div class="attribute-testing">
|
||||
<input type="text" id="attr-elem[with-value]" with-value="some-value"/>
|
||||
<input type="text" id="attr-elem[without-value]" without-value/>
|
||||
<input type="text" id="attr-elem[with-empty-value]" with-empty-value=""/>
|
||||
<input type="text" id="attr-elem[with-missing]"/>
|
||||
</div>
|
||||
|
||||
<div class="travers">
|
||||
<div class="sub">el1</div>
|
||||
<div class="sub">el2</div>
|
||||
<div class="sub">
|
||||
<a href="some_url">some <strong>deep</strong> url</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sub">el4</div>
|
||||
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<form id="search-form">
|
||||
<input type="text" placeholder="Search site..." />
|
||||
</form>
|
||||
<form id="profile">
|
||||
<div data-custom="something">
|
||||
<label>
|
||||
<input type="text" id="user-name" name="username" />
|
||||
</label>
|
||||
</div>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue