Problem/Motivation

ResourceTestBase uses httpClient but it is defined in EntityResourceTestBase

The xdebug header is not forwarded, which makes debugging extremely painful.

Proposed resolution

This fixes both things, but it is a bit ugly. I would prefer to use a proper cookie jar instead of setting the header ourself, but this is already used for authentication.

Remaining tasks

User interface changes

API changes

Data model changes

Comments

Berdir created an issue. See original summary.

berdir’s picture

Status: Active » Needs review
StatusFileSize
new3.26 KB
wim leers’s picture

Status: Needs review » Needs work

Thanks! This is very helpful. Although I personally almost never get xdebug session cookie-based debugging of tests working. But if this works for you, great.

+++ b/core/modules/rest/tests/src/Functional/ResourceTestBase.php
@@ -325,6 +337,19 @@ protected function grantPermissionsToTestedRole(array $permissions) {
+    $session = $this->getSession();
+    $driver = $session->getDriver();
+    if ($driver instanceof BrowserKitDriver) {
+      $client = $driver->getClient();
+      foreach ($client->getCookieJar()->all() as $cookie) {
+        if (isset($request_options[RequestOptions::HEADERS]['Cookie'])) {
+          $request_options[RequestOptions::HEADERS]['Cookie'] .= '; ' . $cookie->getName() . '=' . $cookie->getValue();
+        }
+        else {
+          $request_options[RequestOptions::HEADERS]['Cookie'] = $cookie->getName() . '=' . $cookie->getValue();
+        }
+      }
+    }

All of this, we only do to support sending the Xdebug cookie header.

But where does this cookie header then get set? AFAICT it's these snippets in BrowserTestBase:

  use XdebugRequestTrait;

…

    // According to the W3C WebDriver specification a cookie can only be set if
    // the cookie domain is equal to the domain of the active document. When the
    // browser starts up the active document is not our domain but 'about:blank'
    // or similar. To be able to set our User-Agent and Xdebug cookies at the
    // start of the test we now do a request to the front page so the active
    // document matches the domain.
    // @see https://w3c.github.io/webdriver/webdriver-spec.html#add-cookie
    // @see https://www.w3.org/Bugs/Public/show_bug.cgi?id=20975
    $session = $this->getSession();
    $session->visit($this->baseUrl);

Can we move all this logic to a protected helper method, that is called from this method? That helper method can then have a name such as decorateWithXdebugCookie().

Most requests performed by this logic do NOT actually need/want cookies. So it's currently very confusing/misleading.

berdir’s picture

The cookie needs to be sent with *every* request. That's how cookies work :)

That workaround there is to be able to call setCookie() later on, that has actually nothing to do with what we are doing, that's just working around Mink/WebDriver's validation within setCookie() as far as I understand.

I know the code there is ugly, the problem is that every usage of XdebugRequestTrait looks different, WebTestBase needs to interact with curl, normal BrowserTestBase set cookies with setCookie() which eventually creates a CookieJar in BrowserKit this needs to mess with a cookie string (As I said, a CookieJar would be nicer, but it would be a Guzzle CookieJar, which again works completely different to BrowserKit).

Happy to move it into a helper method, this was just a quick proof of concept. If we refactor how cookies work, then we can actually make this nicer and don't need to manually mess with the cookie header.

wim leers’s picture

The cookie needs to be sent with *every* request. That's how cookies work :)

Yes, but… when somebody is debugging a test using Basic Auth or OAuth2 or even anonymous, then it doesn't make sense to A) see a cookie, B) see a shitton of code relating to cookies for every single request. That's why I'm asking to put that logic in a separate helper method.

If we refactor how cookies work, then we can actually make this nicer and don't need to manually mess with the cookie header.

That sounds good. But at the same time: it doesn't matter. What matters is that "Xdebug cookie" stuff is in a helper method. I don't care how ugly it is :)

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new3.86 KB

Sure, I just had enough time explain why things are so complicated/duplicated everywhere and not to update the patch, but wanted to do that.

This better?

wim leers’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +DX (Developer Experience)

Yes, thanks! :)

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed 89b381f to 8.4.x and a33fb89 to 8.3.x. Thanks!

Backported to 8.3.x since debuggability in testing is important and this is a test-only change in tests that have changed heaps in 8.3.0.

diff --git a/core/modules/rest/tests/src/Functional/ResourceTestBase.php b/core/modules/rest/tests/src/Functional/ResourceTestBase.php
index 70f9273..3f76c43 100644
--- a/core/modules/rest/tests/src/Functional/ResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/ResourceTestBase.php
@@ -8,8 +8,6 @@
 use Drupal\Tests\BrowserTestBase;
 use Drupal\user\Entity\Role;
 use Drupal\user\RoleInterface;
-use GuzzleHttp\Cookie\CookieJar;
-use GuzzleHttp\Cookie\SetCookie;
 use GuzzleHttp\RequestOptions;
 use Psr\Http\Message\ResponseInterface;
 

Remove unused use statements.

  • alexpott committed 89b381f on 8.4.x
    Issue #2851746 by Berdir, Wim Leers: Support xdebug header in...

  • alexpott committed a33fb89 on 8.3.x
    Issue #2851746 by Berdir, Wim Leers: Support xdebug header in...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.