diff --git a/src/Api/Concerns/MakesElementAssertions.php b/src/Api/Concerns/MakesElementAssertions.php index 0270add7..a663318f 100644 --- a/src/Api/Concerns/MakesElementAssertions.php +++ b/src/Api/Concerns/MakesElementAssertions.php @@ -13,6 +13,50 @@ */ trait MakesElementAssertions { + /** + * Assert that the given element is focused. + */ + public function assertFocused(string $selector): Webpage + { + $selector = $this->guessLocator($selector)->selector(); + + $escapedSelector = json_encode($selector); + + $isFocused = $this->page->evaluate(" + () => { + const element = document.querySelector({$escapedSelector}); + const focusedElement = document.activeElement; + return element && focusedElement ? element === focusedElement : false; + } + "); + + expect($isFocused)->toBeTrue("Expected element [{$selector}] to be focused on the page [{$this->initialUrl}], but it was not."); + + return $this; + } + + /** + * Assert that the given element is not focused. + */ + public function assertNotFocused(string $selector): Webpage + { + $selector = $this->guessLocator($selector)->selector(); + + $escapedSelector = json_encode($selector); + + $isNotFocused = $this->page->evaluate(" + () => { + const element = document.querySelector({$escapedSelector}); + const focusedElement = document.activeElement; + return element && focusedElement ? element !== focusedElement : true; + } + "); + + expect($isNotFocused)->toBeTrue("Expected element [{$selector}] not to be focused on the page [{$this->initialUrl}], but it was."); + + return $this; + } + /** * Assert that the page title matches the given text. */ diff --git a/tests/Browser/Webpage/AssertFocusedTest.php b/tests/Browser/Webpage/AssertFocusedTest.php new file mode 100644 index 00000000..72ed4eef --- /dev/null +++ b/tests/Browser/Webpage/AssertFocusedTest.php @@ -0,0 +1,17 @@ + <<<'HTML' +
+ + +
+ HTML); + + $page = visit('/'); + + $page->assertFocused('@firstname'); + $page->assertNotFocused('@lastname'); +});