5 use Illuminate\Foundation\Testing\TestResponse as BaseTestResponse;
6 use PHPUnit\Framework\Assert as PHPUnit;
7 use Symfony\Component\DomCrawler\Crawler;
11 * Custom extension of the default Laravel TestResponse class.
13 class TestResponse extends BaseTestResponse
15 protected $crawlerInstance;
18 * Get the DOM Crawler for the response content.
20 protected function crawler(): Crawler
22 if (!is_object($this->crawlerInstance)) {
23 $this->crawlerInstance = new Crawler($this->getContent());
26 return $this->crawlerInstance;
30 * Assert the response contains the specified element.
34 public function assertElementExists(string $selector)
36 $elements = $this->crawler()->filter($selector);
38 $elements->count() > 0,
39 'Unable to find element matching the selector: ' . PHP_EOL . PHP_EOL .
40 "[{$selector}]" . PHP_EOL . PHP_EOL .
41 'within' . PHP_EOL . PHP_EOL .
42 "[{$this->getContent()}]."
49 * Assert the response does not contain the specified element.
53 public function assertElementNotExists(string $selector)
55 $elements = $this->crawler()->filter($selector);
57 $elements->count() === 0,
58 'Found elements matching the selector: ' . PHP_EOL . PHP_EOL .
59 "[{$selector}]" . PHP_EOL . PHP_EOL .
60 'within' . PHP_EOL . PHP_EOL .
61 "[{$this->getContent()}]."
68 * Assert the response includes a specific element containing the given text.
69 * If an nth match is provided, only that will be checked otherwise all matching
70 * elements will be checked for the given text.
74 public function assertElementContains(string $selector, string $text, ?int $nthMatch = null)
76 $elements = $this->crawler()->filter($selector);
78 $pattern = $this->getEscapedPattern($text);
80 if (!is_null($nthMatch)) {
81 $elements = $elements->eq($nthMatch - 1);
84 foreach ($elements as $element) {
85 $element = new Crawler($element);
86 if (preg_match("/$pattern/i", $element->html())) {
94 'Unable to find element of selector: ' . PHP_EOL . PHP_EOL .
95 ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
96 "[{$selector}]" . PHP_EOL . PHP_EOL .
97 'containing text' . PHP_EOL . PHP_EOL .
98 "[{$text}]" . PHP_EOL . PHP_EOL .
99 'within' . PHP_EOL . PHP_EOL .
100 "[{$this->getContent()}]."
107 * Assert the response does not include a specific element containing the given text.
108 * If an nth match is provided, only that will be checked otherwise all matching
109 * elements will be checked for the given text.
113 public function assertElementNotContains(string $selector, string $text, ?int $nthMatch = null)
115 $elements = $this->crawler()->filter($selector);
117 $pattern = $this->getEscapedPattern($text);
119 if (!is_null($nthMatch)) {
120 $elements = $elements->eq($nthMatch - 1);
123 foreach ($elements as $element) {
124 $element = new Crawler($element);
125 if (preg_match("/$pattern/i", $element->html())) {
133 'Found element of selector: ' . PHP_EOL . PHP_EOL .
134 ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
135 "[{$selector}]" . PHP_EOL . PHP_EOL .
136 'containing text' . PHP_EOL . PHP_EOL .
137 "[{$text}]" . PHP_EOL . PHP_EOL .
138 'within' . PHP_EOL . PHP_EOL .
139 "[{$this->getContent()}]."
146 * Assert there's a notification within the view containing the given text.
150 public function assertNotificationContains(string $text)
152 return $this->assertElementContains('[notification]', $text);
156 * Get the escaped text pattern for the constraint.
160 protected function getEscapedPattern(string $text)
162 $rawPattern = preg_quote($text, '/');
163 $escapedPattern = preg_quote(e($text), '/');
165 return $rawPattern == $escapedPattern
166 ? $rawPattern : "({$rawPattern}|{$escapedPattern})";