Problem/Motivation

#2905922: Implementation issue for Layout Builder went in and one of the HEAD runs failed with LayoutBuilderTest but it passed on re-test

Proposed resolution

Perhaps we have a random fail - investigate

Remaining tasks

Investigate and fix

User interface changes

API changes

Data model changes

CommentFileSizeAuthor
#93 2924201-93.patch18.73 KBtedbow
#93 interdiff-85-93.txt2.93 KBtedbow
#85 2924201-test-85-interdiff.txt687 bytestim.plunkett
#85 2924201-test-85.patch18.65 KBtim.plunkett
#79 2924201-test-79-interdiff.txt955 bytestim.plunkett
#79 2924201-test-79.patch19.32 KBtim.plunkett
#79 2924201-test-79-30x.patch21.17 KBtim.plunkett
#77 2924201-test-77-interdiff.txt25.73 KBtim.plunkett
#77 2924201-test-77.patch19.27 KBtim.plunkett
#77 2924201-test-77-x30.patch21.12 KBtim.plunkett
#73 2924201-73.patch34.29 KBtedbow
#73 x10-2924201-73.patch36.39 KBtedbow
#73 interdiff-71-73.txt5.16 KBtedbow
#72 interdiff-69-71.txt4.79 KBtedbow
#71 interdiff-69-71.txt0 bytestedbow
#71 2924201-70-x25.patch37.33 KBtedbow
#69 interdiff-67-69.txt6.74 KBtedbow
#69 x25-2924201-69.patch37.4 KBtedbow
#67 2924201-67.patch35.21 KBtedbow
#67 interdiff-66-67.txt10.99 KBtedbow
#66 2924201-66.patch29.66 KBtedbow
#66 interdiff-64-66.txt11.34 KBtedbow
#64 x50-2924201-64.patch23.43 KBtedbow
#64 interdiff-62-64.txt3.39 KBtedbow
#62 x50-2924201-62.patch22.06 KBtedbow
#62 interdiff-57-62.txt3.64 KBtedbow
#57 interdiff-56-57.txt3.21 KBAnonymous (not verified)
#57 x50-2924201-57.patch20.46 KBAnonymous (not verified)
#56 interdiff-55-56.txt1.91 KBAnonymous (not verified)
#56 x50-2924201-56.patch17.76 KBAnonymous (not verified)
#55 interdiff-53-55.txt5.31 KBAnonymous (not verified)
#55 x50-2924201-55.patch19.1 KBAnonymous (not verified)
#53 interdiff-49-53.txt4.38 KBAnonymous (not verified)
#53 2924201-53.patch18.6 KBAnonymous (not verified)
#51 interdiff-49-51.txt996 bytesAnonymous (not verified)
#51 2924201-layout-51.patch17.8 KBAnonymous (not verified)
#49 interdiff-44-49.patch6.8 KBAnonymous (not verified)
#49 2924201-layout-49.patch17.97 KBAnonymous (not verified)
#44 interdiff-44-webDriver.txt996 bytesAnonymous (not verified)
#44 2924201-layout-44-webDriver.patch17.99 KBAnonymous (not verified)
#44 interdiff-42-44.txt1.17 KBAnonymous (not verified)
#44 2924201-layout-44.patch17.83 KBAnonymous (not verified)
#42 interdiff-39-42.txt956 bytesAnonymous (not verified)
#42 2924201-layout-42.patch17.84 KBAnonymous (not verified)
#39 interdiff-37-39.txt1.83 KBAnonymous (not verified)
#39 2924201-layout-39.patch17.82 KBAnonymous (not verified)
#37 2924201-layout-37.patch17.49 KBtim.plunkett
#37 2924201-layout-37-interdiff.txt1.5 KBtim.plunkett
#35 interdiff-original-21.txt1001 bytesAnonymous (not verified)
#35 2924201-21.patch17.41 KBAnonymous (not verified)
#30 x13-1500_press_save-2924201-30.patch3.08 KBAnonymous (not verified)
#29 interdiff-w-28-29.txt1.54 KBAnonymous (not verified)
#29 2924201-29.patch5.82 KBAnonymous (not verified)
#28 x13-500_wtf_layout-2924201-28.patch5.5 KBAnonymous (not verified)
#26 x500_wtf_layout-2924201-26.patch5.5 KBAnonymous (not verified)
#25 wtf_layout.patch5.5 KBAnonymous (not verified)
#21 interdiff-original-21.txt1001 bytesAnonymous (not verified)
#21 2924201-21.patch17.41 KBAnonymous (not verified)
#21 x30-stress-2924201-21.patch17.96 KBAnonymous (not verified)
#21 x30-stress-2924201-21-test-only.patch17.84 KBAnonymous (not verified)
#18 2924201-18.patch17.41 KBAnonymous (not verified)
#18 interdiff-16-18.txt1.54 KBAnonymous (not verified)
#17 interdiff-16-17.txt3.02 KBAnonymous (not verified)
#17 2924201-17.patch18.71 KBAnonymous (not verified)
#16 2924201-layout-16.patch17.35 KBtim.plunkett
#2 random-fail.patch408 byteslarowlan
#2 random-fail.patch408 byteslarowlan
#2 random-fail.patch408 byteslarowlan
#2 random-fail.patch408 byteslarowlan
#2 random-fail.patch408 byteslarowlan
#2 random-fail.patch408 byteslarowlan
#2 random-fail.patch408 byteslarowlan
#6 2924201-layout-6.patch911 bytestim.plunkett
#6 2924201-layout-6.patch911 bytestim.plunkett
#6 2924201-layout-6.patch911 bytestim.plunkett
#6 2924201-layout-6.patch911 bytestim.plunkett
#6 2924201-layout-6.patch911 bytestim.plunkett
#6 2924201-layout-6.patch911 bytestim.plunkett
#6 2924201-layout-6.patch911 bytestim.plunkett
#6 2924201-layout-6.patch911 bytestim.plunkett
#6 2924201-layout-6.patch911 bytestim.plunkett
#6 2924201-layout-6.patch911 bytestim.plunkett
#6 2924201-layout-6.patch911 bytestim.plunkett
#10 2924201-10.patch187.27 KBAnonymous (not verified)
#10 interdiff-with-2905922-99.patch2.23 KBAnonymous (not verified)
#12 2924201-12.patch187.44 KBAnonymous (not verified)
#12 interdiff-10-12.txt994 bytesAnonymous (not verified)
#14 2924201-14.patch188.26 KBAnonymous (not verified)
#14 interdiff-12-14.txt2.52 KBAnonymous (not verified)
#15 2924201-15-button.patch187.67 KBAnonymous (not verified)
#15 2924201-15-press.patch187.29 KBAnonymous (not verified)
#15 2924201-15-force.patch187.26 KBAnonymous (not verified)
#15 interdiff-button.txt2.41 KBAnonymous (not verified)
#15 interdiff-press.txt2.16 KBAnonymous (not verified)
#15 interdiff-force.txt2.49 KBAnonymous (not verified)

Comments

larowlan created an issue. See original summary.

larowlan’s picture

Status: Active » Needs review
StatusFileSize
new408 bytes
new408 bytes
new408 bytes
new408 bytes
new408 bytes
new408 bytes
new408 bytes

Status: Needs review » Needs work

The last submitted patch, 2: random-fail.patch, failed testing. View results

larowlan’s picture

1 fail in 7 - confirmed random

tim.plunkett’s picture

Seems to be in testing contextual links. Tomorrow I can try chopping up the test instead of having such a single long running method.

Otherwise I'm out of ideas

tim.plunkett’s picture

Status: Needs work » Needs review
StatusFileSize
new911 bytes
new911 bytes
new911 bytes
new911 bytes
new911 bytes
new911 bytes
new911 bytes
new911 bytes
new911 bytes
new911 bytes
new911 bytes

Stepped through this logic with @Wim Leers, and I think we found the issue.

The custom override for clickContextualLink() is needed because this is the only place in core where the result of clicking on a contextual link doesn't leave the page (this uses the Off Canvas dialog and AjaxResponse to stay on the page).

The logic as written in HEAD:

  1. Force the "pencil icon" portion of the contextual link to be visible.
  2. Attempt to find the link within the page (just that the markup is present)
  3. If the link does not exist, fail
  4. If the link is not visible, press the "pencil icon" to show the list of links
  5. Wait for the link to be present on the page
  6. If the link is still not visible, fail
  7. Otherwise, click the link

Step 6 is where the fail is.
Step 5 is where our bug is.

The waitForLink() is pointless, since the link already exists on the page.
What we need is waitForVisibleLink(), which doesn't exist.
Instead I combined the innards of waitForLink within the call of a waitForVisibleElement.

The last submitted patch, 6: 2924201-layout-6.patch, failed testing. View results

larowlan’s picture

doh!

xjm’s picture

Title: Possible random fail in LayoutBuilderTest » Resolve random failure in LayoutBuilderTest so that it can be added to HEAD

We need to revert the Layout Builder commit for this unfortunately. This is failing at a significant rate in HEAD which will cause serious disruption for other issues. I've done so.

This would be critical otherwise, but we can rescope it to fix and add back this test after Layout Builder (as an alpha module) is committed without it.

Anonymous’s picture

StatusFileSize
new187.27 KB
new2.23 KB

I know that PhantomJS and Mink do not always synchronously determine the visibility of an element (especially if it is set in css through extraneous attributes, like

[aria-hidden="true"] {
  visibility: hidden;
  opacity: 0;
}

But at the same time a phantom error pops up. So this is not the case.

Maybe more explicit waiting of the visible link will help?

Status: Needs review » Needs work

The last submitted patch, 10: interdiff-with-2905922-99.patch, failed testing. View results

Anonymous’s picture

Status: Needs work » Needs review
StatusFileSize
new187.44 KB
new994 bytes

Well, what about [aria-pressed] attribute?

Status: Needs review » Needs work

The last submitted patch, 12: 2924201-12.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Anonymous’s picture

StatusFileSize
new188.26 KB
new2.52 KB

Now error here:

+++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
@@ -0,0 +1,430 @@
+        $element->find('css', '.contextual button')->press();
+        $this->assertTrue($page->waitFor(10, function () use ($element) {
+           return $element->find('css', '.contextual button[aria-pressed="true"]');
+        }));

Because after button->press(), the button doesn't change attribute [aria-pressed]. Why?

Anonymous’s picture

StatusFileSize
new2.49 KB
new2.16 KB
new2.41 KB
new187.26 KB
new187.29 KB
new187.67 KB

30 green runs. It seems the problem is definitely around here. Let's divide the last changes into parts.

tim.plunkett’s picture

Status: Needs work » Needs review
StatusFileSize
new17.35 KB

@vaplas++!
I think you're onto something.

The module was recommitted without the test, so here's the original test but with interdiff-press applied.

Anonymous’s picture

StatusFileSize
new18.71 KB
new3.02 KB

Thank you, @tim.plunkett!

The module was recommitted

This is nice news! Now we can not so worry that an important improvement is reverted.

+++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
@@ -380,7 +381,7 @@ protected function clickContextualLink($selector, $link_locator, $force_visible
-        $element->find('css', '.contextual button')->press();
+        $this->getSession()->executeScript("jQuery('$selector .contextual button').trigger('click');");

But why this works?)

To be honest, I've noticed before in different places (not related with Layout) that by clicking on a pencil contextual links do not always appear, and you need to click again. But earlier I always ignored this oddity, because it happens rarely.

But this can also explain the reason why button still have [aria-pressed="false"] after click. It changed this value on 'true', but then the some trigger worked, which returned the value back to "false".

So, let's try to check the stability without close() and "interdiff-press".

Anonymous’s picture

StatusFileSize
new1.54 KB
new17.41 KB

It's a pity, the theory burst. Looks like without close() works like with forse regim. More stable, but not enough.

Well, we already have issue to improve clickContextualLink(): #2918718: Using ContextualLinkClickTrait::clickContextualLink() multiple times per page can cause random failures. So, I reverted #16 with comment about change press() to trigger('click'), and without extra changes with $page variable.

tim.plunkett’s picture

Status: Needs review » Reviewed & tested by the community

Thanks @vaplas! I think we're good.

xjm’s picture

Status: Reviewed & tested by the community » Needs review

Can we post an interdiff from what was originally committed to this patch, and a multi-run run-tests.sh hack patch with the intended fix, queued a number of times? Every patch here that did have multiple runs failed on the test at least once.

Anonymous’s picture

StatusFileSize
new17.84 KB
new17.96 KB
new17.41 KB
new1001 bytes

Sure! Here is different to original test (#2905922-99: Implementation issue for Layout Builder):

+++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
@@ -380,7 +380,8 @@ protected function clickContextualLink($selector, $link_locator, $force_visible
-        $element->find('css', '.contextual button')->press();
+        // Mink press() works unstable, so the trigger('click') is used here.
+        $this->getSession()->executeScript("jQuery('$selector .contextual button').trigger('click');");

Also repost about this change in the @todo-issue (#2918718-2: Using ContextualLinkClickTrait::clickContextualLink() multiple times per page can cause random failures).

Anonymous’s picture

Wow-wow!!! Stress test-only works stable now! It looks like magic from #2775653: JavascriptTests with webDriver:
https://dispatcher.drupalci.org/job/drupal_patches/39538/console:
MINK_DRIVER_ARGS_WEBDRIVER='["chrome", {"browserName":"chrome","chromeOptions":{"args":["--disable-gpu","--headless"]}},

The last submitted patch, 21: x30-stress-2924201-21-test-only.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Anonymous’s picture

#23: 28 passes, and.. fail. Sorry, I hurried on. But anyway, MINK_DRIVER_ARGS_WEBDRIVER is cool.

Running a couple more tests with fix, for better check it.

Anonymous’s picture

StatusFileSize
new5.5 KB

Well, extensive testing showed the stability of the fix, but.. found the new random fail:

https://www.drupal.org/pift-ci-job/827065

Drupal\Tests\layout_builder\FunctionalJavascript\LayoutBuilderTest::testLayoutBuilderUi
Behat\Mink\Exception\ExpectationException: Link with label Layout found.

How is it possible, that the page contains 'The node body', but not contains 'Layout' link?

I have three versions:

  1. On December 4, the moon at the phase of 0.98 will reach the constellation of Orion. This could have a negative impact on the CI.
  2. Method checkField() works unstable as a press() (although in more rare cases)
  3. Some problem in page caching, or sync with FastBackend.

Moon is definitely the dominant version. But trying to check the rest.

Anonymous’s picture

StatusFileSize
new5.5 KB

Status: Needs review » Needs work

The last submitted patch, 26: x500_wtf_layout-2924201-26.patch, failed testing. View results

Anonymous’s picture

StatusFileSize
new5.5 KB

#26: timeout, so, we haven't info about fails, only counts :(

PHP 5.5: 3/14 fails (https://dispatcher.drupalci.org/job/drupal_patches/39609/console)
PHP 7: 1/22 fails (https://dispatcher.drupalci.org/job/drupal_patches/39608/console)

Try again with fewer runs.

Anonymous’s picture

StatusFileSize
new5.82 KB
new1.54 KB

#28: In all cases, the checkbox was actually set/unset. So, problem with render page.

https://www.drupal.org/pift-ci-job/827779:

Problem with checked page371
Problem with unchecked page 460
Problem with checked page429

https://www.drupal.org/pift-ci-job/827781:

Problem with unchecked page 158
Problem with unchecked page 320
Problem with checked page397
Problem with checked page335
Problem with checked page237

https://www.drupal.org/pift-ci-job/827788:
Problem with checked page363

That is, the prevision version of render node is responded. Because we have random fail with/without Layout mode for node (checked/unchecked page).

To confirm, let's try to clear cache whenever 'Layout' link is not found.

(interdiff with -w flag)

Anonymous’s picture

StatusFileSize
new3.08 KB

You know, I get a fairly stable localy random fail after.. pressButton('Save') :)

xjm’s picture

Priority: Normal » Major

This is major, since it would be a testing gate blocker for a major feature.

tim.plunkett’s picture

larowlan’s picture

I think this might need to be tagged 'Layout Builder beta blocker'

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Anonymous’s picture

Status: Needs work » Needs review
StatusFileSize
new17.41 KB
new1001 bytes

Reuploded #21 patch with interdiff to #2905922-99: Implementation issue for Layout Builder. The stress test showed that this really solves the main fail.

We stopped only because of the discovery of yet another fail: https://www.drupal.org/pift-ci-job/827065. But it is associated with the unstable work of pressButton(). And it seems this problem is inherent in all JTB tests, that use this method.

I opened a separate issue with simple proof-test (#2934064-6: Random fail in JS-tests due to unstable pressButton()). But for some reason I did not mention it anywhere. Apparently #2926309-55: Random fail due to APCu not being able to allocate memory negatively affected my memory too. Very sorry!

Status: Needs review » Needs work

The last submitted patch, 35: 2924201-21.patch, failed testing. View results

tim.plunkett’s picture

Status: Needs work » Needs review
StatusFileSize
new1.5 KB
new17.49 KB

negatively affected my memory too

😂😂😂

Some of the routing has changed, hence the above fail.
Here it is adjusted for those changes.

Status: Needs review » Needs work

The last submitted patch, 37: 2924201-layout-37.patch, failed testing. View results

Anonymous’s picture

Status: Needs work » Needs review
StatusFileSize
new17.82 KB
new1.83 KB

Some logic has also been changed? Now the body of node is placed in one of the blocks by default. So, changed this assertion + replaced deprecated entity_get_display().

Status: Needs review » Needs work

The last submitted patch, 39: 2924201-layout-39.patch, failed testing. View results

tim.plunkett’s picture

Ah yes, that was the other change now that #2922033: Use the Layout Builder for EntityViewDisplays landed.

Anonymous’s picture

Status: Needs work » Needs review
StatusFileSize
new17.84 KB
new956 bytes

#2922033: Use the Layout Builder for EntityViewDisplays - yes, it's awesome!


#40: And after removing all sections - default layout display returns. Therefore, we need to somehow adjust the final assertions, right?
kristen pol’s picture

I reviewed the patch for readability, consistency, and code style and it was difficult to find anything wrong. :) A couple very minor things:

+++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
@@ -0,0 +1,440 @@
+    'layout_builder',
+    'node',
+    'block_content',
+    'field_ui',
+    'layout_test',

Are these in this order for any particular reason? Imports are normally alphabetical so this order threw me off a bit.

+++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
@@ -0,0 +1,440 @@
+        // Mink press() works unstable, so the trigger('click') is used here.

The wording seems awkward. Perhaps:

// Mink press() is unstable, so the trigger('click') is used here.

Thanks.

Anonymous’s picture

StatusFileSize
new17.83 KB
new1.17 KB
new17.99 KB
new996 bytes

Thanks for review, @Kristen Pol! All points make sense. Done.

Also, let's check the test with a webDriver.

The last submitted patch, 44: 2924201-layout-44.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 44: 2924201-layout-44-webDriver.patch, failed testing. View results

tim.plunkett’s picture

+++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
@@ -22,11 +22,11 @@ class LayoutBuilderTest extends JavascriptTestBase {
-    'layout_builder',
...
+    'layout',

This caused the fail :)

Anonymous’s picture

Assigned: Unassigned »

Indeed!) Sorry)

Anonymous’s picture

Assigned: » Unassigned
Status: Needs work » Needs review
StatusFileSize
new17.97 KB
new6.8 KB

Fix #47 point + few more after #2937483: Defining a new type of section storage relies on magic strings and hidden assumptions:

  1. -    $assert_session->addressEquals($this->node->toUrl('layout-builder'));
    +    $layout_url = $this->node->toUrl()->setAbsolute()->toString() . '/layout';
    +    $assert_session->addressEquals($layout_url);
    
  2. -      'section_storage' => 'node:1',
    +      'section_storage' => 'node.1',
    

Status: Needs review » Needs work

The last submitted patch, 49: interdiff-44-49.patch, failed testing. View results

Anonymous’s picture

Status: Needs work » Needs review
StatusFileSize
new17.8 KB
new996 bytes

Revert webDriver.

tim.plunkett’s picture

Component: layout.module » layout_builder.module
Anonymous’s picture

StatusFileSize
new18.6 KB
new4.38 KB

Revert "Revert webDriver." and

-    $assert_session->elementNotExists('css', ...);
+    $this->assertWaitForNoElement(...);

Based on #2946294-14: Fix race conditions in OffCanvasTestBase tedbow's works.

Perhaps armed with assertWaitForElement() and assertWaitForNoElement() we can even remove assertWaitOnAjaxRequest().

tedbow’s picture

Anonymous’s picture

StatusFileSize
new19.1 KB
new5.31 KB

#54: Done. Also renaming this method for better compatibility.

#53: It failed to abandon fomr assertWaitForElement() in favor assertWaitForElement() / assertWaitForNoElement(). So while the idea postponed.

Also tried to remove

-      if (!$form_id_element || !$form_id_element->isVisible() || $expected_form_id !== $form_id_element->getValue()) {
-        return NULL;
-      }

I wonder how faster and more unstable the tests will be after that. (Edit: twice as fast)

Anonymous’s picture

StatusFileSize
new17.76 KB
new1.91 KB

Now the clickContextualLink() method works more stably. Let's check the relevance of our workaround.

Anonymous’s picture

StatusFileSize
new20.46 KB
new3.21 KB

To reproduce random fails which happened with PostgreSQL tests, we can just change:

# core/modules/settings_tray/css/settings_tray.motion.css
 /* Transition the editables on the page, their contextual links and their hover states. */
 .dialog-off-canvas-main-canvas .contextual,
 .dialog-off-canvas-main-canvas .js-settings-tray-edit-mode .settings-tray-editable,
 .dialog-off-canvas-main-canvas.js-off-canvas-dialog-open .js-settings-tray-edit-mode .settings-tray-editable {
-  transition: all 0.7s ease;
+  transition: all 5.7s ease;
 }

It is not unknown problem. See #2901792: Disable all animations in Javascript testing.
@tedbow already made special css-fix fot it. But looks like it needs to be supplemented with rule:
transition: none !important;

Also more enhanced ContextualLinkClickTrait::clickContextualLink() from #2918718-6: Using ContextualLinkClickTrait::clickContextualLink() multiple times per page can cause random failures.

tim.plunkett’s picture

Status: Needs review » Needs work

What is the status of this now with all the chromedriver stuff and with nightwatch coming?

tedbow’s picture

In #2957425: Allow the inline creation of non-reusable Custom Blocks in the layout builder We have JS testing. I have put a lot of work on that issue make sure they test doesn't fail randomly.

The tests there extend \Drupal\FunctionalJavascriptTests\WebDriverTestBase which is what is suppose to be used now. NightWatch is still not ready write tests in I think.

Also related to this issue:https://www.drupal.org/drupalorg/docs/drupal-ci/customizing-drupalci-tes...
You don't have to edit run-test.sh to run single test multiple times.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

tim.plunkett’s picture

Where does this stand after the move away from PhantomJS

tedbow’s picture

Status: Needs work » Needs review
StatusFileSize
new3.64 KB
new22.06 KB

Re #61 this patch change to use WebDriverTestBase so it won't use phantomjs
It also changes core/drupalci.yml instead of run-tests.sh changes to run in multiple times.
I realize the test I added #2957425: Allow the inline creation of non-reusable Custom Blocks in the layout builder always do a page load between operation with contextual links so it might not have problems describe in this issue.

Status: Needs review » Needs work

The last submitted patch, 62: x50-2924201-62.patch, failed testing. View results

tedbow’s picture

Status: Needs work » Needs review
StatusFileSize
new3.39 KB
new23.43 KB
jibran’s picture

We had 50 passing test runs let's create a real patch now.

+++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
@@ -0,0 +1,434 @@
+  protected $minkDefaultDriverClass = DrupalSelenium2Driver::class;

This can be removed now.

tedbow’s picture

StatusFileSize
new11.34 KB
new29.66 KB
  1. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,434 @@
    +  public static $modules = [
    

    This should be protected

  2. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTestBase.php
    @@ -0,0 +1,34 @@
    +  public function enableLayoutsForBundle($path, $allow_custom = FALSE) {
    

    I am going to change all of the other tests that make sense to extend this class so they can use this method.

tedbow’s picture

StatusFileSize
new10.99 KB
new35.21 KB

Now that we are going to have a base class for these tests it makes sense to move some of the functionality that repeats in these tests to the base class. I think if didn't have issue with the random failure we would have been using for the base class all along.

  1. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,429 @@
    +    $this->clickLink('Add Block');
    +    $assert_session->assertWaitOnAjaxRequest();
    +
    +    $assert_session->elementExists('css', '#drupal-off-canvas');
    +
    +    $assert_session->linkExists('Powered by Drupal');
    +    $this->clickLink('Powered by Drupal');
    

    This sequence is repeated many times in this class and other tests when want to add a block and we are not always consistent about check if the links exist first.

    I am going to create openAddBlockForm() that will do this sequence given a block link text.

  2. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,429 @@
    +  protected function waitForOffCanvasForm($expected_form_id, $timeout = 10000) {
    +    $page = $this->getSession()->getPage();
    +    return $page->waitFor($timeout / 1000, function () use ($page, $expected_form_id) {
    +      // Ensure the form ID exists, is visible, and has the correct value.
    +      $form_id_element = $page->find('hidden_field_selector', ['hidden_field', 'form_id']);
    +
    +      // Ensure the off canvas dialog is visible.
    +      $off_canvas = $page->find('css', '#drupal-off-canvas');
    +      if (!$off_canvas || !$off_canvas->isVisible()) {
    +        return NULL;
    +      }
    +      return $form_id_element;
    

    We return NULL if the off-canvas dialog is not there but we don't actually check the return value ever.

    We should change this to assertOffCanvasFormAfterWait and fail if the form is not there or hidden field is not there.

jibran’s picture

Thank, for creating the proper patch. Hopefully, my review helps with 1 and 2.

  1. +++ b/core/modules/contextual/tests/src/FunctionalJavascript/ContextualLinkClickTrait.php
    @@ -16,20 +16,38 @@
    +      $button = $page->waitFor(10, function () use ($element) {
    

    Why are we not using waitForButton() here?

  2. +++ b/core/modules/contextual/tests/src/FunctionalJavascript/ContextualLinkClickTrait.php
    @@ -16,20 +16,38 @@
    +      $link = $page->waitFor(10, function () use ($link) {
    

    Why are we not using waitForLink() here?

  3. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,387 @@
    +    $layout_url = $this->node->toUrl()->setAbsolute()->toString() . '/layout';
    ...
    +    $layout_url = $this->node->toUrl()->setAbsolute()->toString() . '/layout';
    

    This doesn't need to be absolute.

  4. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,387 @@
    +    $this->drupalGet($this->node->toUrl('canonical'));
    ...
    +    $this->drupalGet($this->node->toUrl('canonical'));
    ...
    +    $this->drupalGet($this->node->toUrl('canonical'));
    ...
    +    $assert_session->addressEquals($this->node->toUrl('canonical'));
    ...
    +    $assert_session->addressEquals($this->node->toUrl('canonical'));
    

    'canonical' is not needed at all.

  5. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,387 @@
    +    $assert_session->linkExists('Two column');
    ...
    +    $assert_session->assertWaitOnAjaxRequest();
    ...
    +    $assert_session->linkExists('Add Section');
    

    These can be combined into waitForLink()

  6. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,387 @@
    +    $assert_session->assertWaitOnAjaxRequest();
    ...
    +    $assert_session->elementExists('css', '.layout__region--second .block-system-powered-by-block');
    ...
    +    $assert_session->assertWaitOnAjaxRequest();
    +    $assert_session->elementExists('css', '#drupal-off-canvas');
    ...
    +    $assert_session->assertWaitOnAjaxRequest();
    +    $assert_session->elementExists('css', '#drupal-off-canvas');
    

    These can be combined into waitForElement()

  7. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTestBase.php
    @@ -0,0 +1,83 @@
    +    $this->assertNotEmpty($assert_session->waitForElementVisible('css', "#drupal-off-canvas a:contains('$block_title')"));
    ...
    +    $this->assertNotEmpty($page->waitFor($timeout / 1000, function () use ($page, $expected_form_id) {
    

    This should be assertNotNull()

tedbow’s picture

StatusFileSize
new37.4 KB
new6.74 KB

@jibran thanks for the review again.
re #68

  1. We can't use waitForButton() here because we need find the need to button this with the current element.

    But actually can do this

    $button = $assert_session->waitForElementVisible('css', "$selector .contextual button");
    $this->assertNotEmpty($button);
    $button->press();
    

    Which means we change the lines above to the find the link because we don't need the $element variable anymore.

  2. Because that will not check if the link is visible and also we need find the link only within $selector
  3. Fixed
  4. Replace 1 of these with $this->assertNotEmpty($assert_session->waitForElementVisible('named', ['link', 'Two column']));
    We don't really need to assertWaitOnAjaxRequest() if we know there is something we can check for that will be on the page after wait.

    waitForLink() won't work because it can cause random failures since the link might exist but be on the off-canvas dialog and not visible yet.

  5. We waiting for the off-canvas dialog to open when have a had a lot of random failures when don't >assertWaitOnAjaxRequest() first. So I think we should leave these..

I also noticed

+++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTestBase.php
@@ -0,0 +1,83 @@
+    $this->assertNotEmpty($assert_session->waitForElementVisible('css', "#drupal-off-canvas a:contains('$block_title')"));

I think this more clear as
$this->assertNotEmpty($assert_session->waitForElementVisible('named', ['link', $block_title]));
The only difference would be if the $block_title also was somewhere else besides the off-canvas dialog.

Also these is a lot of changes so uploaded a x25 patch first to just run layout builder javascript tests.

Status: Needs review » Needs work

The last submitted patch, 69: x25-2924201-69.patch, failed testing. View results

tedbow’s picture

Status: Needs work » Needs review
StatusFileSize
new37.33 KB
new0 bytes
  1. got the test a failure

    Current page is "/node/1/layout", but "/subdirectory/node/1/layout" expected.

    This because the removing the absolute url. We can just use hardcoded "node/1/layout" like most tests do.

  2. aslo

    WebDriver\Exception\UnknownError: unknown error: Element ... is not clickable at point (562, 575). Other element would receive the click: ...
    (Session info: headless chrome=62.0.3202.94)
    (Driver info: chromedriver=2.33.506092 (733a02544d189eeb751fe0d7ddca79a0ee28cce4),platform=Linux 4.9.0-0.bpo.6-amd64 x86_64)

    Which I think the off-canvas dialog being in the process of opening so there is motion problem. Adding assertWaitOnAjaxRequest() call because this also checks for jQuery(':animated').length === 0

tedbow’s picture

StatusFileSize
new4.79 KB

Whoops here is the interdiff

tedbow’s picture

StatusFileSize
new5.16 KB
new36.39 KB
new34.29 KB

I chatted with @tim.plunkett about another related issue and he recommended a trait instead of base class.

I think this make sense especially because other core module may need to make Layout Builder integration tests so enableLayoutsForBundle() would very useful there.

The last submitted patch, 73: x10-2924201-73.patch, failed testing. View results

tedbow’s picture

HMM. The test failure was in \Drupal\Tests\BrowserHtmlDebugTrait::initBrowserOutputFile()

if (!is_dir($this->htmlOutputDirectory)) {
   mkdir($this->htmlOutputDirectory, 0775, TRUE);
}

So thinking totally unrelated to this issue and also it only failed once so maybe general DrupalCI error

Retesting to make sure.

bobbygryzynger’s picture

Hi all,

I want to chime in here because I am also seeing some random failures in my feature test suite that depends on adding blocks within layout builder.

The basic issue is this: clicking the 'Save layout' link is not reliably saving the layout.

My assertion for saving the layout was this:

$this->clickLink('Save Layout');
$assert_session->pageTextContains('The layout has been saved.');

About 1 in 10 times this would randomly fail for no apparent reason. Instead of being redirected to the the display UI page (where the confirmation message would be displayed), I would still be on the layout builder UI page.

In order to fix this is in my own test suite, I implemented a retry loop:

$retries = 3;
for ($attempt = 0; $attempt < $retries; $attempt++) {
  $this->clickLink('Save Layout');
  try {
    $assert_session->pageTextContains('The layout has been saved.');
  }
  catch (ResponseTextException $exception) {

    // The retry limit has been reached. stop retying and throw the
    // exception.
    if ($attempt === $retries - 1) {
      throw $exception;
    }

    // Try again.
    continue;
  }

  // No exception was thrown during the last attempt.
  return;
}

If I add some debugging output in the try/catch statement, I still see that failures occur (still at a rate of about 1 in 10), but thus far this has resolved my own random failures.

I hope this can shed some light on what is going on here. Is there anything that can be investigated as far as why the save does not always occur? I've only seen this in tests, if I use the UI myself I've never had a save failure.

tim.plunkett’s picture

StatusFileSize
new21.12 KB
new19.27 KB
new25.73 KB

In order to get this issue done, I'd like to hold off on any helpful traits or other refactoring.
Let's add the test as it is.

This moves all of the trait code directly into the new class and only retains the changes to core/modules/settings_tray/tests/modules/settings_tray_test_css/css/css_fix.theme.css

tedbow’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,517 @@
    +    'settings_tray_test_css',
    

    We shouldn't need. This \Drupal\Tests\system\FunctionalJavascript\OffCanvasTest doesn't having anything like this.

    If we could have x30 patch that removes and proves it is good that would be good.

    If it fails I think we should duplicate the test module instead of having a settings_tray test module here. And with a @todo to remove it here https://www.drupal.org/project/drupal/issues/2901792#comment-12695082

    That issue has a patch to make a system module testing module.

  2. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,517 @@
    +  protected function clickContextualLink($selector, $link_locator, $force_visible = TRUE) {
    

    I think we should have a @todo point to https://www.drupal.org/project/drupal/issues/2918718 to remove this.

tim.plunkett’s picture

Status: Needs work » Needs review
StatusFileSize
new21.17 KB
new19.32 KB
new955 bytes

Fixed both!

tedbow’s picture

Status: Needs review » Reviewed & tested by the community

Looks good 🎉

The last submitted patch, 57: x50-2924201-57.patch, failed testing. View results

xjm’s picture

30x test runs isn't enough to prove that a random fail is resolved or not unless the test is failing like 50% of the time, so queuing multiple test runs of the 30-test patch. However, we also usually want a version of the 30-test-runs patch that does not include the fix, to prove that the number of times we ran the test is enough to repeatedly expose the fail. Otherwise a 30-run patch isn't useful. Statistics! ;)

xjm’s picture

Also, did anyone try running this locally a few hundred times?

tedbow’s picture

Status: Reviewed & tested by the community » Needs work

@xjm

30x test runs isn't enough to prove that a random fail is resolved or not unless the test is failing like 50% of the time, so queuing multiple test runs of the 30-test patch.

Looks they all came back green!

However, we also usually want a version of the 30-test-runs patch that does not include the fix, to prove that the number of times we ran the test is enough to repeatedly expose the fail.

Yes but since this patch just introduces a new test that is not in 8.7.x then I am don't know what "patch that does not include the fix" would actually be. I don't think we can do that here.

Also, did anyone try running this locally a few hundred times?

I haven't but now that you ran it 11 times above that is 330 passing on Drupalci!

found 1 remaining problem though.

+++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
index e07c95194e..89600c5b7f 100644
--- a/core/modules/settings_tray/tests/modules/settings_tray_test_css/css/css_fix.theme.css

--- a/core/modules/settings_tray/tests/modules/settings_tray_test_css/css/css_fix.theme.css
+++ b/core/modules/settings_tray/tests/modules/settings_tray_test_css/css/css_fix.theme.css

We shouldn't need the change in this file because we are no longer including this test module.

tim.plunkett’s picture

Status: Needs work » Needs review
StatusFileSize
new18.65 KB
new687 bytes

Oh, I meant to do that in #79 when I stopped loading the module in the test
New diffstat:

 core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php | 518 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 518 insertions(+)
tedbow’s picture

Status: Needs review » Reviewed & tested by the community

Looks good!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 85: 2924201-test-85.patch, failed testing. View results

tedbow’s picture

Status: Needs work » Reviewed & tested by the community

#87 is totally unrelated non javascript test EntityReferenceAdminTest. Looks to be random failure

xjm’s picture

The 330 test runs still actually isn't enough without knowing the base fail rate. Say the base fail rate was 1% (which is still a pretty high fail rate). Running the test 330 times with a 1% random fail would mean there would be a (.99)^330 = 4% chance every single test run would pass even with the random fail being present. This is why I asked about running the test locally a few hundred times, to know what the base fail rate was previously and compare it to now.

Of course the best thing is always to make a version of the test that fails 100% of the time (by generating whatever random condition is causing the fail 100% of the time, whether with a wait() to slow things down, or hardcoding the random character that breaks the test, or whatever). Anyway, since it looks like the fix involves something like a CSS transition (lol?) then it'd be harder to create that 100% fail patch for something like that. Looks like that change was removed from the patch now.

Regarding x EntityReferenceAdminTest, I confirmed https://www.drupal.org/pift-ci-job/1184261 is in HEAD and has failed twice in the past two weeks. Seems to be missing a core critical issue though... Anyone want to file that for me? :P

Is the earlier version of the patch that included the random fail? We could test that the same number of times to expose the failure rate that's being resolved?

xjm’s picture

OK, reading back on the issue, the original fail rate for the test was in the 5-10% range, so at that point I'm more comfortable with 330 test runs being enough. ;)

xjm’s picture

xjm’s picture

Status: Reviewed & tested by the community » Needs work

This looks good. Just some nitpicks:

  1. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,518 @@
    +    // Drag one block from one region to another.
    +    $this->drupalGet($layout_url);
    +    $this->markCurrentPage();
    +
    +    $assert_session->linkExists('Add Section');
    +    $this->clickLink('Add Section');
    +    $this->assertNotEmpty($assert_session->waitForElementVisible('named', ['link', 'Two column']));
    +
    +    $this->clickLink('Two column');
    +    $assert_session->assertWaitOnAjaxRequest();
    +    $page->pressButton('Add section');
    +    $assert_session->assertWaitOnAjaxRequest();
    

    The inline comment doesn't describe what's happening in the next 10 lines; can we remove it?

  2. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,518 @@
    +    $this->assertNoElementAfterWait('.layout__region--second .block-system-powered-by-block');
    +    $assert_session->elementTextNotContains('css', '.layout__region--second', 'Powered by Drupal');
    +    // Drag the block from one layout to another.
    +    $page->find('css', '.layout__region--content .block-system-powered-by-block')->dragTo($page->find('css', '.layout__region--second'));
    

    "From one layout to another" sounds wrong. From one section to another? From one region within the same section to another?

    Also there's a missing blank line before the comment.

  3. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,518 @@
    +    $assert_session->assertWaitOnAjaxRequest();
    +    // Ensure the drag succeeded.
    

    Missing blank line before the comment again.

  4. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,518 @@
    +    // Ensure the drag persisted after reload.
    ...
    +    // Ensure the drag persisted after save.
    

    Nitpick, but "Ensure the drag persisted" is confusing. Puns abound. How about "Ensure the dragged block is still in the correct position after reload/save"?

  5. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,518 @@
    +    // Configure a block.
    

    I think what's imoportant here is "Reconfigure a block and ensure that the layout content is updated"?

  6. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,518 @@
    +  /**
    +   * Tests configurable layouts.
    +   */
    +  public function testConfigurableLayouts() {
    

    This method name confused me ("Aren't they all?") but it's about configurable layout templates a.k.a. section layouts. I guess we never finalized that terminology issue, so that's why "layouts" is used here without any modifier. We could still clarify the method name.

  7. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,518 @@
    +   * Tests bypassing the Off Canvas dialog.
    

    Nit: "Off Canvas dialog" is wrong. It should be one of "off-canvas dialog".

tedbow’s picture

Status: Needs work » Needs review
StatusFileSize
new2.93 KB
new18.73 KB

@xjm thanks for the review

Fixed
Fixed
Fixed
fixed
fixed
changed to testConfigurableLayoutSections()
fixed

tim.plunkett’s picture

Status: Needs review » Reviewed & tested by the community

Thanks for the review and fixes!

  • xjm committed c029270 on 8.7.x
    Issue #2924201 by tim.plunkett, tedbow, larowlan, xjm, jibran, Kristen...

  • xjm committed d0f9902 on 8.6.x
    Issue #2924201 by tim.plunkett, tedbow, larowlan, xjm, jibran, Kristen...
xjm’s picture

Version: 8.7.x-dev » 8.6.x-dev
Status: Reviewed & tested by the community » Fixed

Thanks, committed to 8.7.x. I also backported it to 8.6.x as a test addition; we'll see in an hour or so if that was a bad idea. :P

  • xjm committed 50c0a04 on 8.6.x
    Revert "Issue #2924201 by tim.plunkett, tedbow, larowlan, xjm, jibran,...
xjm’s picture

Version: 8.6.x-dev » 8.7.x-dev

OK @tedbow indicated a reason it's not 8.6.x-compatible; reverted. Sorry for the emails.

xjm’s picture

Fixing credit; d.o somehow unchecked people that are included in the commit message.

alexpott’s picture

This is still causing random fails. See https://www.drupal.org/pift-ci-job/1196600

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.