Skip to content

Commit 2463efd

Browse files
SVillettefabpot
authored andcommitted
[DomCrawler][FrameworkBundle] Add assertAnySelectorText*
1 parent 67ad353 commit 2463efd

File tree

5 files changed

+220
-0
lines changed

5 files changed

+220
-0
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
6.4
5+
---
6+
7+
* Add `CrawlerAnySelectorTextContains` test constraint
8+
* Add `CrawlerAnySelectorTextSame` test constraint
9+
410
6.3
511
---
612

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DomCrawler\Test\Constraint;
13+
14+
use PHPUnit\Framework\Constraint\Constraint;
15+
use Symfony\Component\DomCrawler\Crawler;
16+
17+
final class CrawlerAnySelectorTextContains extends Constraint
18+
{
19+
private string $selector;
20+
private string $expectedText;
21+
private bool $hasNode = false;
22+
23+
public function __construct(string $selector, string $expectedText)
24+
{
25+
$this->selector = $selector;
26+
$this->expectedText = $expectedText;
27+
}
28+
29+
public function toString(): string
30+
{
31+
if ($this->hasNode) {
32+
return sprintf('the text of any node matching selector "%s" contains "%s"', $this->selector, $this->expectedText);
33+
}
34+
35+
return sprintf('the Crawler has a node matching selector "%s"', $this->selector);
36+
}
37+
38+
protected function matches($other): bool
39+
{
40+
if (!$other instanceof Crawler) {
41+
throw new \InvalidArgumentException(sprintf('"%s" constraint expected an argument of type "%s", got "%s".', self::class, Crawler::class, get_debug_type($other)));
42+
}
43+
44+
$other = $other->filter($this->selector);
45+
if (!\count($other)) {
46+
$this->hasNode = false;
47+
48+
return false;
49+
}
50+
51+
$this->hasNode = true;
52+
53+
$nodes = $other->each(fn (Crawler $node) => $node->text(null, true));
54+
$matches = array_filter($nodes, function (string $node): bool {
55+
return str_contains($node, $this->expectedText);
56+
});
57+
58+
return 0 < \count($matches);
59+
}
60+
61+
protected function failureDescription($other): string
62+
{
63+
if (!$other instanceof Crawler) {
64+
throw new \InvalidArgumentException(sprintf('"%s" constraint expected an argument of type "%s", got "%s".', self::class, Crawler::class, get_debug_type($other)));
65+
}
66+
67+
return $this->toString();
68+
}
69+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DomCrawler\Test\Constraint;
13+
14+
use PHPUnit\Framework\Constraint\Constraint;
15+
use Symfony\Component\DomCrawler\Crawler;
16+
17+
final class CrawlerAnySelectorTextSame extends Constraint
18+
{
19+
private string $selector;
20+
private string $expectedText;
21+
22+
public function __construct(string $selector, string $expectedText)
23+
{
24+
$this->selector = $selector;
25+
$this->expectedText = $expectedText;
26+
}
27+
28+
public function toString(): string
29+
{
30+
return sprintf('has at least a node matching selector "%s" with content "%s"', $this->selector, $this->expectedText);
31+
}
32+
33+
protected function matches($other): bool
34+
{
35+
if (!$other instanceof Crawler) {
36+
throw new \InvalidArgumentException(sprintf('"%s" constraint expected an argument of type "%s", got "%s".', self::class, Crawler::class, get_debug_type($other)));
37+
}
38+
39+
$other = $other->filter($this->selector);
40+
if (!\count($other)) {
41+
return false;
42+
}
43+
44+
$nodes = $other->each(fn (Crawler $node) => trim($node->text(null, true)));
45+
46+
return \in_array($this->expectedText, $nodes, true);
47+
}
48+
49+
protected function failureDescription($other): string
50+
{
51+
if (!$other instanceof Crawler) {
52+
throw new \InvalidArgumentException(sprintf('"%s" constraint expected an argument of type "%s", got "%s".', self::class, Crawler::class, get_debug_type($other)));
53+
}
54+
55+
return 'the Crawler '.$this->toString();
56+
}
57+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DomCrawler\Tests\Test\Constraint;
13+
14+
use PHPUnit\Framework\ExpectationFailedException;
15+
use PHPUnit\Framework\TestCase;
16+
use PHPUnit\Framework\TestFailure;
17+
use Symfony\Component\DomCrawler\Crawler;
18+
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerAnySelectorTextContains;
19+
20+
class CrawlerAnySelectorTextContainsTest extends TestCase
21+
{
22+
public function testConstraint()
23+
{
24+
$constraint = new CrawlerAnySelectorTextContains('ul li', 'Foo');
25+
26+
self::assertTrue($constraint->evaluate(new Crawler('<ul><li>Foo</li>'), '', true));
27+
self::assertTrue($constraint->evaluate(new Crawler('<ul><li>Bar</li><li>Foo'), '', true));
28+
self::assertTrue($constraint->evaluate(new Crawler('<ul><li>Bar</li><li>Foo Bar Baz'), '', true));
29+
self::assertFalse($constraint->evaluate(new Crawler('<ul><li>Bar</li><li>Baz'), '', true));
30+
31+
try {
32+
$constraint->evaluate(new Crawler('<ul><li>Bar</li><li>Baz'));
33+
34+
self::fail();
35+
} catch (ExpectationFailedException $e) {
36+
self::assertEquals("Failed asserting that the text of any node matching selector \"ul li\" contains \"Foo\".\n", TestFailure::exceptionToString($e));
37+
}
38+
39+
try {
40+
$constraint->evaluate(new Crawler('<html><head><title>Foobar'));
41+
42+
self::fail();
43+
} catch (ExpectationFailedException $e) {
44+
self::assertEquals("Failed asserting that the Crawler has a node matching selector \"ul li\".\n", TestFailure::exceptionToString($e));
45+
46+
return;
47+
}
48+
}
49+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DomCrawler\Tests\Test\Constraint;
13+
14+
use PHPUnit\Framework\ExpectationFailedException;
15+
use PHPUnit\Framework\TestCase;
16+
use PHPUnit\Framework\TestFailure;
17+
use Symfony\Component\DomCrawler\Crawler;
18+
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerAnySelectorTextSame;
19+
20+
final class CrawlerAnySelectorTextSameTest extends TestCase
21+
{
22+
public function testConstraint()
23+
{
24+
$constraint = new CrawlerAnySelectorTextSame('ul li', 'Foo');
25+
26+
self::assertTrue($constraint->evaluate(new Crawler('<ul><li>Foo</li>'), '', true));
27+
self::assertTrue($constraint->evaluate(new Crawler('<ul><li>Bar</li><li>Foo'), '', true));
28+
self::assertFalse($constraint->evaluate(new Crawler('<ul><li>Bar</li><li>Foo Bar Baz'), '', true));
29+
self::assertFalse($constraint->evaluate(new Crawler('<ul><li>Bar</li><li>Baz'), '', true));
30+
31+
try {
32+
$constraint->evaluate(new Crawler('<ul><li>Bar</li><li>Baz'));
33+
34+
self::fail();
35+
} catch (ExpectationFailedException $e) {
36+
self::assertEquals("Failed asserting that the Crawler has at least a node matching selector \"ul li\" with content \"Foo\".\n", TestFailure::exceptionToString($e));
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)