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:
- We can't add
submitFormtoHttpKernelUiHelperTraitas it will conflict with kernel tests that also implementFormInterface - #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
- 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:
- Isolate the request stack to not include the main request. This fixes the form action attribute.
- 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
| Comment | File | Size | Author |
|---|
Issue fork drupal-3566881
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
Comment #5
mstrelan commentedTwo things:
HttpKernelBrowserand 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 jarDropped
$this->refreshVariables()- functional tests only need this since the request is a separate processDropped
$this->checkForMetaRefresh()- we're not doing anything with batch api (at the moment)Removed condition on
!$this->isTestUsingGuzzleClient()- kernel tests never use guzzlePerhaps we should keep it in sync though, so we could get to a place where both test bases share the same
submitFormmethod. We could implement these methods as no-ops.Comment #6
mstrelan commentedSome more conversion examples in #3609454: Convert functional tests in system module with submitForm to kernel tests
Comment #7
mstrelan commentedWe can also use HttpKernelTestBrowser in #3609730: Prevent stale kernel in kernel tests with drupalGet
Comment #8
joachim commentedI'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.
Comment #9
mstrelan commentedThat'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.
Comment #10
needs-review-queue-bot commentedThe 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.
Comment #11
mstrelan commentedDiscussed 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.
Comment #12
joachim commentedThis is probably made obsolete by #3618512: Kernel test HTTP requests: sessions and forms.