Problem/Motivation
From the eternal random failure gold mine that is the qa runs (https://www.drupal.org/node/3060/qa):
There was 1 error:
1) Drupal\Tests\ckeditor5\FunctionalJavascript\CKEditor5AllowedTagsTest::testMediaElementAllowedTags
Behat\Mink\Exception\ElementNotFoundException: Form field with id|name|label|value "filters[media_embed][settings][allowed_view_modes][view_mode_2]" not found.
/var/www/html/vendor/behat/mink/src/Element/TraversableElement.php:207
/var/www/html/core/modules/ckeditor5/tests/src/FunctionalJavascript/CKEditor5AllowedTagsTest.php:386
/var/www/html/vendor/phpunit/phpunit/src/Framework/TestResult.php:728
https://www.drupal.org/pift-ci-job/2696423
Steps to reproduce
This one had me searching for a while...
Over here I took a screenshot and dumped the HTML when the ElementNotFoundException is thrown.
The screenshot shows that view_mode_2 is actually not present, there's no AJAXing going on, and the page looks (and turns out to be) completely loaded:

(HTML as txt-file is here)
As it turns out, we start the test by going to the 'admin/config/content/formats/add' page in \Drupal\Tests\ckeditor5\FunctionalJavascript\CKEditor5TestBase::createNewTextFormat, do some stuff and then create two new EntityViewModes.
This can be appearantly to slow for the page to pick up on it, or at least sometimes to pick up on the last of the two, which then does not get displayed when we enable the embed media option.
Proposed resolution
Move the creation of the two new EntityViewModes to the front of the test.
Also, as already said in #7, the waitForField without checking its output is basically a convuloted way to add a sleep.
We remove it, replace it with a $assert_session->assertWaitOnAjaxRequest(), since the line before it ($page->clickLink('Embed media')) triggers an AJAX request.
Finally we remove the $assert_session->assertWaitOnAjaxRequest() below the two checkFields in line 387-388, since they don't trigger any AJAX request and waiting on that is useless.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #11 | 3368509-11.patch | 2.08 KB | spokje |
| #9 | Add text format Drupal._html.txt | 185.25 KB | spokje |
Comments
Comment #2
spokjeLet's first proof that running
Drupal\Tests\ckeditor5\FunctionalJavascript\CKEditor5AllowedTagsTest::testMediaElementAllowedTagsandDrupal\Tests\ckeditor5\FunctionalJavascript\CKEditor5AllowedTagsTest::testMediaElementAllowedTagsalone produces the random test failure.Here's a patch that runs only
Drupal\Tests\ckeditor5\FunctionalJavascript\CKEditor5AllowedTagsTest::testMediaElementAllowedTags1500 times.Comment #3
wim leersThank you, @Spokje! 🤩🙏
We spent so much time and effort making sure the tests were passing reliably. It's sad to see that there's still random failures :/ When we were iterating rapidly in https://www.drupal.org/project/ckeditor5, we chased every random JS test failure to ensure that this wouldn't be a problem once it was in core.
Then again … even a Chrome version update can change this, so I guess it's not too surprising that we're able to detect new random failures later? 😔
Comment #4
wim leersseems to consistently be the failure.
This is the context:
That's … fascinating. We're literally first waiting for the field to appear, and only then checking the fields.
My suspicion: the checking of the first field triggers a new AJAX request, which makes the checkbox briefly uncheckable. So we need to explicitly wait before each
checkField().Comment #5
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch 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 #6
wim leersDidn't work 😬
Comment #7
spokjeJS random test failures are the latest and the greatest, most commonly due to changes in the speed of the testrunners.
Surprisingly not because they got so much faster, but since they get way slower...
Even more fascinating, when the wait doesn't find the element, it returns NULL, when that's not checked anywhere, like in this test, since there's no execption thrown, the test continues (and finds out 2 lines below the element we were waiting on isn't present.
Sadly it isn't, looking into it during today/tomorrow.
Comment #8
spokjeThe normal routine to prove a random failure is fixed is to run the failing patch and the patch with the fix at the same time, whilst the latter has to have ~8000 - 10.000 failure free runs to prove it's credibility.
So let's do that here.
Comment #9
spokjeComment #10
spokjeTurns out 5000x doesn't finish within about an hour, after which the results get "wonky".
Let's do it in 2500x runs.
Comment #11
spokjeThat's 12 * 2500 = 30.000 failure free runs.
Good enough for me, here's the actual patch.
Comment #12
spokjeComment #13
spokjeComment #14
smustgrave commentedNever going to say no to improving the random failures.
Comment #15
wim leersThis part I do not understand. 🤔 Why does this need to be moved? 🤯
AFAICT this should not be necessary.
This part I get: after enabling a filter, rather than just waiting for a field to appear via AJAX, wait for everything to have finished for said AJAX response 👍
Comment #16
spokjeDid you see this from the IS?
Was hoping that would explain things, if not, am happy to (try and) be more explicit.
The key here. IMHO. is the fact that in the current situation we're already on the 'admin/config/content/formats/add' page, before we create the EntityViewModes.
That somehow sometimes doesn't give us/the page enough time to "realize" it has two rather than one EntityViewMode to show when we click he embed media option.
Yep, I really dislike the use of
waitFor[Stuff]($timePeriod).For me it's like when you have to pick somebody up from the train station and you go there and wait for a certain amount of time, then no matter what, you continue with your other business. Even if the train arrives one second later.
So
waitForPerson(20 minutes)Whilst when you know _what_ you're waiting for, it's less random. In the above anology: If the person doesn't come out of the train which you expected them to be on, move on.
If the train's early or late, no problem, because you're not tied to a set amount of time.
So
is much less prone to random test failures when there's outside stuff messing with the trainschedule (or in our case, testrunners).
Comment #17
quietone commentedDoing RTBC triage.
@Spokje, thanks for working on this and finding a solution!
The IS uses the respective heading to explain the problem and the solution. Reading the comments all the question raised have been answered.
Leaving at RTBC.
Comment #20
lauriiiCommitted 1b920b2 and pushed to 11.x. Also cherry-picked to 10.1.x as a test only change. Thanks!
Comment #21
wim leersThanks, @Spokje, including for the wonderful metaphor 😄