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 * 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 does not contain the specified element.
61 public function assertElementNotExists(string $selector)
63 $elements = $this->crawler()->filter($selector);
65 $elements->count() === 0,
66 'Found elements matching the selector: ' . PHP_EOL . PHP_EOL .
67 "[{$selector}]" . PHP_EOL . PHP_EOL .
68 'within' . PHP_EOL . PHP_EOL .
69 "[{$this->getContent()}]."
76 * Assert the response includes a specific element containing the given text.
77 * If an nth match is provided, only that will be checked otherwise all matching
78 * elements will be checked for the given text.
82 public function assertElementContains(string $selector, string $text, ?int $nthMatch = null)
84 $elements = $this->crawler()->filter($selector);
86 $pattern = $this->getEscapedPattern($text);
88 if (!is_null($nthMatch)) {
89 $elements = $elements->eq($nthMatch - 1);
92 foreach ($elements as $element) {
93 $element = new Crawler($element);
94 if (preg_match("/$pattern/i", $element->html())) {
102 'Unable to find element of selector: ' . PHP_EOL . PHP_EOL .
103 ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
104 "[{$selector}]" . PHP_EOL . PHP_EOL .
105 'containing text' . PHP_EOL . PHP_EOL .
106 "[{$text}]" . PHP_EOL . PHP_EOL .
107 'within' . PHP_EOL . PHP_EOL .
108 "[{$this->getContent()}]."
115 * Assert the response does not include a specific element containing the given text.
116 * If an nth match is provided, only that will be checked otherwise all matching
117 * elements will be checked for the given text.
121 public function assertElementNotContains(string $selector, string $text, ?int $nthMatch = null)
123 $elements = $this->crawler()->filter($selector);
125 $pattern = $this->getEscapedPattern($text);
127 if (!is_null($nthMatch)) {
128 $elements = $elements->eq($nthMatch - 1);
131 foreach ($elements as $element) {
132 $element = new Crawler($element);
133 if (preg_match("/$pattern/i", $element->html())) {
141 'Found element of selector: ' . PHP_EOL . PHP_EOL .
142 ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
143 "[{$selector}]" . PHP_EOL . PHP_EOL .
144 'containing text' . PHP_EOL . PHP_EOL .
145 "[{$text}]" . PHP_EOL . PHP_EOL .
146 'within' . PHP_EOL . PHP_EOL .
147 "[{$this->getContent()}]."
154 * Assert there's a notification within the view containing the given text.
158 public function assertNotificationContains(string $text)
160 return $this->assertElementContains('[notification]', $text);
164 * Get the escaped text pattern for the constraint.
168 protected function getEscapedPattern(string $text)
170 $rawPattern = preg_quote($text, '/');
171 $escapedPattern = preg_quote(e($text), '/');
173 return $rawPattern == $escapedPattern
174 ? $rawPattern : "({$rawPattern}|{$escapedPattern})";