Move into nested docroot

This commit is contained in:
Rob Davies 2017-02-13 15:31:17 +00:00
parent 83a0d3a149
commit c8b70abde9
13405 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,475 @@
<?php
/*
* This file is part of the Mink package.
* (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\UnsupportedDriverActionException;
use Behat\Mink\Session;
/**
* Core driver.
* All other drivers should extend this class for future compatibility.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
abstract class CoreDriver implements DriverInterface
{
/**
* @var Session
*/
private $session;
/**
* {@inheritdoc}
*/
public function setSession(Session $session)
{
$this->session = $session;
}
/**
* {@inheritdoc}
*/
public function start()
{
throw new UnsupportedDriverActionException('Starting the driver is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function isStarted()
{
throw new UnsupportedDriverActionException('Checking the driver state is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function stop()
{
throw new UnsupportedDriverActionException('Stopping the driver is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function reset()
{
throw new UnsupportedDriverActionException('Resetting the driver is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function visit($url)
{
throw new UnsupportedDriverActionException('Visiting an url is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function getCurrentUrl()
{
throw new UnsupportedDriverActionException('Getting the current url is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function getContent()
{
throw new UnsupportedDriverActionException('Getting the page content is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function find($xpath)
{
$elements = array();
foreach ($this->findElementXpaths($xpath) as $xpath) {
$elements[] = new NodeElement($xpath, $this->session);
}
return $elements;
}
/**
* Finds elements with specified XPath query.
*
* @see find()
*
* @param string $xpath
*
* @return string[] The XPath of the matched elements
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
*/
protected function findElementXpaths($xpath)
{
throw new UnsupportedDriverActionException('Finding elements is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function getTagName($xpath)
{
throw new UnsupportedDriverActionException('Getting the tag name is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function getText($xpath)
{
throw new UnsupportedDriverActionException('Getting the element text is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function getHtml($xpath)
{
throw new UnsupportedDriverActionException('Getting the element inner HTML is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function getOuterHtml($xpath)
{
throw new UnsupportedDriverActionException('Getting the element outer HTML is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function getAttribute($xpath, $name)
{
throw new UnsupportedDriverActionException('Getting the element attribute is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function getValue($xpath)
{
throw new UnsupportedDriverActionException('Getting the field value is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function setValue($xpath, $value)
{
throw new UnsupportedDriverActionException('Setting the field value is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function check($xpath)
{
throw new UnsupportedDriverActionException('Checking a checkbox is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function uncheck($xpath)
{
throw new UnsupportedDriverActionException('Unchecking a checkbox is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function isChecked($xpath)
{
throw new UnsupportedDriverActionException('Getting the state of a checkbox is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function selectOption($xpath, $value, $multiple = false)
{
throw new UnsupportedDriverActionException('Selecting an option is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function click($xpath)
{
throw new UnsupportedDriverActionException('Clicking on an element is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function attachFile($xpath, $path)
{
throw new UnsupportedDriverActionException('Attaching a file in an input is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function reload()
{
throw new UnsupportedDriverActionException('Page reloading is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function forward()
{
throw new UnsupportedDriverActionException('Forward action is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function back()
{
throw new UnsupportedDriverActionException('Backward action is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function setBasicAuth($user, $password)
{
throw new UnsupportedDriverActionException('Basic auth setup is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function switchToWindow($name = null)
{
throw new UnsupportedDriverActionException('Windows management is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function switchToIFrame($name = null)
{
throw new UnsupportedDriverActionException('iFrames management is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function setRequestHeader($name, $value)
{
throw new UnsupportedDriverActionException('Request headers manipulation is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function getResponseHeaders()
{
throw new UnsupportedDriverActionException('Response headers are not available from %s', $this);
}
/**
* {@inheritdoc}
*/
public function setCookie($name, $value = null)
{
throw new UnsupportedDriverActionException('Cookies manipulation is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function getCookie($name)
{
throw new UnsupportedDriverActionException('Cookies are not available from %s', $this);
}
/**
* {@inheritdoc}
*/
public function getStatusCode()
{
throw new UnsupportedDriverActionException('Status code is not available from %s', $this);
}
/**
* {@inheritdoc}
*/
public function getScreenshot()
{
throw new UnsupportedDriverActionException('Screenshots are not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function getWindowNames()
{
throw new UnsupportedDriverActionException('Listing all window names is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function getWindowName()
{
throw new UnsupportedDriverActionException('Listing this window name is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function doubleClick($xpath)
{
throw new UnsupportedDriverActionException('Double-clicking is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function rightClick($xpath)
{
throw new UnsupportedDriverActionException('Right-clicking is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function isVisible($xpath)
{
throw new UnsupportedDriverActionException('Element visibility check is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function isSelected($xpath)
{
throw new UnsupportedDriverActionException('Element selection check is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function mouseOver($xpath)
{
throw new UnsupportedDriverActionException('Mouse manipulations are not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function focus($xpath)
{
throw new UnsupportedDriverActionException('Mouse manipulations are not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function blur($xpath)
{
throw new UnsupportedDriverActionException('Mouse manipulations are not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function keyPress($xpath, $char, $modifier = null)
{
throw new UnsupportedDriverActionException('Keyboard manipulations are not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function keyDown($xpath, $char, $modifier = null)
{
throw new UnsupportedDriverActionException('Keyboard manipulations are not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function keyUp($xpath, $char, $modifier = null)
{
throw new UnsupportedDriverActionException('Keyboard manipulations are not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function dragTo($sourceXpath, $destinationXpath)
{
throw new UnsupportedDriverActionException('Mouse manipulations are not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function executeScript($script)
{
throw new UnsupportedDriverActionException('JS is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function evaluateScript($script)
{
throw new UnsupportedDriverActionException('JS is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function wait($timeout, $condition)
{
throw new UnsupportedDriverActionException('JS is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function resizeWindow($width, $height, $name = null)
{
throw new UnsupportedDriverActionException('Window resizing is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function maximizeWindow($name = null)
{
throw new UnsupportedDriverActionException('Window maximize is not supported by %s', $this);
}
/**
* {@inheritdoc}
*/
public function submitForm($xpath)
{
throw new UnsupportedDriverActionException('Form submission is not supported by %s', $this);
}
}

View file

@ -0,0 +1,637 @@
<?php
/*
* This file is part of the Mink package.
* (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;
/**
* Driver interface.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
interface DriverInterface
{
/**
* Sets driver's current session.
*
* @param Session $session
*/
public function setSession(Session $session);
/**
* Starts driver.
*
* Once started, the driver should be ready to visit a page.
*
* Calling any action before visiting a page is an undefined behavior.
* The only supported method calls on a fresh driver are
* - visit()
* - setRequestHeader()
* - setBasicAuth()
* - reset()
* - stop()
*
* Calling start on a started driver is an undefined behavior. Driver
* implementations are free to handle it silently or to fail with an
* exception.
*
* @throws DriverException When the driver cannot be started
*/
public function start();
/**
* Checks whether driver is started.
*
* @return Boolean
*/
public function isStarted();
/**
* Stops driver.
*
* Once stopped, the driver should be started again before using it again.
*
* Calling any action on a stopped driver is an undefined behavior.
* The only supported method call after stopping a driver is starting it again.
*
* Calling stop on a stopped driver is an undefined behavior. Driver
* implementations are free to handle it silently or to fail with an
* exception.
*
* @throws DriverException When the driver cannot be closed
*/
public function stop();
/**
* Resets driver state.
*
* This should reset cookies, request headers and basic authentication.
* When possible, the history should be reset as well, but this is not enforced
* as some implementations may not be able to reset it without restarting the
* driver entirely. Consumers requiring a clean history should restart the driver
* to enforce it.
*
* Once reset, the driver should be ready to visit a page.
* Calling any action before visiting a page is an undefined behavior.
* The only supported method calls on a fresh driver are
* - visit()
* - setRequestHeader()
* - setBasicAuth()
* - reset()
* - stop()
*
* Calling reset on a stopped driver is an undefined behavior.
*/
public function reset();
/**
* Visit specified URL.
*
* @param string $url url of the page
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function visit($url);
/**
* Returns current URL address.
*
* @return string
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function getCurrentUrl();
/**
* Reloads current page.
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function reload();
/**
* Moves browser forward 1 page.
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function forward();
/**
* Moves browser backward 1 page.
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function back();
/**
* Sets HTTP Basic authentication parameters.
*
* @param string|Boolean $user user name or false to disable authentication
* @param string $password password
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function setBasicAuth($user, $password);
/**
* Switches to specific browser window.
*
* @param string $name window name (null for switching back to main window)
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function switchToWindow($name = null);
/**
* Switches to specific iFrame.
*
* @param string $name iframe name (null for switching back)
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function switchToIFrame($name = null);
/**
* Sets specific request header on client.
*
* @param string $name
* @param string $value
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function setRequestHeader($name, $value);
/**
* Returns last response headers.
*
* @return array
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function getResponseHeaders();
/**
* Sets cookie.
*
* @param string $name
* @param string $value
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function setCookie($name, $value = null);
/**
* Returns cookie by name.
*
* @param string $name
*
* @return string|null
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function getCookie($name);
/**
* Returns last response status code.
*
* @return int
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function getStatusCode();
/**
* Returns last response content.
*
* @return string
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function getContent();
/**
* Capture a screenshot of the current window.
*
* @return string screenshot of MIME type image/* depending
* on driver (e.g., image/png, image/jpeg)
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function getScreenshot();
/**
* Return the names of all open windows.
*
* @return array array of all open windows
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function getWindowNames();
/**
* Return the name of the currently active window.
*
* @return string the name of the current window
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function getWindowName();
/**
* Finds elements with specified XPath query.
*
* @param string $xpath
*
* @return NodeElement[]
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function find($xpath);
/**
* Returns element's tag name by it's XPath query.
*
* @param string $xpath
*
* @return string
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function getTagName($xpath);
/**
* Returns element's text by it's XPath query.
*
* @param string $xpath
*
* @return string
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function getText($xpath);
/**
* Returns element's inner html by it's XPath query.
*
* @param string $xpath
*
* @return string
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function getHtml($xpath);
/**
* Returns element's outer html by it's XPath query.
*
* @param string $xpath
*
* @return string
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function getOuterHtml($xpath);
/**
* Returns element's attribute by it's XPath query.
*
* @param string $xpath
* @param string $name
*
* @return string|null
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function getAttribute($xpath, $name);
/**
* Returns element's value by it's XPath query.
*
* @param string $xpath
*
* @return string|bool|array
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*
* @see \Behat\Mink\Element\NodeElement::getValue
*/
public function getValue($xpath);
/**
* Sets element's value by it's XPath query.
*
* @param string $xpath
* @param string|bool|array $value
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*
* @see \Behat\Mink\Element\NodeElement::setValue
*/
public function setValue($xpath, $value);
/**
* Checks checkbox by it's XPath query.
*
* @param string $xpath
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*
* @see \Behat\Mink\Element\NodeElement::check
*/
public function check($xpath);
/**
* Unchecks checkbox by it's XPath query.
*
* @param string $xpath
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*
* @see \Behat\Mink\Element\NodeElement::uncheck
*/
public function uncheck($xpath);
/**
* Checks whether checkbox or radio button located by it's XPath query is checked.
*
* @param string $xpath
*
* @return Boolean
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*
* @see \Behat\Mink\Element\NodeElement::isChecked
*/
public function isChecked($xpath);
/**
* Selects option from select field or value in radio group located by it's XPath query.
*
* @param string $xpath
* @param string $value
* @param Boolean $multiple
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*
* @see \Behat\Mink\Element\NodeElement::selectOption
*/
public function selectOption($xpath, $value, $multiple = false);
/**
* Checks whether select option, located by it's XPath query, is selected.
*
* @param string $xpath
*
* @return Boolean
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*
* @see \Behat\Mink\Element\NodeElement::isSelected
*/
public function isSelected($xpath);
/**
* Clicks button or link located by it's XPath query.
*
* @param string $xpath
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function click($xpath);
/**
* Double-clicks button or link located by it's XPath query.
*
* @param string $xpath
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function doubleClick($xpath);
/**
* Right-clicks button or link located by it's XPath query.
*
* @param string $xpath
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function rightClick($xpath);
/**
* Attaches file path to file field located by it's XPath query.
*
* @param string $xpath
* @param string $path
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*
* @see \Behat\Mink\Element\NodeElement::attachFile
*/
public function attachFile($xpath, $path);
/**
* Checks whether element visible located by it's XPath query.
*
* @param string $xpath
*
* @return Boolean
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function isVisible($xpath);
/**
* Simulates a mouse over on the element.
*
* @param string $xpath
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function mouseOver($xpath);
/**
* Brings focus to element.
*
* @param string $xpath
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function focus($xpath);
/**
* Removes focus from element.
*
* @param string $xpath
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function blur($xpath);
/**
* Presses specific keyboard key.
*
* @param string $xpath
* @param string|int $char could be either char ('b') or char-code (98)
* @param string $modifier keyboard modifier (could be 'ctrl', 'alt', 'shift' or 'meta')
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function keyPress($xpath, $char, $modifier = null);
/**
* Pressed down specific keyboard key.
*
* @param string $xpath
* @param string|int $char could be either char ('b') or char-code (98)
* @param string $modifier keyboard modifier (could be 'ctrl', 'alt', 'shift' or 'meta')
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function keyDown($xpath, $char, $modifier = null);
/**
* Pressed up specific keyboard key.
*
* @param string $xpath
* @param string|int $char could be either char ('b') or char-code (98)
* @param string $modifier keyboard modifier (could be 'ctrl', 'alt', 'shift' or 'meta')
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function keyUp($xpath, $char, $modifier = null);
/**
* Drag one element onto another.
*
* @param string $sourceXpath
* @param string $destinationXpath
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function dragTo($sourceXpath, $destinationXpath);
/**
* Executes JS script.
*
* @param string $script
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function executeScript($script);
/**
* Evaluates JS script.
*
* The "return" keyword is optional in the script passed as argument. Driver implementations
* must accept the expression both with and without the keyword.
*
* @param string $script
*
* @return mixed
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function evaluateScript($script);
/**
* Waits some time or until JS condition turns true.
*
* @param int $timeout timeout in milliseconds
* @param string $condition JS condition
*
* @return bool
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function wait($timeout, $condition);
/**
* Set the dimensions of the window.
*
* @param int $width set the window width, measured in pixels
* @param int $height set the window height, measured in pixels
* @param string $name window name (null for the main window)
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function resizeWindow($width, $height, $name = null);
/**
* Maximizes the window if it is not maximized already.
*
* @param string $name window name (null for the main window)
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*/
public function maximizeWindow($name = null);
/**
* Submits the form.
*
* @param string $xpath Xpath.
*
* @throws UnsupportedDriverActionException When operation not supported by the driver
* @throws DriverException When the operation cannot be done
*
* @see \Behat\Mink\Element\NodeElement::submitForm
*/
public function submitForm($xpath);
}

View file

@ -0,0 +1,51 @@
<?php
/*
* This file is part of the Mink package.
* (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\Element;
/**
* Document element.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class DocumentElement extends TraversableElement
{
/**
* Returns XPath for handled element.
*
* @return string
*/
public function getXpath()
{
return '//html';
}
/**
* Returns document content.
*
* @return string
*/
public function getContent()
{
return trim($this->getDriver()->getContent());
}
/**
* Check whether document has specified content.
*
* @param string $content
*
* @return Boolean
*/
public function hasContent($content)
{
return $this->has('named', array('content', $content));
}
}

View file

@ -0,0 +1,214 @@
<?php
/*
* This file is part of the Mink package.
* (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\Element;
use Behat\Mink\Driver\DriverInterface;
use Behat\Mink\Exception\ElementNotFoundException;
use Behat\Mink\Selector\SelectorsHandler;
use Behat\Mink\Selector\Xpath\Manipulator;
use Behat\Mink\Session;
/**
* Base element.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
abstract class Element implements ElementInterface
{
/**
* @var Session
*/
private $session;
/**
* Driver.
*
* @var DriverInterface
*/
private $driver;
/**
* @var SelectorsHandler
*/
private $selectorsHandler;
/**
* @var Manipulator
*/
private $xpathManipulator;
/**
* Initialize element.
*
* @param Session $session
*/
public function __construct(Session $session)
{
$this->xpathManipulator = new Manipulator();
$this->session = $session;
$this->driver = $session->getDriver();
$this->selectorsHandler = $session->getSelectorsHandler();
}
/**
* Returns element session.
*
* @return Session
*
* @deprecated Accessing the session from the element is deprecated as of 1.6 and will be impossible in 2.0.
*/
public function getSession()
{
@trigger_error(sprintf('The method %s is deprecated as of 1.6 and will be removed in 2.0', __METHOD__), E_USER_DEPRECATED);
return $this->session;
}
/**
* Returns element's driver.
*
* @return DriverInterface
*/
protected function getDriver()
{
return $this->driver;
}
/**
* Returns selectors handler.
*
* @return SelectorsHandler
*
* @deprecated Accessing the selectors handler in the element is deprecated as of 1.7 and will be impossible in 2.0.
*/
protected function getSelectorsHandler()
{
@trigger_error(sprintf('The method %s is deprecated as of 1.7 and will be removed in 2.0', __METHOD__), E_USER_DEPRECATED);
return $this->selectorsHandler;
}
/**
* {@inheritdoc}
*/
public function has($selector, $locator)
{
return null !== $this->find($selector, $locator);
}
/**
* {@inheritdoc}
*/
public function isValid()
{
return 1 === count($this->getDriver()->find($this->getXpath()));
}
/**
* {@inheritdoc}
*/
public function waitFor($timeout, $callback)
{
if (!is_callable($callback)) {
throw new \InvalidArgumentException('Given callback is not a valid callable');
}
$start = microtime(true);
$end = $start + $timeout;
do {
$result = call_user_func($callback, $this);
if ($result) {
break;
}
usleep(100000);
} while (microtime(true) < $end);
return $result;
}
/**
* {@inheritdoc}
*/
public function find($selector, $locator)
{
$items = $this->findAll($selector, $locator);
return count($items) ? current($items) : null;
}
/**
* {@inheritdoc}
*/
public function findAll($selector, $locator)
{
if ('named' === $selector) {
$items = $this->findAll('named_exact', $locator);
if (empty($items)) {
$items = $this->findAll('named_partial', $locator);
}
return $items;
}
$xpath = $this->selectorsHandler->selectorToXpath($selector, $locator);
$xpath = $this->xpathManipulator->prepend($xpath, $this->getXpath());
return $this->getDriver()->find($xpath);
}
/**
* {@inheritdoc}
*/
public function getText()
{
return $this->getDriver()->getText($this->getXpath());
}
/**
* {@inheritdoc}
*/
public function getHtml()
{
return $this->getDriver()->getHtml($this->getXpath());
}
/**
* Returns element outer html.
*
* @return string
*/
public function getOuterHtml()
{
return $this->getDriver()->getOuterHtml($this->getXpath());
}
/**
* Builds an ElementNotFoundException.
*
* @param string $type
* @param string|null $selector
* @param string|null $locator
*
* @return ElementNotFoundException
*
* @deprecated as of 1.7, to be removed in 2.0
*/
protected function elementNotFound($type, $selector = null, $locator = null)
{
@trigger_error(sprintf('The method %s is deprecated as of 1.7 and will be removed in 2.0', __METHOD__), E_USER_DEPRECATED);
return new ElementNotFoundException($this->driver, $type, $selector, $locator);
}
}

View file

@ -0,0 +1,115 @@
<?php
/*
* This file is part of the Mink package.
* (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\Element;
use Behat\Mink\Session;
/**
* Element interface.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
interface ElementInterface
{
/**
* Returns XPath for handled element.
*
* @return string
*/
public function getXpath();
/**
* Returns element's session.
*
* @return Session
*
* @deprecated Accessing the session from the element is deprecated as of 1.6 and will be impossible in 2.0.
*/
public function getSession();
/**
* Checks whether element with specified selector exists inside the current element.
*
* @param string $selector selector engine name
* @param string|array $locator selector locator
*
* @return Boolean
*
* @see ElementInterface::findAll for the supported selectors
*/
public function has($selector, $locator);
/**
* Checks if an element still exists in the DOM.
*
* @return bool
*/
public function isValid();
/**
* Waits for an element(-s) to appear and returns it.
*
* @param int|float $timeout Maximal allowed waiting time in seconds.
* @param callable $callback Callback, which result is both used as waiting condition and returned.
* Will receive reference to `this element` as first argument.
*
* @return mixed
*
* @throws \InvalidArgumentException When invalid callback given.
*/
public function waitFor($timeout, $callback);
/**
* Finds first element with specified selector inside the current element.
*
* @param string $selector selector engine name
* @param string|array $locator selector locator
*
* @return NodeElement|null
*
* @see ElementInterface::findAll for the supported selectors
*/
public function find($selector, $locator);
/**
* Finds all elements with specified selector inside the current element.
*
* Valid selector engines are named, xpath, css, named_partial and named_exact.
*
* 'named' is a pseudo selector engine which prefers an exact match but
* will return a partial match if no exact match is found.
* 'xpath' is a pseudo selector engine supported by SelectorsHandler.
*
* More selector engines can be registered in the SelectorsHandler.
*
* @param string $selector selector engine name
* @param string|array $locator selector locator
*
* @return NodeElement[]
*
* @see NamedSelector for the locators supported by the named selectors
*/
public function findAll($selector, $locator);
/**
* Returns element text (inside tag).
*
* @return string
*/
public function getText();
/**
* Returns element inner html.
*
* @return string
*/
public function getHtml();
}

View file

@ -0,0 +1,350 @@
<?php
/*
* This file is part of the Mink package.
* (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\Element;
use Behat\Mink\Session;
use Behat\Mink\Exception\ElementNotFoundException;
/**
* Page element node.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class NodeElement extends TraversableElement
{
private $xpath;
/**
* Initializes node element.
*
* @param string $xpath element xpath
* @param Session $session session instance
*/
public function __construct($xpath, Session $session)
{
$this->xpath = $xpath;
parent::__construct($session);
}
/**
* Returns XPath for handled element.
*
* @return string
*/
public function getXpath()
{
return $this->xpath;
}
/**
* Returns parent element to the current one.
*
* @return NodeElement
*/
public function getParent()
{
return $this->find('xpath', '..');
}
/**
* Returns current node tag name.
*
* The value is always returned in lowercase to allow an easy comparison.
*
* @return string
*/
public function getTagName()
{
return strtolower($this->getDriver()->getTagName($this->getXpath()));
}
/**
* Returns the value of the form field or option element.
*
* For checkbox fields, the value is a boolean indicating whether the checkbox is checked.
* For radio buttons, the value is the value of the selected button in the radio group
* or null if no button is selected.
* For single select boxes, the value is the value of the selected option.
* For multiple select boxes, the value is an array of selected option values.
* for file inputs, the return value is undefined given that browsers don't allow accessing
* the value of file inputs for security reasons. Some drivers may allow accessing the
* path of the file set in the field, but this is not required if it cannot be implemented.
* For textarea elements and all textual fields, the value is the content of the field.
* Form option elements, the value is the value of the option (the value attribute or the text
* content if the attribute is not set).
*
* Calling this method on other elements than form fields or option elements is not allowed.
*
* @return string|bool|array
*/
public function getValue()
{
return $this->getDriver()->getValue($this->getXpath());
}
/**
* Sets the value of the form field.
*
* Calling this method on other elements than form fields is not allowed.
*
* @param string|bool|array $value
*
* @see NodeElement::getValue for the format of the value for each type of field
*/
public function setValue($value)
{
$this->getDriver()->setValue($this->getXpath(), $value);
}
/**
* Checks whether element has attribute with specified name.
*
* @param string $name
*
* @return Boolean
*/
public function hasAttribute($name)
{
return null !== $this->getDriver()->getAttribute($this->getXpath(), $name);
}
/**
* Returns specified attribute value.
*
* @param string $name
*
* @return string|null
*/
public function getAttribute($name)
{
return $this->getDriver()->getAttribute($this->getXpath(), $name);
}
/**
* Checks whether an element has a named CSS class.
*
* @param string $className Name of the class
*
* @return bool
*/
public function hasClass($className)
{
if ($this->hasAttribute('class')) {
return in_array($className, preg_split('/\s+/', $this->getAttribute('class')));
}
return false;
}
/**
* Clicks current node.
*/
public function click()
{
$this->getDriver()->click($this->getXpath());
}
/**
* Presses current button.
*/
public function press()
{
$this->click();
}
/**
* Double-clicks current node.
*/
public function doubleClick()
{
$this->getDriver()->doubleClick($this->getXpath());
}
/**
* Right-clicks current node.
*/
public function rightClick()
{
$this->getDriver()->rightClick($this->getXpath());
}
/**
* Checks current node if it's a checkbox field.
*/
public function check()
{
$this->getDriver()->check($this->getXpath());
}
/**
* Unchecks current node if it's a checkbox field.
*/
public function uncheck()
{
$this->getDriver()->uncheck($this->getXpath());
}
/**
* Checks whether current node is checked if it's a checkbox or radio field.
*
* Calling this method on any other elements is not allowed.
*
* @return Boolean
*/
public function isChecked()
{
return (Boolean) $this->getDriver()->isChecked($this->getXpath());
}
/**
* Selects specified option for select field or specified radio button in the group.
*
* If the current node is a select box, this selects the option found by its value or
* its text.
* If the current node is a radio button, this selects the radio button with the given
* value in the radio button group of the current node.
*
* Calling this method on any other elements is not allowed.
*
* @param string $option
* @param Boolean $multiple whether the option should be added to the selection for multiple selects
*
* @throws ElementNotFoundException when the option is not found in the select box
*/
public function selectOption($option, $multiple = false)
{
if ('select' !== $this->getTagName()) {
$this->getDriver()->selectOption($this->getXpath(), $option, $multiple);
return;
}
$opt = $this->find('named', array('option', $option));
if (null === $opt) {
throw new ElementNotFoundException($this->getDriver(), 'select option', 'value|text', $option);
}
$this->getDriver()->selectOption($this->getXpath(), $opt->getValue(), $multiple);
}
/**
* Checks whether current node is selected if it's a option field.
*
* Calling this method on any other elements is not allowed.
*
* @return Boolean
*/
public function isSelected()
{
return (Boolean) $this->getDriver()->isSelected($this->getXpath());
}
/**
* Attach file to current node if it's a file input.
*
* Calling this method on any other elements than file input is not allowed.
*
* @param string $path path to file (local)
*/
public function attachFile($path)
{
$this->getDriver()->attachFile($this->getXpath(), $path);
}
/**
* Checks whether current node is visible on page.
*
* @return Boolean
*/
public function isVisible()
{
return (Boolean) $this->getDriver()->isVisible($this->getXpath());
}
/**
* Simulates a mouse over on the element.
*/
public function mouseOver()
{
$this->getDriver()->mouseOver($this->getXpath());
}
/**
* Drags current node onto other node.
*
* @param ElementInterface $destination other node
*/
public function dragTo(ElementInterface $destination)
{
$this->getDriver()->dragTo($this->getXpath(), $destination->getXpath());
}
/**
* Brings focus to element.
*/
public function focus()
{
$this->getDriver()->focus($this->getXpath());
}
/**
* Removes focus from element.
*/
public function blur()
{
$this->getDriver()->blur($this->getXpath());
}
/**
* Presses specific keyboard key.
*
* @param string|int $char could be either char ('b') or char-code (98)
* @param string $modifier keyboard modifier (could be 'ctrl', 'alt', 'shift' or 'meta')
*/
public function keyPress($char, $modifier = null)
{
$this->getDriver()->keyPress($this->getXpath(), $char, $modifier);
}
/**
* Pressed down specific keyboard key.
*
* @param string|int $char could be either char ('b') or char-code (98)
* @param string $modifier keyboard modifier (could be 'ctrl', 'alt', 'shift' or 'meta')
*/
public function keyDown($char, $modifier = null)
{
$this->getDriver()->keyDown($this->getXpath(), $char, $modifier);
}
/**
* Pressed up specific keyboard key.
*
* @param string|int $char could be either char ('b') or char-code (98)
* @param string $modifier keyboard modifier (could be 'ctrl', 'alt', 'shift' or 'meta')
*/
public function keyUp($char, $modifier = null)
{
$this->getDriver()->keyUp($this->getXpath(), $char, $modifier);
}
/**
* Submits the form.
*
* Calling this method on anything else than form elements is not allowed.
*/
public function submit()
{
$this->getDriver()->submitForm($this->getXpath());
}
}

View file

@ -0,0 +1,297 @@
<?php
/*
* This file is part of the Mink package.
* (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\Element;
use Behat\Mink\Exception\ElementNotFoundException;
/**
* Traversable element.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
abstract class TraversableElement extends Element
{
/**
* Finds element by its id.
*
* @param string $id element id
*
* @return NodeElement|null
*/
public function findById($id)
{
return $this->find('named', array('id', $id));
}
/**
* Checks whether element has a link with specified locator.
*
* @param string $locator link id, title, text or image alt
*
* @return Boolean
*/
public function hasLink($locator)
{
return null !== $this->findLink($locator);
}
/**
* Finds link with specified locator.
*
* @param string $locator link id, title, text or image alt
*
* @return NodeElement|null
*/
public function findLink($locator)
{
return $this->find('named', array('link', $locator));
}
/**
* Clicks link with specified locator.
*
* @param string $locator link id, title, text or image alt
*
* @throws ElementNotFoundException
*/
public function clickLink($locator)
{
$link = $this->findLink($locator);
if (null === $link) {
throw new ElementNotFoundException($this->getDriver(), 'link', 'id|title|alt|text', $locator);
}
$link->click();
}
/**
* Checks whether element has a button (input[type=submit|image|button|reset], button) with specified locator.
*
* @param string $locator button id, value or alt
*
* @return Boolean
*/
public function hasButton($locator)
{
return null !== $this->findButton($locator);
}
/**
* Finds button (input[type=submit|image|button|reset], button) with specified locator.
*
* @param string $locator button id, value or alt
*
* @return NodeElement|null
*/
public function findButton($locator)
{
return $this->find('named', array('button', $locator));
}
/**
* Presses button (input[type=submit|image|button|reset], button) with specified locator.
*
* @param string $locator button id, value or alt
*
* @throws ElementNotFoundException
*/
public function pressButton($locator)
{
$button = $this->findButton($locator);
if (null === $button) {
throw new ElementNotFoundException($this->getDriver(), 'button', 'id|name|title|alt|value', $locator);
}
$button->press();
}
/**
* Checks whether element has a field (input, textarea, select) with specified locator.
*
* @param string $locator input id, name or label
*
* @return Boolean
*/
public function hasField($locator)
{
return null !== $this->findField($locator);
}
/**
* Finds field (input, textarea, select) with specified locator.
*
* @param string $locator input id, name or label
*
* @return NodeElement|null
*/
public function findField($locator)
{
return $this->find('named', array('field', $locator));
}
/**
* Fills in field (input, textarea, select) with specified locator.
*
* @param string $locator input id, name or label
* @param string $value value
*
* @throws ElementNotFoundException
*
* @see NodeElement::setValue
*/
public function fillField($locator, $value)
{
$field = $this->findField($locator);
if (null === $field) {
throw new ElementNotFoundException($this->getDriver(), 'form field', 'id|name|label|value|placeholder', $locator);
}
$field->setValue($value);
}
/**
* Checks whether element has a checkbox with specified locator, which is checked.
*
* @param string $locator input id, name or label
*
* @return Boolean
*
* @see NodeElement::isChecked
*/
public function hasCheckedField($locator)
{
$field = $this->findField($locator);
return null !== $field && $field->isChecked();
}
/**
* Checks whether element has a checkbox with specified locator, which is unchecked.
*
* @param string $locator input id, name or label
*
* @return Boolean
*
* @see NodeElement::isChecked
*/
public function hasUncheckedField($locator)
{
$field = $this->findField($locator);
return null !== $field && !$field->isChecked();
}
/**
* Checks checkbox with specified locator.
*
* @param string $locator input id, name or label
*
* @throws ElementNotFoundException
*/
public function checkField($locator)
{
$field = $this->findField($locator);
if (null === $field) {
throw new ElementNotFoundException($this->getDriver(), 'form field', 'id|name|label|value', $locator);
}
$field->check();
}
/**
* Unchecks checkbox with specified locator.
*
* @param string $locator input id, name or label
*
* @throws ElementNotFoundException
*/
public function uncheckField($locator)
{
$field = $this->findField($locator);
if (null === $field) {
throw new ElementNotFoundException($this->getDriver(), 'form field', 'id|name|label|value', $locator);
}
$field->uncheck();
}
/**
* Checks whether element has a select field with specified locator.
*
* @param string $locator select id, name or label
*
* @return Boolean
*/
public function hasSelect($locator)
{
return $this->has('named', array('select', $locator));
}
/**
* Selects option from select field with specified locator.
*
* @param string $locator input id, name or label
* @param string $value option value
* @param Boolean $multiple select multiple options
*
* @throws ElementNotFoundException
*
* @see NodeElement::selectOption
*/
public function selectFieldOption($locator, $value, $multiple = false)
{
$field = $this->findField($locator);
if (null === $field) {
throw new ElementNotFoundException($this->getDriver(), 'form field', 'id|name|label|value', $locator);
}
$field->selectOption($value, $multiple);
}
/**
* Checks whether element has a table with specified locator.
*
* @param string $locator table id or caption
*
* @return Boolean
*/
public function hasTable($locator)
{
return $this->has('named', array('table', $locator));
}
/**
* Attach file to file field with specified locator.
*
* @param string $locator input id, name or label
* @param string $path path to file
*
* @throws ElementNotFoundException
*
* @see NodeElement::attachFile
*/
public function attachFileToField($locator, $path)
{
$field = $this->findField($locator);
if (null === $field) {
throw new ElementNotFoundException($this->getDriver(), 'form field', 'id|name|label|value', $locator);
}
$field->attachFile($path);
}
}

View file

@ -0,0 +1,31 @@
<?php
/*
* This file is part of the Mink package.
* (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\Exception;
/**
* Exception thrown by drivers when they fail to perform an action.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class DriverException extends Exception
{
/**
* Initializes exception.
*
* @param string $message
* @param int $code
* @param \Exception|null $previous
*/
public function __construct($message, $code = 0, \Exception $previous = null)
{
parent::__construct($message, $code, $previous);
}
}

View file

@ -0,0 +1,60 @@
<?php
/*
* This file is part of the Mink package.
* (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\Exception;
@trigger_error('The class '.__NAMESPACE__.'\ElementException is deprecated as of Mink 1.6 and will be removed in 2.0', E_USER_DEPRECATED);
use Behat\Mink\Element\Element;
/**
* A standard way for elements to re-throw exceptions.
*
* @deprecated This exception class is not used anymore in Mink 1.6 and will be removed in 2.0
*
* @author Chris Worfolk <xmeltrut@gmail.com>
*/
class ElementException extends Exception
{
private $element;
/**
* Initialises exception.
*
* @param Element $element optional message
* @param \Exception $exception exception
*/
public function __construct(Element $element, \Exception $exception)
{
$this->element = $element;
parent::__construct(sprintf("Exception thrown by %s\n%s", $element->getXpath(), $exception->getMessage()));
}
/**
* Override default toString so we don't send a full backtrace in verbose mode.
*
* @return string
*/
public function __toString()
{
return $this->getMessage();
}
/**
* Get the element that caused the exception.
*
* @return Element
*/
public function getElement()
{
return $this->element;
}
}

View file

@ -0,0 +1,50 @@
<?php
/*
* This file is part of the Mink package.
* (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\Exception;
use Behat\Mink\Driver\DriverInterface;
use Behat\Mink\Element\Element;
use Behat\Mink\Session;
/**
* Exception thrown when an expectation on the HTML of an element fails.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class ElementHtmlException extends ExpectationException
{
/**
* Element instance.
*
* @var Element
*/
protected $element;
/**
* Initializes exception.
*
* @param string $message optional message
* @param DriverInterface|Session $driver driver instance
* @param Element $element element
* @param \Exception $exception expectation exception
*/
public function __construct($message, $driver, Element $element, \Exception $exception = null)
{
$this->element = $element;
parent::__construct($message, $driver, $exception);
}
protected function getContext()
{
return $this->element->getOuterHtml();
}
}

View file

@ -0,0 +1,54 @@
<?php
/*
* This file is part of the Mink package.
* (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\Exception;
use Behat\Mink\Driver\DriverInterface;
use Behat\Mink\Session;
/**
* Exception thrown when an expected element is not found.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class ElementNotFoundException extends ExpectationException
{
/**
* Initializes exception.
*
* @param DriverInterface|Session $driver driver instance
* @param string $type element type
* @param string $selector element selector type
* @param string $locator element locator
*/
public function __construct($driver, $type = null, $selector = null, $locator = null)
{
$message = '';
if (null !== $type) {
$message .= ucfirst($type);
} else {
$message .= 'Tag';
}
if (null !== $locator) {
if (null === $selector || in_array($selector, array('css', 'xpath'))) {
$selector = 'matching '.($selector ?: 'locator');
} else {
$selector = 'with '.$selector;
}
$message .= ' '.$selector.' "'.$locator.'"';
}
$message .= ' not found.';
parent::__construct($message, $driver);
}
}

View file

@ -0,0 +1,24 @@
<?php
/*
* This file is part of the Mink package.
* (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\Exception;
/**
* Exception thrown when an expectation on the text of an element fails.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class ElementTextException extends ElementHtmlException
{
protected function getContext()
{
return $this->element->getText();
}
}

View file

@ -0,0 +1,20 @@
<?php
/*
* This file is part of the Mink package.
* (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\Exception;
/**
* Mink base exception class.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
abstract class Exception extends \Exception
{
}

View file

@ -0,0 +1,175 @@
<?php
/*
* This file is part of the Mink package.
* (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\Exception;
use Behat\Mink\Driver\DriverInterface;
use Behat\Mink\Session;
/**
* Exception thrown for failed expectations.
*
* Some specialized child classes are available to customize the error rendering.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class ExpectationException extends Exception
{
private $session;
private $driver;
/**
* Initializes exception.
*
* @param string $message optional message
* @param DriverInterface|Session $driver driver instance (or session for BC)
* @param \Exception|null $exception expectation exception
*/
public function __construct($message, $driver, \Exception $exception = null)
{
if ($driver instanceof Session) {
@trigger_error('Passing a Session object to the ExpectationException constructor is deprecated as of Mink 1.7. Pass the driver instead.', E_USER_DEPRECATED);
$this->session = $driver;
$this->driver = $driver->getDriver();
} elseif (!$driver instanceof DriverInterface) {
// Trigger an exception as we cannot typehint a disjunction
throw new \InvalidArgumentException('The ExpectationException constructor expects a DriverInterface or a Session.');
} else {
$this->driver = $driver;
}
if (!$message && null !== $exception) {
$message = $exception->getMessage();
}
parent::__construct($message, 0, $exception);
}
/**
* Returns exception message with additional context info.
*
* @return string
*/
public function __toString()
{
try {
$pageText = $this->pipeString($this->trimString($this->getContext())."\n");
$string = sprintf("%s\n\n%s%s", $this->getMessage(), $this->getResponseInfo(), $pageText);
} catch (\Exception $e) {
return $this->getMessage();
}
return $string;
}
/**
* Gets the context rendered for this exception.
*
* @return string
*/
protected function getContext()
{
return $this->trimBody($this->driver->getContent());
}
/**
* Returns driver.
*
* @return DriverInterface
*/
protected function getDriver()
{
return $this->driver;
}
/**
* Returns exception session.
*
* @return Session
*
* @deprecated since 1.7, to be removed in 2.0. Use getDriver and the driver API instead.
*/
protected function getSession()
{
if (null === $this->session) {
throw new \LogicException(sprintf('The deprecated method %s cannot be used when passing a driver in the constructor', __METHOD__));
}
@trigger_error(sprintf('The method %s is deprecated as of Mink 1.7 and will be removed in 2.0. Use getDriver and the driver API instead.'));
return $this->session;
}
/**
* Prepends every line in a string with pipe (|).
*
* @param string $string
*
* @return string
*/
protected function pipeString($string)
{
return '| '.strtr($string, array("\n" => "\n| "));
}
/**
* Removes response header/footer, letting only <body /> content.
*
* @param string $string response content
*
* @return string
*/
protected function trimBody($string)
{
$string = preg_replace(array('/^.*<body>/s', '/<\/body>.*$/s'), array('<body>', '</body>'), $string);
return $string;
}
/**
* Trims string to specified number of chars.
*
* @param string $string response content
* @param int $count trim count
*
* @return string
*/
protected function trimString($string, $count = 1000)
{
$string = trim($string);
if ($count < mb_strlen($string)) {
return mb_substr($string, 0, $count - 3).'...';
}
return $string;
}
/**
* Returns response information string.
*
* @return string
*/
protected function getResponseInfo()
{
$driver = basename(str_replace('\\', '/', get_class($this->driver)));
$info = '+--[ ';
try {
$info .= 'HTTP/1.1 '.$this->driver->getStatusCode().' | ';
} catch (UnsupportedDriverActionException $e) {
// Ignore the status code when not supported
}
$info .= $this->driver->getCurrentUrl().' | '.$driver." ]\n|\n";
return $info;
}
}

View file

@ -0,0 +1,24 @@
<?php
/*
* This file is part of the Mink package.
* (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\Exception;
/**
* Exception thrown when an expectation on the response text fails.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class ResponseTextException extends ExpectationException
{
protected function getContext()
{
return $this->getDriver()->getText('//html');
}
}

View file

@ -0,0 +1,35 @@
<?php
/*
* This file is part of the Mink package.
* (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\Exception;
use Behat\Mink\Driver\DriverInterface;
/**
* Exception thrown by drivers when they don't support the requested action.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class UnsupportedDriverActionException extends DriverException
{
/**
* Initializes exception.
*
* @param string $template what is unsupported?
* @param DriverInterface $driver driver instance
* @param \Exception $previous previous exception
*/
public function __construct($template, DriverInterface $driver, \Exception $previous = null)
{
$message = sprintf($template, get_class($driver));
parent::__construct($message, 0, $previous);
}
}

216
web/vendor/behat/mink/src/Mink.php vendored Normal file
View file

@ -0,0 +1,216 @@
<?php
/*
* This file is part of the Mink package.
* (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;
/**
* Mink sessions manager.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class Mink
{
private $defaultSessionName;
/**
* Sessions.
*
* @var Session[]
*/
private $sessions = array();
/**
* Initializes manager.
*
* @param Session[] $sessions
*/
public function __construct(array $sessions = array())
{
foreach ($sessions as $name => $session) {
$this->registerSession($name, $session);
}
}
/**
* Stops all started sessions.
*/
public function __destruct()
{
$this->stopSessions();
}
/**
* Registers new session.
*
* @param string $name
* @param Session $session
*/
public function registerSession($name, Session $session)
{
$name = strtolower($name);
$this->sessions[$name] = $session;
}
/**
* Checks whether session with specified name is registered.
*
* @param string $name
*
* @return Boolean
*/
public function hasSession($name)
{
return isset($this->sessions[strtolower($name)]);
}
/**
* Sets default session name to use.
*
* @param string $name name of the registered session
*
* @throws \InvalidArgumentException
*/
public function setDefaultSessionName($name)
{
$name = strtolower($name);
if (!isset($this->sessions[$name])) {
throw new \InvalidArgumentException(sprintf('Session "%s" is not registered.', $name));
}
$this->defaultSessionName = $name;
}
/**
* Returns default session name or null if none.
*
* @return null|string
*/
public function getDefaultSessionName()
{
return $this->defaultSessionName;
}
/**
* Returns registered session by it's name or active one and automatically starts it if required.
*
* @param string $name session name
*
* @return Session
*
* @throws \InvalidArgumentException If the named session is not registered
*/
public function getSession($name = null)
{
$session = $this->locateSession($name);
// start session if needed
if (!$session->isStarted()) {
$session->start();
}
return $session;
}
/**
* Checks whether a named session (or the default session) has already been started.
*
* @param string $name session name - if null then the default session will be checked
*
* @return bool whether the session has been started
*
* @throws \InvalidArgumentException If the named session is not registered
*/
public function isSessionStarted($name = null)
{
$session = $this->locateSession($name);
return $session->isStarted();
}
/**
* Returns session asserter.
*
* @param Session|string $session session object or name
*
* @return WebAssert
*/
public function assertSession($session = null)
{
if (!($session instanceof Session)) {
$session = $this->getSession($session);
}
return new WebAssert($session);
}
/**
* Resets all started sessions.
*/
public function resetSessions()
{
foreach ($this->sessions as $session) {
if ($session->isStarted()) {
$session->reset();
}
}
}
/**
* Restarts all started sessions.
*/
public function restartSessions()
{
foreach ($this->sessions as $session) {
if ($session->isStarted()) {
$session->restart();
}
}
}
/**
* Stops all started sessions.
*/
public function stopSessions()
{
foreach ($this->sessions as $session) {
if ($session->isStarted()) {
$session->stop();
}
}
}
/**
* Returns the named or default session without starting it.
*
* @param string $name session name
*
* @return Session
*
* @throws \InvalidArgumentException If the named session is not registered
*/
protected function locateSession($name = null)
{
$name = strtolower($name) ?: $this->defaultSessionName;
if (null === $name) {
throw new \InvalidArgumentException('Specify session name to get');
}
if (!isset($this->sessions[$name])) {
throw new \InvalidArgumentException(sprintf('Session "%s" is not registered.', $name));
}
$session = $this->sessions[$name];
return $session;
}
}

View file

@ -0,0 +1,46 @@
<?php
/*
* This file is part of the Mink package.
* (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\Selector;
use Symfony\Component\CssSelector\CssSelector as CSS;
use Symfony\Component\CssSelector\CssSelectorConverter;
/**
* CSS selector engine. Transforms CSS to XPath.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class CssSelector implements SelectorInterface
{
/**
* Translates CSS into XPath.
*
* @param string|array $locator current selector locator
*
* @return string
*/
public function translateToXPath($locator)
{
if (!is_string($locator)) {
throw new \InvalidArgumentException('The CssSelector expects to get a string as locator');
}
// Symfony 2.8+ API
if (class_exists('Symfony\Component\CssSelector\CssSelectorConverter')) {
$converter = new CssSelectorConverter();
return $converter->toXPath($locator);
}
// old static API for Symfony 2.7 and older
return CSS::toXPath($locator);
}
}

View file

@ -0,0 +1,29 @@
<?php
/*
* This file is part of the Mink package.
* (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\Selector;
/**
* Exact match selector engine. Like the Named selector engine but ignores partial matches.
*/
class ExactNamedSelector extends NamedSelector
{
public function __construct()
{
$this->registerReplacement('%tagTextMatch%', 'normalize-space(string(.)) = %locator%');
$this->registerReplacement('%valueMatch%', './@value = %locator%');
$this->registerReplacement('%titleMatch%', './@title = %locator%');
$this->registerReplacement('%altMatch%', './@alt = %locator%');
$this->registerReplacement('%relMatch%', './@rel = %locator%');
$this->registerReplacement('%labelAttributeMatch%', './@label = %locator%');
parent::__construct();
}
}

View file

@ -0,0 +1,263 @@
<?php
/*
* This file is part of the Mink package.
* (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\Selector;
use Behat\Mink\Selector\Xpath\Escaper;
/**
* Named selectors engine. Uses registered XPath selectors to create new expressions.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class NamedSelector implements SelectorInterface
{
private $replacements = array(
// simple replacements
'%lowercaseType%' => "translate(./@type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')",
'%lowercaseRole%' => "translate(./@role, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')",
'%tagTextMatch%' => 'contains(normalize-space(string(.)), %locator%)',
'%labelTextMatch%' => './@id = //label[%tagTextMatch%]/@for',
'%idMatch%' => './@id = %locator%',
'%valueMatch%' => 'contains(./@value, %locator%)',
'%idOrValueMatch%' => '(%idMatch% or %valueMatch%)',
'%idOrNameMatch%' => '(%idMatch% or ./@name = %locator%)',
'%placeholderMatch%' => './@placeholder = %locator%',
'%titleMatch%' => 'contains(./@title, %locator%)',
'%altMatch%' => 'contains(./@alt, %locator%)',
'%relMatch%' => 'contains(./@rel, %locator%)',
'%labelAttributeMatch%' => 'contains(./@label, %locator%)',
// complex replacements
'%inputTypeWithoutPlaceholderFilter%' => "%lowercaseType% = 'radio' or %lowercaseType% = 'checkbox' or %lowercaseType% = 'file'",
'%fieldFilterWithPlaceholder%' => 'self::input[not(%inputTypeWithoutPlaceholderFilter%)] | self::textarea',
'%fieldMatchWithPlaceholder%' => '(%idOrNameMatch% or %labelTextMatch% or %placeholderMatch%)',
'%fieldMatchWithoutPlaceholder%' => '(%idOrNameMatch% or %labelTextMatch%)',
'%fieldFilterWithoutPlaceholder%' => 'self::input[%inputTypeWithoutPlaceholderFilter%] | self::select',
'%buttonTypeFilter%' => "%lowercaseType% = 'submit' or %lowercaseType% = 'image' or %lowercaseType% = 'button' or %lowercaseType% = 'reset'",
'%notFieldTypeFilter%' => "not(%buttonTypeFilter% or %lowercaseType% = 'hidden')",
'%buttonMatch%' => '%idOrNameMatch% or %valueMatch% or %titleMatch%',
'%linkMatch%' => '(%idMatch% or %tagTextMatch% or %titleMatch% or %relMatch%)',
'%imgAltMatch%' => './/img[%altMatch%]',
);
private $selectors = array(
'fieldset' => <<<XPATH
.//fieldset
[(%idMatch% or .//legend[%tagTextMatch%])]
XPATH
,'field' => <<<XPATH
.//*
[%fieldFilterWithPlaceholder%][%notFieldTypeFilter%][%fieldMatchWithPlaceholder%]
|
.//label[%tagTextMatch%]//.//*[%fieldFilterWithPlaceholder%][%notFieldTypeFilter%]
|
.//*
[%fieldFilterWithoutPlaceholder%][%notFieldTypeFilter%][%fieldMatchWithoutPlaceholder%]
|
.//label[%tagTextMatch%]//.//*[%fieldFilterWithoutPlaceholder%][%notFieldTypeFilter%]
XPATH
,'link' => <<<XPATH
.//a
[./@href][(%linkMatch% or %imgAltMatch%)]
|
.//*
[%lowercaseRole% = 'link'][(%idOrValueMatch% or %titleMatch% or %tagTextMatch%)]
XPATH
,'button' => <<<XPATH
.//input
[%buttonTypeFilter%][(%buttonMatch%)]
|
.//input
[%lowercaseType% = 'image'][%altMatch%]
|
.//button
[(%buttonMatch% or %tagTextMatch%)]
|
.//*
[%lowercaseRole% = 'button'][(%buttonMatch% or %tagTextMatch%)]
XPATH
,'link_or_button' => <<<XPATH
.//a
[./@href][(%linkMatch% or %imgAltMatch%)]
|
.//input
[%buttonTypeFilter%][(%idOrValueMatch% or %titleMatch%)]
|
.//input
[%lowercaseType% = 'image'][%altMatch%]
|
.//button
[(%idOrValueMatch% or %titleMatch% or %tagTextMatch%)]
|
.//*
[(%lowercaseRole% = 'button' or %lowercaseRole% = 'link')][(%idOrValueMatch% or %titleMatch% or %tagTextMatch%)]
XPATH
,'content' => <<<XPATH
./descendant-or-self::*
[%tagTextMatch%]
XPATH
,'select' => <<<XPATH
.//select
[%fieldMatchWithoutPlaceholder%]
|
.//label[%tagTextMatch%]//.//select
XPATH
,'checkbox' => <<<XPATH
.//input
[%lowercaseType% = 'checkbox'][%fieldMatchWithoutPlaceholder%]
|
.//label[%tagTextMatch%]//.//input[%lowercaseType% = 'checkbox']
XPATH
,'radio' => <<<XPATH
.//input
[%lowercaseType% = 'radio'][%fieldMatchWithoutPlaceholder%]
|
.//label[%tagTextMatch%]//.//input[%lowercaseType% = 'radio']
XPATH
,'file' => <<<XPATH
.//input
[%lowercaseType% = 'file'][%fieldMatchWithoutPlaceholder%]
|
.//label[%tagTextMatch%]//.//input[%lowercaseType% = 'file']
XPATH
,'optgroup' => <<<XPATH
.//optgroup
[%labelAttributeMatch%]
XPATH
,'option' => <<<XPATH
.//option
[(./@value = %locator% or %tagTextMatch%)]
XPATH
,'table' => <<<XPATH
.//table
[(%idMatch% or .//caption[%tagTextMatch%])]
XPATH
,'id' => <<<XPATH
.//*[%idMatch%]
XPATH
,'id_or_name' => <<<XPATH
.//*[%idOrNameMatch%]
XPATH
);
private $xpathEscaper;
/**
* Creates selector instance.
*/
public function __construct()
{
$this->xpathEscaper = new Escaper();
foreach ($this->replacements as $from => $to) {
$this->replacements[$from] = strtr($to, $this->replacements);
}
foreach ($this->selectors as $alias => $selector) {
$this->selectors[$alias] = strtr($selector, $this->replacements);
}
}
/**
* Registers new XPath selector with specified name.
*
* @param string $name name for selector
* @param string $xpath xpath expression
*/
public function registerNamedXpath($name, $xpath)
{
$this->selectors[$name] = $xpath;
}
/**
* Translates provided locator into XPath.
*
* @param string|array $locator selector name or array of (selector_name, locator)
*
* @return string
*
* @throws \InvalidArgumentException
*/
public function translateToXPath($locator)
{
if (2 < count($locator)) {
throw new \InvalidArgumentException('NamedSelector expects array(name, locator) as argument');
}
if (2 == count($locator)) {
$selector = $locator[0];
$locator = $locator[1];
} else {
$selector = (string) $locator;
$locator = null;
}
if (!isset($this->selectors[$selector])) {
throw new \InvalidArgumentException(sprintf(
'Unknown named selector provided: "%s". Expected one of (%s)',
$selector,
implode(', ', array_keys($this->selectors))
));
}
$xpath = $this->selectors[$selector];
if (null !== $locator) {
$xpath = strtr($xpath, array('%locator%' => $this->escapeLocator($locator)));
}
return $xpath;
}
/**
* Registers a replacement in the list of replacements.
*
* This method must be called in the constructor before calling the parent constructor.
*
* @param string $from
* @param string $to
*/
protected function registerReplacement($from, $to)
{
$this->replacements[$from] = $to;
}
private function escapeLocator($locator)
{
// If the locator looks like an escaped one, don't escape it again for BC reasons.
if (
preg_match('/^\'[^\']*+\'$/', $locator)
|| (false !== strpos($locator, '\'') && preg_match('/^"[^"]*+"$/', $locator))
|| ((8 < $length = strlen($locator)) && 'concat(' === substr($locator, 0, 7) && ')' === $locator[$length - 1])
) {
@trigger_error(
'Passing an escaped locator to the named selector is deprecated as of 1.7 and will be removed in 2.0.'
.' Pass the raw value instead.',
E_USER_DEPRECATED
);
return $locator;
}
return $this->xpathEscaper->escapeLiteral($locator);
}
}

View file

@ -0,0 +1,31 @@
<?php
/*
* This file is part of the Mink package.
* (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\Selector;
/**
* Named selectors engine. Uses registered XPath selectors to create new expressions.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class PartialNamedSelector extends NamedSelector
{
public function __construct()
{
$this->registerReplacement('%tagTextMatch%', 'contains(normalize-space(string(.)), %locator%)');
$this->registerReplacement('%valueMatch%', 'contains(./@value, %locator%)');
$this->registerReplacement('%titleMatch%', 'contains(./@title, %locator%)');
$this->registerReplacement('%altMatch%', 'contains(./@alt, %locator%)');
$this->registerReplacement('%relMatch%', 'contains(./@rel, %locator%)');
$this->registerReplacement('%labelAttributeMatch%', 'contains(./@label, %locator%)');
parent::__construct();
}
}

View file

@ -0,0 +1,28 @@
<?php
/*
* This file is part of the Mink package.
* (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\Selector;
/**
* Mink selector engine interface.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
interface SelectorInterface
{
/**
* Translates provided locator into XPath.
*
* @param string|array $locator current selector locator
*
* @return string
*/
public function translateToXPath($locator);
}

View file

@ -0,0 +1,135 @@
<?php
/*
* This file is part of the Mink package.
* (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\Selector;
use Behat\Mink\Selector\Xpath\Escaper;
/**
* Selectors handler.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class SelectorsHandler
{
private $selectors;
private $escaper;
/**
* Initializes selectors handler.
*
* @param SelectorInterface[] $selectors default selectors to register
*/
public function __construct(array $selectors = array())
{
$this->escaper = new Escaper();
$this->registerSelector('named_partial', new PartialNamedSelector());
$this->registerSelector('named_exact', new ExactNamedSelector());
$this->registerSelector('css', new CssSelector());
foreach ($selectors as $name => $selector) {
$this->registerSelector($name, $selector);
}
}
/**
* Registers new selector engine with specified name.
*
* @param string $name selector engine name
* @param SelectorInterface $selector selector engine instance
*/
public function registerSelector($name, SelectorInterface $selector)
{
$this->selectors[$name] = $selector;
}
/**
* Checks whether selector with specified name is registered on handler.
*
* @param string $name selector engine name
*
* @return Boolean
*/
public function isSelectorRegistered($name)
{
return isset($this->selectors[$name]);
}
/**
* Returns selector engine with specified name.
*
* @param string $name selector engine name
*
* @return SelectorInterface
*
* @throws \InvalidArgumentException
*/
public function getSelector($name)
{
if ('named' === $name) {
@trigger_error(
'Using the "named" selector directly from the handler is deprecated as of 1.6 and will be removed in 2.0.'
.' Use the "named_partial" or use the "named" selector through the Element API instead.',
E_USER_DEPRECATED
);
$name = 'named_partial';
}
if (!$this->isSelectorRegistered($name)) {
throw new \InvalidArgumentException("Selector \"$name\" is not registered.");
}
return $this->selectors[$name];
}
/**
* Translates selector with specified name to XPath.
*
* @param string $selector selector engine name (registered)
* @param string|array $locator selector locator (an array or a string depending of the selector being used)
*
* @return string
*/
public function selectorToXpath($selector, $locator)
{
if ('xpath' === $selector) {
if (!is_string($locator)) {
throw new \InvalidArgumentException('The xpath selector expects to get a string as locator');
}
return $locator;
}
return $this->getSelector($selector)->translateToXPath($locator);
}
/**
* Translates string to XPath literal.
*
* @deprecated since Mink 1.7. Use \Behat\Mink\Selector\Xpath\Escaper::escapeLiteral when building Xpath
* or pass the unescaped value when using the named selector.
*
* @param string $s
*
* @return string
*/
public function xpathLiteral($s)
{
@trigger_error(
'The '.__METHOD__.' method is deprecated as of 1.7 and will be removed in 2.0.'
.' Use \Behat\Mink\Selector\Xpath\Escaper::escapeLiteral instead when building Xpath'
.' or pass the unescaped value when using the named selector.',
E_USER_DEPRECATED
);
return $this->escaper->escapeLiteral($s);
}
}

View file

@ -0,0 +1,52 @@
<?php
/*
* This file is part of the Mink package.
* (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\Selector\Xpath;
/**
* XPath escaper.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class Escaper
{
/**
* Escapes the string as a XPath literal.
*
* @param string $s
*
* @return string
*/
public function escapeLiteral($s)
{
if (false === strpos($s, "'")) {
return sprintf("'%s'", $s);
}
if (false === strpos($s, '"')) {
return sprintf('"%s"', $s);
}
$string = $s;
$parts = array();
while (true) {
if (false !== $pos = strpos($string, "'")) {
$parts[] = sprintf("'%s'", substr($string, 0, $pos));
$parts[] = "\"'\"";
$string = substr($string, $pos + 1);
} else {
$parts[] = "'$string'";
break;
}
}
return sprintf('concat(%s)', implode($parts, ','));
}
}

View file

@ -0,0 +1,69 @@
<?php
/*
* This file is part of the Mink package.
* (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\Selector\Xpath;
/**
* XPath manipulation utility.
*
* @author Graham Bates
* @author Christophe Coevoet <stof@notk.org>
*/
class Manipulator
{
/**
* Regex to find union operators not inside brackets.
*/
const UNION_PATTERN = '/\|(?![^\[]*\])/';
/**
* Prepends the XPath prefix to the given XPath.
*
* The returned XPath will match elements matching the XPath inside an element
* matching the prefix.
*
* @param string $xpath
* @param string $prefix
*
* @return string
*/
public function prepend($xpath, $prefix)
{
$expressions = array();
// If the xpath prefix contains a union we need to wrap it in parentheses.
if (preg_match(self::UNION_PATTERN, $prefix)) {
$prefix = '('.$prefix.')';
}
// Split any unions into individual expressions.
foreach (preg_split(self::UNION_PATTERN, $xpath) as $expression) {
$expression = trim($expression);
$parenthesis = '';
// If the union is inside some braces, we need to preserve the opening braces and apply
// the prefix only inside it.
if (preg_match('/^[\(\s*]+/', $expression, $matches)) {
$parenthesis = $matches[0];
$expression = substr($expression, strlen($parenthesis));
}
// add prefix before element selector
if (0 === strpos($expression, '/')) {
$expression = $prefix.$expression;
} else {
$expression = $prefix.'/'.$expression;
}
$expressions[] = $parenthesis.$expression;
}
return implode(' | ', $expressions);
}
}

373
web/vendor/behat/mink/src/Session.php vendored Normal file
View file

@ -0,0 +1,373 @@
<?php
/*
* This file is part of the Mink package.
* (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;
use Behat\Mink\Driver\DriverInterface;
use Behat\Mink\Selector\SelectorsHandler;
use Behat\Mink\Element\DocumentElement;
/**
* Mink session.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class Session
{
private $driver;
private $page;
private $selectorsHandler;
/**
* Initializes session.
*
* @param DriverInterface $driver
* @param SelectorsHandler $selectorsHandler
*/
public function __construct(DriverInterface $driver, SelectorsHandler $selectorsHandler = null)
{
$driver->setSession($this);
if (null === $selectorsHandler) {
$selectorsHandler = new SelectorsHandler();
}
$this->driver = $driver;
$this->selectorsHandler = $selectorsHandler;
$this->page = new DocumentElement($this);
}
/**
* Checks whether session (driver) was started.
*
* @return Boolean
*/
public function isStarted()
{
return $this->driver->isStarted();
}
/**
* Starts session driver.
*
* Calling any action before visiting a page is an undefined behavior.
* The only supported method calls on a fresh driver are
* - visit()
* - setRequestHeader()
* - setBasicAuth()
* - reset()
* - stop()
*/
public function start()
{
$this->driver->start();
}
/**
* Stops session driver.
*/
public function stop()
{
$this->driver->stop();
}
/**
* Restart session driver.
*/
public function restart()
{
$this->driver->stop();
$this->driver->start();
}
/**
* Reset session driver state.
*
* Calling any action before visiting a page is an undefined behavior.
* The only supported method calls on a fresh driver are
* - visit()
* - setRequestHeader()
* - setBasicAuth()
* - reset()
* - stop()
*/
public function reset()
{
$this->driver->reset();
}
/**
* Returns session driver.
*
* @return DriverInterface
*/
public function getDriver()
{
return $this->driver;
}
/**
* Returns page element.
*
* @return DocumentElement
*/
public function getPage()
{
return $this->page;
}
/**
* Returns selectors handler.
*
* @return SelectorsHandler
*/
public function getSelectorsHandler()
{
return $this->selectorsHandler;
}
/**
* Visit specified URL.
*
* @param string $url url of the page
*/
public function visit($url)
{
$this->driver->visit($url);
}
/**
* Sets HTTP Basic authentication parameters.
*
* @param string|Boolean $user user name or false to disable authentication
* @param string $password password
*/
public function setBasicAuth($user, $password = '')
{
$this->driver->setBasicAuth($user, $password);
}
/**
* Sets specific request header.
*
* @param string $name
* @param string $value
*/
public function setRequestHeader($name, $value)
{
$this->driver->setRequestHeader($name, $value);
}
/**
* Returns all response headers.
*
* @return array
*/
public function getResponseHeaders()
{
return $this->driver->getResponseHeaders();
}
/**
* Returns specific response header.
*
* @param string $name
*
* @return string|null
*/
public function getResponseHeader($name)
{
$headers = $this->driver->getResponseHeaders();
$name = strtolower($name);
$headers = array_change_key_case($headers, CASE_LOWER);
if (!isset($headers[$name])) {
return null;
}
return is_array($headers[$name]) ? $headers[$name][0] : $headers[$name];
}
/**
* Sets cookie.
*
* @param string $name
* @param string $value
*/
public function setCookie($name, $value = null)
{
$this->driver->setCookie($name, $value);
}
/**
* Returns cookie by name.
*
* @param string $name
*
* @return string|null
*/
public function getCookie($name)
{
return $this->driver->getCookie($name);
}
/**
* Returns response status code.
*
* @return int
*/
public function getStatusCode()
{
return $this->driver->getStatusCode();
}
/**
* Returns current URL address.
*
* @return string
*/
public function getCurrentUrl()
{
return $this->driver->getCurrentUrl();
}
/**
* Capture a screenshot of the current window.
*
* @return string screenshot of MIME type image/* depending
* on driver (e.g., image/png, image/jpeg)
*/
public function getScreenshot()
{
return $this->driver->getScreenshot();
}
/**
* Return the names of all open windows.
*
* @return array Array of all open window's names.
*/
public function getWindowNames()
{
return $this->driver->getWindowNames();
}
/**
* Return the name of the currently active window.
*
* @return string The name of the current window.
*/
public function getWindowName()
{
return $this->driver->getWindowName();
}
/**
* Reloads current session page.
*/
public function reload()
{
$this->driver->reload();
}
/**
* Moves backward 1 page in history.
*/
public function back()
{
$this->driver->back();
}
/**
* Moves forward 1 page in history.
*/
public function forward()
{
$this->driver->forward();
}
/**
* Switches to specific browser window.
*
* @param string $name window name (null for switching back to main window)
*/
public function switchToWindow($name = null)
{
$this->driver->switchToWindow($name);
}
/**
* Switches to specific iFrame.
*
* @param string $name iframe name (null for switching back)
*/
public function switchToIFrame($name = null)
{
$this->driver->switchToIFrame($name);
}
/**
* Execute JS in browser.
*
* @param string $script javascript
*/
public function executeScript($script)
{
$this->driver->executeScript($script);
}
/**
* Execute JS in browser and return it's response.
*
* @param string $script javascript
*
* @return string
*/
public function evaluateScript($script)
{
return $this->driver->evaluateScript($script);
}
/**
* Waits some time or until JS condition turns true.
*
* @param int $time time in milliseconds
* @param string $condition JS condition
*
* @return bool
*/
public function wait($time, $condition = 'false')
{
return $this->driver->wait($time, $condition);
}
/**
* Set the dimensions of the window.
*
* @param int $width set the window width, measured in pixels
* @param int $height set the window height, measured in pixels
* @param string $name window name (null for the main window)
*/
public function resizeWindow($width, $height, $name = null)
{
$this->driver->resizeWindow($width, $height, $name);
}
/**
* Maximize the window if it is not maximized already.
*
* @param string $name window name (null for the main window)
*/
public function maximizeWindow($name = null)
{
$this->driver->maximizeWindow($name);
}
}

849
web/vendor/behat/mink/src/WebAssert.php vendored Normal file
View file

@ -0,0 +1,849 @@
<?php
/*
* This file is part of the Mink package.
* (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;
use Behat\Mink\Element\Element;
use Behat\Mink\Element\ElementInterface;
use Behat\Mink\Element\NodeElement;
use Behat\Mink\Element\TraversableElement;
use Behat\Mink\Exception\ElementNotFoundException;
use Behat\Mink\Exception\ExpectationException;
use Behat\Mink\Exception\ResponseTextException;
use Behat\Mink\Exception\ElementHtmlException;
use Behat\Mink\Exception\ElementTextException;
/**
* Mink web assertions tool.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
class WebAssert
{
protected $session;
/**
* Initializes assertion engine.
*
* @param Session $session
*/
public function __construct(Session $session)
{
$this->session = $session;
}
/**
* Checks that current session address is equals to provided one.
*
* @param string $page
*
* @throws ExpectationException
*/
public function addressEquals($page)
{
$expected = $this->cleanUrl($page);
$actual = $this->getCurrentUrlPath();
$this->assert($actual === $expected, sprintf('Current page is "%s", but "%s" expected.', $actual, $expected));
}
/**
* Checks that current session address is not equals to provided one.
*
* @param string $page
*
* @throws ExpectationException
*/
public function addressNotEquals($page)
{
$expected = $this->cleanUrl($page);
$actual = $this->getCurrentUrlPath();
$this->assert($actual !== $expected, sprintf('Current page is "%s", but should not be.', $actual));
}
/**
* Checks that current session address matches regex.
*
* @param string $regex
*
* @throws ExpectationException
*/
public function addressMatches($regex)
{
$actual = $this->getCurrentUrlPath();
$message = sprintf('Current page "%s" does not match the regex "%s".', $actual, $regex);
$this->assert((bool) preg_match($regex, $actual), $message);
}
/**
* Checks that specified cookie exists and its value equals to a given one.
*
* @param string $name cookie name
* @param string $value cookie value
*
* @throws ExpectationException
*/
public function cookieEquals($name, $value)
{
$this->cookieExists($name);
$actualValue = $this->session->getCookie($name);
$message = sprintf('Cookie "%s" value is "%s", but should be "%s".', $name, $actualValue, $value);
$this->assert($actualValue == $value, $message);
}
/**
* Checks that specified cookie exists.
*
* @param string $name cookie name
*
* @throws ExpectationException
*/
public function cookieExists($name)
{
$message = sprintf('Cookie "%s" is not set, but should be.', $name);
$this->assert($this->session->getCookie($name) !== null, $message);
}
/**
* Checks that current response code equals to provided one.
*
* @param int $code
*
* @throws ExpectationException
*/
public function statusCodeEquals($code)
{
$actual = $this->session->getStatusCode();
$message = sprintf('Current response status code is %d, but %d expected.', $actual, $code);
$this->assert(intval($code) === intval($actual), $message);
}
/**
* Checks that current response code not equals to provided one.
*
* @param int $code
*
* @throws ExpectationException
*/
public function statusCodeNotEquals($code)
{
$actual = $this->session->getStatusCode();
$message = sprintf('Current response status code is %d, but should not be.', $actual);
$this->assert(intval($code) !== intval($actual), $message);
}
/**
* Checks that current response header equals value.
*
* @param string $name
* @param string $value
*
* @throws ExpectationException
*/
public function responseHeaderEquals($name, $value)
{
$actual = $this->session->getResponseHeader($name);
$message = sprintf('Current response header "%s" is "%s", but "%s" expected.', $name, $actual, $value);
$this->assert($value === $actual, $message);
}
/**
* Checks that current response header does not equal value.
*
* @param string $name
* @param string $value
*
* @throws ExpectationException
*/
public function responseHeaderNotEquals($name, $value)
{
$actual = $this->session->getResponseHeader($name);
$message = sprintf('Current response header "%s" is "%s", but should not be.', $name, $actual, $value);
$this->assert($value !== $actual, $message);
}
/**
* Checks that current response header contains value.
*
* @param string $name
* @param string $value
*
* @throws ExpectationException
*/
public function responseHeaderContains($name, $value)
{
$actual = $this->session->getResponseHeader($name);
$message = sprintf('The text "%s" was not found anywhere in the "%s" response header.', $value, $name);
$this->assert(false !== stripos($actual, $value), $message);
}
/**
* Checks that current response header does not contain value.
*
* @param string $name
* @param string $value
*
* @throws ExpectationException
*/
public function responseHeaderNotContains($name, $value)
{
$actual = $this->session->getResponseHeader($name);
$message = sprintf('The text "%s" was found in the "%s" response header, but it should not.', $value, $name);
$this->assert(false === stripos($actual, $value), $message);
}
/**
* Checks that current response header matches regex.
*
* @param string $name
* @param string $regex
*
* @throws ExpectationException
*/
public function responseHeaderMatches($name, $regex)
{
$actual = $this->session->getResponseHeader($name);
$message = sprintf('The pattern "%s" was not found anywhere in the "%s" response header.', $regex, $name);
$this->assert((bool) preg_match($regex, $actual), $message);
}
/**
* Checks that current response header does not match regex.
*
* @param string $name
* @param string $regex
*
* @throws ExpectationException
*/
public function responseHeaderNotMatches($name, $regex)
{
$actual = $this->session->getResponseHeader($name);
$message = sprintf(
'The pattern "%s" was found in the text of the "%s" response header, but it should not.',
$regex,
$name
);
$this->assert(!preg_match($regex, $actual), $message);
}
/**
* Checks that current page contains text.
*
* @param string $text
*
* @throws ResponseTextException
*/
public function pageTextContains($text)
{
$actual = $this->session->getPage()->getText();
$actual = preg_replace('/\s+/u', ' ', $actual);
$regex = '/'.preg_quote($text, '/').'/ui';
$message = sprintf('The text "%s" was not found anywhere in the text of the current page.', $text);
$this->assertResponseText((bool) preg_match($regex, $actual), $message);
}
/**
* Checks that current page does not contains text.
*
* @param string $text
*
* @throws ResponseTextException
*/
public function pageTextNotContains($text)
{
$actual = $this->session->getPage()->getText();
$actual = preg_replace('/\s+/u', ' ', $actual);
$regex = '/'.preg_quote($text, '/').'/ui';
$message = sprintf('The text "%s" appears in the text of this page, but it should not.', $text);
$this->assertResponseText(!preg_match($regex, $actual), $message);
}
/**
* Checks that current page text matches regex.
*
* @param string $regex
*
* @throws ResponseTextException
*/
public function pageTextMatches($regex)
{
$actual = $this->session->getPage()->getText();
$message = sprintf('The pattern %s was not found anywhere in the text of the current page.', $regex);
$this->assertResponseText((bool) preg_match($regex, $actual), $message);
}
/**
* Checks that current page text does not matches regex.
*
* @param string $regex
*
* @throws ResponseTextException
*/
public function pageTextNotMatches($regex)
{
$actual = $this->session->getPage()->getText();
$message = sprintf('The pattern %s was found in the text of the current page, but it should not.', $regex);
$this->assertResponseText(!preg_match($regex, $actual), $message);
}
/**
* Checks that page HTML (response content) contains text.
*
* @param string $text
*
* @throws ExpectationException
*/
public function responseContains($text)
{
$actual = $this->session->getPage()->getContent();
$regex = '/'.preg_quote($text, '/').'/ui';
$message = sprintf('The string "%s" was not found anywhere in the HTML response of the current page.', $text);
$this->assert((bool) preg_match($regex, $actual), $message);
}
/**
* Checks that page HTML (response content) does not contains text.
*
* @param string $text
*
* @throws ExpectationException
*/
public function responseNotContains($text)
{
$actual = $this->session->getPage()->getContent();
$regex = '/'.preg_quote($text, '/').'/ui';
$message = sprintf('The string "%s" appears in the HTML response of this page, but it should not.', $text);
$this->assert(!preg_match($regex, $actual), $message);
}
/**
* Checks that page HTML (response content) matches regex.
*
* @param string $regex
*
* @throws ExpectationException
*/
public function responseMatches($regex)
{
$actual = $this->session->getPage()->getContent();
$message = sprintf('The pattern %s was not found anywhere in the HTML response of the page.', $regex);
$this->assert((bool) preg_match($regex, $actual), $message);
}
/**
* Checks that page HTML (response content) does not matches regex.
*
* @param $regex
*
* @throws ExpectationException
*/
public function responseNotMatches($regex)
{
$actual = $this->session->getPage()->getContent();
$message = sprintf('The pattern %s was found in the HTML response of the page, but it should not.', $regex);
$this->assert(!preg_match($regex, $actual), $message);
}
/**
* Checks that there is specified number of specific elements on the page.
*
* @param string $selectorType element selector type (css, xpath)
* @param string|array $selector element selector
* @param int $count expected count
* @param ElementInterface $container document to check against
*
* @throws ExpectationException
*/
public function elementsCount($selectorType, $selector, $count, ElementInterface $container = null)
{
$container = $container ?: $this->session->getPage();
$nodes = $container->findAll($selectorType, $selector);
$message = sprintf(
'%d %s found on the page, but should be %d.',
count($nodes),
$this->getMatchingElementRepresentation($selectorType, $selector, count($nodes) !== 1),
$count
);
$this->assert(intval($count) === count($nodes), $message);
}
/**
* Checks that specific element exists on the current page.
*
* @param string $selectorType element selector type (css, xpath)
* @param string|array $selector element selector
* @param ElementInterface $container document to check against
*
* @return NodeElement
*
* @throws ElementNotFoundException
*/
public function elementExists($selectorType, $selector, ElementInterface $container = null)
{
$container = $container ?: $this->session->getPage();
$node = $container->find($selectorType, $selector);
if (null === $node) {
if (is_array($selector)) {
$selector = implode(' ', $selector);
}
throw new ElementNotFoundException($this->session->getDriver(), 'element', $selectorType, $selector);
}
return $node;
}
/**
* Checks that specific element does not exists on the current page.
*
* @param string $selectorType element selector type (css, xpath)
* @param string|array $selector element selector
* @param ElementInterface $container document to check against
*
* @throws ExpectationException
*/
public function elementNotExists($selectorType, $selector, ElementInterface $container = null)
{
$container = $container ?: $this->session->getPage();
$node = $container->find($selectorType, $selector);
$message = sprintf(
'An %s appears on this page, but it should not.',
$this->getMatchingElementRepresentation($selectorType, $selector)
);
$this->assert(null === $node, $message);
}
/**
* Checks that specific element contains text.
*
* @param string $selectorType element selector type (css, xpath)
* @param string|array $selector element selector
* @param string $text expected text
*
* @throws ElementTextException
*/
public function elementTextContains($selectorType, $selector, $text)
{
$element = $this->elementExists($selectorType, $selector);
$actual = $element->getText();
$regex = '/'.preg_quote($text, '/').'/ui';
$message = sprintf(
'The text "%s" was not found in the text of the %s.',
$text,
$this->getMatchingElementRepresentation($selectorType, $selector)
);
$this->assertElementText((bool) preg_match($regex, $actual), $message, $element);
}
/**
* Checks that specific element does not contains text.
*
* @param string $selectorType element selector type (css, xpath)
* @param string|array $selector element selector
* @param string $text expected text
*
* @throws ElementTextException
*/
public function elementTextNotContains($selectorType, $selector, $text)
{
$element = $this->elementExists($selectorType, $selector);
$actual = $element->getText();
$regex = '/'.preg_quote($text, '/').'/ui';
$message = sprintf(
'The text "%s" appears in the text of the %s, but it should not.',
$text,
$this->getMatchingElementRepresentation($selectorType, $selector)
);
$this->assertElementText(!preg_match($regex, $actual), $message, $element);
}
/**
* Checks that specific element contains HTML.
*
* @param string $selectorType element selector type (css, xpath)
* @param string|array $selector element selector
* @param string $html expected text
*
* @throws ElementHtmlException
*/
public function elementContains($selectorType, $selector, $html)
{
$element = $this->elementExists($selectorType, $selector);
$actual = $element->getHtml();
$regex = '/'.preg_quote($html, '/').'/ui';
$message = sprintf(
'The string "%s" was not found in the HTML of the %s.',
$html,
$this->getMatchingElementRepresentation($selectorType, $selector)
);
$this->assertElement((bool) preg_match($regex, $actual), $message, $element);
}
/**
* Checks that specific element does not contains HTML.
*
* @param string $selectorType element selector type (css, xpath)
* @param string|array $selector element selector
* @param string $html expected text
*
* @throws ElementHtmlException
*/
public function elementNotContains($selectorType, $selector, $html)
{
$element = $this->elementExists($selectorType, $selector);
$actual = $element->getHtml();
$regex = '/'.preg_quote($html, '/').'/ui';
$message = sprintf(
'The string "%s" appears in the HTML of the %s, but it should not.',
$html,
$this->getMatchingElementRepresentation($selectorType, $selector)
);
$this->assertElement(!preg_match($regex, $actual), $message, $element);
}
/**
* Checks that an attribute exists in an element.
*
* @param string $selectorType
* @param string|array $selector
* @param string $attribute
*
* @return NodeElement
*
* @throws ElementHtmlException
*/
public function elementAttributeExists($selectorType, $selector, $attribute)
{
$element = $this->elementExists($selectorType, $selector);
$message = sprintf(
'The attribute "%s" was not found in the %s.',
$attribute,
$this->getMatchingElementRepresentation($selectorType, $selector)
);
$this->assertElement($element->hasAttribute($attribute), $message, $element);
return $element;
}
/**
* Checks that an attribute of a specific elements contains text.
*
* @param string $selectorType
* @param string|array $selector
* @param string $attribute
* @param string $text
*
* @throws ElementHtmlException
*/
public function elementAttributeContains($selectorType, $selector, $attribute, $text)
{
$element = $this->elementAttributeExists($selectorType, $selector, $attribute);
$actual = $element->getAttribute($attribute);
$regex = '/'.preg_quote($text, '/').'/ui';
$message = sprintf(
'The text "%s" was not found in the attribute "%s" of the %s.',
$text,
$attribute,
$this->getMatchingElementRepresentation($selectorType, $selector)
);
$this->assertElement((bool) preg_match($regex, $actual), $message, $element);
}
/**
* Checks that an attribute of a specific elements does not contain text.
*
* @param string $selectorType
* @param string|array $selector
* @param string $attribute
* @param string $text
*
* @throws ElementHtmlException
*/
public function elementAttributeNotContains($selectorType, $selector, $attribute, $text)
{
$element = $this->elementAttributeExists($selectorType, $selector, $attribute);
$actual = $element->getAttribute($attribute);
$regex = '/'.preg_quote($text, '/').'/ui';
$message = sprintf(
'The text "%s" was found in the attribute "%s" of the %s.',
$text,
$attribute,
$this->getMatchingElementRepresentation($selectorType, $selector)
);
$this->assertElement(!preg_match($regex, $actual), $message, $element);
}
/**
* Checks that specific field exists on the current page.
*
* @param string $field field id|name|label|value
* @param TraversableElement $container document to check against
*
* @return NodeElement
*
* @throws ElementNotFoundException
*/
public function fieldExists($field, TraversableElement $container = null)
{
$container = $container ?: $this->session->getPage();
$node = $container->findField($field);
if (null === $node) {
throw new ElementNotFoundException($this->session->getDriver(), 'form field', 'id|name|label|value', $field);
}
return $node;
}
/**
* Checks that specific field does not exists on the current page.
*
* @param string $field field id|name|label|value
* @param TraversableElement $container document to check against
*
* @throws ExpectationException
*/
public function fieldNotExists($field, TraversableElement $container = null)
{
$container = $container ?: $this->session->getPage();
$node = $container->findField($field);
$this->assert(null === $node, sprintf('A field "%s" appears on this page, but it should not.', $field));
}
/**
* Checks that specific field have provided value.
*
* @param string $field field id|name|label|value
* @param string $value field value
* @param TraversableElement $container document to check against
*
* @throws ExpectationException
*/
public function fieldValueEquals($field, $value, TraversableElement $container = null)
{
$node = $this->fieldExists($field, $container);
$actual = $node->getValue();
$regex = '/^'.preg_quote($value, '/').'$/ui';
$message = sprintf('The field "%s" value is "%s", but "%s" expected.', $field, $actual, $value);
$this->assert((bool) preg_match($regex, $actual), $message);
}
/**
* Checks that specific field have provided value.
*
* @param string $field field id|name|label|value
* @param string $value field value
* @param TraversableElement $container document to check against
*
* @throws ExpectationException
*/
public function fieldValueNotEquals($field, $value, TraversableElement $container = null)
{
$node = $this->fieldExists($field, $container);
$actual = $node->getValue();
$regex = '/^'.preg_quote($value, '/').'$/ui';
$message = sprintf('The field "%s" value is "%s", but it should not be.', $field, $actual);
$this->assert(!preg_match($regex, $actual), $message);
}
/**
* Checks that specific checkbox is checked.
*
* @param string $field field id|name|label|value
* @param TraversableElement $container document to check against
*
* @throws ExpectationException
*/
public function checkboxChecked($field, TraversableElement $container = null)
{
$node = $this->fieldExists($field, $container);
$this->assert($node->isChecked(), sprintf('Checkbox "%s" is not checked, but it should be.', $field));
}
/**
* Checks that specific checkbox is unchecked.
*
* @param string $field field id|name|label|value
* @param TraversableElement $container document to check against
*
* @throws ExpectationException
*/
public function checkboxNotChecked($field, TraversableElement $container = null)
{
$node = $this->fieldExists($field, $container);
$this->assert(!$node->isChecked(), sprintf('Checkbox "%s" is checked, but it should not be.', $field));
}
/**
* Gets current url of the page.
*
* @return string
*/
protected function getCurrentUrlPath()
{
return $this->cleanUrl($this->session->getCurrentUrl());
}
/**
* Trims scriptname from the URL.
*
* @param string $url
*
* @return string
*/
protected function cleanUrl($url)
{
$parts = parse_url($url);
$fragment = empty($parts['fragment']) ? '' : '#'.$parts['fragment'];
$path = empty($parts['path']) ? '/' : $parts['path'];
return preg_replace('/^\/[^\.\/]+\.php\//', '/', $path).$fragment;
}
/**
* Asserts a condition.
*
* @param bool $condition
* @param string $message Failure message
*
* @throws ExpectationException when the condition is not fulfilled
*/
private function assert($condition, $message)
{
if ($condition) {
return;
}
throw new ExpectationException($message, $this->session->getDriver());
}
/**
* Asserts a condition involving the response text.
*
* @param bool $condition
* @param string $message Failure message
*
* @throws ResponseTextException when the condition is not fulfilled
*/
private function assertResponseText($condition, $message)
{
if ($condition) {
return;
}
throw new ResponseTextException($message, $this->session->getDriver());
}
/**
* Asserts a condition on an element.
*
* @param bool $condition
* @param string $message Failure message
* @param Element $element
*
* @throws ElementHtmlException when the condition is not fulfilled
*/
private function assertElement($condition, $message, Element $element)
{
if ($condition) {
return;
}
throw new ElementHtmlException($message, $this->session->getDriver(), $element);
}
/**
* Asserts a condition involving the text of an element.
*
* @param bool $condition
* @param string $message Failure message
* @param Element $element
*
* @throws ElementTextException when the condition is not fulfilled
*/
private function assertElementText($condition, $message, Element $element)
{
if ($condition) {
return;
}
throw new ElementTextException($message, $this->session->getDriver(), $element);
}
/**
* @param string $selectorType
* @param string|array $selector
* @param bool $plural
*
* @return string
*/
private function getMatchingElementRepresentation($selectorType, $selector, $plural = false)
{
$pluralization = $plural ? 's' : '';
if (in_array($selectorType, array('named', 'named_exact', 'named_partial'))
&& is_array($selector) && 2 === count($selector)
) {
return sprintf('%s%s matching locator "%s"', $selector[0], $pluralization, $selector[1]);
}
if (is_array($selector)) {
$selector = implode(' ', $selector);
}
return sprintf('element%s matching %s "%s"', $pluralization, $selectorType, $selector);
}
}