Mercurial > hg > cmmr2012-drupal-site
comparison core/tests/Drupal/Tests/WebAssert.php @ 0:c75dbcec494b
Initial commit from drush-created site
author | Chris Cannam |
---|---|
date | Thu, 05 Jul 2018 14:24:15 +0000 |
parents | |
children | a9cd425dd02b |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c75dbcec494b |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Tests; | |
4 | |
5 use Behat\Mink\Exception\ExpectationException; | |
6 use Behat\Mink\WebAssert as MinkWebAssert; | |
7 use Behat\Mink\Element\TraversableElement; | |
8 use Behat\Mink\Exception\ElementNotFoundException; | |
9 use Behat\Mink\Session; | |
10 use Drupal\Component\Utility\Html; | |
11 use Drupal\Core\Url; | |
12 | |
13 /** | |
14 * Defines a class with methods for asserting presence of elements during tests. | |
15 */ | |
16 class WebAssert extends MinkWebAssert { | |
17 | |
18 /** | |
19 * The absolute URL of the site under test. | |
20 * | |
21 * @var string | |
22 */ | |
23 protected $baseUrl = ''; | |
24 | |
25 /** | |
26 * Constructor. | |
27 * | |
28 * @param \Behat\Mink\Session $session | |
29 * The Behat session object; | |
30 * @param string $base_url | |
31 * The base URL of the site under test. | |
32 */ | |
33 public function __construct(Session $session, $base_url = '') { | |
34 parent::__construct($session); | |
35 $this->baseUrl = $base_url; | |
36 } | |
37 | |
38 /** | |
39 * {@inheritdoc} | |
40 */ | |
41 protected function cleanUrl($url) { | |
42 if ($url instanceof Url) { | |
43 $url = $url->setAbsolute()->toString(); | |
44 } | |
45 // Strip the base URL from the beginning for absolute URLs. | |
46 if ($this->baseUrl !== '' && strpos($url, $this->baseUrl) === 0) { | |
47 $url = substr($url, strlen($this->baseUrl)); | |
48 } | |
49 // Make sure there is a forward slash at the beginning of relative URLs for | |
50 // consistency. | |
51 if (parse_url($url, PHP_URL_HOST) === NULL && strpos($url, '/') !== 0) { | |
52 $url = "/$url"; | |
53 } | |
54 return parent::cleanUrl($url); | |
55 } | |
56 | |
57 /** | |
58 * Checks that specific button exists on the current page. | |
59 * | |
60 * @param string $button | |
61 * One of id|name|label|value for the button. | |
62 * @param \Behat\Mink\Element\TraversableElement $container | |
63 * (optional) The document to check against. Defaults to the current page. | |
64 * | |
65 * @return \Behat\Mink\Element\NodeElement | |
66 * The matching element. | |
67 * | |
68 * @throws \Behat\Mink\Exception\ElementNotFoundException | |
69 * When the element doesn't exist. | |
70 */ | |
71 public function buttonExists($button, TraversableElement $container = NULL) { | |
72 $container = $container ?: $this->session->getPage(); | |
73 $node = $container->findButton($button); | |
74 | |
75 if ($node === NULL) { | |
76 throw new ElementNotFoundException($this->session, 'button', 'id|name|label|value', $button); | |
77 } | |
78 | |
79 return $node; | |
80 } | |
81 | |
82 /** | |
83 * Checks that the specific button does NOT exist on the current page. | |
84 * | |
85 * @param string $button | |
86 * One of id|name|label|value for the button. | |
87 * @param \Behat\Mink\Element\TraversableElement $container | |
88 * (optional) The document to check against. Defaults to the current page. | |
89 * | |
90 * @throws \Behat\Mink\Exception\ExpectationException | |
91 * When the button exists. | |
92 */ | |
93 public function buttonNotExists($button, TraversableElement $container = NULL) { | |
94 $container = $container ?: $this->session->getPage(); | |
95 $node = $container->findButton($button); | |
96 | |
97 $this->assert(NULL === $node, sprintf('A button "%s" appears on this page, but it should not.', $button)); | |
98 } | |
99 | |
100 /** | |
101 * Checks that specific select field exists on the current page. | |
102 * | |
103 * @param string $select | |
104 * One of id|name|label|value for the select field. | |
105 * @param \Behat\Mink\Element\TraversableElement $container | |
106 * (optional) The document to check against. Defaults to the current page. | |
107 * | |
108 * @return \Behat\Mink\Element\NodeElement | |
109 * The matching element | |
110 * | |
111 * @throws \Behat\Mink\Exception\ElementNotFoundException | |
112 * When the element doesn't exist. | |
113 */ | |
114 public function selectExists($select, TraversableElement $container = NULL) { | |
115 $container = $container ?: $this->session->getPage(); | |
116 $node = $container->find('named', [ | |
117 'select', | |
118 $this->session->getSelectorsHandler()->xpathLiteral($select), | |
119 ]); | |
120 | |
121 if ($node === NULL) { | |
122 throw new ElementNotFoundException($this->session, 'select', 'id|name|label|value', $select); | |
123 } | |
124 | |
125 return $node; | |
126 } | |
127 | |
128 /** | |
129 * Checks that specific option in a select field exists on the current page. | |
130 * | |
131 * @param string $select | |
132 * One of id|name|label|value for the select field. | |
133 * @param string $option | |
134 * The option value. | |
135 * @param \Behat\Mink\Element\TraversableElement $container | |
136 * (optional) The document to check against. Defaults to the current page. | |
137 * | |
138 * @return \Behat\Mink\Element\NodeElement | |
139 * The matching option element | |
140 * | |
141 * @throws \Behat\Mink\Exception\ElementNotFoundException | |
142 * When the element doesn't exist. | |
143 */ | |
144 public function optionExists($select, $option, TraversableElement $container = NULL) { | |
145 $container = $container ?: $this->session->getPage(); | |
146 $select_field = $container->find('named', [ | |
147 'select', | |
148 $this->session->getSelectorsHandler()->xpathLiteral($select), | |
149 ]); | |
150 | |
151 if ($select_field === NULL) { | |
152 throw new ElementNotFoundException($this->session, 'select', 'id|name|label|value', $select); | |
153 } | |
154 | |
155 $option_field = $select_field->find('named', ['option', $option]); | |
156 | |
157 if ($option_field === NULL) { | |
158 throw new ElementNotFoundException($this->session, 'select', 'id|name|label|value', $option); | |
159 } | |
160 | |
161 return $option_field; | |
162 } | |
163 | |
164 /** | |
165 * Checks that an option in a select field does NOT exist on the current page. | |
166 * | |
167 * @param string $select | |
168 * One of id|name|label|value for the select field. | |
169 * @param string $option | |
170 * The option value that shoulkd not exist. | |
171 * @param \Behat\Mink\Element\TraversableElement $container | |
172 * (optional) The document to check against. Defaults to the current page. | |
173 * | |
174 * @throws \Behat\Mink\Exception\ElementNotFoundException | |
175 * When the select element doesn't exist. | |
176 */ | |
177 public function optionNotExists($select, $option, TraversableElement $container = NULL) { | |
178 $container = $container ?: $this->session->getPage(); | |
179 $select_field = $container->find('named', [ | |
180 'select', | |
181 $this->session->getSelectorsHandler()->xpathLiteral($select), | |
182 ]); | |
183 | |
184 if ($select_field === NULL) { | |
185 throw new ElementNotFoundException($this->session, 'select', 'id|name|label|value', $select); | |
186 } | |
187 | |
188 $option_field = $select_field->find('named', ['option', $option]); | |
189 | |
190 $this->assert($option_field === NULL, sprintf('An option "%s" exists in select "%s", but it should not.', $option, $select)); | |
191 } | |
192 | |
193 /** | |
194 * Pass if the page title is the given string. | |
195 * | |
196 * @param string $expected_title | |
197 * The string the page title should be. | |
198 * | |
199 * @throws \Behat\Mink\Exception\ExpectationException | |
200 * Thrown when element doesn't exist, or the title is a different one. | |
201 */ | |
202 public function titleEquals($expected_title) { | |
203 $title_element = $this->session->getPage()->find('css', 'title'); | |
204 if (!$title_element) { | |
205 throw new ExpectationException('No title element found on the page', $this->session->getDriver()); | |
206 } | |
207 $actual_title = $title_element->getText(); | |
208 $this->assert($expected_title === $actual_title, 'Title found'); | |
209 } | |
210 | |
211 /** | |
212 * Passes if a link with the specified label is found. | |
213 * | |
214 * An optional link index may be passed. | |
215 * | |
216 * @param string $label | |
217 * Text between the anchor tags. | |
218 * @param int $index | |
219 * Link position counting from zero. | |
220 * @param string $message | |
221 * (optional) A message to display with the assertion. Do not translate | |
222 * messages: use strtr() to embed variables in the message text, not | |
223 * t(). If left blank, a default message will be displayed. | |
224 * | |
225 * @throws \Behat\Mink\Exception\ExpectationException | |
226 * Thrown when element doesn't exist, or the link label is a different one. | |
227 */ | |
228 public function linkExists($label, $index = 0, $message = '') { | |
229 $message = ($message ? $message : strtr('Link with label %label found.', ['%label' => $label])); | |
230 $links = $this->session->getPage()->findAll('named', ['link', $label]); | |
231 $this->assert(!empty($links[$index]), $message); | |
232 } | |
233 | |
234 /** | |
235 * Passes if a link with the exactly specified label is found. | |
236 * | |
237 * An optional link index may be passed. | |
238 * | |
239 * @param string $label | |
240 * Text between the anchor tags. | |
241 * @param int $index | |
242 * Link position counting from zero. | |
243 * @param string $message | |
244 * (optional) A message to display with the assertion. Do not translate | |
245 * messages: use strtr() to embed variables in the message text, not | |
246 * t(). If left blank, a default message will be displayed. | |
247 * | |
248 * @throws \Behat\Mink\Exception\ExpectationException | |
249 * Thrown when element doesn't exist, or the link label is a different one. | |
250 */ | |
251 public function linkExistsExact($label, $index = 0, $message = '') { | |
252 $message = ($message ? $message : strtr('Link with label %label found.', ['%label' => $label])); | |
253 $links = $this->session->getPage()->findAll('named_exact', ['link', $label]); | |
254 $this->assert(!empty($links[$index]), $message); | |
255 } | |
256 | |
257 /** | |
258 * Passes if a link with the specified label is not found. | |
259 * | |
260 * An optional link index may be passed. | |
261 * | |
262 * @param string $label | |
263 * Text between the anchor tags. | |
264 * @param string $message | |
265 * (optional) A message to display with the assertion. Do not translate | |
266 * messages: use strtr() to embed variables in the message text, not | |
267 * t(). If left blank, a default message will be displayed. | |
268 * | |
269 * @throws \Behat\Mink\Exception\ExpectationException | |
270 * Thrown when element doesn't exist, or the link label is a different one. | |
271 */ | |
272 public function linkNotExists($label, $message = '') { | |
273 $message = ($message ? $message : strtr('Link with label %label not found.', ['%label' => $label])); | |
274 $links = $this->session->getPage()->findAll('named', ['link', $label]); | |
275 $this->assert(empty($links), $message); | |
276 } | |
277 | |
278 /** | |
279 * Passes if a link with the exactly specified label is not found. | |
280 * | |
281 * An optional link index may be passed. | |
282 * | |
283 * @param string $label | |
284 * Text between the anchor tags. | |
285 * @param string $message | |
286 * (optional) A message to display with the assertion. Do not translate | |
287 * messages: use strtr() to embed variables in the message text, not | |
288 * t(). If left blank, a default message will be displayed. | |
289 * | |
290 * @throws \Behat\Mink\Exception\ExpectationException | |
291 * Thrown when element doesn't exist, or the link label is a different one. | |
292 */ | |
293 public function linkNotExistsExact($label, $message = '') { | |
294 $message = ($message ? $message : strtr('Link with label %label not found.', ['%label' => $label])); | |
295 $links = $this->session->getPage()->findAll('named_exact', ['link', $label]); | |
296 $this->assert(empty($links), $message); | |
297 } | |
298 | |
299 /** | |
300 * Passes if a link containing a given href (part) is found. | |
301 * | |
302 * @param string $href | |
303 * The full or partial value of the 'href' attribute of the anchor tag. | |
304 * @param int $index | |
305 * Link position counting from zero. | |
306 * @param string $message | |
307 * (optional) A message to display with the assertion. Do not translate | |
308 * messages: use \Drupal\Component\Utility\SafeMarkup::format() to embed | |
309 * variables in the message text, not t(). If left blank, a default message | |
310 * will be displayed. | |
311 * | |
312 * @throws \Behat\Mink\Exception\ExpectationException | |
313 * Thrown when element doesn't exist, or the link label is a different one. | |
314 */ | |
315 public function linkByHrefExists($href, $index = 0, $message = '') { | |
316 $xpath = $this->buildXPathQuery('//a[contains(@href, :href)]', [':href' => $href]); | |
317 $message = ($message ? $message : strtr('Link containing href %href found.', ['%href' => $href])); | |
318 $links = $this->session->getPage()->findAll('xpath', $xpath); | |
319 $this->assert(!empty($links[$index]), $message); | |
320 } | |
321 | |
322 /** | |
323 * Passes if a link containing a given href (part) is not found. | |
324 * | |
325 * @param string $href | |
326 * The full or partial value of the 'href' attribute of the anchor tag. | |
327 * @param string $message | |
328 * (optional) A message to display with the assertion. Do not translate | |
329 * messages: use \Drupal\Component\Utility\SafeMarkup::format() to embed | |
330 * variables in the message text, not t(). If left blank, a default message | |
331 * will be displayed. | |
332 * | |
333 * @throws \Behat\Mink\Exception\ExpectationException | |
334 * Thrown when element doesn't exist, or the link label is a different one. | |
335 */ | |
336 public function linkByHrefNotExists($href, $message = '') { | |
337 $xpath = $this->buildXPathQuery('//a[contains(@href, :href)]', [':href' => $href]); | |
338 $message = ($message ? $message : strtr('No link containing href %href found.', ['%href' => $href])); | |
339 $links = $this->session->getPage()->findAll('xpath', $xpath); | |
340 $this->assert(empty($links), $message); | |
341 } | |
342 | |
343 /** | |
344 * Builds an XPath query. | |
345 * | |
346 * Builds an XPath query by replacing placeholders in the query by the value | |
347 * of the arguments. | |
348 * | |
349 * XPath 1.0 (the version supported by libxml2, the underlying XML library | |
350 * used by PHP) doesn't support any form of quotation. This function | |
351 * simplifies the building of XPath expression. | |
352 * | |
353 * @param string $xpath | |
354 * An XPath query, possibly with placeholders in the form ':name'. | |
355 * @param array $args | |
356 * An array of arguments with keys in the form ':name' matching the | |
357 * placeholders in the query. The values may be either strings or numeric | |
358 * values. | |
359 * | |
360 * @return string | |
361 * An XPath query with arguments replaced. | |
362 */ | |
363 public function buildXPathQuery($xpath, array $args = []) { | |
364 // Replace placeholders. | |
365 foreach ($args as $placeholder => $value) { | |
366 if (is_object($value)) { | |
367 throw new \InvalidArgumentException('Just pass in scalar values for $args and remove all t() calls from your test.'); | |
368 } | |
369 // XPath 1.0 doesn't support a way to escape single or double quotes in a | |
370 // string literal. We split double quotes out of the string, and encode | |
371 // them separately. | |
372 if (is_string($value)) { | |
373 // Explode the text at the quote characters. | |
374 $parts = explode('"', $value); | |
375 | |
376 // Quote the parts. | |
377 foreach ($parts as &$part) { | |
378 $part = '"' . $part . '"'; | |
379 } | |
380 | |
381 // Return the string. | |
382 $value = count($parts) > 1 ? 'concat(' . implode(', \'"\', ', $parts) . ')' : $parts[0]; | |
383 } | |
384 | |
385 // Use preg_replace_callback() instead of preg_replace() to prevent the | |
386 // regular expression engine from trying to substitute backreferences. | |
387 $replacement = function ($matches) use ($value) { | |
388 return $value; | |
389 }; | |
390 $xpath = preg_replace_callback('/' . preg_quote($placeholder) . '\b/', $replacement, $xpath); | |
391 } | |
392 return $xpath; | |
393 } | |
394 | |
395 /** | |
396 * Passes if the raw text IS NOT found escaped on the loaded page. | |
397 * | |
398 * Raw text refers to the raw HTML that the page generated. | |
399 * | |
400 * @param string $raw | |
401 * Raw (HTML) string to look for. | |
402 */ | |
403 public function assertNoEscaped($raw) { | |
404 $this->responseNotContains(Html::escape($raw)); | |
405 } | |
406 | |
407 /** | |
408 * Passes if the raw text IS found escaped on the loaded page. | |
409 * | |
410 * Raw text refers to the raw HTML that the page generated. | |
411 * | |
412 * @param string $raw | |
413 * Raw (HTML) string to look for. | |
414 */ | |
415 public function assertEscaped($raw) { | |
416 $this->responseContains(Html::escape($raw)); | |
417 } | |
418 | |
419 /** | |
420 * Asserts a condition. | |
421 * | |
422 * The parent method is overridden because it is a private method. | |
423 * | |
424 * @param bool $condition | |
425 * The condition. | |
426 * @param string $message | |
427 * The success message. | |
428 * | |
429 * @throws \Behat\Mink\Exception\ExpectationException | |
430 * When the condition is not fulfilled. | |
431 */ | |
432 public function assert($condition, $message) { | |
433 if ($condition) { | |
434 return; | |
435 } | |
436 | |
437 throw new ExpectationException($message, $this->session->getDriver()); | |
438 } | |
439 | |
440 /** | |
441 * Checks that a given form field element is disabled. | |
442 * | |
443 * @param string $field | |
444 * One of id|name|label|value for the field. | |
445 * @param \Behat\Mink\Element\TraversableElement $container | |
446 * (optional) The document to check against. Defaults to the current page. | |
447 * | |
448 * @return \Behat\Mink\Element\NodeElement | |
449 * The matching element. | |
450 * | |
451 * @throws \Behat\Mink\Exception\ElementNotFoundException | |
452 * @throws \Behat\Mink\Exception\ExpectationException | |
453 */ | |
454 public function fieldDisabled($field, TraversableElement $container = NULL) { | |
455 $container = $container ?: $this->session->getPage(); | |
456 $node = $container->findField($field); | |
457 | |
458 if ($node === NULL) { | |
459 throw new ElementNotFoundException($this->session->getDriver(), 'field', 'id|name|label|value', $field); | |
460 } | |
461 | |
462 if (!$node->hasAttribute('disabled')) { | |
463 throw new ExpectationException("Field $field is disabled", $this->session->getDriver()); | |
464 } | |
465 | |
466 return $node; | |
467 } | |
468 | |
469 /** | |
470 * Checks that specific hidden field exists. | |
471 * | |
472 * @param string $field | |
473 * One of id|name|value for the hidden field. | |
474 * @param \Behat\Mink\Element\TraversableElement $container | |
475 * (optional) The document to check against. Defaults to the current page. | |
476 * | |
477 * @return \Behat\Mink\Element\NodeElement | |
478 * The matching element. | |
479 * | |
480 * @throws \Behat\Mink\Exception\ElementNotFoundException | |
481 */ | |
482 public function hiddenFieldExists($field, TraversableElement $container = NULL) { | |
483 $container = $container ?: $this->session->getPage(); | |
484 if ($node = $container->find('hidden_field_selector', ['hidden_field', $field])) { | |
485 return $node; | |
486 } | |
487 throw new ElementNotFoundException($this->session->getDriver(), 'form hidden field', 'id|name|value', $field); | |
488 } | |
489 | |
490 /** | |
491 * Checks that specific hidden field does not exists. | |
492 * | |
493 * @param string $field | |
494 * One of id|name|value for the hidden field. | |
495 * @param \Behat\Mink\Element\TraversableElement $container | |
496 * (optional) The document to check against. Defaults to the current page. | |
497 * | |
498 * @throws \Behat\Mink\Exception\ExpectationException | |
499 */ | |
500 public function hiddenFieldNotExists($field, TraversableElement $container = NULL) { | |
501 $container = $container ?: $this->session->getPage(); | |
502 $node = $container->find('hidden_field_selector', ['hidden_field', $field]); | |
503 $this->assert($node === NULL, "A hidden field '$field' exists on this page, but it should not."); | |
504 } | |
505 | |
506 /** | |
507 * Checks that specific hidden field have provided value. | |
508 * | |
509 * @param string $field | |
510 * One of id|name|value for the hidden field. | |
511 * @param string $value | |
512 * The hidden field value that needs to be checked. | |
513 * @param \Behat\Mink\Element\TraversableElement $container | |
514 * (optional) The document to check against. Defaults to the current page. | |
515 * | |
516 * @throws \Behat\Mink\Exception\ElementNotFoundException | |
517 * @throws \Behat\Mink\Exception\ExpectationException | |
518 */ | |
519 public function hiddenFieldValueEquals($field, $value, TraversableElement $container = NULL) { | |
520 $node = $this->hiddenFieldExists($field, $container); | |
521 $actual = $node->getValue(); | |
522 $regex = '/^' . preg_quote($value, '/') . '$/ui'; | |
523 $message = "The hidden field '$field' value is '$actual', but '$value' expected."; | |
524 $this->assert((bool) preg_match($regex, $actual), $message); | |
525 } | |
526 | |
527 /** | |
528 * Checks that specific hidden field doesn't have the provided value. | |
529 * | |
530 * @param string $field | |
531 * One of id|name|value for the hidden field. | |
532 * @param string $value | |
533 * The hidden field value that needs to be checked. | |
534 * @param \Behat\Mink\Element\TraversableElement $container | |
535 * (optional) The document to check against. Defaults to the current page. | |
536 * | |
537 * @throws \Behat\Mink\Exception\ElementNotFoundException | |
538 * @throws \Behat\Mink\Exception\ExpectationException | |
539 */ | |
540 public function hiddenFieldValueNotEquals($field, $value, TraversableElement $container = NULL) { | |
541 $node = $this->hiddenFieldExists($field, $container); | |
542 $actual = $node->getValue(); | |
543 $regex = '/^' . preg_quote($value, '/') . '$/ui'; | |
544 $message = "The hidden field '$field' value is '$actual', but it should not be."; | |
545 $this->assert(!preg_match($regex, $actual), $message); | |
546 } | |
547 | |
548 } |