2021-06-26 23:23:15 +08:00
|
|
|
<?php
|
2018-09-21 22:15:16 +08:00
|
|
|
|
2021-06-26 23:23:15 +08:00
|
|
|
namespace Tests;
|
|
|
|
|
2021-10-27 05:04:18 +08:00
|
|
|
use Illuminate\Testing\TestResponse as BaseTestResponse;
|
2018-09-21 22:15:16 +08:00
|
|
|
use PHPUnit\Framework\Assert as PHPUnit;
|
2021-06-26 23:23:15 +08:00
|
|
|
use Symfony\Component\DomCrawler\Crawler;
|
2018-09-21 22:15:16 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Class TestResponse
|
|
|
|
* Custom extension of the default Laravel TestResponse class.
|
|
|
|
*/
|
2021-06-26 23:23:15 +08:00
|
|
|
class TestResponse extends BaseTestResponse
|
|
|
|
{
|
2018-09-21 22:15:16 +08:00
|
|
|
protected $crawlerInstance;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the DOM Crawler for the response content.
|
|
|
|
*/
|
2020-11-06 20:54:39 +08:00
|
|
|
protected function crawler(): Crawler
|
2018-09-21 22:15:16 +08:00
|
|
|
{
|
|
|
|
if (!is_object($this->crawlerInstance)) {
|
|
|
|
$this->crawlerInstance = new Crawler($this->getContent());
|
|
|
|
}
|
2021-06-26 23:23:15 +08:00
|
|
|
|
2018-09-21 22:15:16 +08:00
|
|
|
return $this->crawlerInstance;
|
|
|
|
}
|
|
|
|
|
2021-07-03 02:51:30 +08:00
|
|
|
/**
|
|
|
|
* Get the HTML of the first element at the given selector.
|
|
|
|
*/
|
|
|
|
public function getElementHtml(string $selector): string
|
|
|
|
{
|
|
|
|
return $this->crawler()->filter($selector)->first()->outerHtml();
|
|
|
|
}
|
|
|
|
|
2018-09-21 22:15:16 +08:00
|
|
|
/**
|
|
|
|
* Assert the response contains the specified element.
|
2021-06-26 23:23:15 +08:00
|
|
|
*
|
2018-09-21 22:15:16 +08:00
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function assertElementExists(string $selector)
|
|
|
|
{
|
|
|
|
$elements = $this->crawler()->filter($selector);
|
|
|
|
PHPUnit::assertTrue(
|
|
|
|
$elements->count() > 0,
|
2021-06-26 23:23:15 +08:00
|
|
|
'Unable to find element matching the selector: ' . PHP_EOL . PHP_EOL .
|
|
|
|
"[{$selector}]" . PHP_EOL . PHP_EOL .
|
|
|
|
'within' . PHP_EOL . PHP_EOL .
|
2018-09-21 22:15:16 +08:00
|
|
|
"[{$this->getContent()}]."
|
|
|
|
);
|
2021-06-26 23:23:15 +08:00
|
|
|
|
2018-09-21 22:15:16 +08:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2021-11-07 05:54:02 +08:00
|
|
|
/**
|
|
|
|
* Assert the response contains the given count of elements
|
|
|
|
* that match the given css selector.
|
|
|
|
*
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function assertElementCount(string $selector, int $count)
|
|
|
|
{
|
|
|
|
$elements = $this->crawler()->filter($selector);
|
|
|
|
PHPUnit::assertTrue(
|
|
|
|
$elements->count() === $count,
|
|
|
|
'Unable to ' . $count . ' element(s) matching the selector: ' . PHP_EOL . PHP_EOL .
|
|
|
|
"[{$selector}]" . PHP_EOL . PHP_EOL .
|
|
|
|
'found ' . $elements->count() . ' within' . PHP_EOL . PHP_EOL .
|
|
|
|
"[{$this->getContent()}]."
|
|
|
|
);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2018-09-21 22:15:16 +08:00
|
|
|
/**
|
|
|
|
* Assert the response does not contain the specified element.
|
2021-06-26 23:23:15 +08:00
|
|
|
*
|
2018-09-21 22:15:16 +08:00
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function assertElementNotExists(string $selector)
|
|
|
|
{
|
|
|
|
$elements = $this->crawler()->filter($selector);
|
|
|
|
PHPUnit::assertTrue(
|
|
|
|
$elements->count() === 0,
|
2021-06-26 23:23:15 +08:00
|
|
|
'Found elements matching the selector: ' . PHP_EOL . PHP_EOL .
|
|
|
|
"[{$selector}]" . PHP_EOL . PHP_EOL .
|
|
|
|
'within' . PHP_EOL . PHP_EOL .
|
2018-09-21 22:15:16 +08:00
|
|
|
"[{$this->getContent()}]."
|
|
|
|
);
|
2021-06-26 23:23:15 +08:00
|
|
|
|
2018-09-21 22:15:16 +08:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Assert the response includes a specific element containing the given text.
|
2021-03-22 07:06:15 +08:00
|
|
|
* If an nth match is provided, only that will be checked otherwise all matching
|
|
|
|
* elements will be checked for the given text.
|
2021-06-26 23:23:15 +08:00
|
|
|
*
|
2018-09-21 22:15:16 +08:00
|
|
|
* @return $this
|
|
|
|
*/
|
2021-03-22 07:06:15 +08:00
|
|
|
public function assertElementContains(string $selector, string $text, ?int $nthMatch = null)
|
2018-09-21 22:15:16 +08:00
|
|
|
{
|
|
|
|
$elements = $this->crawler()->filter($selector);
|
|
|
|
$matched = false;
|
|
|
|
$pattern = $this->getEscapedPattern($text);
|
2021-03-22 07:06:15 +08:00
|
|
|
|
|
|
|
if (!is_null($nthMatch)) {
|
|
|
|
$elements = $elements->eq($nthMatch - 1);
|
|
|
|
}
|
|
|
|
|
2018-09-21 22:15:16 +08:00
|
|
|
foreach ($elements as $element) {
|
|
|
|
$element = new Crawler($element);
|
2022-05-16 21:05:21 +08:00
|
|
|
if (preg_match("/$pattern/i", $element->text())) {
|
2018-09-21 22:15:16 +08:00
|
|
|
$matched = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PHPUnit::assertTrue(
|
|
|
|
$matched,
|
2021-06-26 23:23:15 +08:00
|
|
|
'Unable to find element of selector: ' . PHP_EOL . PHP_EOL .
|
|
|
|
($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
|
|
|
|
"[{$selector}]" . PHP_EOL . PHP_EOL .
|
|
|
|
'containing text' . PHP_EOL . PHP_EOL .
|
|
|
|
"[{$text}]" . PHP_EOL . PHP_EOL .
|
|
|
|
'within' . PHP_EOL . PHP_EOL .
|
2018-09-21 22:15:16 +08:00
|
|
|
"[{$this->getContent()}]."
|
|
|
|
);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Assert the response does not include a specific element containing the given text.
|
2021-03-22 07:06:15 +08:00
|
|
|
* If an nth match is provided, only that will be checked otherwise all matching
|
|
|
|
* elements will be checked for the given text.
|
2021-06-26 23:23:15 +08:00
|
|
|
*
|
2018-09-21 22:15:16 +08:00
|
|
|
* @return $this
|
|
|
|
*/
|
2021-03-22 07:06:15 +08:00
|
|
|
public function assertElementNotContains(string $selector, string $text, ?int $nthMatch = null)
|
2018-09-21 22:15:16 +08:00
|
|
|
{
|
|
|
|
$elements = $this->crawler()->filter($selector);
|
|
|
|
$matched = false;
|
|
|
|
$pattern = $this->getEscapedPattern($text);
|
2021-03-22 07:06:15 +08:00
|
|
|
|
|
|
|
if (!is_null($nthMatch)) {
|
|
|
|
$elements = $elements->eq($nthMatch - 1);
|
|
|
|
}
|
|
|
|
|
2018-09-21 22:15:16 +08:00
|
|
|
foreach ($elements as $element) {
|
|
|
|
$element = new Crawler($element);
|
|
|
|
if (preg_match("/$pattern/i", $element->html())) {
|
|
|
|
$matched = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PHPUnit::assertTrue(
|
|
|
|
!$matched,
|
2021-06-26 23:23:15 +08:00
|
|
|
'Found element of selector: ' . PHP_EOL . PHP_EOL .
|
|
|
|
($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
|
|
|
|
"[{$selector}]" . PHP_EOL . PHP_EOL .
|
|
|
|
'containing text' . PHP_EOL . PHP_EOL .
|
|
|
|
"[{$text}]" . PHP_EOL . PHP_EOL .
|
|
|
|
'within' . PHP_EOL . PHP_EOL .
|
2018-09-21 22:15:16 +08:00
|
|
|
"[{$this->getContent()}]."
|
|
|
|
);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2020-11-06 20:54:39 +08:00
|
|
|
/**
|
|
|
|
* Assert there's a notification within the view containing the given text.
|
2021-06-26 23:23:15 +08:00
|
|
|
*
|
2020-11-06 20:54:39 +08:00
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function assertNotificationContains(string $text)
|
|
|
|
{
|
|
|
|
return $this->assertElementContains('[notification]', $text);
|
|
|
|
}
|
|
|
|
|
2018-09-21 22:15:16 +08:00
|
|
|
/**
|
|
|
|
* Get the escaped text pattern for the constraint.
|
2021-06-26 23:23:15 +08:00
|
|
|
*
|
2018-09-21 22:15:16 +08:00
|
|
|
* @return string
|
|
|
|
*/
|
2020-11-06 20:54:39 +08:00
|
|
|
protected function getEscapedPattern(string $text)
|
2018-09-21 22:15:16 +08:00
|
|
|
{
|
|
|
|
$rawPattern = preg_quote($text, '/');
|
|
|
|
$escapedPattern = preg_quote(e($text), '/');
|
2021-06-26 23:23:15 +08:00
|
|
|
|
2018-09-21 22:15:16 +08:00
|
|
|
return $rawPattern == $escapedPattern
|
|
|
|
? $rawPattern : "({$rawPattern}|{$escapedPattern})";
|
|
|
|
}
|
|
|
|
}
|