diff --git a/tests/Unit/HtmlTestingSupportMetaTest.php b/tests/Unit/HtmlTestingSupportMetaTest.php new file mode 100644 index 00000000..4d7a92a5 --- /dev/null +++ b/tests/Unit/HtmlTestingSupportMetaTest.php @@ -0,0 +1,453 @@ +html ??= file_get_contents(Hyde::vendorPath('resources/views/homepages/welcome.blade.php')); + } + + public function testHtmlHelper() + { + $this->assertInstanceOf(TestableHtmlDocument::class, $this->html($this->html)); + } + + public function testAssertSee() + { + $this->html($this->html) + ->assertSee('Welcome to HydePHP!') + ->assertDontSee('Unwelcome to HydePHP!'); + } + + public function testAssertSeeEscaped() + { + $this->html(e('
Foo
').'
Bar
') + ->assertSeeEscaped('
Foo
') + ->assertDontSeeEscaped('
Bar
') + ->assertDontSee('
Foo
') + ->assertSee('
Bar
'); + } + + public function testTapElement() + { + $this->assertInstanceOf(TestableHtmlDocument::class, + $this->html($this->html)->tapElement('head > title', fn (TestableHtmlElement $element) => $element->assertSee('Welcome to HydePHP!')) + ); + } + + public function testTapElementUsingId() + { + $this->assertInstanceOf(TestableHtmlDocument::class, + $this->html('
Foo
')->tapElement('#foo', fn (TestableHtmlElement $element) => $element->assertSee('Foo')) + ); + } + + public function testGetElementUsingQuery() + { + $this->assertInstanceOf(TestableHtmlElement::class, + $this->html($this->html)->getElementUsingQuery('head > title')->assertSee('Welcome to HydePHP!') + ); + } + + public function testGetRootElement() + { + $element = $this->html('
Foo
')->getRootElement(); + + $this->assertInstanceOf(TestableHtmlElement::class, $element); + $this->assertSame('
Foo
', $element->html); + } + + public function testGetElementById() + { + $this->assertInstanceOf(TestableHtmlElement::class, + $this->html('
Foo
')->getElementById('foo')->assertSee('Foo') + ); + + $this->assertNull($this->html('
Foo
')->getElementById('bar')); + } + + public function testElementUsingId() + { + $this->assertInstanceOf(TestableHtmlElement::class, + $this->html('
Baz
')->element('#foo')->assertSee('Baz') + ); + + $this->assertNull($this->html('
Baz
')->element('#bar')); + } + + public function testElementUsingSelector() + { + $this->assertInstanceOf(TestableHtmlElement::class, + $this->html('
Baz
')->element('foo > bar')->assertSee('Baz') + ); + + $this->assertNull($this->html('
Baz
')->element('foo > baz')); + } + + public function testElementUsingUnknownSyntax() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("The selector syntax 'foo' is not supported."); + + $this->html('Baz')->element('foo'); + } + + public function testGetElementsByClass() + { + $this->assertCount(1, $this->html('
Foo
')->getElementsByClass('foo')); + $this->assertCount(0, $this->html('
Foo
')->getElementsByClass('bar')); + } + + public function testGetElementsByClassTypes() + { + $document = $this->html('
Foo
Bar
'); + + $collection = $document->getElementsByClass('foo'); + + $this->assertInstanceOf(Collection::class, $collection); + $this->assertContainsOnlyInstancesOf(TestableHtmlElement::class, $collection); + $this->assertSame(['Foo', 'Bar'], $collection->map->text->all()); + } + + public function testGetElementsByClassWithChildNodes() + { + $html = <<<'HTML' +
+
Foo
+
+
Bar Baz
+
+
+ HTML; + + $collection = $this->html($html)->getElementsByClass('foo'); + + $this->assertCount(5, $collection); + $this->assertContainsOnlyInstancesOf(TestableHtmlElement::class, $collection); + $this->assertSame(['Foo', 'Bar', 'Baz'], $collection->map->text->filter()->values()->all()); + } + + public function testFluentClassAssertions() + { + $html = <<<'HTML' +
+
Foo
+
Foo
+
Foo
+
+ HTML; + + $collection = $this->html($html)->getElementsByClass('foo'); + + $this->assertSame( + $collection->each(fn (TestableHtmlElement $element) => $element->assertSee('Foo')), + $collection->each->assertSee('Foo') + ); + } + + public function testQuery() + { + $this->assertInstanceOf(TestableHtmlElement::class, + $this->html($this->html)->query('head > title')->assertSee('Welcome to HydePHP!') + ); + + $this->assertNull($this->html($this->html)->query('head > title > h1')); + } + + public function testQueryWithEdgeCases() + { + $this->assertSame('foo', $this->html('')->query('')->tag); + $this->assertSame('bar', $this->html('')->query('bar')->tag); + $this->assertSame('bar', $this->html('')->query('bar')->tag); + $this->assertSame('bar', $this->html('Baz')->query('bar')->tag); + + $this->assertSame('foo', $this->html('
')->query('foo')->tag); + $this->assertSame('bar', $this->html('
')->query('foo > bar')->tag); + $this->assertSame('bar', $this->html('
')->query('foo > bar')->tag); + $this->assertSame('bar', $this->html('
Baz
')->query('foo > bar')->tag); + } + + public function testDumpHelper() + { + $dump = $this->html($this->html)->dump(false); + + $this->assertStringContainsString('Document Dump', $dump); + $this->assertStringContainsString('Document Preview', $dump); + $this->assertStringContainsString('Raw HTML', $dump); + $this->assertStringContainsString('Nodes', $dump); + + $this->assertStringContainsString(e('Welcome to HydePHP!'), $dump); + } + + public function testGetStructure() + { + $html = <<<'HTML' +
+
+

Foo

+

Bar Baz

+
+
+ HTML; + + $expected = <<<'TXT' + main + div + h1 + p + small + TXT; + + $this->assertSame($expected, $this->html($html)->getStructure()); + } + + public function testGetTextRepresentation() + { + $html = <<<'HTML' +
+
+

Foo

+

Bar Baz

+
+
+ HTML; + + $expected = <<<'TXT' + Foo + Bar Baz + TXT; + + $this->assertSame($expected, $this->html($html)->getTextRepresentation()); + } + + public function testGetTextRepresentationWithMultipleLines() + { + $html = <<<'HTML' +
+
+

Foo

+

Bar Baz

+
+
Line 2
+
+

Line 3

+
+ HTML; + + $expected = <<<'TXT' + Foo + Bar Baz + Line 2 + Line 3 + Line 3 + TXT; + + $this->assertSame($expected, $this->html($html)->getTextRepresentation()); + } + + public function testComplexTextRepresentationParsing() + { + $expected = <<<'HTML' +Welcome to HydePHP! +You're running on HydePHP +Leap into the future of static HTML blogs and documentation with the tools you already know and love. +Made with Tailwind, Laravel, and Coffee. +This is the default homepage stored as index.blade.php, however you can publish any of the built-in views using the following command: +php hyde php hyde php hyde publish:homepage +Resources for getting started +Documentation +Getting Started +GitHub Source Code +HTML; + + $this->assertSame($expected, $this->html($this->html)->getTextRepresentation()); + } + + public function testAssertStructureLooksLike() + { + $html = <<<'HTML' +
+
+

Foo

+

Bar Baz

+
+
+ HTML; + + $expected = <<<'TXT' + main + div + h1 + p + small + TXT; + + $this->html($html)->assertStructureLooksLike($expected); + } + + public function testAssertLooksLike() + { + $html = <<<'HTML' +
+
+

Foo

+

Bar Baz

+
+
+ HTML; + + $expected = <<<'TXT' + Foo + Bar Baz + TXT; + + $this->html($html)->assertLooksLike($expected); + } + + public function testElementInstance() + { + $this->assertInstanceOf(TestableHtmlElement::class, $this->exampleElement()); + } + + public function testElementTag() + { + $this->assertSame('div', $this->exampleElement()->tag); + } + + public function testElementText() + { + $this->assertSame('Foo', $this->exampleElement()->text); + } + + public function testElementHtml() + { + $this->assertSame('
Foo
', $this->exampleElement()->html); + } + + public function testElementId() + { + $this->assertSame('foo', $this->exampleElement()->id); + + $this->assertNull($this->html('
Foo
')->getRootElement()->id); + } + + public function testElementClasses() + { + $this->assertSame([], $this->html('
Foo
')->getRootElement()->classes); + $this->assertSame(['foo', 'bar'], $this->html('
Foo
')->getRootElement()->classes); + } + + public function testElementAttributes() + { + $this->assertSame([], $this->html('
Foo
')->getRootElement()->attributes); + + /** @noinspection HtmlUnknownAttribute */ + $this->assertSame([ + 'name' => 'test', + 'foo' => 'bar', + 'href' => 'https://example.com/', + ], $this->html('
Foo
')->getRootElement()->attributes); + } + + public function testElementNodes() + { + $this->assertNull($this->exampleElement()->nodes->first()); + } + + public function testElementNodesWithChild() + { + $child = $this->html('
Bar
')->getRootElement()->nodes->first(); + + $this->assertInstanceOf(TestableHtmlElement::class, $child); + $this->assertSame('foo', $child->tag); + $this->assertSame('Bar', $child->text); + } + + public function testElementNodesWithChildren() + { + $element = $this->html('
BarBazFoo
')->getRootElement(); + + $this->assertCount(2, $element->nodes); + $this->assertSame('foo', $element->nodes->first()->tag); + $this->assertSame('bar', $element->nodes->last()->tag); + + $this->assertCount(1, $element->nodes->last()->nodes); + $this->assertSame('small', $element->nodes->last()->nodes->first()->tag); + + $this->assertSame('Foo', $element->nodes->last()->nodes->first()->text); + $this->assertNull($element->nodes->last()->nodes->first()->nodes->first()); + } + + public function testElementToArray() + { + $this->assertSame( + ['id' => 'foo', 'tag' => 'div', 'text' => 'Foo', 'classes' => ['bar']], + $this->exampleElement()->toArray() + ); + } + + public function testToArrayWithChildren() + { + $this->assertEquals( + ['tag' => 'div', 'nodes' => collect([$this->html('
')->getRootElement()->nodes->first()])], + $this->html('
')->getRootElement()->toArray() + ); + + $this->assertSame( + ['id', 'tag', 'text', 'classes', 'attributes', 'nodes'], + array_keys($this->html('
Foo
')->getRootElement()->toArray()) + ); + } + + 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 testElementAssertHasClass() + { + $this->html('
Foo
')->getRootElement()->hasClass('foo'); + } + + public function testElementAssertDoesNotHaveClass() + { + $this->html('
Foo
')->getRootElement()->doesNotHaveClass('bar'); + } + + protected function exampleElement(): TestableHtmlElement + { + return $this->html('
Foo
')->getElementById('foo'); + } +}