You can register the mixin class in the register
method of a Laravel service provider:
use Illuminate\Foundation\Testing\TestResponse;
TestResponse::mixin(TestResponseMixin::class);
<?php | |
use DOMXPath; | |
use DOMDocument; | |
use DOMNodeList; | |
use Illuminate\Support\Str; | |
use Illuminate\Foundation\Testing\Assert as PHPUnit; | |
use Symfony\Component\CssSelector\CssSelectorConverter; | |
class TestResponseMixin | |
{ | |
public function getSelectorContents() | |
{ | |
return function (string $selector): DOMNodeList { | |
$dom = new DOMDocument(); | |
@$dom->loadHTML( | |
mb_convert_encoding($this->getContent(), 'HTML-ENTITIES', 'UTF-8'), | |
LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | |
); | |
$xpath = new DOMXPath($dom); | |
$converter = new CssSelectorConverter(); | |
$xpathSelector = $converter->toXPath($selector); | |
$elements = $xpath->query($xpathSelector); | |
return $elements; | |
}; | |
} | |
public function assertSelectorContains() | |
{ | |
return function (string $selector, string $value) { | |
$selectorContents = $this->getSelectorContents($selector); | |
if (empty($selectorContents)) { | |
PHPUnit::fail("The selector '{$selector}' was not found in the response."); | |
} | |
foreach ($selectorContents as $element) { | |
if (Str::contains($element->textContent, $value)) { | |
PHPUnit::assertTrue(true); | |
return $this; | |
} | |
} | |
PHPUnit::fail("The selector '{$selector}' did not contain the value '{$value}'."); | |
return $this; | |
}; | |
} | |
public function assertSelectorsAllContain() | |
{ | |
return function (string $selector, string $value) { | |
$selectorContents = $this->getSelectorContents($selector); | |
if (empty($selectorContents)) { | |
PHPUnit::fail("The selector '{$selector}' was not found in the response."); | |
} | |
foreach ($selectorContents as $element) { | |
if (!Str::contains($element->textContent, $value)) { | |
PHPUnit::fail("The selector '{$selector}' did not contain the value '{$value}'."); | |
return $this; | |
} | |
} | |
PHPUnit::assertTrue(true); | |
return $this; | |
}; | |
} | |
public function assertSelectorAttributeEquals() | |
{ | |
return function (string $selector, string $attribute, $expected) { | |
$nodes = $this->getSelectorContents($selector); | |
if (count($nodes) === 0) { | |
PHPUnit::fail("The selector '{$selector} was not found in the response."); | |
return $this; | |
} | |
$firstNode = $nodes[0]; | |
PHPUnit::assertEquals($expected, $firstNode->getAttribute($attribute)); | |
return $this; | |
}; | |
} | |
} |
This is awesome. @imliam it would be great to have this available as a package.