diff --git a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php
index 914244c22324..6ea659a79ec7 100644
--- a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php
+++ b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php
@@ -2,6 +2,7 @@
namespace Illuminate\Foundation\Testing\Concerns;
+use Closure;
use Exception;
use Illuminate\Support\Str;
use InvalidArgumentException;
@@ -20,6 +21,13 @@ trait InteractsWithPages
*/
protected $crawler;
+ /**
+ * Subcrawler instances used by the within method.
+ *
+ * @var array
+ */
+ protected $subCrawlers = [];
+
/**
* All of the stored inputs for the current page.
*
@@ -67,6 +75,8 @@ protected function makeRequest($method, $uri, $parameters = [], $cookies = [], $
$this->crawler = new Crawler($this->response->getContent(), $uri);
+ $this->subCrawlers = [];
+
return $this;
}
@@ -169,6 +179,34 @@ protected function assertPageLoaded($uri, $message = null)
}
}
+ /**
+ * Get the right crawler according to the current test context.
+ *
+ * @return \Symfony\Component\DomCrawler\Crawler
+ */
+ protected function getCrawler()
+ {
+ return ! empty($this->subCrawlers)
+ ? end($this->subCrawlers)
+ : $this->crawler;
+ }
+
+ /**
+ * Narrow the test content to a specific area of the page.
+ *
+ * @param string $element
+ * @param \Closure $callback
+ * @return $this
+ */
+ public function within($element, Closure $callback)
+ {
+ $this->subCrawlers[] = $this->getCrawler()->filter($element);
+
+ $callback();
+
+ array_pop($this->subCrawlers);
+ }
+
/**
* Assert that a given string is seen on the page.
*
@@ -187,7 +225,7 @@ protected function see($text, $negate = false)
$pattern = $rawPattern == $escapedPattern
? $rawPattern : "({$rawPattern}|{$escapedPattern})";
- $this->$method("/$pattern/i", $this->response->getContent());
+ $this->$method("/$pattern/i", $this->getCrawler()->html());
return $this;
}
@@ -251,7 +289,7 @@ public function dontSeeInElement($element, $text)
*/
protected function hasInElement($element, $text)
{
- $elements = $this->crawler->filter($element);
+ $elements = $this->getCrawler()->filter($element);
$rawPattern = preg_quote($text, '/');
@@ -320,7 +358,7 @@ public function dontSeeLink($text, $url = null)
*/
protected function hasLink($text, $url = null)
{
- $links = $this->crawler->selectLink($text);
+ $links = $this->getCrawler()->selectLink($text);
if ($links->count() == 0) {
return false;
@@ -592,7 +630,7 @@ protected function isChecked($selector)
*/
protected function click($name)
{
- $link = $this->crawler->selectLink($name);
+ $link = $this->getCrawler()->selectLink($name);
if (! count($link)) {
$link = $this->filterByNameOrId($name, 'a');
@@ -725,10 +763,10 @@ protected function getForm($buttonText = null)
{
try {
if ($buttonText) {
- return $this->crawler->selectButton($buttonText)->form();
+ return $this->getCrawler()->selectButton($buttonText)->form();
}
- return $this->crawler->filter('form')->form();
+ return $this->getCrawler()->filter('form')->form();
} catch (InvalidArgumentException $e) {
throw new InvalidArgumentException(
"Could not find a form that has submit button [{$buttonText}]."
@@ -792,7 +830,7 @@ protected function filterByNameOrId($name, $elements = '*')
$element = "{$element}#{$id}, {$element}[name='{$name}']";
});
- return $this->crawler->filter(implode(', ', $elements));
+ return $this->getCrawler()->filter(implode(', ', $elements));
}
/**
diff --git a/tests/Foundation/FoundationInteractsWithPagesTest.php b/tests/Foundation/FoundationInteractsWithPagesTest.php
index e1369a8d20ed..a62553f61bb8 100644
--- a/tests/Foundation/FoundationInteractsWithPagesTest.php
+++ b/tests/Foundation/FoundationInteractsWithPagesTest.php
@@ -7,18 +7,20 @@ class FoundationCrawlerTraitIntegrationTest extends PHPUnit_Framework_TestCase
{
use MakesHttpRequests;
- public function testSeeInElement()
+ protected function setCrawler($html)
{
- $this->crawler = new Crawler(
- '
Laravel was created by Taylor Otwell
'
- );
+ $this->crawler = new Crawler($html);
+ }
+ public function testSeeInElement()
+ {
+ $this->setCrawler('Laravel was created by Taylor Otwell
');
$this->seeInElement('strong', 'Taylor');
}
public function testSeeInElementSearchInAllElements()
{
- $this->crawler = new Crawler(
+ $this->setCrawler(
'
Laravel is a
PHP framework
created by
Taylor Otwell
@@ -30,7 +32,7 @@ public function testSeeInElementSearchInAllElements()
public function testSeeInElementSearchInHtmlTags()
{
- $this->crawler = new Crawler(
+ $this->setCrawler(
'
'
@@ -41,7 +43,7 @@ public function testSeeInElementSearchInHtmlTags()
public function testdontSeeInElement()
{
- $this->crawler = new Crawler(
+ $this->setCrawler(
'
Laravel was created by Taylor Otwell
'
);
@@ -51,7 +53,7 @@ public function testdontSeeInElement()
public function testSeeLink()
{
- $this->crawler = new Crawler(
+ $this->setCrawler(
'
Laravel'
);
@@ -61,7 +63,7 @@ public function testSeeLink()
public function testDontSeeLink()
{
- $this->crawler = new Crawler(
+ $this->setCrawler(
'
Laravel'
);
@@ -76,13 +78,13 @@ protected function getInputHtml()
public function testSeeInInput()
{
- $this->crawler = new Crawler($this->getInputHtml());
+ $this->setCrawler($this->getInputHtml());
$this->seeInField('framework', 'Laravel');
}
public function testDontSeeInInput()
{
- $this->crawler = new Crawler($this->getInputHtml());
+ $this->setCrawler($this->getInputHtml());
$this->dontSeeInField('framework', 'Rails');
}
@@ -93,13 +95,13 @@ protected function getInputArrayHtml()
public function testSeeInInputArray()
{
- $this->crawler = new Crawler($this->getInputArrayHtml());
+ $this->setCrawler($this->getInputArrayHtml());
$this->seeInField('framework[]', 'Laravel');
}
public function testDontSeeInInputArray()
{
- $this->crawler = new Crawler($this->getInputArrayHtml());
+ $this->setCrawler($this->getInputArrayHtml());
$this->dontSeeInField('framework[]', 'Rails');
}
@@ -110,13 +112,13 @@ protected function getTextareaHtml()
public function testSeeInTextarea()
{
- $this->crawler = new Crawler($this->getTextareaHtml());
+ $this->setCrawler($this->getTextareaHtml());
$this->seeInField('description', 'Laravel is awesome');
}
public function testDontSeeInTextarea()
{
- $this->crawler = new Crawler($this->getTextareaHtml());
+ $this->setCrawler($this->getTextareaHtml());
$this->dontSeeInField('description', 'Rails is awesome');
}
@@ -131,13 +133,13 @@ protected function getSelectHtml()
public function testSeeOptionIsSelected()
{
- $this->crawler = new Crawler($this->getSelectHtml());
+ $this->setCrawler($this->getSelectHtml());
$this->seeIsSelected('availability', 'full_time');
}
public function testDontSeeOptionIsSelected()
{
- $this->crawler = new Crawler($this->getSelectHtml());
+ $this->setCrawler($this->getSelectHtml());
$this->dontSeeIsSelected('availability', 'partial_time');
}
@@ -150,13 +152,13 @@ protected function getRadiosHtml()
public function testSeeRadioIsChecked()
{
- $this->crawler = new Crawler($this->getRadiosHtml());
+ $this->setCrawler($this->getRadiosHtml());
$this->seeIsSelected('availability', 'full_time');
}
public function testDontSeeRadioIsChecked()
{
- $this->crawler = new Crawler($this->getRadiosHtml());
+ $this->setCrawler($this->getRadiosHtml());
$this->dontSeeIsSelected('availability', 'partial_time');
}
@@ -169,13 +171,63 @@ protected function getCheckboxesHtml()
public function testSeeCheckboxIsChecked()
{
- $this->crawler = new Crawler($this->getCheckboxesHtml());
+ $this->setCrawler($this->getCheckboxesHtml());
$this->seeIsChecked('terms');
}
public function testDontSeeCheckboxIsChecked()
{
- $this->crawler = new Crawler($this->getCheckboxesHtml());
+ $this->setCrawler($this->getCheckboxesHtml());
$this->dontSeeIsChecked('list');
}
+
+ protected function getLayoutHtml()
+ {
+ return
+ '
+
+ The PHP Framework For Web Artisans
+ Elegant applications delivered at warp speed.
+
+
';
+ }
+
+ public function testWithin()
+ {
+ $this->setCrawler($this->getLayoutHtml());
+
+ // Limit the search to the "header" area
+ $this->within('header', function () {
+ $this->see('Laravel')
+ ->dontSeeInElement('h2', 'PHP Framework');
+ });
+
+ // Make sure we are out of the within context
+ $this->seeLink('Documentation');
+
+ // Test other methods as well
+ $this->within('#features', function () {
+ $this->seeInElement('h2', 'PHP Framework')
+ ->dontSee('Laravel')
+ ->dontSeeLink('Documentation');
+ });
+ }
+
+ public function testNestedWithin()
+ {
+ $this->setCrawler($this->getLayoutHtml());
+
+ $this->within('#features', function () {
+ $this->dontSee('Laravel')
+ ->see('Web Artisans')
+ ->within('h2', function () {
+ $this->see('PHP Framework')
+ ->dontSee('Elegant applications');
+ });
+ });
+ }
}