Problem/Motivation

Follow-on from #3390193: Add a drupalGet() method to KernelTestBase which allows HTTP requests to be made in Kernel tests.

This would allow forms to be submitted too.

There are some challenges that need to be ironed out to make this possible:

  1. We can't add submitForm to HttpKernelUiHelperTrait as it will conflict with kernel tests that also implement FormInterface
  2. #2505339: Stop using getMainRequest() to build $form['#action'] - when FormBuilder gets the main request to build the form's 'action' attribute, it is getting the CLI request for the PHPUnit test, whose path is '/'. Therefore, the form submission goes to the wrong URL
  3. Not strictly related to submitForm, but various static properties need to be reset after each request

Steps to reproduce

N/A

Proposed resolution

Add submitForm to a new HttpKernelFormHelperTrait trait that can be used selectively. Tests that implement FormInterface can alias the submitForm function to avoid conflicts.

Introduce a HttpKernelTestBrowser class that extends \Symfony\Component\HttpKernel\HttpKernelBrowser. The doRequest method can workaround these challenges, by doing the following:

  1. Isolate the request stack to not include the main request. This fixes the form action attribute.
  2. Reset static properties. Initially this includes:
    • Html::$seenIds
    • FormState::$anyErrors

Additional workarounds can be added as they are found, and can be removed as they are fixed in upstream issues, such as #1852090: Cached render elements can have duplicate HTML IDs.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Issue fork drupal-3566881

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

joachim created an issue. See original summary.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

mstrelan made their first commit to this issue’s fork.

mstrelan’s picture

Status: Postponed » Needs review

Two things:

  1. Kernel tests that also implement FormInterface will fatal if we add this to KernelTestBase. It will need another name or will need to be added via a trait.
  2. We can get around #2505339: Stop using getMainRequest() to build $form['#action'] by extending HttpKernelBrowser and popping requests off the stack. This could be a temporary measure until the blocker is in.

I've posted a proof of concept with one conversion for review. I used an LLM to formulate this solution, and have also tested it on much more complex tests, but keeping it simple for this issue.

The differences in submitForm are:

Dropped $this->prepareRequest() - it's not needed since HttpKernelBrowser manages its own cookie jar
Dropped $this->refreshVariables() - functional tests only need this since the request is a separate process
Dropped $this->checkForMetaRefresh() - we're not doing anything with batch api (at the moment)
Removed condition on !$this->isTestUsingGuzzleClient() - kernel tests never use guzzle

Perhaps we should keep it in sync though, so we could get to a place where both test bases share the same submitForm method. We could implement these methods as no-ops.

mstrelan’s picture

mstrelan’s picture

We can also use HttpKernelTestBrowser in #3609730: Prevent stale kernel in kernel tests with drupalGet

joachim’s picture

I'm going to stop working on this issue and unfollow it -- I refuse to work on or look at code written by LLMs.
LLMs' high energy consumption accelerates climate change, and the proliferation of data centres have impacts on the communities in their vicinity.

I don't even see what the point of using an LLM is here -- this is completely uncharted territory, nobody has yet tried to make a kernel test submit forms, so as all LLMs do is regurgitate what they've seen elsewhere I don't see what it can do.

mstrelan’s picture

That's fine. As I said, there is one test conversion here, and I've done multiple others, so this is working. Having submitForm in kernel tests allows for more test conversions meaning more performance and less energy spent on CI jobs.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

mstrelan’s picture

Issue summary: View changes
Status: Needs work » Needs review

Discussed with @catch in #3613739: [PP-1] Convert ManageFieldsFunctionalTestBase and sub classes to Kernel tests and updated the issue summary with the proposed solution. Rebased the MR and brought in some more changes from the other issue.

joachim’s picture