Problem/Motivation

The basis for this test was build in #1686174: Refactor machine-name.js

Currently the machine name element has no javascript test coverage. There are a number of issues with the machine name field that will all require javascript testing.
This issue will provide a base test setup that the other issues can then build upon. It will only test functionality that currently works, and bugs found while building this will be addressed in follow up issues.

Issues that depend on this (add more if we find more issues):

Proposed resolution

- Add test

Remaining tasks

- Review
- Rework(?)
- Commit :)

User interface changes

- NO

API changes

- NO

Data model changes

- NO

Comments

michielnugter created an issue. See original summary.

michielnugter’s picture

Interdiff is for changes from the last patch in #1686174.

michielnugter’s picture

Status: Active » Needs review
michielnugter’s picture

Small question: Is there a meta issue for adding functional JavaScript testcoverage to Drupal Core? If not, should there be one? I'd really like to work on this some more.

lendude’s picture

Issue summary: View changes

Updated the issue summary a bit.

A javascript meta issue for the whole of core would probably be too big in scope.

I set up a meta issue just for Views #2752931: [meta] Implement Javascript testing for Views and the Views UI so that is somewhat more limited in scope and pretty maintainable. There might be other meta's like that floating around.

droplet’s picture

@michielnugter,

There're some issues needed JSTests:

https://www.drupal.org/project/issues/search?projects=Drupal+core&projec...

Huge one:
#2809161: Convert Javascript/AJAX testing to use JavascriptTestBase

I very enjoy to see your detail reports of each update, you might be interested in the following issue:
#2820079: Convert \Drupal\book\Tests\BookTest::testBookOrdering() to a JavascriptTestBase test

michielnugter’s picture

Thanks for the links, I'll start following these issues.

I'll try to review some patches and create tests where missing. I also hope (eventually) to be able to contribute some to the ES6 refactoring step.

lendude’s picture

Status: Needs review » Needs work

Last couple of nitpicks then I think this is ready:

  1. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/MachineNameTest.php
    @@ -0,0 +1,120 @@
    + * @group session
    

    needs a different @group

  2. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/MachineNameTest.php
    @@ -0,0 +1,120 @@
    +
    

    One newline too many.

  3. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/MachineNameTest.php
    @@ -0,0 +1,120 @@
    +      // Set the value for the role, triggering the machine name update.
    

    'role' Left over from when this used add role page.

  4. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/MachineNameTest.php
    @@ -0,0 +1,120 @@
    +      $generated_value = $machine_name_1_value->getHTML();
    ...
    +      $generated_value_2 = $machine_name_2_value->getHTML();
    

    These variables are not really needed, this can just be done in the assert right?

  5. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/MachineNameTest.php
    @@ -100,14 +103,18 @@
    +    $this->assertEquals(TRUE, $machine_name_1_wrapper->hasClass('visually-hidden'), 'The ID field must not be visible');
    

    Maybe add an short explanation why isVisible() doesn't work here.

  6. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/MachineNameTest.php
    @@ -100,14 +103,18 @@
    +    $last_test = array_pop($test_values);
    

    I would just use $test_values[1]['expected'], that way the $test_values can be reused in further test we might want to add later.

michielnugter’s picture

Status: Needs work » Needs review
StatusFileSize
new2.86 KB
new6.94 KB

Thanks for the review again!

I fixed all the mentioned issues, I chose the field group as other field tests are in this group as well.

droplet’s picture

+++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/MachineNameTest.php
@@ -0,0 +1,120 @@
+      // Get the generated machine name.
+      $generated_value = $machine_name_1_value->getHTML();
...
+      // Validate the generated machine name.
+      $this->assertEquals($test_info['expected'], $generated_value, $test_info['message']);
...
+      // Get value for the second machine name field.
+      $generated_value_2 = $machine_name_2_value->getHTML();
...
+      // Validate the second machine name field is empty.
+      $this->assertEmpty($generated_value_2, 'The second machine name field should still be empty');

WOW mate! I think you're the only one will understand me on another issue #2820079: Convert \Drupal\book\Tests\BookTest::testBookOrdering() to a JavascriptTestBase test. It's great code. Validate result on generated HTML ( ->getHTML() )

+++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/MachineNameTest.php
@@ -0,0 +1,120 @@
+      // Wait the set timeout for fetching the machine name.
+      $this->getSession()->wait(300);

It needed longer timeout and JS condition to aviod random failing. 300ms isn't always 300ms in JS :)

lendude’s picture

Assigned: michielnugter » Unassigned
Status: Needs review » Reviewed & tested by the community

It needed longer timeout and JS condition to aviod random failing. 300ms isn't always 300ms in JS :)

Well waitOnAutocomplete also adds another wait(300), so the total wait before waiting for the ajax request to finish is already 600ms. I feel this should be sufficient. If that won't do then we need to not wait() a set number of ms, but just wait for the expected value to appear, but I think this is much cleaner.

@droplet I feel this is good to go now, but of course feel free to set back to needs work if you disagree on the timing thing!

@michielnugter nice work!

droplet’s picture

@Lendude,

OK. Let's go.

michielnugter’s picture

I tried various things with the timing and I actually got the test to fail once at 250ms. It seems risky to keep it at 300ms as it's a risk that the test will fail incorrectly. I upped to timeout to 400ms, this is safe for the average range the timout ms is in. It shouldn't be too high again because it will delay each complete test suite on Drupal..

As for waiting for the value to appear, that's actually the behaviour we're testing here. If implemented this way a max. time is still required, thus keeping the risk of incorrect failure.

See interdiff for the change.

michielnugter’s picture

@droplet I'll look into the mentioned issue and see if I can make sense of it :)

droplet’s picture

@michielnugter,

Thanks.

It will be stopped when the JS condition is met.

->wait(1000, JS-Condition)

@see: \vendor\behat\mink\src\Driver\DriverInterface.php

    /**
     * Waits some time or until JS condition turns true.
     *
     * @param int    $timeout   timeout in milliseconds
     * @param string $condition JS condition
     *
     * @return bool
     *
     * @throws UnsupportedDriverActionException When operation not supported by the driver
     * @throws DriverException                  When the operation cannot be done
     */
    public function wait($timeout, $condition);

In fact, the `waitOnAutocomplete()` should not set a fixed 300ms also. But it's out of this issue scope.

Actually we have a real example with similar problem over there, you can see how unstable the PhantomJS test is.
https://www.drupal.org/node/2782915#comment-11728915

Unless we think it's a UX issue and should be tested the action within 300ms execution time. Otherwise, we can increase the timeout there with JS condition.

michielnugter’s picture

Really helpful feedback, I'm learning a lot and fast. Thanks!

I updated the patch to use the wait() command instead of the manual timeout and waitOnAutocomplete().

droplet’s picture

All good.

Enhanced a little bit to cover 2nd machine name also. It's easy to use a bad selector & bubble up in JS

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed 2cde5b6 to 8.3.x and d97733a to 8.2.x. Thanks!

  • alexpott committed 2cde5b6 on 8.3.x
    Issue #2821320 by michielnugter, droplet, Lendude: Add test coverage for...

  • alexpott committed d97733a on 8.2.x
    Issue #2821320 by michielnugter, droplet, Lendude: Add test coverage for...

Status: Fixed » Closed (fixed)

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