@@ -388,8 +388,8 @@ public function testFilterXpathComplexQueries()
388388 $ this ->assertCount (1 , $ crawler ->filterXPath ('//body ' ));
389389 $ this ->assertCount (1 , $ crawler ->filterXPath ('descendant-or-self::body ' ));
390390 $ this ->assertCount (1 , $ crawler ->filterXPath ('//div[@id="parent"] ' )->filterXPath ('./div ' ), 'A child selection finds only the current div ' );
391- $ this ->assertCount (2 , $ crawler ->filterXPath ('//div[@id="parent"] ' )->filterXPath ('descendant::div ' ), 'A descendant selector matches the current div and its child ' );
392- $ this ->assertCount (2 , $ crawler ->filterXPath ('//div[@id="parent"] ' )->filterXPath ('//div ' ), 'A descendant selector matches the current div and its child ' );
391+ $ this ->assertCount (3 , $ crawler ->filterXPath ('//div[@id="parent"] ' )->filterXPath ('descendant::div ' ), 'A descendant selector matches the current div and its child ' );
392+ $ this ->assertCount (3 , $ crawler ->filterXPath ('//div[@id="parent"] ' )->filterXPath ('//div ' ), 'A descendant selector matches the current div and its child ' );
393393 $ this ->assertCount (5 , $ crawler ->filterXPath ('(//a | //div)//img ' ));
394394 $ this ->assertCount (7 , $ crawler ->filterXPath ('((//a | //div)//img | //ul) ' ));
395395 $ this ->assertCount (7 , $ crawler ->filterXPath ('( ( //a | //div )//img | //ul ) ' ));
@@ -411,72 +411,104 @@ public function testFilterXPath()
411411 $ this ->assertCount (3 , $ crawler ->filterXPath ('//body ' )->filterXPath ('//button ' )->parents (), '->filterXpath() preserves parents when chained ' );
412412 }
413413
414+ public function testFilterXPathWithFakeRoot ()
415+ {
416+ $ crawler = $ this ->createTestCrawler ();
417+ $ this ->assertCount (0 , $ crawler ->filterXPath ('. ' ), '->filterXPath() returns an empty result if the XPath references the fake root node ' );
418+ $ this ->assertCount (0 , $ crawler ->filterXPath ('/_root ' ), '->filterXPath() returns an empty result if the XPath references the fake root node ' );
419+ $ this ->assertCount (0 , $ crawler ->filterXPath ('self::* ' ), '->filterXPath() returns an empty result if the XPath references the fake root node ' );
420+ $ this ->assertCount (0 , $ crawler ->filterXPath ('self::_root ' ), '->filterXPath() returns an empty result if the XPath references the fake root node ' );
421+ }
422+
414423 public function testFilterXPathWithAncestorAxis ()
415424 {
416425 $ crawler = $ this ->createTestCrawler ()->filterXPath ('//form ' );
417426
418- $ this ->assertCount (2 , $ crawler ->filterXPath ('ancestor::* ' ));
427+ $ this ->assertCount (0 , $ crawler ->filterXPath ('ancestor::* ' ), ' The fake root node has no ancestor nodes ' );
419428 }
420429
421430 public function testFilterXPathWithAncestorOrSelfAxis ()
422431 {
423432 $ crawler = $ this ->createTestCrawler ()->filterXPath ('//form ' );
424433
425- $ this ->assertCount (3 , $ crawler ->filterXPath ('ancestor-or-self::* ' ));
434+ $ this ->assertCount (0 , $ crawler ->filterXPath ('ancestor-or-self::* ' ), ' The fake root node has no ancestor nodes ' );
426435 }
427436
428437 public function testFilterXPathWithAttributeAxis ()
429438 {
430439 $ crawler = $ this ->createTestCrawler ()->filterXPath ('//form ' );
431440
432- $ this ->assertCount (2 , $ crawler ->filterXPath ('attribute::* ' ));
441+ $ this ->assertCount (0 , $ crawler ->filterXPath ('attribute::* ' ), 'The fake root node has no attribute nodes ' );
442+ }
443+
444+ public function testFilterXPathWithAttributeAxisAfterElementAxis ()
445+ {
446+ $ this ->assertCount (3 , $ this ->createTestCrawler ()->filterXPath ('//form/button/attribute::* ' ), '->filterXPath() handles attribute axes properly when they are preceded by an element filtering axis ' );
433447 }
434448
435449 public function testFilterXPathWithChildAxis ()
436450 {
437- $ crawler = $ this ->createTestCrawler ()->filterXPath ('//body ' );
451+ $ crawler = $ this ->createTestCrawler ()->filterXPath ('//div[@id="parent"] ' );
438452
439- $ this ->assertCount (2 , $ crawler ->filterXPath ('child::input ' ) );
453+ $ this ->assertCount (1 , $ crawler ->filterXPath ('child::div ' ), ' A child selection finds only the current div ' );
440454 }
441455
442456 public function testFilterXPathWithFollowingAxis ()
443457 {
444458 $ crawler = $ this ->createTestCrawler ()->filterXPath ('//a ' );
445459
446- $ this ->assertCount (3 , $ crawler ->filterXPath ('following::div ' ));
460+ $ this ->assertCount (0 , $ crawler ->filterXPath ('following::div ' ), ' The fake root node has no following nodes ' );
447461 }
448462
449463 public function testFilterXPathWithFollowingSiblingAxis ()
450464 {
451465 $ crawler = $ this ->createTestCrawler ()->filterXPath ('//a ' );
452466
453- $ this ->assertCount (2 , $ crawler ->filterXPath ('following-sibling::div ' ));
467+ $ this ->assertCount (0 , $ crawler ->filterXPath ('following-sibling::div ' ), 'The fake root node has no following nodes ' );
468+ }
469+
470+ public function testFilterXPathWithNamespaceAxis ()
471+ {
472+ $ crawler = $ this ->createTestCrawler ()->filterXPath ('//button ' );
473+
474+ $ this ->assertCount (0 , $ crawler ->filterXPath ('namespace::* ' ), 'The fake root node has no namespace nodes ' );
475+ }
476+
477+ public function testFilterXPathWithNamespaceAxisAfterElementAxis ()
478+ {
479+ $ crawler = $ this ->createTestCrawler ()->filterXPath ('//div[@id="parent"]/namespace::* ' );
480+
481+ $ this ->assertCount (0 , $ crawler ->filterXPath ('namespace::* ' ), 'Namespace axes cannot be requested ' );
454482 }
455483
456484 public function testFilterXPathWithParentAxis ()
457485 {
458486 $ crawler = $ this ->createTestCrawler ()->filterXPath ('//button ' );
459487
460- $ this ->assertEquals ( ' foo ' , $ crawler ->filterXPath ('parent::* ' )-> attr ( ' action ' ) );
488+ $ this ->assertCount ( 0 , $ crawler ->filterXPath ('parent::* ' ), ' The fake root node has no parent nodes ' );
461489 }
462490
463491 public function testFilterXPathWithPrecedingAxis ()
464492 {
465493 $ crawler = $ this ->createTestCrawler ()->filterXPath ('//form ' );
466494
467- $ this ->assertCount (13 , $ crawler ->filterXPath ('preceding::* ' ));
495+ $ this ->assertCount (0 , $ crawler ->filterXPath ('preceding::* ' ), ' The fake root node has no preceding nodes ' );
468496 }
469497
470498 public function testFilterXPathWithPrecedingSiblingAxis ()
471499 {
472500 $ crawler = $ this ->createTestCrawler ()->filterXPath ('//form ' );
473501
474- $ this ->assertCount (9 , $ crawler ->filterXPath ('preceding-sibling::* ' ));
502+ $ this ->assertCount (0 , $ crawler ->filterXPath ('preceding-sibling::* ' ), ' The fake root node has no preceding nodes ' );
475503 }
476504
477505 public function testFilterXPathWithSelfAxes ()
478506 {
479- $ this ->assertCount (1 , $ this ->createTestCrawler ()->filterXPath ('self::* ' ));
507+ $ crawler = $ this ->createTestCrawler ()->filterXPath ('//a ' );
508+
509+ $ this ->assertCount (0 , $ crawler ->filterXPath ('self::a ' ), 'The fake root node has no "real" element name ' );
510+ $ this ->assertCount (0 , $ crawler ->filterXPath ('self::a/img ' ), 'The fake root node has no "real" element name ' );
511+ $ this ->assertCount (9 , $ crawler ->filterXPath ('self::*/a ' ));
480512 }
481513
482514 /**
@@ -844,6 +876,7 @@ public function createTestCrawler($uri = null)
844876 </ul>
845877 <div id="parent">
846878 <div id="child"></div>
879+ <div id="child2" xmlns:foo="http://example.com"></div>
847880 </div>
848881 <div id="sibling"><img /></div>
849882 </body>
0 commit comments