Commit c9fb29d5 authored by catch's avatar catch

Issue #2750941 by dawehner, klausi, jibran: Additional BC assertions from...

Issue #2750941 by dawehner, klausi, jibran: Additional BC assertions from WebTestBase to BrowserTestBase
parent 2125663d
......@@ -124,7 +124,7 @@ protected function assertResponse($code) {
protected function assertFieldByName($name, $value = NULL) {
$this->assertSession()->fieldExists($name);
if ($value !== NULL) {
$this->assertSession()->fieldValueEquals($name, $value);
$this->assertSession()->fieldValueEquals($name, (string) $value);
}
}
......@@ -147,6 +147,32 @@ protected function assertFieldById($id, $value = NULL) {
$this->assertFieldByName($id, $value);
}
/**
* Asserts that a field exists with the given name or ID.
*
* @param string $field
* Name or ID of field to assert.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->fieldExists() instead.
*/
protected function assertField($field) {
$this->assertSession()->fieldExists($field);
}
/**
* Asserts that a field exists with the given name or ID does NOT exist.
*
* @param string $field
* Name or ID of field to assert.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->fieldNotExists() instead.
*/
protected function assertNoField($field) {
$this->assertSession()->fieldNotExists($field);
}
/**
* Passes if the raw text IS found on the loaded page, fail otherwise.
*
......@@ -162,13 +188,33 @@ protected function assertRaw($raw) {
$this->assertSession()->responseContains($raw);
}
/**
* Passes if the raw text IS not found on the loaded page, fail otherwise.
*
* Raw text refers to the raw HTML that the page generated.
*
* @param string $raw
* Raw (HTML) string to look for.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->responseNotContains() instead.
*/
protected function assertNoRaw($raw) {
$this->assertSession()->responseNotContains($raw);
}
/**
* Pass if the page title is the given string.
*
* @param string $expected_title
* The string the page title should be.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->titleEquals() instead.
*/
protected function assertTitle($expected_title) {
// Cast MarkupInterface to string.
$expected_title = (string) $expected_title;
return $this->assertSession()->titleEquals($expected_title);
}
......@@ -181,11 +227,92 @@ protected function assertTitle($expected_title) {
* Text between the anchor tags.
* @param int $index
* Link position counting from zero.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->linkExists() instead.
*/
protected function assertLink($label, $index = 0) {
return $this->assertSession()->linkExists($label, $index);
}
/**
* Passes if a link with the specified label is not found.
*
* @param string|\Drupal\Component\Render\MarkupInterface $label
* Text between the anchor tags.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->linkNotExists() instead.
*/
protected function assertNoLink($label) {
return $this->assertSession()->linkNotExists($label);
}
/**
* Passes if a link containing a given href (part) is found.
*
* @param string $href
* The full or partial value of the 'href' attribute of the anchor tag.
* @param int $index
* Link position counting from zero.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->linkByHref() instead.
*/
protected function assertLinkByHref($href, $index = 0) {
$this->assertSession()->linkByHrefExists($href, $index);
}
/**
* Passes if a link containing a given href (part) is not found.
*
* @param string $href
* The full or partial value of the 'href' attribute of the anchor tag.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->linkByHrefNotExists() instead.
*/
protected function assertNoLinkByHref($href) {
$this->assertSession()->linkByHrefNotExists($href);
}
/**
* Asserts that a field does not exist with the given ID and value.
*
* @param string $id
* ID of field to assert.
* @param string $value
* (optional) Value for the field, to assert that the field's value on the
* page doesn't match it. You may pass in NULL to skip checking the value,
* while still checking that the field doesn't exist. However, the default
* value ('') asserts that the field value is not an empty string.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->fieldNotExists() or
* $this->assertSession()->fieldValueNotEquals() instead.
*/
protected function assertNoFieldById($id, $value = '') {
if ($this->getSession()->getPage()->findField($id)) {
$this->assertSession()->fieldValueNotEquals($id, (string) $value);
}
else {
$this->assertSession()->fieldNotExists($id);
}
}
/**
* Passes if the internal browser's URL matches the given path.
*
* @param \Drupal\Core\Url|string $path
* The expected system path or URL.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->addressEquals() instead.
*/
protected function assertUrl($path) {
$this->assertSession()->addressEquals($path);
}
/**
* Asserts that a select option in the current page exists.
*
......@@ -217,20 +344,22 @@ protected function assertNoOption($id, $option) {
}
/**
* Passes if the internal browser's URL matches the given path.
* Passes if the raw text IS found escaped on the loaded page, fail otherwise.
*
* @param string $path
* The expected system path.
* Raw text refers to the raw HTML that the page generated.
*
* @param string $raw
* Raw (HTML) string to look for.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->addressEquals() instead.
* Use $this->assertSession()->assertEscaped() instead.
*/
protected function assertUrl($path) {
$this->assertSession()->addressEquals($path);
protected function assertEscaped($raw) {
$this->assertSession()->assertEscaped($raw);
}
/**
* Passes if the raw text IS NOT found escaped on the loaded page.
* Passes if the raw text is not found escaped on the loaded page.
*
* Raw text refers to the raw HTML that the page generated.
*
......@@ -244,4 +373,55 @@ protected function assertNoEscaped($raw) {
$this->assertSession()->assertNoEscaped($raw);
}
/**
* Asserts whether an expected cache tag was present in the last response.
*
* @param string $expected_cache_tag
* The expected cache tag.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->responseHeaderContains() instead.
*/
protected function assertCacheTag($expected_cache_tag) {
$this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', $expected_cache_tag);
}
/**
* Returns WebAssert object.
*
* @param string $name
* (optional) Name of the session. Defaults to the active session.
*
* @return \Drupal\Tests\WebAssert
* A new web-assert option for asserting the presence of elements with.
*/
abstract public function assertSession($name = NULL);
/**
* Builds an XPath query.
*
* Builds an XPath query by replacing placeholders in the query by the value
* of the arguments.
*
* XPath 1.0 (the version supported by libxml2, the underlying XML library
* used by PHP) doesn't support any form of quotation. This function
* simplifies the building of XPath expression.
*
* @param string $xpath
* An XPath query, possibly with placeholders in the form ':name'.
* @param array $args
* An array of arguments with keys in the form ':name' matching the
* placeholders in the query. The values may be either strings or numeric
* values.
*
* @return string
* An XPath query with arguments replaced.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->buildXPathQuery() instead.
*/
public function buildXPathQuery($xpath, array $args = array()) {
return $this->assertSession()->buildXPathQuery($xpath, $args);
}
}
......@@ -43,11 +43,14 @@
*/
abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase {
use AssertHelperTrait;
use BlockCreationTrait;
use BlockCreationTrait {
placeBlock as drupalPlaceBlock;
}
use AssertLegacyTrait;
use RandomGeneratorTrait;
use SessionTestTrait;
use NodeCreationTrait {
getNodeByTitle as drupalGetNodeByTitle;
createNode as drupalCreateNode;
}
use ContentTypeCreationTrait {
......@@ -575,40 +578,60 @@ protected function prepareRequest() {
}
/**
* Retrieves a Drupal path or an absolute path.
* Builds an a absolute URL from a system path or a URL object.
*
* @param string|\Drupal\Core\Url $path
* Drupal path or URL to load into Mink controlled browser.
* A system path or a URL.
* @param array $options
* (optional) Options to be forwarded to the url generator.
* Options to be passed to Url::fromUri().
*
* @return string
* The retrieved HTML string, also available as $this->getRawContent()
* An absolute URL stsring.
*/
protected function drupalGet($path, array $options = array()) {
$options['absolute'] = TRUE;
protected function buildUrl($path, array $options = array()) {
if ($path instanceof Url) {
$url_options = $path->getOptions();
$options = $url_options + $options;
$path->setOptions($options);
$url = $path->setAbsolute()->toString();
return $path->setAbsolute()->toString();
}
// The URL generator service is not necessarily available yet; e.g., in
// interactive installer tests.
elseif ($this->container->has('url_generator')) {
if (UrlHelper::isExternal($path)) {
$url = Url::fromUri($path, $options)->toString();
$force_internal = isset($options['external']) && $options['external'] == FALSE;
if (!$force_internal && UrlHelper::isExternal($path)) {
return Url::fromUri($path, $options)->toString();
}
else {
// This is needed for language prefixing.
$options['path_processing'] = TRUE;
$url = Url::fromUri('base:/' . $path, $options)->toString();
$uri = $path === '<front>' ? 'base:/' : 'base:/' . $path;
// Path processing is needed for language prefixing. Skip it when a
// path that may look like an external URL is being used as internal.
$options['path_processing'] = !$force_internal;
return Url::fromUri($uri, $options)
->setAbsolute()
->toString();
}
}
else {
$url = $this->getAbsoluteUrl($path);
return $this->getAbsoluteUrl($path);
}
}
/**
* Retrieves a Drupal path or an absolute path.
*
* @param string|\Drupal\Core\Url $path
* Drupal path or URL to load into Mink controlled browser.
* @param array $options
* (optional) Options to be forwarded to the url generator.
*
* @return string
* The retrieved HTML string, also available as $this->getRawContent()
*/
protected function drupalGet($path, array $options = array()) {
$options['absolute'] = TRUE;
$url = $this->buildUrl($path, $options);
$session = $this->getSession();
$this->prepareRequest();
......@@ -902,6 +925,16 @@ protected function submitForm(array $edit, $submit, $form_html_id = NULL) {
// Edit the form values.
foreach ($edit as $name => $value) {
$field = $assert_session->fieldExists($name, $form);
// Provide support for the values '1' and '0' for checkboxes instead of
// TRUE and FALSE.
// @todo Get rid of supporting 1/0 by converting all tests cases using
// this to boolean values.
$field_type = $field->getAttribute('type');
if ($field_type === 'checkbox') {
$value = (bool) $value;
}
$field->setValue($value);
}
......@@ -1690,63 +1723,10 @@ protected function getTextContent() {
* The list of elements matching the xpath expression.
*/
protected function xpath($xpath, array $arguments = []) {
$xpath = $this->buildXPathQuery($xpath, $arguments);
$xpath = $this->assertSession()->buildXPathQuery($xpath, $arguments);
return $this->getSession()->getPage()->findAll('xpath', $xpath);
}
/**
* Builds an XPath query.
*
* Builds an XPath query by replacing placeholders in the query by the value
* of the arguments.
*
* XPath 1.0 (the version supported by libxml2, the underlying XML library
* used by PHP) doesn't support any form of quotation. This function
* simplifies the building of XPath expression.
*
* @param string $xpath
* An XPath query, possibly with placeholders in the form ':name'.
* @param array $args
* An array of arguments with keys in the form ':name' matching the
* placeholders in the query. The values may be either strings or numeric
* values.
*
* @return string
* An XPath query with arguments replaced.
*/
protected function buildXPathQuery($xpath, array $args = array()) {
// Replace placeholders.
foreach ($args as $placeholder => $value) {
// Cast MarkupInterface objects to string.
if (is_object($value)) {
$value = (string) $value;
}
// XPath 1.0 doesn't support a way to escape single or double quotes in a
// string literal. We split double quotes out of the string, and encode
// them separately.
if (is_string($value)) {
// Explode the text at the quote characters.
$parts = explode('"', $value);
// Quote the parts.
foreach ($parts as &$part) {
$part = '"' . $part . '"';
}
// Return the string.
$value = count($parts) > 1 ? 'concat(' . implode(', \'"\', ', $parts) . ')' : $parts[0];
}
// Use preg_replace_callback() instead of preg_replace() to prevent the
// regular expression engine from trying to substitute backreferences.
$replacement = function ($matches) use ($value) {
return $value;
};
$xpath = preg_replace_callback('/' . preg_quote($placeholder) . '\b/', $replacement, $xpath);
}
return $xpath;
}
/**
* Configuration accessor for tests. Returns non-overridden configuration.
*
......
......@@ -8,6 +8,7 @@
use Behat\Mink\Exception\ElementNotFoundException;
use Behat\Mink\Session;
use Drupal\Component\Utility\Html;
use Drupal\Core\Url;
/**
* Defines a class with methods for asserting presence of elements during tests.
......@@ -38,6 +39,9 @@ public function __construct(Session $session, $base_url = '') {
* {@inheritdoc}
*/
protected function cleanUrl($url) {
if ($url instanceof Url) {
$url = $url->setAbsolute()->toString();
}
// Strip the base URL from the beginning for absolute URLs.
if ($this->baseUrl !== '' && strpos($url, $this->baseUrl) === 0) {
$url = substr($url, strlen($this->baseUrl));
......@@ -75,6 +79,24 @@ public function buttonExists($button, TraversableElement $container = NULL) {
return $node;
}
/**
* Checks that the specific button does NOT exist on the current page.
*
* @param string $button
* One of id|name|label|value for the button.
* @param \Behat\Mink\Element\TraversableElement $container
* (optional) The document to check against. Defaults to the current page.
*
* @throws \Behat\Mink\Exception\ExpectationException
* When the button exists.
*/
public function buttonNotExists($button, TraversableElement $container = NULL) {
$container = $container ?: $this->session->getPage();
$node = $container->findButton($button);
$this->assert(NULL === $node, sprintf('A button "%s" appears on this page, but it should not.', $button));
}
/**
* Checks that specific select field exists on the current page.
*
......@@ -191,7 +213,7 @@ public function titleEquals($expected_title) {
*
* An optional link index may be passed.
*
* @param string|\Drupal\Component\Render\MarkupInterface $label
* @param string $label
* Text between the anchor tags.
* @param int $index
* Link position counting from zero.
......@@ -204,14 +226,126 @@ public function titleEquals($expected_title) {
* Thrown when element doesn't exist, or the link label is a different one.
*/
public function linkExists($label, $index = 0, $message = '') {
// Cast MarkupInterface objects to string.
$label = (string) $label;
$message = ($message ? $message : strtr('Link with label %label found.', ['%label' => $label]));
$links = $this->session->getPage()->findAll('named', ['link', $label]);
if (empty($links[$index])) {
throw new ExpectationException($message);
$this->assert(!empty($links[$index]), $message);
}
/**
* Passes if a link with the specified label is not found.
*
* An optional link index may be passed.
*
* @param string $label
* Text between the anchor tags.
* @param string $message
* (optional) A message to display with the assertion. Do not translate
* messages: use strtr() to embed variables in the message text, not
* t(). If left blank, a default message will be displayed.
*
* @throws \Behat\Mink\Exception\ExpectationException
* Thrown when element doesn't exist, or the link label is a different one.
*/
public function linkNotExists($label, $message = '') {
$message = ($message ? $message : strtr('Link with label %label found.', ['%label' => $label]));
$links = $this->session->getPage()->findAll('named', ['link', $label]);
$this->assert(empty($links), $message);
}
/**
* Passes if a link containing a given href (part) is found.
*
* @param string $href
* The full or partial value of the 'href' attribute of the anchor tag.
* @param int $index
* Link position counting from zero.
* @param string $message
* (optional) A message to display with the assertion. Do not translate
* messages: use \Drupal\Component\Utility\SafeMarkup::format() to embed
* variables in the message text, not t(). If left blank, a default message
* will be displayed.
*
* @throws \Behat\Mink\Exception\ExpectationException
* Thrown when element doesn't exist, or the link label is a different one.
*/
public function linkByHrefExists($href, $index = 0, $message = '') {
$xpath = $this->buildXPathQuery('//a[contains(@href, :href)]', [':href' => $href]);
$message = ($message ? $message : strtr('Link containing href %href found.', ['%href' => $href]));
$links = $this->session->getPage()->findAll('xpath', $xpath);
$this->assert(!empty($links[$index]), $message);
}
/**
* Passes if a link containing a given href (part) is not found.
*
* @param string $href
* The full or partial value of the 'href' attribute of the anchor tag.
* @param string $message
* (optional) A message to display with the assertion. Do not translate
* messages: use \Drupal\Component\Utility\SafeMarkup::format() to embed
* variables in the message text, not t(). If left blank, a default message
* will be displayed.
*
* @throws \Behat\Mink\Exception\ExpectationException
* Thrown when element doesn't exist, or the link label is a different one.
*/
public function linkByHrefNotExists($href, $message = '') {
$xpath = $this->buildXPathQuery('//a[contains(@href, :href)]', [':href' => $href]);
$message = ($message ? $message : strtr('Link containing href %href found.', ['%href' => $href]));
$links = $this->session->getPage()->findAll('xpath', $xpath);
$this->assert(empty($links), $message);
}
/**
* Builds an XPath query.
*
* Builds an XPath query by replacing placeholders in the query by the value
* of the arguments.
*
* XPath 1.0 (the version supported by libxml2, the underlying XML library
* used by PHP) doesn't support any form of quotation. This function
* simplifies the building of XPath expression.
*
* @param string $xpath
* An XPath query, possibly with placeholders in the form ':name'.
* @param array $args
* An array of arguments with keys in the form ':name' matching the
* placeholders in the query. The values may be either strings or numeric
* values.
*
* @return string
* An XPath query with arguments replaced.
*/
public function buildXPathQuery($xpath, array $args = array()) {
// Replace placeholders.
foreach ($args as $placeholder => $value) {
if (is_object($value)) {
throw new \InvalidArgumentException('Just pass in scalar values.');
}
// XPath 1.0 doesn't support a way to escape single or double quotes in a
// string literal. We split double quotes out of the string, and encode
// them separately.
if (is_string($value)) {
// Explode the text at the quote characters.
$parts = explode('"', $value);
// Quote the parts.
foreach ($parts as &$part) {
$part = '"' . $part . '"';
}
// Return the string.
$value = count($parts) > 1 ? 'concat(' . implode(', \'"\', ', $parts) . ')' : $parts[0];
}
// Use preg_replace_callback() instead of preg_replace() to prevent the
// regular expression engine from trying to substitute backreferences.
$replacement = function ($matches) use ($value) {
return $value;
};
$xpath = preg_replace_callback('/' . preg_quote($placeholder) . '\b/', $replacement, $xpath);
}
$this->assert($links[$index] !== NULL, $message);
return $xpath;
}
/**
......@@ -223,7 +357,19 @@ public function linkExists($label, $index = 0, $message = '') {
* Raw (HTML) string to look for.
*/
public function assertNoEscaped($raw) {
$this->pageTextNotContains(Html::escape($raw));
$this->responseNotContains(Html::escape($raw));
}
/**
* Passes if the raw text IS found escaped on the loaded page.
*
* Raw text refers to the raw HTML that the page generated.
*
* @param string $raw
* Raw (HTML) string to look for.
*/
public function assertEscaped($raw) {
$this->responseContains(Html::escape($raw));
}
/**
......@@ -247,4 +393,33 @@ public function assert($condition, $message) {
throw new ExpectationException($message, $this->session->getDriver());
}
/**
* Checks that a given form field element is disabled.
*
* @param string $field
* One of id|name|label|value for the field.
* @param \Behat\Mink\Element\TraversableElement $container
* (optional) The document to check against. Defaults to the current page.
*
* @return \Behat\Mink\Element\NodeElement
* The matching element.
*
* @throws \Behat\Mink\Exception\ElementNotFoundException
* @throws \Behat\Mink\Exception\ExpectationException
*/
public function fieldDisabled($field, TraversableElement $container = NULL) {
$container = $container ?: $this->session->getPage();
$node = $container->findField($field);
if ($node === NULL) {
throw new ElementNotFoundException($this->session->getDriver(), 'field', 'id|name|label|value', $field);
}
if (!$node->hasAttribute('disabled')) {
throw new ExpectationException("Field $field is disabled", $this->session->getDriver());
}
return $node;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment