Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
drupalPostAjaxForm()
is simulating the behaviour of ajax.js
, so using it, doesn't really provide fundamental guarantees.
#2809161: Convert Javascript/AJAX testing to use JavascriptTestBase suggests to convert them to JavascriptTestBase
Proposed resolution
- Figure out which part of the test is testing PHP code and which part ajax behaviour
- Extract the ajax behaviour into a test that extends JavascriptTestBase
Remaining tasks
User interface changes
API changes
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#60 | 2809503-60.patch | 63.7 KB | Lendude |
#60 | interdiff-2809503-57-60.txt | 1.5 KB | Lendude |
#57 | interdiff-2809503-51-57.txt | 601 bytes | voleger |
#57 | 2809503-57.patch | 62.66 KB | voleger |
#51 | 2809503-51.patch | 62.65 KB | andypost |
Comments
Comment #3
michielnugter CreditAttribution: michielnugter as a volunteer and at Synetic commentedComment #5
Anonymous (not verified) CreditAttribution: Anonymous commentedThe first push :) This patch is not very convenient to read). But if someone is already working on this problem, then this stuff can be useful. Review some main points:
1.
FileFieldWidgetTest::testMultiValuedWidget()
contains part of test, where we try to upload more files than allowed form viadrupalPostForm
. But in BTB:drupalPostForm() we can not test this, because it is blocked by Behat\Mink. We need to find some the most convenient alternative. Now this code is left in the simpletest location.2.
A similar problem occurs in
testTemporaryFileRemovalExploit()
andtestTemporaryFileRemovalExploitAnonymous()
, where we need change hidden field, but it also prevent by Behat\Mink. I added a small hack to work around this. But this is only a temporary solution:Also these tests have test coverage for nojs and js side. But I can not find any special behavior in javascript. All logical in the server side and does not depend on how the post-request is sent. Current patch implemented a separate tests for js, but perhaps this does not make sense. In the next patch it will be removed (or sent back to the simpletest before clarifying problem with send hidden fields?)
3.
Upload button not works now (it is hidden by default, and does not work show it by manual). So, the patch testing
Remove
button on visible, but not Upload. Also we already have few issues about the problems with javascript uploading:4.
BTB:uploadNodeFiles
has regression with name of submit button. How many tests will affect if revert it again?5.
FileFieldTestBase
contains a couple of methods that would be useful in javascript tests too. Therefore, they are transferred to the TestFileCreationTrait:7.
JS:testWidgetElement()
contains some test based on uploading phase. It is possible to be better to made additional module, that will be return file by control, for more stable testing (sorry for the clumsy explanation).Comment #6
Anonymous (not verified) CreditAttribution: Anonymous commentedThis patch is still an unreadable (--find-copies do not help, because there are lots of whitespace changes). I will work on a step-by-step description later. Now I just wanted to share the last state.
Patch contains
DrupalPostFormHack
trait, which containsdrupalPostFormHack()
, which works likedrupalPostForm()
from simpletest. But with differences:$postResponse
instead of$this->setRawContent($content);
, because i don't know how to implementsetRawContent()
in BTB. As result:Before:
After:
In other words, I just stole the
handleForm()
from simpletest with replaces SimpleXMLElement/NodeElement API. And used this to prepare a multipart request through the Guzzle client.Now we can fully port FileFieldWidgetTest, without BrowserTestBase::submitForm() modifications 🚀. This is possible, thanks to the replacement of the standard
drupalPostForm()
ondrupalPostFormHack()
in hack part oftestMultiValuedWidget()
anddoTestTemporaryFileRemovalExploit()
.Comment #7
Anonymous (not verified) CreditAttribution: Anonymous commentedSeparate issue for drupalPostFormHack() #2917885: Add drupalPostFormWithInvalidOptions() to BrowserTestBase.
Comment #8
Anonymous (not verified) CreditAttribution: Anonymous commentedPatch with #2917885: Add drupalPostFormWithInvalidOptions() to BrowserTestBase and #2919352: Move methods from FileFieldTestBase to Trait. Even if it is green, it still needs refactoring (for example, FileFieldTestBaseTrait are not used to the fullest while).
Comment #9
Anonymous (not verified) CreditAttribution: Anonymous commented🎉 Green, woot! In fact, the patch contains very minor changes. I will present a readable interdiff after the dependent issues are solved:
Comment #12
LendudeTaking this of postponed so we can take a fresh look at this. We've done some file conversions now, so maybe we can get this to work too now.
Comment #13
LendudeNew stab at this, trying to make this more minimal.
I only converted part of the testMultiValuedWidget test to WebDriverTestBase since that seems like the most complex use case, all the others seem a little too much with the both js and nojs options.
testMultiValuedWidget tries to upload multiple files which Mink doesn't support (see https://github.com/minkphp/Mink/issues/358) because Selenium doesn't support it (see https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/...)
#2917885: Add drupalPostFormWithInvalidOptions() to BrowserTestBase was aimed at working around this, but that seems like massive overkill just for this and that would mean we need to maintain that too. Bah!
So this strips out the overloading of the file widget, so we lose coverage for that. There are no other tests for this (kernel/unit). So that is not good. If anybody has an idea how to tackle this, feel free to chime in!
Comment #15
LendudeHa!, so Mink doesn't support multiple file uploads, but Chromedriver does, so here is a Nightwatch test for it. Works on my machine, lets see if the bot can handle it!
Haven't fixed the other fail yet, just about nightwatch test for now.
Comment #17
LendudeSo the bot handles the Nightwatch test differently then local testing. I've borrowed from \Drupal\Tests\file\Functional\MultipleFileUploadTest how to do multiple file uploads. Doesn't quite work in our scenario since the raised error is a warning not a blocking error, it gets redirected to the node view page and the error is lost.
But we can verify that only 3 files are uploaded.
I would suggest using this version and try to get the nightwatch test running in a follow up. So removed that for now.
Comment #19
LendudeOk, now with the Nightwatch test really removed.
Comment #20
jibranPatch seems ready to me.
Comment #22
alexpottNeeds a reroll
Comment #23
jibranIt conflicts with #2402533: Provide File::createFileUrl() as a replacement for the deprecated File:url() implementation.
Comment #24
LendudeThanks @jibran.
Reroll looks good, back to RTBC.
Comment #25
alexpottI think we need the nightwatch issue created and probably committed before we commit this one as we'd be losing test coverage.
This assumes the multi value widget and single value widget share the same codepaths both in JS and non-JS which would surprise me. Are we sure that losing this coverage is ok?
Comment #26
Lendude@alexpott yeah that all makes sense to look onto. Created the nightwatch issue #3028957: Replicate multi file upload part of \Drupal\file\Tests\FileFieldWidgetTest to Nightwatch
Comment #27
LendudeAdded a javascript test for the single file widget.
Also cleaned up some stale comments.
the Nightwatch test can take a while to land I'm afraid, bot vs local.
Comment #28
MixologicI did a bunch of research over in https://www.drupal.org/project/drupal/issues/3028957, and I've come to the conclusion that we should probably be able to do this in a FunctionalJavascriptTest. Mink doesnt support uploading multiple files, and neither does nightwatch.js, so we'll have to do it ourselves.
We can add a new method to
core/tests/Drupal/FunctionalJavascriptTests/DrupalSelenium2Driver.php
that adds an additional behavior similar to "attachFile" https://github.com/minkphp/MinkSelenium2Driver/blob/a65a77efd76cce4fd1fd...But one that accepts an xpath, and an array of filenames.
"attachMultipleFiles". It would do what uploadFile in the original driver does, except it would upload all the files to the remote chromedriver , (by mimicing what 'uploadFile' does here:
https://github.com/minkphp/MinkSelenium2Driver/blob/a65a77efd76cce4fd1fd..., and finally it would concatenate the filenames together with the \n's and set that to the value of the filefield button.
Then, we can use that similar to how we used attachFile directly in the quickedit test:
http://cgit.drupalcode.org/drupal/tree/core/modules/image/tests/src/Func...
Except, we'll have to step around Mink's implementation of attachFile (https://github.com/minkphp/Mink/blob/master/src/Element/NodeElement.php#...) and use our's directly on the driver.
so pseudo something like :
This is all a mess of pseudo code and ideas, but I dont see how else we're going to mimic uploading multiple files at the same time and also have our chrome instance be non local/not inside the SUT at all.
Comment #29
alexpottHow about we convert everything but the multiple upload test and then do that in a follow-up. So we only have one thing to focus on in that issue?
Comment #30
mondrakeHi, not sure if this helps, but the test in #2644468: Multiple image upload breaks image dimensions is managing multiple files upload in the ImageWidget.
Comment #31
Mixologic@alexpott: re #29: sure that makes sense, I had put it here because It was originally part of this test. And I think that work may already be done for us.
@mondrake re: #30 Awesome. Yes, that issue is doing pretty much exactly what I was imagining we'd need to do. I think the blocker to getting this last test in is actually #2947517: Selenium driver: API to get remote file paths, which appears to be pretty much the follow up we want, and it's already somewhat solved for us.
Comment #32
mondrake#31 I'll bump #2947517: Selenium driver: API to get remote file paths to critical then, since that's a blocker for this and an helper for #2644468: Multiple image upload breaks image dimensions which is a crtical on its own.
Comment #33
LendudeTried the multiple file upload scenario with the method from #2947517: Selenium driver: API to get remote file paths, upload 4 files with cardinality 3 and got the expected error, so when that lands/works this should be trivial to test and there should be no need to split this.
Comment #34
LendudeThanks @all for all the research and digging done for this!
Here is a patch that should be green when #2947517: Selenium driver: API to get remote file paths lands.
Comment #36
jibranThese can be replaced with
loadUnchanged
.Comment #37
markdorisonRe-rolled #34.
Comment #38
markdorisonIncorporated suggestion from #36.
Comment #39
markdorisonHad accidentally removed
FileFieldTestBase.php
when re-rolling patch. Resolved that here.Comment #43
voleger#2947517: Selenium driver: API to get remote file paths in
retest triggered for #39
Comment #44
volegerLooks like #39 pass the tests. +1 for rtbc.
Comment #45
jibranNeeds some PHPCS love.
Comment #46
alexpottRe #45
Comment #47
volegerAddressed #46
Comment #48
andypostshould use inheritdoc
should go after variables as we have it all over core
Comment #49
alexpottpublic static $modules
should be protected not public - whilst we're changing themComment #50
andypostFixed it
Comment #51
andypostFix #49 and comments for test classes
Comment #52
Manuel Garcia CreditAttribution: Manuel Garcia as a volunteer and at Appnovation for Pfizer, Inc. commentedSo excited this is the last one! Just a drive by review here:
assertResponse()
is deprecated, can we use$this->assertSession()->statusCodeEquals()
instead?Can we split these permissions into multiple lines?
Comment #53
LendudePlease keep in mind we are still trying to do the minimal changes for this to pass, even though this is the last one and we all feel bad for it so we want to give it some extra love ;)
Comment #54
Manuel Garcia CreditAttribution: Manuel Garcia as a volunteer and at Appnovation for Pfizer, Inc. commentedlol, fair enough @Lendude :D
Comment #55
andypostStill not sure about changes, this 2 files are new so should not use deprecated methods, but there's more - this methods has no second argument (message)
The same applies to assertRaw()
Comment #56
volegerThis issue is about conversion. Regarding #55 we have #3027952: [Plan] Remove the usage of deprecated methods in tests.
Comment #57
volegerThe only thing that requires to be consistent.
+ 1 for rtbc
Comment #58
jibranThanks, patch is looking good now so RTBC.
Comment #59
alexpottI've done a line-by-line comparision of the old test with the new tests and only one thing appears to be missing (and there might be a reason for that but it is not documented here). The JS part of ::testWidgetValidation() has not been converted to a test in \Drupal\Tests\file\FunctionalJavascript\FileFieldWidgetTest
Comment #60
Lendude@alexpott spot on, yeah that got lost somewhere, added it.
Comment #61
jibranNice catch @alexpott. Interdiff looks good. As #59 is addressed so back to RTBC.
Comment #62
alexpottThanks @Lendude - I checked the new test and it does match the old functionality.
yay... no... YAYAYAYAYAYAYAYAYAYAYAYYAYAYAYAYAYAYAYAYAY!
Comment #64
LendudeWOOOOOOOO!