]> BookStack Code Mirror - bookstack/blobdiff - tests/TestResponse.php
Started work on details/summary blocks
[bookstack] / tests / TestResponse.php
index 9c6b78782b4c91bb8576bfb535666559a588d772..4e53aa020ba3ca5054e8d75e14a2ed57dc277276 100644 (file)
@@ -1,16 +1,17 @@
-<?php namespace Tests;
+<?php
 
-use \Illuminate\Foundation\Testing\TestResponse as BaseTestResponse;
-use Symfony\Component\DomCrawler\Crawler;
+namespace Tests;
+
+use Illuminate\Testing\TestResponse as BaseTestResponse;
 use PHPUnit\Framework\Assert as PHPUnit;
+use Symfony\Component\DomCrawler\Crawler;
 
 /**
  * Class TestResponse
  * Custom extension of the default Laravel TestResponse class.
- * @package Tests
  */
-class TestResponse extends BaseTestResponse {
-
+class TestResponse extends BaseTestResponse
+{
     protected $crawlerInstance;
 
     /**
@@ -21,11 +22,21 @@ class TestResponse extends BaseTestResponse {
         if (!is_object($this->crawlerInstance)) {
             $this->crawlerInstance = new Crawler($this->getContent());
         }
+
         return $this->crawlerInstance;
     }
 
+    /**
+     * Get the HTML of the first element at the given selector.
+     */
+    public function getElementHtml(string $selector): string
+    {
+        return $this->crawler()->filter($selector)->first()->outerHtml();
+    }
+
     /**
      * Assert the response contains the specified element.
+     *
      * @return $this
      */
     public function assertElementExists(string $selector)
@@ -33,16 +44,38 @@ class TestResponse extends BaseTestResponse {
         $elements = $this->crawler()->filter($selector);
         PHPUnit::assertTrue(
             $elements->count() > 0,
-            'Unable to find element matching the selector: '.PHP_EOL.PHP_EOL.
-            "[{$selector}]".PHP_EOL.PHP_EOL.
-            'within'.PHP_EOL.PHP_EOL.
+            'Unable to find element matching the selector: ' . PHP_EOL . PHP_EOL .
+            "[{$selector}]" . PHP_EOL . PHP_EOL .
+            'within' . PHP_EOL . PHP_EOL .
+            "[{$this->getContent()}]."
+        );
+
+        return $this;
+    }
+
+    /**
+     * Assert the response contains the given count of elements
+     * that match the given css selector.
+     *
+     * @return $this
+     */
+    public function assertElementCount(string $selector, int $count)
+    {
+        $elements = $this->crawler()->filter($selector);
+        PHPUnit::assertTrue(
+            $elements->count() === $count,
+            'Unable to ' . $count . ' element(s) matching the selector: ' . PHP_EOL . PHP_EOL .
+            "[{$selector}]" . PHP_EOL . PHP_EOL .
+            'found ' . $elements->count() . ' within' . PHP_EOL . PHP_EOL .
             "[{$this->getContent()}]."
         );
+
         return $this;
     }
 
     /**
      * Assert the response does not contain the specified element.
+     *
      * @return $this
      */
     public function assertElementNotExists(string $selector)
@@ -50,23 +83,32 @@ class TestResponse extends BaseTestResponse {
         $elements = $this->crawler()->filter($selector);
         PHPUnit::assertTrue(
             $elements->count() === 0,
-            'Found elements matching the selector: '.PHP_EOL.PHP_EOL.
-            "[{$selector}]".PHP_EOL.PHP_EOL.
-            'within'.PHP_EOL.PHP_EOL.
+            'Found elements matching the selector: ' . PHP_EOL . PHP_EOL .
+            "[{$selector}]" . PHP_EOL . PHP_EOL .
+            'within' . PHP_EOL . PHP_EOL .
             "[{$this->getContent()}]."
         );
+
         return $this;
     }
 
     /**
      * Assert the response includes a specific element containing the given text.
+     * If an nth match is provided, only that will be checked otherwise all matching
+     * elements will be checked for the given text.
+     *
      * @return $this
      */
-    public function assertElementContains(string $selector, string $text)
+    public function assertElementContains(string $selector, string $text, ?int $nthMatch = null)
     {
         $elements = $this->crawler()->filter($selector);
         $matched = false;
         $pattern = $this->getEscapedPattern($text);
+
+        if (!is_null($nthMatch)) {
+            $elements = $elements->eq($nthMatch - 1);
+        }
+
         foreach ($elements as $element) {
             $element = new Crawler($element);
             if (preg_match("/$pattern/i", $element->html())) {
@@ -77,11 +119,12 @@ class TestResponse extends BaseTestResponse {
 
         PHPUnit::assertTrue(
             $matched,
-            'Unable to find element of selector: '.PHP_EOL.PHP_EOL.
-            "[{$selector}]".PHP_EOL.PHP_EOL.
-            'containing text'.PHP_EOL.PHP_EOL.
-            "[{$text}]".PHP_EOL.PHP_EOL.
-            'within'.PHP_EOL.PHP_EOL.
+            'Unable to find element of selector: ' . PHP_EOL . PHP_EOL .
+            ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
+            "[{$selector}]" . PHP_EOL . PHP_EOL .
+            'containing text' . PHP_EOL . PHP_EOL .
+            "[{$text}]" . PHP_EOL . PHP_EOL .
+            'within' . PHP_EOL . PHP_EOL .
             "[{$this->getContent()}]."
         );
 
@@ -90,13 +133,21 @@ class TestResponse extends BaseTestResponse {
 
     /**
      * Assert the response does not include a specific element containing the given text.
+     * If an nth match is provided, only that will be checked otherwise all matching
+     * elements will be checked for the given text.
+     *
      * @return $this
      */
-    public function assertElementNotContains(string $selector, string $text)
+    public function assertElementNotContains(string $selector, string $text, ?int $nthMatch = null)
     {
         $elements = $this->crawler()->filter($selector);
         $matched = false;
         $pattern = $this->getEscapedPattern($text);
+
+        if (!is_null($nthMatch)) {
+            $elements = $elements->eq($nthMatch - 1);
+        }
+
         foreach ($elements as $element) {
             $element = new Crawler($element);
             if (preg_match("/$pattern/i", $element->html())) {
@@ -107,11 +158,12 @@ class TestResponse extends BaseTestResponse {
 
         PHPUnit::assertTrue(
             !$matched,
-            'Found element of selector: '.PHP_EOL.PHP_EOL.
-            "[{$selector}]".PHP_EOL.PHP_EOL.
-            'containing text'.PHP_EOL.PHP_EOL.
-            "[{$text}]".PHP_EOL.PHP_EOL.
-            'within'.PHP_EOL.PHP_EOL.
+            'Found element of selector: ' . PHP_EOL . PHP_EOL .
+            ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
+            "[{$selector}]" . PHP_EOL . PHP_EOL .
+            'containing text' . PHP_EOL . PHP_EOL .
+            "[{$text}]" . PHP_EOL . PHP_EOL .
+            'within' . PHP_EOL . PHP_EOL .
             "[{$this->getContent()}]."
         );
 
@@ -120,6 +172,7 @@ class TestResponse extends BaseTestResponse {
 
     /**
      * Assert there's a notification within the view containing the given text.
+     *
      * @return $this
      */
     public function assertNotificationContains(string $text)
@@ -129,14 +182,15 @@ class TestResponse extends BaseTestResponse {
 
     /**
      * Get the escaped text pattern for the constraint.
+     *
      * @return string
      */
     protected function getEscapedPattern(string $text)
     {
         $rawPattern = preg_quote($text, '/');
         $escapedPattern = preg_quote(e($text), '/');
+
         return $rawPattern == $escapedPattern
             ? $rawPattern : "({$rawPattern}|{$escapedPattern})";
     }
-
 }