5 use Illuminate\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 * Get the HTML of the first element at the given selector.
32 public function getElementHtml(string $selector): string
34 return $this->crawler()->filter($selector)->first()->outerHtml();
38 * Assert the response contains the specified element.
42 public function assertElementExists(string $selector)
44 $elements = $this->crawler()->filter($selector);
46 $elements->count() > 0,
47 'Unable to find element matching the selector: ' . PHP_EOL . PHP_EOL .
48 "[{$selector}]" . PHP_EOL . PHP_EOL .
49 'within' . PHP_EOL . PHP_EOL .
50 "[{$this->getContent()}]."
57 * Assert the response contains the given count of elements
58 * that match the given css selector.
62 public function assertElementCount(string $selector, int $count)
64 $elements = $this->crawler()->filter($selector);
66 $elements->count() === $count,
67 'Unable to ' . $count . ' element(s) matching the selector: ' . PHP_EOL . PHP_EOL .
68 "[{$selector}]" . PHP_EOL . PHP_EOL .
69 'found ' . $elements->count() . ' within' . PHP_EOL . PHP_EOL .
70 "[{$this->getContent()}]."
77 * Assert the response does not contain the specified element.
81 public function assertElementNotExists(string $selector)
83 $elements = $this->crawler()->filter($selector);
85 $elements->count() === 0,
86 'Found elements matching the selector: ' . PHP_EOL . PHP_EOL .
87 "[{$selector}]" . PHP_EOL . PHP_EOL .
88 'within' . PHP_EOL . PHP_EOL .
89 "[{$this->getContent()}]."
96 * Assert the response includes a specific element containing the given text.
97 * If an nth match is provided, only that will be checked otherwise all matching
98 * elements will be checked for the given text.
102 public function assertElementContains(string $selector, string $text, ?int $nthMatch = null)
104 $elements = $this->crawler()->filter($selector);
106 $pattern = $this->getEscapedPattern($text);
108 if (!is_null($nthMatch)) {
109 $elements = $elements->eq($nthMatch - 1);
112 foreach ($elements as $element) {
113 $element = new Crawler($element);
114 if (preg_match("/$pattern/i", $element->text())) {
122 'Unable to find element of selector: ' . PHP_EOL . PHP_EOL .
123 ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
124 "[{$selector}]" . PHP_EOL . PHP_EOL .
125 'containing text' . PHP_EOL . PHP_EOL .
126 "[{$text}]" . PHP_EOL . PHP_EOL .
127 'within' . PHP_EOL . PHP_EOL .
128 "[{$this->getContent()}]."
135 * Assert the response does not include a specific element containing the given text.
136 * If an nth match is provided, only that will be checked otherwise all matching
137 * elements will be checked for the given text.
141 public function assertElementNotContains(string $selector, string $text, ?int $nthMatch = null)
143 $elements = $this->crawler()->filter($selector);
145 $pattern = $this->getEscapedPattern($text);
147 if (!is_null($nthMatch)) {
148 $elements = $elements->eq($nthMatch - 1);
151 foreach ($elements as $element) {
152 $element = new Crawler($element);
153 if (preg_match("/$pattern/i", $element->html())) {
161 'Found element of selector: ' . PHP_EOL . PHP_EOL .
162 ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
163 "[{$selector}]" . PHP_EOL . PHP_EOL .
164 'containing text' . PHP_EOL . PHP_EOL .
165 "[{$text}]" . PHP_EOL . PHP_EOL .
166 'within' . PHP_EOL . PHP_EOL .
167 "[{$this->getContent()}]."
174 * Assert there's a notification within the view containing the given text.
178 public function assertNotificationContains(string $text)
180 return $this->assertElementContains('[notification]', $text);
184 * Get the escaped text pattern for the constraint.
188 protected function getEscapedPattern(string $text)
190 $rawPattern = preg_quote($text, '/');
191 $escapedPattern = preg_quote(e($text), '/');
193 return $rawPattern == $escapedPattern
194 ? $rawPattern : "({$rawPattern}|{$escapedPattern})";