I'm trying to show a custom message (the URL being tested) when a PHPUnit 9.5.11 test fails. in my Symfony 4.4 app.
The class is simple:
class BaseTestCase extends PantherTestCase
In my test, I've:
$client = static::createPantherClient();
$crawler = $client->request('GET', $url);
$this->assertSelectorExists('.some-class', $url); // <- this should display the tested $url, since the second argument is supposed to be the message to show on failure
But when the test fails, all I get is:
- App\Tests\PropertyListingTest::testListingWithFullQueryString with data set #0 ('') Facebook\WebDriver\Exception\NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":".some-class"} (Session info: headless chrome=97.0.4692.71)
What's going on here? If I run this:
$this->assertEquals("a", "b", "!!!!TEST FAILED!!!!");
It works as expected:
!!!!TEST FAILED!!!! Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -'a' +'b'
That behaviour actually looks like a bug to me.
Because if you look at what assertSelectorExists
does internally (see below)...
public static function assertSelectorExists(string $selector, string $message = ''): void
{
$client = self::getClient();
if ($client instanceof PantherClient) {
$element = self::findElement($selector); // NoSuchElementException is thrown here
self::assertNotNull($element, $message); // so the message is never used
return;
}
self::assertNotEmpty($client->getCrawler()->filter($selector));
}
...you'll notice that it expects findElement
to return null in case if no element was found. But the problem is that findElement
doesn't return null in that case, it throws an exception instead.
To fix this, I would make my own version of assertSelectorExists like this:
$client = static::createPantherClient();
$crawler = $client->request('GET', $url);
$this->assertSelectorExistsSafe($client, '.some-class', $url);
protected function assertSelectorExistsSafe($client, $selector, $message)
{
try {
$element = $client->findElement($client->createWebDriverByFromLocator($selector));
} catch (\Facebook\WebDriver\Exception\NoSuchElementException $e) {
$element = null;
}
self::assertNotNull($element, $message);
}