diff --git a/packages/framework/tests/Feature/Views/SidebarBrandViewTest.php b/packages/framework/tests/Feature/Views/SidebarBrandViewTest.php
index 10b840bf5e4..03670822588 100644
--- a/packages/framework/tests/Feature/Views/SidebarBrandViewTest.php
+++ b/packages/framework/tests/Feature/Views/SidebarBrandViewTest.php
@@ -16,7 +16,7 @@ class SidebarBrandViewTest extends TestCase
public function testSidebarBrandView()
{
- $view = $this->test(view('hyde::components.docs.sidebar-brand'));
+ $view = $this->view(view('hyde::components.docs.sidebar-brand'));
$view->assertSee('HydePHP Docs');
$view->assertSee('theme-toggle-button');
@@ -27,7 +27,7 @@ public function testSidebarBrandViewWithHomeRoute()
{
Hyde::routes()->addRoute((new DocumentationPage('index'))->getRoute());
- $view = $this->test(view('hyde::components.docs.sidebar-brand'));
+ $view = $this->view(view('hyde::components.docs.sidebar-brand'));
$view->assertSee('HydePHP Docs');
$view->assertSee('theme-toggle-button');
@@ -38,7 +38,7 @@ public function testSidebarBrandViewWithDefaultHeaderText()
{
config(['docs.sidebar' => []]);
- $view = $this->test(view('hyde::components.docs.sidebar-brand'));
+ $view = $this->view(view('hyde::components.docs.sidebar-brand'));
$view->assertSee('Documentation');
$view->assertDontSee('HydePHP Docs');
@@ -50,7 +50,7 @@ public function testSidebarBrandViewWithDefaultHeaderTextAndHomeRoute()
config(['docs.sidebar' => []]);
- $view = $this->test(view('hyde::components.docs.sidebar-brand'));
+ $view = $this->view(view('hyde::components.docs.sidebar-brand'));
$view->assertSee('Documentation');
$view->assertSeeHtml('Documentation', true);
@@ -63,7 +63,7 @@ public function testSidebarBrandViewWithoutDarkmodeFeature()
$mock->shouldReceive('hasFeature')->with('darkmode')->andReturn(false);
HydeKernel::setInstance($mock);
- $view = $this->test(view('hyde::components.docs.sidebar-brand'));
+ $view = $this->view(view('hyde::components.docs.sidebar-brand'));
$view->assertSee('HydePHP Docs');
$view->assertDontSee('theme-toggle-button');
diff --git a/packages/framework/tests/Feature/Views/SidebarFooterTextViewTest.php b/packages/framework/tests/Feature/Views/SidebarFooterTextViewTest.php
index e4d5c21e9a3..0b27fa6f467 100644
--- a/packages/framework/tests/Feature/Views/SidebarFooterTextViewTest.php
+++ b/packages/framework/tests/Feature/Views/SidebarFooterTextViewTest.php
@@ -14,7 +14,7 @@ class SidebarFooterTextViewTest extends TestCase
public function testSidebarFooterTextViewWithDefaultConfig()
{
- $view = $this->test(view('hyde::components.docs.sidebar-footer-text'));
+ $view = $this->view(view('hyde::components.docs.sidebar-footer-text'));
$view->assertSeeHtml('Back to home page');
}
@@ -23,7 +23,7 @@ public function testSidebarFooterTextViewWhenConfigOptionIsTrue()
{
Config::set('docs.sidebar.footer', true);
- $view = $this->test(view('hyde::components.docs.sidebar-footer-text'));
+ $view = $this->view(view('hyde::components.docs.sidebar-footer-text'));
$view->assertSeeHtml('Back to home page');
}
@@ -32,7 +32,7 @@ public function testSidebarFooterTextViewWhenConfigOptionIsMarkdownString()
{
Config::set('docs.sidebar.footer', 'Your Markdown String Here');
- $view = $this->test(view('hyde::components.docs.sidebar-footer-text'));
+ $view = $this->view(view('hyde::components.docs.sidebar-footer-text'));
$view->assertSeeText('Your Markdown String Here');
}
diff --git a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php
index 4d7a92a5cc7..5b6ec6f42da 100644
--- a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php
+++ b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php
@@ -1,5 +1,7 @@
assertSame([], $this->html('
Foo
')->getRootElement()->attributes);
- /** @noinspection HtmlUnknownAttribute */
$this->assertSame([
'name' => 'test',
'foo' => 'bar',
@@ -429,21 +431,79 @@ public function testToArrayWithChildren()
public function testToArrayWithAttributes()
{
- /** @noinspection HtmlUnknownAttribute */
$this->assertSame(
['id' => 'id', 'tag' => 'div', 'text' => 'Bar', 'classes' => ['class'], 'attributes' => ['name' => 'name']],
$this->html('Bar
')->getRootElement()->toArray()
);
}
+ public function testElementAssertHasId()
+ {
+ $this->html('Foo
')->getRootElement()->assertHasId('foo');
+ }
+
+ public function testElementAssertDoesNotHaveId()
+ {
+ $this->html('Foo
')->getRootElement()->assertDoesNotHaveId('foo');
+ }
+
public function testElementAssertHasClass()
{
- $this->html('Foo
')->getRootElement()->hasClass('foo');
+ $this->html('Foo
')->getRootElement()->assertHasClass('foo');
}
public function testElementAssertDoesNotHaveClass()
{
- $this->html('Foo
')->getRootElement()->doesNotHaveClass('bar');
+ $this->html('Foo
')->getRootElement()->assertDoesNotHaveClass('bar');
+ }
+
+ public function testElementAssertHasAttribute()
+ {
+ $this->html('Foo
')->getRootElement()->assertHasAttribute('name');
+ }
+
+ public function testElementAssertDoesNotHaveAttribute()
+ {
+ $this->html('Foo
')->getRootElement()->assertDoesNotHaveAttribute('href');
+ }
+
+ public function testElementAssertHasAttributeWithValue()
+ {
+ $this->html('Foo
')->getRootElement()->assertHasAttribute('name', 'foo');
+ }
+
+ public function testElementAssertHasAttributeWithWrongValue()
+ {
+ try {
+ $this->html('Foo
')->getRootElement()->assertHasAttribute('name', 'bar');
+ } catch (ExpectationFailedException $exception) {
+ $this->assertSame("The attribute 'name' did not have the expected value.\nFailed asserting that two strings are identical.", $exception->getMessage());
+ }
+ }
+
+ public function testElementAssertHasAttributeForwardsIdAssertions()
+ {
+ $this->html('Foo
')->getRootElement()->assertHasAttribute('id', 'foo');
+ }
+
+ public function testElementAssertHasAttributeForwardsClassAssertions()
+ {
+ $this->html('Foo
')->getRootElement()->assertHasAttribute('class', 'foo');
+ }
+
+ public function testAssertionCallsOnDocumentAreForwardedToRootElement()
+ {
+ $this->assertInstanceOf(TestableHtmlElement::class,
+ $this->html('Foo
')
+ ->assertSee('Foo')
+ ->assertHasId('foo')
+ ->assertDoesNotHaveId('bar')
+ ->assertHasClass('bar')
+ ->assertDoesNotHaveClass('baz')
+ ->assertHasAttribute('class', 'bar')
+ ->assertDoesNotHaveAttribute('href')
+ ->assertSee('Foo')
+ );
}
protected function exampleElement(): TestableHtmlElement
diff --git a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php
index 351be0cf0c5..4b9da2ff53e 100644
--- a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php
+++ b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php
@@ -4,6 +4,7 @@
namespace Hyde\Testing\Support\HtmlTesting;
+use Closure;
use Illuminate\Testing\Assert as PHPUnit;
trait HtmlTestingAssertions
@@ -33,10 +34,70 @@ public function assertDontSeeEscaped(string $value): static
return $this->doAssert(fn () => PHPUnit::assertStringNotContainsString(e($value), $this->html, "The escaped string '$value' was found in the HTML."));
}
- protected function doAssert(callable $assertion): static
+ public function assertHasId(string $id): TestableHtmlElement
+ {
+ return $this->doElementAssert(fn () => PHPUnit::assertSame($id, $this->id, 'The id attribute did not have the expected value.'));
+ }
+
+ public function assertDoesNotHaveId(string $id): TestableHtmlElement
+ {
+ return $this->doElementAssert(fn () => PHPUnit::assertNotSame($id, $this->id, 'The id attribute had the unexpected value.'));
+ }
+
+ public function assertHasClass(string $class): TestableHtmlElement
+ {
+ return $this->doElementAssert(fn () => PHPUnit::assertContains($class, $this->classes, "The class '$class' was not found in the element."));
+ }
+
+ public function assertDoesNotHaveClass(string $class): TestableHtmlElement
+ {
+ return $this->doElementAssert(fn () => PHPUnit::assertNotContains($class, $this->classes, "The class '$class' was found in the element."));
+ }
+
+ public function assertHasAttribute(string $attribute, ?string $value = null): TestableHtmlElement
+ {
+ if ($attribute === 'id') {
+ return $this->assertHasId($value);
+ }
+
+ if ($attribute === 'class') {
+ return $this->assertHasClass($value);
+ }
+
+ $this->doElementAssert(fn () => PHPUnit::assertArrayHasKey($attribute, $this->attributes, "The attribute '$attribute' was not found in the element."));
+
+ if ($value) {
+ return $this->doElementAssert(fn () => PHPUnit::assertSame($value, $this->attributes[$attribute], "The attribute '$attribute' did not have the expected value."));
+ }
+
+ return $this;
+ }
+
+ public function assertDoesNotHaveAttribute(string $attribute): TestableHtmlElement
+ {
+ return $this->doElementAssert(fn () => PHPUnit::assertArrayNotHasKey($attribute, $this->attributes, "The attribute '$attribute' was found in the element."));
+ }
+
+ /** @internal */
+ public function doAssert(Closure $assertion): static
{
$assertion();
return $this;
}
+
+ protected function doElementAssert(Closure $assertion): TestableHtmlElement
+ {
+ // Proxy to the root element if we're a TestableHtmlDocument.
+ if ($this instanceof TestableHtmlDocument) {
+ $rootElement = $this->getRootElement();
+
+ // Bind closure to the root element.
+ $assertion = $assertion->bindTo($rootElement);
+
+ return $rootElement->doAssert($assertion);
+ }
+
+ return $this->doAssert($assertion);
+ }
}
diff --git a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php
index fd65429518c..cb647ec0ff9 100644
--- a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php
+++ b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php
@@ -8,10 +8,8 @@
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Contracts\Support\Arrayable;
-use Illuminate\Testing\Assert as PHPUnit;
use function trim;
-use function filled;
use function strlen;
use function explode;
use function preg_match;
@@ -61,7 +59,7 @@ public function __construct(string $html, DOMElement $element, ?TestableHtmlElem
$this->attributes = $this->parseAttributes($element);
}
- /** @return array{id: ?string, tag: string, text: string, classes: ?array, attributes: ?array, nodes: \Illuminate\Support\Collection<\Hyde\Testing\Support\HtmlTesting\TestableHtmlElement>} */
+ /** @return array{id: ?string, tag: string, text: string, classes: ?array, attributes: ?array, nodes: ?\Illuminate\Support\Collection<\Hyde\Testing\Support\HtmlTesting\TestableHtmlElement>} */
public function toArray(): array
{
return array_filter([
@@ -70,18 +68,8 @@ public function toArray(): array
'text' => $this->text,
'classes' => $this->classes,
'attributes' => $this->attributes,
- 'nodes' => $this->nodes,
- ], fn ($value): bool => filled($value));
- }
-
- public function hasClass(string $class): static
- {
- return $this->doAssert(fn () => PHPUnit::assertContains($class, $this->classes, "The class '$class' was not found in the element."));
- }
-
- public function doesNotHaveClass(string $class): static
- {
- return $this->doAssert(fn () => PHPUnit::assertNotContains($class, $this->classes, "The class '$class' was found in the element."));
+ 'nodes' => $this->nodes->count() ? $this->nodes : null,
+ ]);
}
protected function parseTag(string $html): string
diff --git a/packages/testing/src/TestsBladeViews.php b/packages/testing/src/TestsBladeViews.php
index 01366963558..267932fa516 100644
--- a/packages/testing/src/TestsBladeViews.php
+++ b/packages/testing/src/TestsBladeViews.php
@@ -16,7 +16,7 @@ trait TestsBladeViews
/**
* Test a Blade view.
*/
- protected function test(string|View $view, $data = []): TestView
+ protected function view(string|View $view, $data = []): TestView
{
$data = array_merge($this->testViewData(), $data);