Problem/Motivation

We need to start covering existing JavaScript functionality within Views with tests. See #2752931: [meta] Implement Javascript testing for Views and the Views UI

This is about adding test coverage to the basic search functionality in the Views filter listing.

Proposed resolution

Add a filter handler via the UI. Search the list with both the selector and the text field. Add one. Expose it, see if it gets added to the list.

Remaining tasks

  1. Commit #44 2754985-46.9_x-only.patch to 9.y.x branches
  2. Commit #44 2754985-46.8_x-only.patch to 8.y.x branch

User interface changes

N/A

API changes

N/A

Data model changes

N/A

Release notes snippet

N/A

CommentFileSizeAuthor
#46 2754985.44_46.interdiff.txt820 bytesdww
#46 2754985-46.8_x-only.patch5.18 KBdww
#46 2754985-46.9_x-only.patch5.18 KBdww
#44 2754985-44.8_x-only.patch5.17 KBdww
#44 2754985-44.9_x-only.patch5.18 KBdww
#36 2754985.32_36.interdiff.txt592 bytesdww
#36 2754985-36.8_9_x.patch5.17 KBdww
#32 2754985-32.patch5.18 KBLendude
#32 interdiff-2754985-29-32.txt2.01 KBLendude
#29 interdiff-26-29.txt4.2 KBkishor_kolekar
#29 2754985-29.patch4.94 KBkishor_kolekar
#26 interdiff_24-26.txt683 bytesravi.shankar
#26 2754985-26.patch5.19 KBravi.shankar
#24 interdiff_21-24.txt677 bytesravi.shankar
#24 2754985-24.patch5.19 KBravi.shankar
#21 2754985-21.patch5.19 KBLendude
#21 interdiff-2754985-20-21.txt1.99 KBLendude
#20 2754985-20.patch4.6 KBLendude
#20 interdiff-2754985-2-20.txt3.88 KBLendude
#11 viewsui_filter_javascript-2754985-11.patch5.15 KBmichielnugter
#11 interdiff-2-11.txt3.89 KBmichielnugter
#2 viewsui_filter_javascript-2754985-2.patch3.73 KBLendude
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Lendude created an issue. See original summary.

Lendude’s picture

This is a start. This fails because for some reason the post request for adding the filter gets done by the anonymous user. Haven't figured out what is going wrong yet.

Status: Needs review » Needs work

The last submitted patch, 2: viewsui_filter_javascript-2754985-2.patch, failed testing.

Lendude’s picture

I also see that the form submission that fails doesn't contain any of the form data (form-id etc.). Using other ways to trigger submission (directly triggering submitting the form via jQuery, clicking the hidden submit button that's actually inside the form element) doesn't solve this problem so far.

Lendude’s picture

Version: 8.1.x-dev » 8.2.x-dev

The reason was #2771547: In Browser and FunctionalJavascript tests SIMPLETEST_USER_AGENT cookie needs to be set every 5 seconds, that's in now, so lets see what this does. Needs to go to 8.2.x though because the fix isn't in 8.1.x

The last submitted patch, 2: viewsui_filter_javascript-2754985-2.patch, failed testing.

The last submitted patch, 2: viewsui_filter_javascript-2754985-2.patch, failed testing.

michielnugter’s picture

I looked into it and found 1 actual Javascript bug:

TypeError: event.data is undefined[Meer info] jquery.min.js:43:7
	resetSize http://drupal.dev/core/assets/vendor/jquery/jquery.min.js:43:7
	Drupal.debounce/</later http://drupal.dev/core/misc/debounce.js:41:18

Which is an error triggered in:
core/misc/dialog/dialog.position.js - line 59.

Reproducable with the following steps:
1. Open add filter
2. Check body (body) filter
3. Click Add and configure button
4. Resize your window

I think that this JavaScript error is the cause for the test failure. The problem occurs when clicking the Apply button. This closes the dialog and causes the error. I have seen the error in the test if you change the pressButton('Apply') to:

$this->assertEquals('', $page->getHTML());

Which should work just fine but somehow triggers the Javascript error.

... update:

There is a bug open for the dialog error: #2731419: "cannot call methods on dialog prior to initialization" logged when resizing after closing a modal

When applied I can extract the HTML but the test still failes. Will search some more tomorrow..

michielnugter’s picture

... update 2:

I found the actual (javascript) bug, not sure yet on how to fix it.

A new dialog is opened after adding the body field but the previous one isn't closed. This causes the dialog:beforeclose event not to be fired and the window not unbinding the 'dialogResize' event. On the second dialog 2 events are attached to the window, the first causing errors..

update:
Dug a little deeper. The dialogs are opened via commands. However, no close command is send.

To fix this either one of the following must be done:
1. In views, send a closeDialog command before the open command to properly close it before opening it.
2. Adapt the dialog open to check if there already is a dialog with the passed selector open and close it first
3. Change the dialog.position javascript to only add the event once per dialog selector.

Option 1 seems the right way to go but I'm not sure yet on UX, wil the dialog quickly open/close and 'flicker'?
Options 2 and 3 seem quite large in scope and will dig deep into the core javascript, they will provide somewhat better DX though and possibly UX as you don't have to worry about opening dialogs that currently exist and no flickering will be visible..

Lendude’s picture

Nice digging around! Discussed this with @michielnugter on IRC.

Option 1 sounds like the the best way to do this, but we indeed need to check for a flicker. It might not be perceptible and it just sounds like the best way to clean up after ourselves.

Bumping this to a bug, lets update the IS when we have a concrete description of the bug we are running into.

We should probably postpone on #2731419: "cannot call methods on dialog prior to initialization" logged when resizing after closing a modal, but hopefully that will get in soon.

michielnugter’s picture

VERY dirty fix for the popup in this case just to see if it fixes the problems. They don't unfortunately :(

What we learned:
- Yes, there is a small flicker sometimes, more that without the close. The dialog seems to align from the bottom of my screan to the center. Doesn't happen each time but it seems far more frequent than without the close.
- Yes there is a bug: as it's not related to this issue I think we should open a new one and discuss the solution there as I'm not sure requiring a closeDialog is DX / UX friendly.
- Despite the bugs the test still failes with PhantomJS responding the the following 500 error:

REQUEST: {"name":"click","args":[4,261]}

2017-01-09T08:43:47 [DEBUG] WebPage - evaluateJavaScript result QVariant(QString, "object")
2017-01-09T08:43:47 [DEBUG] WebPage - evaluateJavaScript "(function() { return (function() { return PoltergeistAgent.stringify((function (name, args) {\n      return window.__poltergeist.externalCall(name, args);\n    }).apply(this, JSON.parse(\"[\\\"nodeCall\\\",[261,\\\"scrollIntoView\\\",[]]]\"))) })(); })()"
2017-01-09T08:43:47 [DEBUG] WebPage - evaluateJavaScript result QVariant(QString, "{}")
2017-01-09T08:43:47 [DEBUG] WebPage - evaluateJavaScript "(function() { return (function () {\n      return typeof window.__poltergeist;\n    })(); })()"
2017-01-09T08:43:47 [DEBUG] WebPage - evaluateJavaScript result QVariant(QString, "object")
2017-01-09T08:43:47 [DEBUG] WebPage - evaluateJavaScript "(function() { return (function() { return PoltergeistAgent.stringify((function (name, args) {\n      return window.__poltergeist.externalCall(name, args);\n    }).apply(this, JSON.parse(\"[\\\"nodeCall\\\",[261,\\\"position\\\",[]]]\"))) })(); })()"
2017-01-09T08:43:47 [DEBUG] WebPage - evaluateJavaScript result QVariant(QString, "{\"value\":{\"top\":680,\"right\":129,\"left\":128,\"bottom\":681,\"width\":1,\"height\":1}}")
2017-01-09T08:43:47 [DEBUG] WebPage - evaluateJavaScript "(function() { return (function () {\n      return typeof window.__poltergeist;\n    })(); })()"
2017-01-09T08:43:47 [DEBUG] WebPage - evaluateJavaScript result QVariant(QString, "object")
2017-01-09T08:43:47 [DEBUG] WebPage - evaluateJavaScript "(function() { return (function() { return PoltergeistAgent.stringify((function (name, args) {\n      return window.__poltergeist.externalCall(name, args);\n    }).apply(this, JSON.parse(\"[\\\"nodeCall\\\",[261,\\\"mouseEventTest\\\",[128.5,680.5]]]\"))) })(); })()"
2017-01-09T08:43:47 [DEBUG] WebPage - evaluateJavaScript result QVariant(QString, "{\"value\":{\"status\":\"failure\",\"selector\":\"html.touchevents.details.js body.user-logged-in.path-admin div.ui-dialog.ui-widget.ui-widget-content.ui-corner-all.ui-front.ui-dialog-buttons.views-ui-dialog-scroll.views-ui-dialog.js-views-ui-dialog div#drupal-modal.ui-front.ui-dialog-content.ui-widget-content div form#views-ui-config-item-form--Tou9urHIYX4 div#edit-options--Nk8ipRM2SSw.scroll.js-form-wrapper.form-wrapper\"}}")
2017-01-09T08:43:47 [DEBUG] HTTP Response - Status Code 500 Internal Server Error
2017-01-09T08:43:47 [DEBUG] HTTP Response - Sending Header "Content-Type" = "application/json"

There is a warning on the preview in the logs but the preview is disabled in the test:

Warning: Illegal string offset '#markup' in views_ui_preprocess_views_view() (line 137 of /Library/WebServer/Documents/drupal/core/modules/views_ui/views_ui.module)

I couldn't find any other warning in my server logs.

I'm completely stuck here on finding the problem.

michielnugter’s picture

Status: Needs work » Postponed

I did a small cleanup of the test by the way but I think the final version should be postponed untill #2837676: Provide a better way to validate all javascript activity is completed is in.

Lendude’s picture

We should really split the handler search part of this test of into its own test. Might be happening in #2846428: Views add dialog filter searches on label instead of title

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

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

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should 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.

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

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should 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.

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

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Lendude’s picture

Status: Postponed » Needs work
Issue tags: -JavaScript +JavaScript

Not postponed anymore

Lendude’s picture

Category: Bug report » Task
Status: Needs work » Needs review
Issue tags: -Needs issue summary update
FileSize
3.88 KB
4.6 KB

As in all things javascript test related, just wait and the problem will go away :)

Tweaked #2 a bit for WebDriver vs the old PhantomJs setup.

Running this with WebDriverTestBase gives no problems locally, so lets see if the bot agrees

Lendude’s picture

longwave’s picture

xjm’s picture

Status: Reviewed & tested by the community » Needs work

The fail on D9 is:

Views.Drupal\Tests\views\FunctionalJavascript\Plugin\views\Handler\FilterTest
✗	
Drupal\Tests\views\FunctionalJavascript\Plugin\views\Handler\FilterTest
fail: [Other] Line 0 of sites/default/files/simpletest/phpunit-142.xml:
PHPunit Test failed to complete; Error: PHPUnit 8.5.3 by Sebastian Bergmann and contributors.

Testing Drupal\Tests\views\FunctionalJavascript\Plugin\views\Handler\FilterTest
.                                                                   1 / 1 (100%)

Time: 18.06 seconds, Memory: 4.00 MB

OK (1 test, 8 assertions)

Remaining self deprecation notices (1)

  1x: Declaring ::setUp without a void return typehint in Drupal\Tests\views\FunctionalJavascript\Plugin\views\Handler\FilterTest is deprecated in drupal:9.0.0. Typehinting will be required before drupal:10.0.0. See https://www.drupal.org/node/3114724
    1x in DrupalListener::startTest from Drupal\Tests\Listeners

ravi.shankar’s picture

Status: Needs work » Needs review
FileSize
5.19 KB
677 bytes

Here I have tried to fix failed tests for Drupal 9.1.x.

longwave’s picture

Status: Needs review » Needs work

Thanks for the patch!

+++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php
@@ -0,0 +1,169 @@
+  protected function setUp() : void {

There should be no space between () and :, i.e.

protected function setUp(): void {
ravi.shankar’s picture

Status: Needs work » Needs review
FileSize
5.19 KB
683 bytes

Here I have addressed comment #25.

longwave’s picture

Status: Needs review » Reviewed & tested by the community

Looks good.

dww’s picture

Status: Reviewed & tested by the community » Needs work

Mostly looks good, thanks! A few concerns / nits:

  1. +++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php
    @@ -0,0 +1,169 @@
    +   * Test adding a filter handler.
    

    s/Test/Tests/

  2. +++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php
    @@ -0,0 +1,169 @@
    +    $session = $this->getSession();
    

    We don't seem to use this variable anywhere, let's remove it.

  3. +++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php
    @@ -0,0 +1,169 @@
    +    $web_assert->assertWaitOnAjaxRequest();
    ...
    +    $web_assert->assertWaitOnAjaxRequest();
    ...
    +    $web_assert->assertWaitOnAjaxRequest();
    ...
    +    $web_assert->assertWaitOnAjaxRequest();
    

    According to @Lendude at #2842525-80: Ajax attached to Views exposed filter form does not trigger callbacks we should avoid assertWaitOnAjaxRequest() whenever possible.

  4. +++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php
    @@ -0,0 +1,169 @@
    +   * @return Bool|null
    +   *   TRUE is the required number was matched, NULL if not.
    ...
    +      return NULL;
    

    Why NULL on failure? Why not just @return bool and use FALSE if we time out before we get the right count?

  5. +++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php
    @@ -0,0 +1,169 @@
    +    $result = $page->waitFor($timeout / 1000, function () use ($count, $page, $locator) {
    ...
    +    return $result;
    

    Why bother with a local $result variable? Why not just:

        return $page->waitFor(...)
    
  6. +++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php
    @@ -0,0 +1,169 @@
    +   * @return Bool|null
    +   *   TRUE is the required number was matched, NULL if not.
    

    Same here. Why not FALSE on failure?

  7. +++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php
    @@ -0,0 +1,169 @@
    +    $result = $page->waitFor($timeout / 1000, function () use ($page) {
    ...
    +    return $result;
    

    Same here... why have $result at all?

kishor_kolekar’s picture

Status: Needs work » Needs review
FileSize
4.94 KB
4.2 KB

addressed comment #28
please review the patch.

Lendude’s picture

+++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php
@@ -84,27 +81,24 @@
-    $web_assert->assertWaitOnAjaxRequest();

It's not that we should just remove it, it's that we should replace it with more specific waitForX methods when possible.

Status: Needs review » Needs work

The last submitted patch, 29: 2754985-29.patch, failed testing. View results

Lendude’s picture

Fixed the test and a small typo.

kishor_kolekar’s picture

@Lendude Thanks for #30

dww’s picture

Title: Add javascript test coverage for adding an exposed filter in Views UI » Add JavaScript test coverage for adding an exposed filter in Views UI
Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

re #29 / #30 Sorry I wasn't clear. I meant to paste the relevant quote, but forgot:

#78.2 is because assertWaitForAjaxRequest is notoriously fickle, it has been the cause of many a random fail on Drupal CI. It has been shown that actually waiting for the change to appear is much more stable. So unless there is no change to detect, try never to use assertWaitForAjaxRequest. Since this is fairly straight forward I would not expect problems here, but best to be safe.

There are plenty of examples in #2829040: [meta] Known intermittent, random, and environment-specific test failures that in the fixes come down to 'replace assertWaitForAjaxRequest with other wait options'.

So yeah, thanks for #32!

All the changes since my review now look great, and all feedback addressed. I tried this manually on the 9.1.x branch, and it applies and passes there, too (no sense wasting 1.25 hours of bot cycles to tell us that).

RTBC!

dww’s picture

Status: Reviewed & tested by the community » Needs work

Actually, if we're targeting 8.y.x, we need another version of this without the :void typehint in setUp(), or we break stuff on PHP 7.0. Anyone else want to re-roll so I can still re-RTBC?

#32 is still RTBC for 9.y.x branches, but we should probably have the backports ready before this is committed.

Thanks/sorry,
-Derek

dww’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
5.17 KB
592 bytes

Oh, FFS, this is ridiculous. I'm just gonna fix it and self-RTBC. I think I can be trusted to do a 5 byte fix myself. ;)

dww’s picture

Issue summary: View changes

Great, so the bot results agree with me. ;) #32 fails on PHP 7.0, but #36 passes.

Updated with a proper summary, including links to which patch is RTBC for which branch.

Enjoy,
-Derek

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

lauriii’s picture

Version: 8.9.x-dev » 9.1.x-dev
Status: Reviewed & tested by the community » Needs work
  1. There's a deprecation warning in Drupal 9.1.x which should be addressed.
  2. +++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php
    @@ -0,0 +1,163 @@
    +   *   (Optional) Timeout in milliseconds, defaults to 10000.
    ...
    +  protected function waitForOnlyContentRows($timeout = 10000) {
    ...
    +    return $page->waitFor($timeout / 1000, function () use ($page) {
    

    Do we have a pre-existing pattern to define durations in milliseconds? Just wondering because it seems potentially confusing to have different unit in comparison to Mink.

  3. +++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php
    @@ -0,0 +1,163 @@
    +    $add_button = $page->find('css', '.ui-dialog-buttonset .button--primary');
    

    Any thoughts on using the button text instead of .button--primary for selecting which button to press? This would make it easier for us to run this test on other themes (it's more likely they'll customize the button class compared to customizing the text).

dww’s picture

Status: Needs work » Reviewed & tested by the community

Re: #39:

1. Patch #32 is correct for 9.1.x and 9.0.x. As I tried to make clear (both in my comments and in the summary), #36 is only the D8 backport.

2. Yes, tons. See core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php and search for 'milliseconds'. Every wait*() method core already provides does it this way.

3. We only test this with Stark, so I'm not sure that it matters. I'm also slightly worried that there might be a lot of 'Add' buttons. ;) The existing seems more resilient.

Thanks,
-Derek

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

The last submitted patch, 32: 2754985-32.patch, failed testing. View results

quietone’s picture

Status: Reviewed & tested by the community » Needs work

Setting to NW because the patch for 9.1.x, in #36, has a failing test.

dww’s picture

Uploading #32 as 2754985-44.9_x-only.patch
Uploading #36 as 2754985-44.8_x-only.patch
Re-updating the summary to continue to point to the right patches.

Hopefully everyone will be clear on what to test / commit where.

Thanks!
-Derek

lauriii’s picture

Status: Reviewed & tested by the community » Needs review

Thank you for clarifying #39.1.

Re: #39.3: Isn't the button text "Add and configure filter criteria" which would be quite specific? We also use that for the Apply button few rows below, so why we couldn't use the same approach there? Stark is one of the themes we are allowed to change and for that reason we could change that class in the future.

dww’s picture

Lendude’s picture

Status: Needs review » Reviewed & tested by the community

#45 addressed, looks good, back to RTBC

  • lauriii committed 1f522e2 on 9.2.x
    Issue #2754985 by dww, Lendude, ravi.shankar, michielnugter,...
lauriii’s picture

Version: 9.2.x-dev » 9.1.x-dev

Committed 1f522e2 and pushed to 9.2.x. Thanks!

Leaving open for backport.

dww’s picture

Title: Add JavaScript test coverage for adding an exposed filter in Views UI » [backport] Add JavaScript test coverage for adding an exposed filter in Views UI

Wonderful, thanks!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 46: 2754985-46.8_x-only.patch, failed testing. View results

Lendude’s picture

Status: Needs work » Reviewed & tested by the community

Unrelated fail in Drupal\Tests\media_library\FunctionalJavascript\WidgetUploadTest

  • lauriii committed 3451649 on 9.1.x
    Issue #2754985 by dww, Lendude, ravi.shankar, michielnugter,...
lauriii’s picture

Status: Reviewed & tested by the community » Fixed

Discussed with @catch and we agreed that this could be backported to 9.1.x. We also agreed to not backport this to 8.9.x because it's pretty much only open for critical issues at this point.

Status: Fixed » Closed (fixed)

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