Problem/Motivation

A big area of problems of the PHPUnit conversions are the usages of $this->xpath(), because mink uses domdocument objects.

Proposed resolution

Provide a FC layer:

  • Add a ::xpathUsingMink() to WTB. This allows people to convert existing WTB without adding the risk to move to BTB
  • Moving to BTB later is then way easier (again just renaming the base class).

Remaining tasks

User interface changes

API changes

Data model changes

Comments

dawehner created an issue. See original summary.

dawehner’s picture

Status: Active » Needs review
StatusFileSize
new5.24 KB

Here is a try

Status: Needs review » Needs work

The last submitted patch, 2: 2809181-2.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new6.9 KB
new3.51 KB

Let's make it actually working

dawehner’s picture

Parent issue: » #2807237: PHPUnit initiative
daffie’s picture

Maybe a stupid idea, but is it an idea to do #1333730: [Meta] PHP DOM (libxml2) misinterprets HTML5 first and make all the tests HTML5.

claudiu.cristea’s picture

+++ b/core/modules/system/src/Tests/System/PageTitleTest.php
@@ -102,15 +102,15 @@ public function testRoutingTitle() {
-    $this->assertEqual('Foo', (string) $result[0]);
...
+    $this->assertEqual('Foo', $result[0]->getText());

Looking at this change, I don't understand what this FC brings. My initial understanding was that $this->xpathUsingMink() will return exactly the same structure as WebTestBase::xpath() did so that we can completely avoid this kind of change.

dawehner’s picture

Issue summary: View changes

Looking at this change, I don't understand what this FC brings. My initial understanding was that $this->xpathUsingMink() will return exactly the same structure as WebTestBase::xpath() did so that we can completely avoid this kind of change.

Let me explain it with more details in the issue summary. I hope this makes more sense.

klausi’s picture

Status: Needs review » Needs work

Nice work, that looks easier than I would have expected!

  1. +++ b/core/modules/simpletest/src/AssertContentTrait.php
    @@ -235,6 +237,38 @@ protected function xpath($xpath, array $arguments = []) {
       /**
    +   * Performs an xpath search on the contents of the internal browser.
    +   *
    +   * The search is relative to the root element (HTML tag normally) of the page.
    +   *
    

    We should mention here that this is a forward compatibility helper for the conversion to BrowserTestBase.

    "This method is a forwards compatibility helper for the conversion to \Drupal\Tests\BrowserTestBase".

  2. +++ b/core/modules/simpletest/src/GoutteWithManualResponse.php
    @@ -0,0 +1,27 @@
    +  /**
    +   * Creates a crawler and sets it to the object.
    +   *
    +   * This method returns null if the DomCrawler component is not available.
    +   *
    

    hm, the DomCrawler component is always available in our case, so this comment should be removed.

  3. +++ b/core/modules/simpletest/src/GoutteWithManualResponse.php
    @@ -0,0 +1,27 @@
    +   * @return \Symfony\Component\DomCrawler\Crawler|null
    +   */
    

    Why does this method return something? We are not even interested in the return value?

  4. +++ b/core/tests/Drupal/Tests/BrowserTestBase.php
    @@ -1715,6 +1715,25 @@ protected function xpath($xpath, array $arguments = []) {
    +   * @return \Behat\Mink\Element\NodeElement[]
    +   *   The list of elements matching the xpath expression.
    +   */
    +  protected function xpathUsingMink($xpath, array $arguments = []) {
    

    The method on BrowserTestBase should have an @deprecated tag because people should not use it for new code. They should use the xpath method.

    "@deprecated Scheduled for removal in Drupal 9.0.0. Use self:xpath() instead."

claudiu.cristea’s picture

Status: Needs work » Needs review
StatusFileSize
new6.96 KB
new2.34 KB

Fixed #9 issues.

klausi’s picture

Status: Needs review » Needs work

Thanks, almost ready! I'm not 100% sold on the method name "xpathUsingMink", but I also don't have a better idea.

+++ b/core/modules/simpletest/src/GoutteWithManualResponse.php
@@ -0,0 +1,23 @@
+
+class GoutteWithManualResponse extends Client {

Class comment is missing. We should mention here that this is used in WebTestBase::xpathUsingMink() for forwards compatibility. We should also mention that we need to have this class because there is no way to set an artificial response on the Goutte client otherwise because createFromCrawler() is protected.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new673 bytes
new7.22 KB

Here is some documentation

klausi’s picture

Status: Needs review » Needs work

Just a round of nitpicks, otherwise looks good to go to me.

  1. +++ b/core/modules/simpletest/src/AssertContentTrait.php
    @@ -235,6 +237,40 @@ protected function xpath($xpath, array $arguments = []) {
    +   * @return \Behat\Mink\Element\NodeElement[]|bool
    +   *   The return value of the xpath search or FALSE on failure. For details on
    +   *   the xpath string format and return values see the domdocument.
    +   *   documentation.
    +   *
    +   * @see http://php.net/manual/class.domdocument.php
    

    The last part of the sentence is broken. Did you mean see the Mink documentation or DOMDocument?

    And the data type should be "...|false" because this never returns TRUE.

  2. +++ b/core/modules/simpletest/src/GoutteWithManualResponse.php
    @@ -0,0 +1,33 @@
    +/**
    + * Used by \Drupal\simpletest\AssertContentTrait::xpathUsingMink as a FC layer.
    + *
    

    I think we should avoid uncommon abbreviations such as "FC", let's use forward compatibility layer.

    Can be just "Used as part of the forward compatibility layer for BrowserTestBase."

  3. +++ b/core/modules/simpletest/src/GoutteWithManualResponse.php
    @@ -0,0 +1,33 @@
    + * This class allowed you to set the response content manually onto goutte
    + * responses.
    

    Should be "This class allows you to set the response content manually on a Goutte client."

  4. +++ b/core/tests/Drupal/Tests/BrowserTestBase.php
    @@ -1719,6 +1719,28 @@ protected function xpath($xpath, array $arguments = []) {
    +   * @deprecated Scheduled for removal in Drupal 9.0.0.
    +   *   Use self:xpath() instead.
    

    Should have 2 "::" after self.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new7.69 KB
new2.76 KB

Sorry klausi for the slow response :(

I think we should avoid uncommon abbreviations such as "FC", let's use forward compatibility layer.

I totally agree.

klausi’s picture

Title: Provide FC layer for BrowserTestBase::xpath » Provide forward compatibility layer for BrowserTestBase::xpath
Status: Needs review » Needs work
Issue tags: +Novice

Cool, one minor doc nit pick that can be cleaned up by a novice contributor:

+++ b/core/modules/simpletest/src/AssertContentTrait.php
@@ -208,6 +210,9 @@ protected function buildXPathQuery($xpath, array $args = array()) {
+   * For future compatibility with BrowserTestBase you could use xpathUsingMink
+   * instead as wel..

"For future compatibility with BrowserTestBase you can use the method xpathUsingMink() instead."

hardikpandya’s picture

Assigned: Unassigned » hardikpandya
hardikpandya’s picture

Assigned: hardikpandya » Unassigned
Status: Needs work » Needs review
StatusFileSize
new734 bytes
new7.69 KB
klausi’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Novice

Thanks, looks god to me.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 17: 2809181-17.patch, failed testing.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dawehner’s picture

Status: Needs work » Reviewed & tested by the community

Back to RTBC

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs change record, +8.3.0 release notes
  1. I think we need a CR
  2. +++ b/core/modules/simpletest/src/GoutteWithManualResponse.php
    @@ -0,0 +1,33 @@
    +/**
    + * Used as part of the forward compatibility layer for BrowserTestBase.
    + *
    + * This class allows you to set the response content manually on a Goutte
    + * client.
    + *
    + * @internal
    + *
    + * @see \Drupal\simpletest\AssertContentTrait::xpathUsingMink
    + */
    +class GoutteWithManualResponse extends Client {
    

    I think we should mark this as deprecated too - so we don't forget to remove it in 9.0.x :)

  3. +++ b/core/modules/simpletest/src/AssertContentTrait.php
    @@ -208,6 +210,9 @@ protected function buildXPathQuery($xpath, array $args = array()) {
    +   * For future compatibility with BrowserTestBase you can use the method
    +   * xpathUsingMink() instead.
    

    I think we should deprecate the method specifically so people know to use xpathUsingMink(). So their IDEs tell the easy to upgrade. It would also be useful if this documentation gave the developer some idea about what they might need to change given the new return type.

  4. +++ b/core/modules/simpletest/src/AssertContentTrait.php
    @@ -235,6 +240,41 @@ protected function xpath($xpath, array $arguments = []) {
    +   *   The return value of the xpath search or FALSE on failure. For details on
    +   *   the xpath string format checkout the DomDocument documentation. For more
    +   *   details on the return values, checkout the mink documentation.
    

    Should checkout have a comma before it yes or no. It looks like this documentation is hedging its bets :).

mpdonadio’s picture

+++ b/core/modules/simpletest/src/AssertContentTrait.php
@@ -235,6 +240,41 @@ protected function xpath($xpath, array $arguments = []) {
+  protected function xpathUsingMink($xpath, array $arguments = []) {
+    $client = new GoutteWithManualResponse();
+    $client->setCrawlerFromContent($this->getUrl(), $this->getRawContent(), $this->drupalGetHeader('Content-Type'));
+
+    $driver = new GoutteDriver($client);
+    $session = new Session($driver);
+
+    $session->start();
+
+    $xpath = $this->buildXPathQuery($xpath, $arguments);
+    return $session->getPage()->findAll('xpath', $xpath);
+  }
+

Just discovered this issue, and don't want to hijack it, but could this technique be used to update the handful of places where \Drupal\simpletest\AssertContentTrait::setRawContent() is used?

dawehner’s picture

Just discovered this issue, and don't want to hijack it, but could this technique be used to update the handful of places where \Drupal\simpletest\AssertContentTrait::setRawContent() is used?

Yeah I guess we would actually maybe provide an API for that, even I actually don't like it. If you want to set raw content you can use a kernel test IMHO.

klausi’s picture

Now that #2770921: Feb 21st: Convert chunk of WTB to BTB by just moving classes, changing use statements adding traits landed I think this forward compatibility is not necessary anymore. The hope was that we could use this to convert even more tests with the big bang patch.

Now this forward compatibility layer would just create more work:
1. Update test case to use forward compatibility layer.
2. Move test case to use BrowserTestBase

While without the forward compatibility layer we just do this in one step. Maybe I'm missing something?

Munavijayalakshmi’s picture

Version: 8.4.x-dev » 8.3.x-dev
Assigned: Unassigned » Munavijayalakshmi
Issue tags: +Needs reroll
Munavijayalakshmi’s picture

Assigned: Munavijayalakshmi » Unassigned
jofitz’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new6.78 KB

Re-rolled.

Excluded changes to ContactAuthenticatedUserTest.php because they introduced calls to a deprecated function (in favour of the replacement function).

klausi’s picture

Status: Needs review » Closed (won't fix)
Issue tags: -8.3.0 release notes

I'm closing this because right now it seems we can work through converting Simpletests without this layer. As I said above it is probably too late for this and just creates more work.