BrowserTestBase::drupalGet() does not appear to be handling base url properly

Created on 19 July 2018, over 6 years ago
Updated 8 September 2023, over 1 year ago

Problem/Motivation

While investigating a strange failure on #2857157: Implement registration after guest checkout I was getting some weird behaviour when trying to recreate and fix the test failures:

$this->assertUrl('user/3/edit'); was causing:

'Current page is "/subdirectory/user/3/edit", but "/user/3/edit" expected.'

When I first tried to run tests locally with drupal in a subdirectory (i.e. /var/www/htdocs/subdirectory with php ./core/scripts/run-tests.sh --url http://test.local/subdirectory ...) then a lot of url assertions failed and only after replicating the CI environment by moving drupal to /var/www/html and creating the symlink (ln -s /var/www/html /var/www/html/subdirectory) could I get all tests to pass except the one in question.

I was able to 'fix' the test by changing $this->drupalGet($this->product->toUrl()->toString()); to $this->drupalGet($this->product->toUrl());.

I think this weird fix works because the url generator used by $this->product->toUrl()->toString() is correctly adding '/subdirectory' but $this->drupalGet() is not. This kicks the test environment to / but still works because although run-tests.sh is called with i.e. --url "http://php-apache-jenkins-drupal8-contrib-patches-32847/subdirectory" and starts off at /subdirectory, it is just a symlink of the webroot so all paths without /subdirectory will always work still.

As unlikely as this first seems, I think an explanation for no other tests spotting it could be because nobody has committed a test that passes a Url->toString() to $this->drupalGet(), always a Url object (i.e. $this->drupalGet(Url::fromRoute('<front>'));) or a hard coded uri (i.e. $this->drupalGet('admin/content');) and anyone who even notices the /subdirectory in URLs assumes that drupalGet() is automatically adding '/subdirectory' and assertUrl() is handling it like a uri.

Proposed resolution

Strip $base_path from the path given to "drupalGet" when this path is a string and the "url_generator" service is available.
Note that when a string is given and the service is not available, the function "getAbsoluteUrl" already strips the base path.

Remaining tasks

  1. Confirm that tests fail with drupal installed in a subdirectory
  2. Review proposed resolution
  3. Do fixes
  4. Fix tests broken by fixes
  5. Open a discussion in the relevant project about removing the symlink from drupal CI and installing to /var/www/htdocs/subdirectory (there is probably a very good reason for the symlink but i assume the whole point of it was to test everything works when drupal is in a subdirectory?)
🐛 Bug report
Status

Fixed

Version

10.1

Component
PHPUnit 

Last updated 32 minutes ago

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024