diff --git a/src/Concerns/MakesAssertions.php b/src/Concerns/MakesAssertions.php index 8e6c2067f..79598770d 100644 --- a/src/Concerns/MakesAssertions.php +++ b/src/Concerns/MakesAssertions.php @@ -766,6 +766,27 @@ public function assertAttribute($selector, $attribute, $value) return $this; } + /** + * Assert that the element matching the given selector is missing the provided attribute. + * + * @param string $selector + * @param string $attribute + * @return $this + */ + public function assertAttributeMissing($selector, $attribute) + { + $fullSelector = $this->resolver->format($selector); + + $actual = $this->resolver->findOrFail($selector)->getAttribute($attribute); + + PHPUnit::assertNull( + $actual, + "Saw unexpected attribute [{$attribute}] within element [{$fullSelector}]." + ); + + return $this; + } + /** * Assert that the element matching the given selector contains the given value in the provided attribute. * diff --git a/tests/Unit/MakesAssertionsTest.php b/tests/Unit/MakesAssertionsTest.php index 091a1cb6d..3160ffd43 100644 --- a/tests/Unit/MakesAssertionsTest.php +++ b/tests/Unit/MakesAssertionsTest.php @@ -595,6 +595,35 @@ public function test_assert_attribute() } } + public function test_assert_attribute_missing() + { + $driver = m::mock(stdClass::class); + + $element = m::mock(stdClass::class); + $element->shouldReceive('getAttribute')->with('bar')->andReturn( + null, + 'joe', + ); + + $resolver = m::mock(stdClass::class); + $resolver->shouldReceive('format')->with('foo')->andReturn('Foo'); + $resolver->shouldReceive('findOrFail')->with('foo')->andReturn($element); + + $browser = new Browser($driver, $resolver); + + $browser->assertAttributeMissing('foo', 'bar'); + + try { + $browser->assertAttributeMissing('foo', 'bar'); + $this->fail(); + } catch (ExpectationFailedException $e) { + $this->assertStringContainsString( + 'Saw unexpected attribute [bar] within element [Foo].', + $e->getMessage() + ); + } + } + public function test_assert_attribute_contains() { $driver = m::mock(stdClass::class);