From cf216df05b1fa4d32eabac159328735932421d7c Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 28 Sep 2025 01:34:00 +0100 Subject: [PATCH 01/13] trait and base assert --- src/Asserts/BaseAssert.php | 2 ++ src/Asserts/Traits/TracksSelectorPath.php | 24 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/Asserts/Traits/TracksSelectorPath.php diff --git a/src/Asserts/BaseAssert.php b/src/Asserts/BaseAssert.php index 96cba2a..c8e369f 100644 --- a/src/Asserts/BaseAssert.php +++ b/src/Asserts/BaseAssert.php @@ -8,6 +8,7 @@ use Sinnbeck\DomAssertions\Asserts\Traits\CanGatherAttributes; use Sinnbeck\DomAssertions\Asserts\Traits\Debugging; use Sinnbeck\DomAssertions\Asserts\Traits\InteractsWithParser; +use Sinnbeck\DomAssertions\Asserts\Traits\TracksSelectorPath; use Sinnbeck\DomAssertions\Asserts\Traits\UsesElementAsserts; use Sinnbeck\DomAssertions\Support\DomParser; @@ -22,6 +23,7 @@ abstract class BaseAssert use Macroable { __call as protected callMacro; } + use TracksSelectorPath; use UsesElementAsserts; protected array $attributes = []; diff --git a/src/Asserts/Traits/TracksSelectorPath.php b/src/Asserts/Traits/TracksSelectorPath.php new file mode 100644 index 0000000..2709f4e --- /dev/null +++ b/src/Asserts/Traits/TracksSelectorPath.php @@ -0,0 +1,24 @@ +selectorPath = array_merge($previousPath, [$selector]); + + return $this; + } + + public function getSelectors(): string + { + if (empty($this->selectorPath)) { + return '(root)'; + } + + return implode(' > ', $this->selectorPath); + } +} From ccda5834d161289eaf3e026704c717f9aa9476ad Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 28 Sep 2025 01:34:37 +0100 Subject: [PATCH 02/13] tests and improvements --- src/Asserts/Traits/UsesElementAsserts.php | 38 +++++++++++++++++------ tests/DomTest.php | 24 ++++++++++++++ 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/Asserts/Traits/UsesElementAsserts.php b/src/Asserts/Traits/UsesElementAsserts.php index ff2779b..1500899 100644 --- a/src/Asserts/Traits/UsesElementAsserts.php +++ b/src/Asserts/Traits/UsesElementAsserts.php @@ -29,7 +29,7 @@ public function has(string $attribute, mixed $value = null): self $value, $found = $this->getAttribute($attribute) ), - sprintf('Could not find an attribute "%s" with value "%s". "%s" found', $attribute, $value, trim($found)) + sprintf('Could not find an attribute "%s" with value "%s". "%s" found within: %s', $attribute, $value, trim($found), $this->getSelectors()) ); return $this; @@ -52,7 +52,7 @@ public function doesntHave(string $attribute, mixed $value = null): self $value, $this->getAttribute($attribute) ), - sprintf('Found an attribute "%s" with value "%s"', $attribute, $value) + sprintf('Found an attribute "%s" with value "%s" within: %s', $attribute, $value, $this->getSelectors()) ); return $this; @@ -67,6 +67,9 @@ public function find(string $selector, $callback = null): self if (! is_null($callback)) { $elementAssert = new AssertElement($this->getContent(), $element); + + $elementAssert->trackSelector($this->selectorPath, $selector); + $callback($elementAssert); } @@ -93,7 +96,11 @@ public function contains(string $selector, $attributes = null, $count = 0): self { Assert::assertNotNull( $this->getParser()->query($selector), - sprintf('Could not find any matching element of type "%s"', $selector) + sprintf( + 'Could not find any matching element of type "%s" within: %s', + $selector, + $this->getSelectors() + ) ); if (is_numeric($attributes)) { @@ -109,7 +116,7 @@ public function contains(string $selector, $attributes = null, $count = 0): self Assert::assertEquals( $count, $found = $this->getParser()->queryAll($selector)->count(), - sprintf('Expected to find %s elements but found %s for %s', $count, $found, $selector) + sprintf('Expected to find %s elements but found %s for %s within: %s', $count, $found, $selector, $this->getSelectors()) ); return $this; @@ -123,7 +130,13 @@ public function contains(string $selector, $attributes = null, $count = 0): self $found = collect($this->attributes[$selector]) ->filter(fn ($foundAttributes) => $this->compareAttributesArrays($attributes, $foundAttributes)) ->count(), - sprintf('Expected to find %s elements but found %s for %s', $count, $found, $selector) + sprintf( + 'Expected to find %s elements but found %s for "%s" within: %s', + $count, + $found, + $selector, + $this->getSelectors() + ) ); } @@ -132,7 +145,12 @@ public function contains(string $selector, $attributes = null, $count = 0): self Assert::assertNotFalse( $first, - sprintf('Could not find a matching "%s" with data: %s', $selector, json_encode($attributes, JSON_PRETTY_PRINT)) + sprintf( + 'Could not find a matching "%s" with data: %s within: %s', + $selector, + json_encode($attributes, JSON_PRETTY_PRINT), + $this->getSelectors() + ) ); return $this; @@ -157,7 +175,7 @@ public function doesntContain(string $elementName, array $attributes = []): self Assert::assertFalse( $first, - sprintf('Found a matching "%s" with data: %s', $elementName, json_encode($attributes, JSON_PRETTY_PRINT)) + sprintf('Found a matching "%s" with data: %s within: %s', $elementName, json_encode($attributes, JSON_PRETTY_PRINT), $this->getSelectors()) ); return $this; @@ -175,7 +193,7 @@ public function containsText(string $needle, bool $ignoreCase = false): self [PHPUnit::class, $assertFunction], $needle, $text, - sprintf('Could not find text content "%s" containing %s', $text, $needle) + sprintf('Could not find text content "%s" containing %s within: %s', $text, $needle, $this->getSelectors()) ); return $this; @@ -193,7 +211,7 @@ public function doesntContainText(string $needle, bool $ignoreCase = false): sel [PHPUnit::class, $assertFunction], $needle, $text, - sprintf('Found text content "%s" containing %s', $text, $needle) + sprintf('Found text content "%s" containing %s within: %s', $text, $needle, $this->getSelectors()) ); return $this; @@ -204,7 +222,7 @@ public function is(string $type): self PHPUnit::assertEquals( $type, $this->getParser()->getType(), - sprintf('Element is not of type "%s"', $type) + sprintf('Element is not of type "%s" within: %s', $type, $this->getSelectors()) ); return $this; diff --git a/tests/DomTest.php b/tests/DomTest.php index 9d8bc41..3cc36e2 100644 --- a/tests/DomTest.php +++ b/tests/DomTest.php @@ -410,6 +410,30 @@ }); }); +it('includes dom selectors when nesting and and error occurs when nested', function () { + $this->get('nesting') + ->assertElementExists(function (AssertElement $element) { + $element->findDiv(function (AssertElement $element) { + $element->is('div'); + $element->find('div', function (AssertElement $element) { + $element->is('div'); + $element->findDiv(function (AssertElement $element) { + $element->contains('not-existing'); + }); + }); + }); + }); +})->throws(AssertionFailedError::class, 'Could not find any matching element of type "not-existing" within: div > div > div'); + +it('includes dom selectors when nesting and and error occurs when not nested', function () { + $this->get('nesting') + ->assertElementExists(function (AssertElement $element) { + $element->findDiv(function (AssertElement $element) { + $element->is('not-real'); + }); + }); +})->throws(AssertionFailedError::class, 'Element is not of type "not-real" within: div'); + it('can run the example from the readme', function () { $this->get(route('about')) ->assertOk() From 627d792897e95cde4dcf37aac35cacf83ccb76ca Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 28 Sep 2025 01:34:53 +0100 Subject: [PATCH 03/13] test tests --- .github/workflows/run-tests.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 33f3bf7..c2f45dd 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -2,11 +2,6 @@ name: Run all tests on: push: - branches: - - main - pull_request: - branches: - - main jobs: test: From 97c3908c60c6a92928bcb2b48e178aeea560807f Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 28 Sep 2025 01:36:25 +0100 Subject: [PATCH 04/13] Update DomTest.php --- tests/DomTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/DomTest.php b/tests/DomTest.php index 3cc36e2..f7b1134 100644 --- a/tests/DomTest.php +++ b/tests/DomTest.php @@ -410,7 +410,7 @@ }); }); -it('includes dom selectors when nesting and and error occurs when nested', function () { +it('includes dom selectors when nesting and errors occur', function () { $this->get('nesting') ->assertElementExists(function (AssertElement $element) { $element->findDiv(function (AssertElement $element) { @@ -425,7 +425,7 @@ }); })->throws(AssertionFailedError::class, 'Could not find any matching element of type "not-existing" within: div > div > div'); -it('includes dom selectors when nesting and and error occurs when not nested', function () { +it('includes dom selectors when nesting and errors occur', function () { $this->get('nesting') ->assertElementExists(function (AssertElement $element) { $element->findDiv(function (AssertElement $element) { From 4d66d56edc39db2134eabaf4f9f1c7f8eb19c022 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 28 Sep 2025 01:38:25 +0100 Subject: [PATCH 05/13] Revert "test tests" This reverts commit 627d792897e95cde4dcf37aac35cacf83ccb76ca. --- .github/workflows/run-tests.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index c2f45dd..33f3bf7 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -2,6 +2,11 @@ name: Run all tests on: push: + branches: + - main + pull_request: + branches: + - main jobs: test: From c89b7220f50470b8aab7e228f959674c8d68b6cc Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 28 Sep 2025 01:43:48 +0100 Subject: [PATCH 06/13] diff bits --- src/Asserts/Traits/UsesElementAsserts.php | 22 +++------------------- tests/DomTest.php | 2 +- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/src/Asserts/Traits/UsesElementAsserts.php b/src/Asserts/Traits/UsesElementAsserts.php index 1500899..8506ff4 100644 --- a/src/Asserts/Traits/UsesElementAsserts.php +++ b/src/Asserts/Traits/UsesElementAsserts.php @@ -96,12 +96,7 @@ public function contains(string $selector, $attributes = null, $count = 0): self { Assert::assertNotNull( $this->getParser()->query($selector), - sprintf( - 'Could not find any matching element of type "%s" within: %s', - $selector, - $this->getSelectors() - ) - ); + sprintf('Could not find any matching element of type "%s" within: %s', $selector, $this->getSelectors())); if (is_numeric($attributes)) { $count = $attributes; @@ -130,13 +125,7 @@ public function contains(string $selector, $attributes = null, $count = 0): self $found = collect($this->attributes[$selector]) ->filter(fn ($foundAttributes) => $this->compareAttributesArrays($attributes, $foundAttributes)) ->count(), - sprintf( - 'Expected to find %s elements but found %s for "%s" within: %s', - $count, - $found, - $selector, - $this->getSelectors() - ) + sprintf('Expected to find %s elements but found %s for %s within: %s', $count, $found, $selector, $this->getSelectors()) ); } @@ -145,12 +134,7 @@ public function contains(string $selector, $attributes = null, $count = 0): self Assert::assertNotFalse( $first, - sprintf( - 'Could not find a matching "%s" with data: %s within: %s', - $selector, - json_encode($attributes, JSON_PRETTY_PRINT), - $this->getSelectors() - ) + sprintf('Could not find a matching "%s" with data: %s within: %s', $selector, json_encode($attributes, JSON_PRETTY_PRINT), $this->getSelectors()) ); return $this; diff --git a/tests/DomTest.php b/tests/DomTest.php index f7b1134..5b3e731 100644 --- a/tests/DomTest.php +++ b/tests/DomTest.php @@ -425,7 +425,7 @@ }); })->throws(AssertionFailedError::class, 'Could not find any matching element of type "not-existing" within: div > div > div'); -it('includes dom selectors when nesting and errors occur', function () { +it('includes dom selectors when only one deep', function () { $this->get('nesting') ->assertElementExists(function (AssertElement $element) { $element->findDiv(function (AssertElement $element) { From 189086f3c555ae99d69dcdc4ffd309bab1275da7 Mon Sep 17 00:00:00 2001 From: jackbayliss Date: Sun, 28 Sep 2025 00:53:57 +0000 Subject: [PATCH 07/13] Fix styling --- tests/DomTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/DomTest.php b/tests/DomTest.php index 5834126..5f17984 100644 --- a/tests/DomTest.php +++ b/tests/DomTest.php @@ -428,7 +428,7 @@ it('includes dom selectors when only one deep', function () { $this->get('nesting') ->assertElementExists(function (AssertElement $element) { - $element->find('.foobar',function (AssertElement $element) { + $element->find('.foobar', function (AssertElement $element) { $element->is('not-real'); }); }); From fa06d945a5f5595a34949edf85a236d8c4423be3 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 28 Sep 2025 01:55:41 +0100 Subject: [PATCH 08/13] Update DomTest.php --- tests/DomTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/DomTest.php b/tests/DomTest.php index 5b3e731..5834126 100644 --- a/tests/DomTest.php +++ b/tests/DomTest.php @@ -428,11 +428,11 @@ it('includes dom selectors when only one deep', function () { $this->get('nesting') ->assertElementExists(function (AssertElement $element) { - $element->findDiv(function (AssertElement $element) { + $element->find('.foobar',function (AssertElement $element) { $element->is('not-real'); }); }); -})->throws(AssertionFailedError::class, 'Element is not of type "not-real" within: div'); +})->throws(AssertionFailedError::class, 'Element is not of type "not-real" within: .foobar'); it('can run the example from the readme', function () { $this->get(route('about')) From 7ee8854265fc6bf21596f8421bc6e7637807426d Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 28 Sep 2025 01:58:21 +0100 Subject: [PATCH 09/13] Update UsesElementAsserts.php --- src/Asserts/Traits/UsesElementAsserts.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Asserts/Traits/UsesElementAsserts.php b/src/Asserts/Traits/UsesElementAsserts.php index 8506ff4..7bcb3fe 100644 --- a/src/Asserts/Traits/UsesElementAsserts.php +++ b/src/Asserts/Traits/UsesElementAsserts.php @@ -96,7 +96,8 @@ public function contains(string $selector, $attributes = null, $count = 0): self { Assert::assertNotNull( $this->getParser()->query($selector), - sprintf('Could not find any matching element of type "%s" within: %s', $selector, $this->getSelectors())); + sprintf('Could not find any matching element of type "%s" within: %s', $selector, $this->getSelectors()) + ); if (is_numeric($attributes)) { $count = $attributes; From 674697c7fc149d099ec48f6d331718f43ace74b7 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 28 Sep 2025 02:01:00 +0100 Subject: [PATCH 10/13] rename --- src/Asserts/Traits/TracksSelectorPath.php | 2 +- src/Asserts/Traits/UsesElementAsserts.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Asserts/Traits/TracksSelectorPath.php b/src/Asserts/Traits/TracksSelectorPath.php index 2709f4e..dd388bf 100644 --- a/src/Asserts/Traits/TracksSelectorPath.php +++ b/src/Asserts/Traits/TracksSelectorPath.php @@ -6,7 +6,7 @@ trait TracksSelectorPath { protected array $selectorPath = []; - public function trackSelector(array $previousPath, string $selector): self + public function withSelectors(array $previousPath, string $selector): self { $this->selectorPath = array_merge($previousPath, [$selector]); diff --git a/src/Asserts/Traits/UsesElementAsserts.php b/src/Asserts/Traits/UsesElementAsserts.php index 7bcb3fe..f5af7e6 100644 --- a/src/Asserts/Traits/UsesElementAsserts.php +++ b/src/Asserts/Traits/UsesElementAsserts.php @@ -68,7 +68,7 @@ public function find(string $selector, $callback = null): self if (! is_null($callback)) { $elementAssert = new AssertElement($this->getContent(), $element); - $elementAssert->trackSelector($this->selectorPath, $selector); + $elementAssert->withSelectors($this->selectorPath, $selector); $callback($elementAssert); } From 485c11d1ccf8d70d56f28483b4964c3a53228b32 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 28 Sep 2025 02:04:30 +0100 Subject: [PATCH 11/13] rename this too --- src/Asserts/BaseAssert.php | 4 ++-- .../Traits/{TracksSelectorPath.php => TracksSelectors.php} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/Asserts/Traits/{TracksSelectorPath.php => TracksSelectors.php} (95%) diff --git a/src/Asserts/BaseAssert.php b/src/Asserts/BaseAssert.php index c8e369f..b531d36 100644 --- a/src/Asserts/BaseAssert.php +++ b/src/Asserts/BaseAssert.php @@ -8,7 +8,7 @@ use Sinnbeck\DomAssertions\Asserts\Traits\CanGatherAttributes; use Sinnbeck\DomAssertions\Asserts\Traits\Debugging; use Sinnbeck\DomAssertions\Asserts\Traits\InteractsWithParser; -use Sinnbeck\DomAssertions\Asserts\Traits\TracksSelectorPath; +use Sinnbeck\DomAssertions\Asserts\Traits\TracksSelectors; use Sinnbeck\DomAssertions\Asserts\Traits\UsesElementAsserts; use Sinnbeck\DomAssertions\Support\DomParser; @@ -23,7 +23,7 @@ abstract class BaseAssert use Macroable { __call as protected callMacro; } - use TracksSelectorPath; + use TracksSelectors; use UsesElementAsserts; protected array $attributes = []; diff --git a/src/Asserts/Traits/TracksSelectorPath.php b/src/Asserts/Traits/TracksSelectors.php similarity index 95% rename from src/Asserts/Traits/TracksSelectorPath.php rename to src/Asserts/Traits/TracksSelectors.php index dd388bf..4cb72bf 100644 --- a/src/Asserts/Traits/TracksSelectorPath.php +++ b/src/Asserts/Traits/TracksSelectors.php @@ -2,7 +2,7 @@ namespace Sinnbeck\DomAssertions\Asserts\Traits; -trait TracksSelectorPath +trait TracksSelectors { protected array $selectorPath = []; From 93eafd572deb4a0832e6f91b15c00bb73fb36cef Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 28 Sep 2025 02:12:31 +0100 Subject: [PATCH 12/13] last --- src/Asserts/BaseAssert.php | 4 ++-- .../Traits/{TracksSelectors.php => TrackSelectors.php} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/Asserts/Traits/{TracksSelectors.php => TrackSelectors.php} (95%) diff --git a/src/Asserts/BaseAssert.php b/src/Asserts/BaseAssert.php index b531d36..3f41ce6 100644 --- a/src/Asserts/BaseAssert.php +++ b/src/Asserts/BaseAssert.php @@ -8,7 +8,7 @@ use Sinnbeck\DomAssertions\Asserts\Traits\CanGatherAttributes; use Sinnbeck\DomAssertions\Asserts\Traits\Debugging; use Sinnbeck\DomAssertions\Asserts\Traits\InteractsWithParser; -use Sinnbeck\DomAssertions\Asserts\Traits\TracksSelectors; +use Sinnbeck\DomAssertions\Asserts\Traits\TrackSelectors; use Sinnbeck\DomAssertions\Asserts\Traits\UsesElementAsserts; use Sinnbeck\DomAssertions\Support\DomParser; @@ -23,7 +23,7 @@ abstract class BaseAssert use Macroable { __call as protected callMacro; } - use TracksSelectors; + use TrackSelectors; use UsesElementAsserts; protected array $attributes = []; diff --git a/src/Asserts/Traits/TracksSelectors.php b/src/Asserts/Traits/TrackSelectors.php similarity index 95% rename from src/Asserts/Traits/TracksSelectors.php rename to src/Asserts/Traits/TrackSelectors.php index 4cb72bf..fd6cc77 100644 --- a/src/Asserts/Traits/TracksSelectors.php +++ b/src/Asserts/Traits/TrackSelectors.php @@ -2,7 +2,7 @@ namespace Sinnbeck\DomAssertions\Asserts\Traits; -trait TracksSelectors +trait TrackSelectors { protected array $selectorPath = []; From 044603f3c3efb7e908774ab7bc1105039f4ae085 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 28 Sep 2025 02:18:50 +0100 Subject: [PATCH 13/13] Update TrackSelectors.php --- src/Asserts/Traits/TrackSelectors.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Asserts/Traits/TrackSelectors.php b/src/Asserts/Traits/TrackSelectors.php index fd6cc77..9c8e31d 100644 --- a/src/Asserts/Traits/TrackSelectors.php +++ b/src/Asserts/Traits/TrackSelectors.php @@ -6,9 +6,9 @@ trait TrackSelectors { protected array $selectorPath = []; - public function withSelectors(array $previousPath, string $selector): self + public function withSelectors(array $previousSelectors, string $currentSelector): self { - $this->selectorPath = array_merge($previousPath, [$selector]); + $this->selectorPath = array_merge($previousSelectors, [$currentSelector]); return $this; }