class WebAssertTest

Same name in this branch
  1. 10 core/tests/Drupal/FunctionalTests/WebAssertTest.php \Drupal\FunctionalTests\WebAssertTest
Same name and namespace in other branches
  1. 9 core/tests/Drupal/FunctionalTests/WebAssertTest.php \Drupal\FunctionalTests\WebAssertTest
  2. 11.x core/tests/Drupal/FunctionalTests/WebAssertTest.php \Drupal\FunctionalTests\WebAssertTest
  3. 11.x core/tests/Drupal/Tests/Core/Test/WebAssertTest.php \Drupal\Tests\Core\Test\WebAssertTest

Tests WebAssert functionality.

@group browsertestbase @coversDefaultClass \Drupal\Tests\WebAssert

Hierarchy

Expanded class hierarchy of WebAssertTest

File

core/tests/Drupal/Tests/Core/Test/WebAssertTest.php, line 25

Namespace

Drupal\Tests\Core\Test
View source
class WebAssertTest extends UnitTestCase {
  
  /**
   * Session mock.
   */
  protected Session $session;
  
  /**
   * Client mock.
   */
  protected AbstractBrowser $client;
  
  /**
   * {@inheritdoc}
   */
  public function setUp() : void {
    parent::setUp();
    $this->client = new MockClient();
    $driver = new BrowserKitDriver($this->client);
    $this->session = new Session($driver);
  }
  
  /**
   * Get the mocked session.
   */
  protected function assertSession() : WebAssert {
    return new WebAssert($this->session);
  }
  
  /**
   * Simulate a page visit and expect a response.
   *
   * @param string $uri
   *   The URI to visit. This is only required if assertions are made about the
   *   URL, otherwise it can be left empty.
   * @param string $content
   *   The expected response content.
   * @param array $responseHeaders
   *   The expected response headers.
   */
  protected function visit(string $uri = '', string $content = '', array $responseHeaders = []) : void {
    $this->client
      ->setExpectedResponse(new Response($content, 200, $responseHeaders));
    $this->session
      ->visit($uri);
  }
  
  /**
   * Tests WebAssert::responseHeaderExists().
   *
   * @covers ::responseHeaderExists
   */
  public function testResponseHeaderExists() : void {
    $this->visit('', '', [
      'Null-Header' => '',
    ]);
    $this->assertSession()
      ->responseHeaderExists('Null-Header');
    $this->expectException(AssertionFailedError::class);
    $this->expectExceptionMessage("Failed asserting that the response has a 'does-not-exist' header.");
    $this->assertSession()
      ->responseHeaderExists('does-not-exist');
  }
  
  /**
   * Tests WebAssert::responseHeaderDoesNotExist().
   *
   * @covers ::responseHeaderDoesNotExist
   */
  public function testResponseHeaderDoesNotExist() : void {
    $this->visit('', '', [
      'Null-Header' => '',
    ]);
    $this->assertSession()
      ->responseHeaderDoesNotExist('does-not-exist');
    $this->expectException(AssertionFailedError::class);
    $this->expectExceptionMessage("Failed asserting that the response does not have a 'Null-Header' header.");
    $this->assertSession()
      ->responseHeaderDoesNotExist('Null-Header');
  }
  
  /**
   * @covers ::pageTextMatchesCount
   */
  public function testPageTextMatchesCount() : void {
    $this->visit('', 'Test page text. <a href="#">Foo</a>');
    $this->assertSession()
      ->pageTextMatchesCount(1, '/Test page text\\./');
    $this->expectException(AssertionFailedError::class);
    $this->expectExceptionMessage("Failed asserting that the page matches the pattern '/does-not-exist/' 1 time(s), 0 found.");
    $this->assertSession()
      ->pageTextMatchesCount(1, '/does-not-exist/');
  }
  
  /**
   * @covers ::pageTextContainsOnce
   */
  public function testPageTextContainsOnce() : void {
    $this->visit('', 'Test page text. <a href="#">Foo</a>');
    $this->assertSession()
      ->pageTextContainsOnce('Test page text.');
    $this->expectException(ResponseTextException::class);
    $this->expectExceptionMessage("Failed asserting that the page matches the pattern '/does\\-not\\-exist/ui' 1 time(s), 0 found.");
    $this->assertSession()
      ->pageTextContainsOnce('does-not-exist');
  }
  
  /**
   * @covers ::elementTextEquals
   */
  public function testElementTextEquals() : void {
    $this->visit('', '<h1>Test page</h1>');
    $this->assertSession()
      ->elementTextEquals('xpath', '//h1', 'Test page');
    $this->expectException(AssertionFailedError::class);
    $this->expectExceptionMessage("Failed asserting that the text of the element identified by '//h1' equals 'Foo page'.");
    $this->assertSession()
      ->elementTextEquals('xpath', '//h1', 'Foo page');
  }
  
  /**
   * @covers ::addressEquals
   */
  public function testAddressEquals() : void {
    $this->visit('http://localhost/test-page');
    $this->assertSession()
      ->addressEquals('test-page');
    $this->assertSession()
      ->addressEquals('test-page?');
    $this->assertSession()
      ->addressNotEquals('test-page?a=b');
    $this->assertSession()
      ->addressNotEquals('other-page');
    $this->visit('http://localhost/test-page?a=b&c=d');
    $this->assertSession()
      ->addressEquals('test-page');
    $this->assertSession()
      ->addressEquals('test-page?a=b&c=d');
    $url = $this->createMock(Url::class);
    $url->expects($this->any())
      ->method('setAbsolute')
      ->willReturn($url);
    $url->expects($this->any())
      ->method('toString')
      ->willReturn('test-page?a=b&c=d');
    $this->assertSession()
      ->addressEquals($url);
    $this->assertSession()
      ->addressNotEquals('test-page?c=d&a=b');
    $this->assertSession()
      ->addressNotEquals('test-page?a=b');
    $this->assertSession()
      ->addressNotEquals('test-page?a=b&c=d&e=f');
    $this->assertSession()
      ->addressNotEquals('other-page');
    $this->assertSession()
      ->addressNotEquals('other-page?a=b&c=d');
    $this->expectException(ExpectationException::class);
    $this->expectExceptionMessage('Current page is "/test-page?a=b&c=d", but "/test-page?a=b&c=e" expected.');
    $this->assertSession()
      ->addressEquals('test-page?a=b&c=e');
  }
  
  /**
   * @covers ::addressNotEquals
   */
  public function testAddressNotEqualsException() : void {
    $this->visit('http://localhost/test-page?a=b&c=d');
    $this->expectException(ExpectationException::class);
    $this->expectExceptionMessage('Current page is "/test-page?a=b&c=d", but should not be.');
    $this->assertSession()
      ->addressNotEquals('test-page?a=b&c=d');
  }
  
  /**
   * Tests linkExists() with pipe character (|) in locator.
   *
   * @covers ::linkExists
   */
  public function testPipeCharInLocator() : void {
    $this->visit('', '<a href="http://example.com">foo|bar|baz</a>');
    $this->assertSession()
      ->linkExists('foo|bar|baz');
    $this->addToAssertionCount(1);
  }
  
  /**
   * Tests linkExistsExact() functionality.
   *
   * @covers ::linkExistsExact
   */
  public function testLinkExistsExact() : void {
    $this->visit('', '<a href="http://example.com">foo|bar|baz</a>');
    $this->assertSession()
      ->linkExistsExact('foo|bar|baz');
    $this->addToAssertionCount(1);
  }
  
  /**
   * Tests linkExistsExact() functionality fail.
   *
   * @covers ::linkExistsExact
   */
  public function testInvalidLinkExistsExact() : void {
    $this->visit('', '<a href="http://example.com">foo|bar|baz</a>');
    $this->expectException(ExpectationException::class);
    $this->expectExceptionMessage('Link with label foo|bar not found');
    $this->assertSession()
      ->linkExistsExact('foo|bar');
  }
  
  /**
   * Tests linkNotExistsExact() functionality.
   *
   * @covers ::linkNotExistsExact
   */
  public function testLinkNotExistsExact() : void {
    $this->visit('', '<a href="http://example.com">foo|bar|baz</a>');
    $this->assertSession()
      ->linkNotExistsExact('foo|bar');
    $this->addToAssertionCount(1);
  }
  
  /**
   * Tests linkNotExistsExact() functionality fail.
   *
   * @covers ::linkNotExistsExact
   */
  public function testInvalidLinkNotExistsExact() : void {
    $this->visit('', '<a href="http://example.com">foo|bar|baz</a>');
    $this->expectException(ExpectationException::class);
    $this->expectExceptionMessage('Link with label foo|bar|baz found');
    $this->assertSession()
      ->linkNotExistsExact('foo|bar|baz');
    $this->addToAssertionCount(1);
  }
  
  /**
   * Tests linkExistsByHref() functionality.
   *
   * @covers ::linkByHrefExists
   */
  public function testLinkByHrefExists() : void {
    $this->visit('', '<a href="/user/login">Log in</a><a href="/user/register">Register</a>');
    // Partial matching.
    $this->assertSession()
      ->linkByHrefExists('/user');
    // Full matching.
    $this->assertSession()
      ->linkByHrefExists('/user/login');
    $this->addToAssertionCount(1);
  }
  
  /**
   * Tests linkExistsByHref() functionality fail.
   *
   * @covers ::linkByHrefExists
   */
  public function testInvalidLinkByHrefExists() : void {
    $this->visit('', '<a href="/user/login">Log in</a><a href="/user/register">Register</a>');
    $this->expectException(ExpectationException::class);
    $this->assertSession()
      ->linkByHrefExists('/foo');
    $this->addToAssertionCount(1);
  }
  
  /**
   * Tests linkByHrefNotExists() functionality.
   *
   * @covers ::linkByHrefNotExists
   */
  public function testLinkByHrefNotExists() : void {
    $this->visit('', '<a href="/user/login">Log in</a><a href="/user/register">Register</a>');
    $this->assertSession()
      ->linkByHrefNotExists('/foo');
    $this->addToAssertionCount(1);
  }
  
  /**
   * Tests LinkByHrefNotExists() functionality fail partial match.
   *
   * @covers ::linkByHrefNotExists
   */
  public function testInvalidLinkByHrefNotExistsPartial() : void {
    $this->visit('', '<a href="/user/login">Log in</a><a href="/user/register">Register</a>');
    $this->expectException(ExpectationException::class);
    $this->assertSession()
      ->linkByHrefNotExists('/user');
    $this->addToAssertionCount(1);
  }
  
  /**
   * Tests LinkByHrefNotExists() functionality fail full match.
   *
   * @covers ::linkByHrefNotExists
   */
  public function testInvalidLinkByHrefNotExistsFull() : void {
    $this->visit('', '<a href="/user/login">Log in</a><a href="/user/register">Register</a>');
    $this->expectException(ExpectationException::class);
    $this->assertSession()
      ->linkByHrefNotExists('/user/login');
  }
  
  /**
   * Tests linkExistsByHref() functionality.
   *
   * @covers ::linkByHrefExistsExact
   */
  public function testLinkByHrefExistsExact() : void {
    $this->visit('', '<a href="/user/login">Log in</a><a href="/user/register">Register</a>');
    $this->assertSession()
      ->linkByHrefExistsExact('/user/login');
    $this->addToAssertionCount(1);
  }
  
  /**
   * Tests linkByHrefExistsExact() functionality fail.
   *
   * @covers ::linkByHrefExistsExact
   */
  public function testInvalidLinkByHrefExistsExact() : void {
    $this->visit('', '<a href="/user/login">Log in</a><a href="/user/register">Register</a>');
    $this->expectException(ExpectationException::class);
    $this->assertSession()
      ->linkByHrefExistsExact('/foo');
  }
  
  /**
   * Tests linkByHrefNotExistsExact() functionality.
   *
   * @covers ::linkByHrefNotExistsExact
   */
  public function testLinkByHrefNotExistsExact() : void {
    $this->visit('', '<a href="/user/login">Log in</a><a href="/user/register">Register</a>');
    $this->assertSession()
      ->linkByHrefNotExistsExact('/foo');
    $this->addToAssertionCount(1);
  }
  
  /**
   * Tests linkByHrefNotExistsExact() functionality fail.
   *
   * @covers ::linkByHrefNotExistsExact
   */
  public function testInvalidLinkByHrefNotExistsExact() : void {
    $this->visit('', '<a href="/user/login">Log in</a><a href="/user/register">Register</a>');
    $this->expectException(ExpectationException::class);
    $this->assertSession()
      ->linkByHrefNotExistsExact('/user/login');
  }
  
  /**
   * Tests legacy text asserts.
   *
   * @covers ::responseContains
   * @covers ::responseNotContains
   */
  public function testTextAsserts() : void {
    $this->visit('', 'Bad html &lt;script&gt;alert(123);&lt;/script&gt;');
    $dangerous = 'Bad html <script>alert(123);</script>';
    $sanitized = Html::escape($dangerous);
    $this->assertSession()
      ->responseNotContains($dangerous);
    $this->assertSession()
      ->responseContains($sanitized);
    $this->addToAssertionCount(2);
  }
  
  /**
   * Tests legacy field asserts for button field type.
   *
   * @covers ::buttonExists
   * @covers ::buttonNotExists
   */
  public function testFieldAssertsForButton() : void {
    $this->visit('', <<<HTML
      <input type="submit" id="edit-save" value="Save" name="op">
      <input type="submit" id="duplicate_button" value="Duplicate button 1" name="duplicate_button">
      <input type="submit" id="duplicate_button" value="Duplicate button 2" name="duplicate_button">
HTML
);
    // Verify if the test passes with button ID.
    $this->assertSession()
      ->buttonExists('edit-save');
    // Verify if the test passes with button Value.
    $this->assertSession()
      ->buttonExists('Save');
    // Verify if the test passes with button Name.
    $this->assertSession()
      ->buttonExists('op');
    // Verify if the test passes with button ID.
    $this->assertSession()
      ->buttonNotExists('i-do-not-exist');
    // Verify if the test passes with button Value.
    $this->assertSession()
      ->buttonNotExists('I do not exist');
    // Verify if the test passes with button Name.
    $this->assertSession()
      ->buttonNotExists('no');
    // Test that multiple fields with the same name are validated correctly.
    $this->assertSession()
      ->buttonExists('duplicate_button');
    $this->assertSession()
      ->buttonExists('Duplicate button 1');
    $this->assertSession()
      ->buttonExists('Duplicate button 2');
    $this->assertSession()
      ->buttonNotExists('Rabbit');
    try {
      $this->assertSession()
        ->buttonNotExists('Duplicate button 2');
      $this->fail('The "duplicate_button" field with the value Duplicate button 2 was not found.');
    } catch (ExpectationException $e) {
      // Expected exception; just continue testing.
    }
    $this->addToAssertionCount(11);
  }
  
  /**
   * Tests pageContainsNoDuplicateId() functionality.
   *
   * @covers ::pageContainsNoDuplicateId
   */
  public function testPageContainsNoDuplicateId() : void {
    $this->visit('', <<<HTML
      <h1 id="page-element-title">Hello</h1>
      <h2 id="page-element-description">World</h2>
HTML
);
    $assert_session = $this->assertSession();
    $assert_session->pageContainsNoDuplicateId();
    $this->visit('', <<<HTML
      <h1 id="page-element">Hello</h1>
      <h2 id="page-element">World</h2>
HTML
);
    $this->expectException(ExpectationException::class);
    $this->expectExceptionMessage('The page contains a duplicate HTML ID "page-element".');
    $assert_session->pageContainsNoDuplicateId();
  }
  
  /**
   * Tests assertEscaped() and assertUnescaped().
   *
   * @covers ::assertNoEscaped
   * @covers ::assertEscaped
   */
  public function testEscapingAssertions() : void {
    $assert = $this->assertSession();
    $this->visit('', '<div class="escaped">Escaped: &lt;&quot;&#039;&amp;&gt;</div>');
    $assert->assertNoEscaped('<div class="escaped">');
    $assert->responseContains('<div class="escaped">');
    $assert->assertEscaped('Escaped: <"\'&>');
    $this->visit('', '<div class="escaped">&lt;script&gt;alert(&#039;XSS&#039;);alert(&quot;XSS&quot;);&lt;/script&gt;</div>');
    $assert->assertNoEscaped('<div class="escaped">');
    $assert->responseContains('<div class="escaped">');
    $assert->assertEscaped("<script>alert('XSS');alert(\"XSS\");</script>");
    $this->visit('', <<<HTML
        <div class="unescaped"><script>alert('Marked safe');alert("Marked safe");</script></div>
HTML
);
    $this->session
      ->visit('');
    $assert->assertNoEscaped('<div class="unescaped">');
    $assert->responseContains('<div class="unescaped">');
    $assert->responseContains("<script>alert('Marked safe');alert(\"Marked safe\");</script>");
    $assert->assertNoEscaped("<script>alert('Marked safe');alert(\"Marked safe\");</script>");
    $this->addToAssertionCount(10);
  }

}

Members

Title Sort descending Deprecated Modifiers Object type Summary Overriden Title Overrides
PhpUnitWarnings::$deprecationWarnings private static property Deprecation warnings from PHPUnit to raise with @trigger_error().
PhpUnitWarnings::addWarning public function Converts PHPUnit deprecation warnings to E_USER_DEPRECATED.
RandomGeneratorTrait::getRandomGenerator protected function Gets the random generator for the utility methods.
RandomGeneratorTrait::randomMachineName protected function Generates a unique random string containing letters and numbers.
RandomGeneratorTrait::randomObject public function Generates a random PHP object.
RandomGeneratorTrait::randomString public function Generates a pseudo-random string of ASCII characters of codes 32 to 126.
RandomGeneratorTrait::randomStringValidate Deprecated public function Callback for random string validation.
UnitTestCase::$root protected property The app root. 1
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::setUpBeforeClass public static function
UnitTestCase::__get public function
WebAssertTest::$client protected property Client mock.
WebAssertTest::$session protected property Session mock.
WebAssertTest::assertSession protected function Get the mocked session.
WebAssertTest::setUp public function Overrides UnitTestCase::setUp
WebAssertTest::testAddressEquals public function @covers ::addressEquals[[api-linebreak]]
WebAssertTest::testAddressNotEqualsException public function @covers ::addressNotEquals[[api-linebreak]]
WebAssertTest::testElementTextEquals public function @covers ::elementTextEquals[[api-linebreak]]
WebAssertTest::testEscapingAssertions public function Tests assertEscaped() and assertUnescaped().
WebAssertTest::testFieldAssertsForButton public function Tests legacy field asserts for button field type.
WebAssertTest::testInvalidLinkByHrefExists public function Tests linkExistsByHref() functionality fail.
WebAssertTest::testInvalidLinkByHrefExistsExact public function Tests linkByHrefExistsExact() functionality fail.
WebAssertTest::testInvalidLinkByHrefNotExistsExact public function Tests linkByHrefNotExistsExact() functionality fail.
WebAssertTest::testInvalidLinkByHrefNotExistsFull public function Tests LinkByHrefNotExists() functionality fail full match.
WebAssertTest::testInvalidLinkByHrefNotExistsPartial public function Tests LinkByHrefNotExists() functionality fail partial match.
WebAssertTest::testInvalidLinkExistsExact public function Tests linkExistsExact() functionality fail.
WebAssertTest::testInvalidLinkNotExistsExact public function Tests linkNotExistsExact() functionality fail.
WebAssertTest::testLinkByHrefExists public function Tests linkExistsByHref() functionality.
WebAssertTest::testLinkByHrefExistsExact public function Tests linkExistsByHref() functionality.
WebAssertTest::testLinkByHrefNotExists public function Tests linkByHrefNotExists() functionality.
WebAssertTest::testLinkByHrefNotExistsExact public function Tests linkByHrefNotExistsExact() functionality.
WebAssertTest::testLinkExistsExact public function Tests linkExistsExact() functionality.
WebAssertTest::testLinkNotExistsExact public function Tests linkNotExistsExact() functionality.
WebAssertTest::testPageContainsNoDuplicateId public function Tests pageContainsNoDuplicateId() functionality.
WebAssertTest::testPageTextContainsOnce public function @covers ::pageTextContainsOnce[[api-linebreak]]
WebAssertTest::testPageTextMatchesCount public function @covers ::pageTextMatchesCount[[api-linebreak]]
WebAssertTest::testPipeCharInLocator public function Tests linkExists() with pipe character (|) in locator.
WebAssertTest::testResponseHeaderDoesNotExist public function Tests WebAssert::responseHeaderDoesNotExist().
WebAssertTest::testResponseHeaderExists public function Tests WebAssert::responseHeaderExists().
WebAssertTest::testTextAsserts public function Tests legacy text asserts.
WebAssertTest::visit protected function Simulate a page visit and expect a response.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.