Problem/Motivation

#2416987: Fix UI regression in the menu link form, in an effort to remove a fieldset style for menu links add/edit form (which uses the link widget always with link text (disabled),
broke using the link widget elsewhere.

Steps to reproduce

  1. Install Drupal
  2. Add a Link field - with an "Help text" and "Allow link text" set to "Disabled" - to any content type
  3. Create a node of this content type

Expected result: the "Help text" is shown under the link field
Current result: the "Help text" is not shown

Cases

  • menu link
  • shortcut
  • link widget used in content types (or other things that have fields):
    • cardinality 1, link text disabled, internal url only
    • cardinality 1, link text disabled, external url only
    • cardinality 1, link text disabled, internal and external url
    • cardinality 1, link text enabled, internal url only
    • cardinality 1, link text enabled, external url only
    • cardinality >1, link text enabled, internal and external url
    • cardinality >1, link text disabled, internal url only
    • cardinality >1, link text disabled, external url only
    • cardinality >1, link text disabled, internal and external url
    • cardinality >1, link text enabled, internal url only
    • cardinality >1, link text enabled, external url only
    • cardinality >1, link text enabled, internal and external url

Proposed resolution

Remaining tasks

Contributor tasks needed
Task Novice task? Contributor instructions Complete?
Create a patch Instructions Done
Reroll the patch if it no longer applies. Instructions Done
Update the issue summary Instructions Done
Add automated tests Instructions Done
Update the patch to incorporate feedback from reviews (include an interdiff) Instructions To Do. See:
Manually test the patch Novice Instructions Done
Add steps to reproduce the issue Novice Instructions Done
Embed before and after screenshots in the issue summary Novice Instructions Done
Review patch to ensure that it fixes the issue, stays within scope, is properly documented, and follows coding standards Instructions

User interface changes

Before

After

API changes

Only local images are allowed.

CommentFileSizeAuthor
#124 2421001-124.patch13.65 KBgnuget
#124 interdiff-2421001-120-124.txt858 bytesgnuget
#120 2421001-120.patch13.42 KBDuaelFr
#120 interdiff.2421001.118.120.txt1.28 KBDuaelFr
#118 interdiff.txt687 bytespfrenssen
#118 2421001-118.patch13.67 KBpfrenssen
#117 interdiff.txt3.08 KBpfrenssen
#117 2421001-117.patch13.68 KBpfrenssen
#112 interdiff-2421001-109-112.txt2.74 KBgnuget
#112 2421001-112.patch13.56 KBgnuget
#109 2421001-109.patch13.36 KBgnuget
#109 interdiff-2421001-108-109.txt1.34 KBgnuget
#108 2421001-108.patch13.48 KBLendude
#108 interdiff-2421001-104-108.txt4.85 KBLendude
#105 Screen Shot 2017-10-10 at 09.56.49.png27.62 KBSinan Erdem
#105 Screen Shot 2017-10-10 at 09.56.28.png151.72 KBSinan Erdem
#104 interdiff-2421001-101-104.txt6.69 KBgnuget
#104 2421001-104.patch12.21 KBgnuget
#101 2421001-97-rebase-101.patch12 KBgnuget
#98 2421001-97.patch11.96 KBandrewmacpherson
#98 interdiff-2421001-87-97.txt1.45 KBandrewmacpherson
#90 link field urb - after.png79.42 KBJohn Cook
#90 link field urb - before.png79.53 KBJohn Cook
#90 link field ure - after.png52.38 KBJohn Cook
#90 link field ure - before.png51.66 KBJohn Cook
#90 link field uri - after.png74.03 KBJohn Cook
#90 link field uri - before.png73.26 KBJohn Cook
#90 link field udb - after.png73.19 KBJohn Cook
#90 link field udb - before.png72.98 KBJohn Cook
#90 link field ude - after.png45.78 KBJohn Cook
#90 link field ude - before.png45.76 KBJohn Cook
#90 link field udi - after.png68.13 KBJohn Cook
#90 link field udi - before.png68.03 KBJohn Cook
#90 link field srb - after.png66.15 KBJohn Cook
#90 link field srb - before.png65.86 KBJohn Cook
#90 link field sre - after.png40.43 KBJohn Cook
#90 link field sre - before.png40.5 KBJohn Cook
#90 link field sri - after.png63.07 KBJohn Cook
#90 link field sri - before.png62.99 KBJohn Cook
#90 link field sdb - after.png55.59 KBJohn Cook
#90 link field sdb - before.png45.92 KBJohn Cook
#90 link field sde - after.png29.54 KBJohn Cook
#90 link field sde - before.png21.06 KBJohn Cook
#90 link field sdi - after.png50.55 KBJohn Cook
#90 link field sdi - before.png42.7 KBJohn Cook
#90 shortcut - after.png50.38 KBJohn Cook
#90 shortcut - before.png42.9 KBJohn Cook
#90 menu - after.png54.18 KBJohn Cook
#90 menu - before.png45.35 KBJohn Cook
#87 2421001-87.patch11.89 KBgeertvd
#85 2421001-85.patch11.86 KBpfrenssen
#83 interdiff.txt9.79 KBpfrenssen
#83 2421001-82.patch11.97 KBpfrenssen
#80 2421001-80.patch9.36 KBjofitz
#80 interdiff-76-80.txt5.16 KBjofitz
#76 2421001-76-test_only.patch8.03 KBpfrenssen
#76 2421001-76.patch9.71 KBpfrenssen
#69 fix_regression_in_the-2421001-67.patch9.64 KBYesCT
#69 fix_regression_in_the-2421001-67-testsonly.patch7.97 KBYesCT
#68 fix_regression_in_the-2421001-67.patch9.64 KBDuaelFr
#68 interdiff.2421001.65.67.txt960 bytesDuaelFr
#1 2416987.43.patch8.26 KBYesCT
#6 regression-link-widget-2416987.6.patch8.44 KBmgifford
#12 2416987.12.patch10.37 KBYesCT
#14 2421001.14.patch20.87 KBYesCT
#14 interdiff.2421001.12.14.txt14.49 KBYesCT
#14 2421001.14.tests-only.patch14.49 KBYesCT
#18 2421001-18.patch14.04 KBeiriksm
#18 2421001-18-test-only.patch7.66 KBeiriksm
#18 interdiff.txt15.7 KBeiriksm
#22 link_widget_description-2421001-22.patch841 bytesDuaelFr
#24 link_widget_description-2421001-24.patch967 bytesDuaelFr
#24 interdiff.2421001.22.24.txt1.12 KBDuaelFr
#27 test_only-fix_regression_in_the-2421001-27.patch7.86 KBStryKaizer
#27 fix_regression_in_the-2421001-27.patch8.99 KBStryKaizer
#29 2421001-before.png77.44 KBDuaelFr
#29 2421001-after.png67.71 KBDuaelFr
#31 interdiff-2421001-27-31.txt6.84 KBeiriksm
#31 fix_regression_in_the-2421001-31.patch9.37 KBeiriksm
#32 External-link-help-text.jpg14.89 KBthorandre
#37 fix_regression_in_the-2421001-37.patch9.51 KBeiriksm
#37 interdiff31-37.txt3.44 KBeiriksm
#39 link description text.png46.47 KByoroy
#39 link description shortcut.png34.15 KByoroy
#46 interdiff.txt5.49 KBeiriksm
#46 fix_regression_in_the-2421001-46.patch9.89 KBeiriksm
#48 fix_regression_in_the-2421001-48.patch9.89 KBeiriksm
#49 2421001-48-after.png64.17 KBmohit_aghera
#49 2421001-48-1-after.png42.9 KBmohit_aghera
#51 fix_regression_in_the-2421001-51.patch10.18 KBeiriksm
#51 interdiff2421001.txt1.12 KBeiriksm
#52 2421001-51.png56.36 KBmohit_aghera
#52 2421001-51-1.png42.5 KBmohit_aghera
#65 interdiff.2421001.51.65.txt1.4 KBDuaelFr
#65 fix_regression_in_the-2421001-65.patch10.11 KBDuaelFr
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

YesCT’s picture

Issue summary: View changes
Status: Active » Needs review
FileSize
8.26 KB

this will not apply, but is the patch from #43 from the other issue.
it did the approach "use logic based on cardinality and link text being disabled or enabled" (the bit about fixing the short cut page title will have a separate issue).

Status: Needs review » Needs work

The last submitted patch, 1: 2416987.43.patch, failed testing.

YesCT’s picture

next step is to strip out all the unrelated stuff from that patch.

amateescu’s picture

What was wrong with the patch from #2416987-61: Fix UI regression in the menu link form?

YesCT’s picture

taking the fieldset off made the help text that used to show, not show.
(we traded a task that removed a boarder for a bug that made helptext not show)

mgifford’s picture

Status: Needs work » Needs review
FileSize
8.44 KB

Mostly testing out the credit link on a patch I've already contributed.

amateescu’s picture

@YesCT, in #4 I linked to a specific comment from [#9580553], which is comment #61 from that issue :)

YesCT’s picture

#2421021: Missing help text for external url only for link widget went in, now we can expand those tests for all the cases here.

kerby70’s picture

Issue tags: -Need tests +Needs tests

Correcting non standard tag 'Need tests' to 'Needs tests'

idebr’s picture

Status: Needs review » Needs work
  1. The patch from #6 includes changes that are out of scope for this issue. Per YesCT in #2:

    next step is to strip out all the unrelated stuff from that patch

  2. +++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
    @@ -184,16 +192,38 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
    +      if ($this->supportsExternalLinks() && $this->supportsInternalLinks()) {
    +        $element['uri']['#description'] .= $this->t('This can be an internal Drupal path such as %add-node or an external URL such as %drupal. Enter %front to link to the front page.', array('%front' => '<front>', '%add-node' => 'node/add', '%drupal' => 'http://drupal.org'));
    +      }
    +      elseif ($this->supportsExternalLinks() && !$this->supportsInternalLinks()) {
    +        $element['uri']['#description'] .= $this->t('This must be an external URL such as %drupal.', array('%drupal' => 'http://drupal.org'));
    +      }
    

    User facing strings of an example url should no longer use drupal.org, see #2418209: Replace user facing strings that use drupal.org as example of an external url.

YesCT’s picture

I'm going to start on this.

YesCT’s picture

Status: Needs work » Needs review
FileSize
10.37 KB

For menu link,
it used to be labeled "Link path"
#2416987: Fix UI regression in the menu link form changed the label to just be "Link".

So far, this changes it to be "Link (URL)"
since the premise is to use the label from the field, and also use the label from the widget.

--

I did not use a const for the optional/required/disabled link text. could not find a const on the interface.

--

used random machine name for the help text. there might be a better way.

--

I'm having trouble setting the description and the link text setting in the field form....
uploading this for now. If anyone has ideas, let me know. I'll continue to work on this some more now though also.

Status: Needs review » Needs work

The last submitted patch, 12: 2416987.12.patch, failed testing.

YesCT’s picture

Status: Needs work » Needs review
FileSize
20.87 KB
14.49 KB
14.49 KB

there are many permutations...

might be nice to add in tests for the field label, and the url label. but I'm done (for today).

[edit: hm. made interdiff wrong as it is exactly the same size as patch)

Status: Needs review » Needs work

The last submitted patch, 14: 2421001.14.tests-only.patch, failed testing.

YesCT’s picture

The fails in #14
Are:

1.
Raw "q1aT6RQm" found Other LinkFieldUITest.php 275 Drupal\link\Tests\LinkFieldUITest->testFieldUI()
Raw "hw9dscwI" found Other LinkFieldUITest.php 306 Drupal\link\Tests\LinkFieldUITest->testFieldUI()
Raw "kKFeJtau" found Other LinkFieldUITest.php 338 Drupal\link\Tests\LinkFieldUITest->testFieldUI()

All three when the link text is disabled, the field help text (description) is missing.

2.
MenuLinkContentFormTest.php 46
ShortcutLinksTest.php 61

The field help text (description) from the base field definitions:

core/modules/menu_link_content/src/Entity/MenuLinkContent.php
298: ->setDescription(t('The location this menu link points to.'))

core/modules/shortcut/src/Entity/Shortcut.php
151: ->setDescription(t('The location this shortcut points to.'))

We should either show them (which this patch does). Or take them out (... throwing an error if they are try and set).

YesCT’s picture

1. I'm not sure if we want to test *where* the description is (with xpath selectors).

2. I'm also not sure how to organize the tests.

3. The combination of link text optional is not tested with cardinality greater than 1.

4. Some of the comments are cut and paste and need to be corrected.

5. In this issue, I think we might want to NOT append the (URL) to the label for the field.

6. In fact, I think we might want to change the label there to Link location and not URL.
Since the thing that is typed there is not always (not often) a url... for example... people might type part of a title of a node, or an internal path.
Changing the label on the default link widget would be a separate issue.
#2461361: Change link widget URL field label to Link location, since what people put in the field does not have to be (usually will not be) a URL

eiriksm’s picture

I ran into this issue while building a Drupal 8 site. Had me wondering for a while :)

Tested the patch and it does not apply anymore. So here is a reroll, which also include these changes:

- Refactor all cases of testing for help texts into a loop (maybe address your concern #2). This also addresses concern #3 and #4.

Now, the code changes in this patch addresses the mentioned regression, but I was wondering about another thing (potentially another issue i guess):
- Why do we hide the description for internal links (and instead rely on the "helpful" prefix)? The help text that in the case of external/internal states that "Start typing the title of a piece of content" and this also applies when the setting is set to "only internal", only no-one gets this helpful hint. In fact, adding the prefix kind of makes you think that the input is required to be a internal URL, when it can in fact be the title of a node.

Thoughts?

eiriksm’s picture

Status: Needs work » Needs review

Setting to needs review.

Status: Needs review » Needs work

The last submitted patch, 18: 2421001-18-test-only.patch, failed testing.

eiriksm’s picture

Status: Needs work » Needs review

Yes, that was expected :)

DuaelFr’s picture

I don't understand why this patch is so complicated.

The following cases seems to already be handled by default :
- cardinality > 1, all cases
- cardinality = 1, title enabled, all cases

We just need to handle
- cardinality = 1, title disabled, all cases

Please find attached a simple solution that fixes the issue (without tests, sorry).

The side effect of this fix is that, in the Menu UI, the MenuLinkContent 'link' base field description ('The location this menu link points to.') is appended to the field description. This leads to that help text displayed on the field : 'Start typing the title of a piece of content to select it. You can also enter an internal path such as /node/add or an external URL such as http://example.com. Enter to link to the front page.
The location this menu link points to.'

I think that the appended information improves the usability of the field so it might not be considered as a problem.

Let's see what the testbot have to say about that patch an discuss my tiny solution.

Status: Needs review » Needs work

The last submitted patch, 22: link_widget_description-2421001-22.patch, failed testing.

DuaelFr’s picture

Status: Needs work » Needs review
FileSize
967 bytes
1.12 KB

Better handling of empty descriptions (fixes tests)

eiriksm’s picture

Status: Needs review » Needs work

Looks fine to me. Fixes the bug.

Can we add some quick tests, though? You can still base it on the "test-only" patch in #18 I guess.

dawehner’s picture

+++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
@@ -244,6 +244,14 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
+        if (!empty($element['#description'])) {
+          if (empty($element['uri']['#description'])) {
+            $element['uri']['#description'] = $element['#description'];
+          }
+          else {
+            $element['uri']['#description'] .= '<br />' . $element['#description'];

It would be great to have some quick comment why we have this logic here.

StryKaizer’s picture

Attached you can find a test only, which should fail, and a test + patch.

Test is the code from #18, added 1 verbose command to see which variant is being tested.

Patch is taken from #24, added comment as asked in #26

The last submitted patch, 27: test_only-fix_regression_in_the-2421001-27.patch, failed testing.

DuaelFr’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
77.44 KB
67.71 KB

Thanks @StryKaizer for your work!

Tests pass.
Coding standards are OK.
And finally, labels are where they're supposed to be \o/

Before

After

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
@@ -244,6 +244,17 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
+          else {
+            $element['uri']['#description'] .= '<br />' . $element['#description'];
+          }

There does not seem to be any test for this. Since adding html together is one of losing safeness with need to confirm that we're not introducing an escaping bug here.

eiriksm’s picture

Status: Needs work » Needs review
FileSize
6.84 KB
9.37 KB

There does not seem to be any test for this. Since adding html together is one of losing safeness with need to confirm that we're not introducing an escaping bug here.

+++ b/core/modules/link/src/Tests/LinkFieldUITest.php
@@ -67,31 +71,84 @@ function testFieldUI() {
+          // Also assert that the description we made is here, no matter what
+          // the cardinality or link setting.
+          $this->assertRaw($description);
+        }

I might misunderstand your comment, but this should cover the case you are asking for, no?

Granted, we do not test _not_ adding a custom description, so here is a quick patch adding that as well. Since you mention " Since adding html together is one of losing safeness with need to confirm that we're not introducing an escaping bug here." do you want to add an assertion that we are not seeing the
tag as text also? (for the record, it does not introduce an escaping bug, i just tested manually)

thorandre’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
14.89 KB

Manually tested. Looking good.

thorandre’s picture

Issue tags: +dcoslo15
thorandre’s picture

Issue summary: View changes
thorandre’s picture

Issue summary: View changes
eiriksm’s picture

Assigned: Unassigned » eiriksm
Status: Reviewed & tested by the community » Needs work

Re-read the comment in #30 and I think I might have misunderstood the concern, so I'll just add a quick test for that. Also, want to replace the random data in there (see #2571183: Deprecate random() usage in tests to avoid random test failures for more info)

eiriksm’s picture

Status: Needs work » Needs review
FileSize
9.51 KB
3.44 KB

- Replaced some random data.
- Fixed some lines that were 81 characters :p
- Added html in the descriptions, to test this does not get escaped (hope that was what you were after, @alexpott?)

DuaelFr’s picture

I made a new round of manual testing and that still looks good!
Thank you @eiriksm.

yoroy’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
46.47 KB
34.15 KB

Tested on simplytest with a link field on the article content type and editing a shortcut link.

Link field:

Shortcut:

Whenn I compare that shortcut screen with a Drupal 8 install without the patch the description "The location this shortcut points to." is not shown in the latter.

I *think* this is rtbc.

Committers want to look at #30, #31 and #37

catch’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
@@ -243,6 +243,17 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
+            $element['uri']['#description'] .= '<br />' . $element['#description'];

Why the <br /> tag?

Also it's not clear to me whether the test covers the case where the uri description and field description are concatenated.

mgifford’s picture

Seems to have been added in #31.

eiriksm’s picture

To first comment on the <br>, it was first introduced in #22. I guess the reason was not explicitly defined, but I assume the main point is that we want to differentiate between "core help text" and "user entered help text". As an example, look at this image:

example

If the text "Here is my link help text" would be just after the "core help text", that would appear strange. In my opinion, anyway.

Would it be preferable if we added these in different render arrays, making them paragraphs instead of concatenating them with a <br>? Or was your point that you would prefer it to not be there, and instead be concatenated with no markup between?

Now, regarding test coverage for the above mentioned. It is not really tested that the concatenated text is on the page. It is, however, tested that both the user entered and the "core help text" is on the page. Although I guess an extra assertion would not hurt. :)

Let's just first decide how to proceed with the "<br> problem". Any thoughts from anyone there? Keep it? Remove it? Change it?

DuaelFr’s picture

@eiriksm You're totally right. I introduced that <br> because I thought it was less confusing than without.
I don't know at all if it's better than paragraphs but I'm afraid that paragraphs default style would make it bad looking.

mgifford’s picture

So do we style the <p>, add documentation to the <br> or just set it back to RTBC?

I'm for adding a comment in the PHP to explain why this was added.

DuaelFr’s picture

I'm not de the right guy to write comments.
I can put it in the code and make the patch file but I'm not confident enough in english to write it :)

eiriksm’s picture

OK, here is an updated patch.

- Added a comment in both the test and the widget why we add the BR tag.
- Fixed a typo.
- Simplified the test code a little.
- Added assertions for when the BR tag should be added.

swentel’s picture

+++ b/core/modules/link/src/Tests/LinkFieldUITest.php
@@ -126,32 +131,24 @@ function testFieldUI() {
+              // If the link type was not internal, and the cardinalyty was 1,

typo: cardinality

Looks good to me other than that.

eiriksm’s picture

oops. Oh well, typo fixed.

mohit_aghera’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
64.17 KB
42.9 KB

I tested #48 on simplytest.
Things are appearing fine. Screenshots are attached.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
@@ -243,6 +243,21 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
+            // If we have the description of the type of field together with
+            // the user provided description, we want to make a distinction
+            // between "core help text" and "user entered help text". To make
+            // this distinction more clear, we separate them with a line break.
+            $element['uri']['#description'] .= '<br />' . $element['#description'];

This is concatenating markup which will lose safe-ness. This works because #description is XSS admin filtered. Not sure what is the right thing to do here. Setting back to needs review to get more people than just me thinking about this.

eiriksm’s picture

How about this? An inline template for the description?

mohit_aghera’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
56.36 KB
42.5 KB

Looks good by testing on simplytest.me
Moving it to RTBC

DuaelFr’s picture

+1 RTBC for the online template, good idea @eiriksm

catch’s picture

Status: Reviewed & tested by the community » Needs review

Is the br tag necessary? Why not just a space?

mohit_aghera’s picture

Issue summary: View changes

@catch
As per me it will look good and add some more user friendliness.
For ex: See 2421001-51-1.png in #52

In Link 3 field, if we don't separate link description in new line it will be hard to identify link description and link help text. Same holds true for this snapshot as well.

catch’s picture

@mohit that's what I'm saying though. If the description and help text are actually semantically different, then they should not be within the same HTML tag. The <br > tag is not visible to screen readers for example.

mohit_aghera’s picture

@catch
How about moving both to separate div like

$element['uri']['#description'] = [
              '#type' => 'inline_template',
              '#template' => '<div class="uri-core-description">{{ core_description }}</div><div class="uri-user-description">{{ user_description }}</div>',
              '#context' => [
                'core_description' => $element['uri']['#description'],
                'user_description' => $element['#description'],
              ],
            ];

https://api.drupal.org/api/drupal/core%21modules%21block%21src%21Control...

DuaelFr’s picture

Assigned: eiriksm » Unassigned
Issue tags: +Accessibility

<div> are not read by screen readers. Most of the time, they don't vocalize <p> either (and they would need an extra layer of theming to avoid too big margins at this place).
The best option would be to add visually hidden labels to these elements but I'm not sure we can find something really relevant.

I also think we should put the user defined description first because screen readers users often skip content they already know. So, if that starts with the exact same words as everywhere else on the website, they'll tend to skip it entirely and miss the user entered part.

joelpittet’s picture

Component: menu system » link.module
Issue tags: +Twig

Nice work on getting tests going for this and resolving the regression.

Toying with link.module component vs maybe form api as this doesn't really touch the menu system. Please correct this if it's wrong.

I'm reviewing this to see if I can't get this back to RTBC.

I'd prefer to move this markup to the template(as always).

  1. +++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
    @@ -243,6 +243,28 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
    +        // By default the field description is added to the title field. Since
    +        // the title field is disabled, we add the description, if given, to the
    +        // uri element instead.
    

    Why do we add the description to the uri? Was it the only thing to add it to? Maybe there is a more appropriate place for this?

  2. +++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
    @@ -243,6 +243,28 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
    +            // between "core help text" and "user entered help text". To make
    +            // this distinction more clear, we separate them with a line break.
    

    This may be harder but it would be nice to get this variable into the template to make it easier to theme. Even if a break tag is the solution, it will make it much easier to override.(I hope)

Ping me on irc #drupal-contribute if you have any questions.

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

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

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

xjm’s picture

Version: 8.1.x-dev » 8.2.x-dev
Priority: Major » Normal

The core committers (@xjm, @alexpott, @catch, @effulgentsia, @Cottser) and theme maintainers (@lauriii, @joelpittet) discussed this issue today and agreed that this issue does not need to be major priority. However, we did accidentally remove the ability to add this text to these fields, and that can be considered a bug.

The screenshots in the summary explain the problem, but this issue would be easier to understand with specific steps to reproduce in the summary. (I see the issue has test coverage already in the patch, although I did not review the changes thoroughly.)

@joelpittet also noted that using an inline template and joining two strings with a <br /> tag are non-ideal (though the inline template is at least not introducing any escaping bugs, so it is an improvement over earlier patches for that reason.) If possible, we should use actual templates for markup, and/or more semantic markup. (For example, maybe it should be an unordered list?) It's worth considering whether this is the best way to ensure both description texts are available.

We should consider whether the issue might be better targeted for 8.2.x, because it is making a user-facing change and adding new UI text. (Some module could already be altering to add text back in addition, and this patch could result in that text being repeated twice, for example.) I've moved it to 8.2.x for now.

Finally, it looks like the feedback from @DuaelFr, @catch, and @joelpittet all still needs to be addressed as well.

Thanks everyone for your work so far on this bug!

xjm’s picture

Per #61, let's add the specific steps to reproduce to the summary.

DuaelFr’s picture

Issue summary: View changes
Status: Needs review » Needs work
Issue tags: -Needs steps to reproduce +DevDaysMilan

Added steps to reproduce and improved remaining tasks.

DuaelFr’s picture

Issue summary: View changes
DuaelFr’s picture

Here is a new patch where I choosed to use an item_list to show both descriptions.

To anwser @joelpittet in #59.1: no, we sadly don't have any better option. In the case we are talking about, the only element we have is that 'uri' element. That's only when we get both uri and text that we have a surrounding container.

The last submitted patch, 65: fix_regression_in_the-2421001-65.patch, failed testing.

YesCT’s picture

Status: Needs review » Needs work

#65 uses a render array.
a template would be better.
but since this is in a field widget, which is already using a render array, the change to template would be out of scope and a separate issue.

I discussed test changed with @DuaelFr (at dev days)
and I think that asserting the strings are there is sufficient,
and we should NOT test if the html is br or ul, that would be a test of the list generator, or an accessibility testing layer, or in a theme test.

Since the order of the strings was agreed to be important though,
if there is a somewhat easy way of testing the order (maybe an existing assert method) it could be worth doing in this issue,
if it is difficult and complex xpath things are needed, maybe we can go on without a test of the order.

DuaelFr’s picture

Status: Needs work » Needs review
FileSize
960 bytes
9.64 KB

@YesCT thanks for the review :)
I wasn't able to find any usefull existing assertion to test strings order.
This new patch removes the part where we try to test the html structure of that description.

YesCT’s picture

uploading a testsonly patch so we can check the tests fail appropriately
(and the same whole patch, so that retests will also retest the whole patch and not just the testonly one, which will fail and change the status to needs work confusingly)

The last submitted patch, 69: fix_regression_in_the-2421001-67-testsonly.patch, failed testing.

DuaelFr’s picture

Green! \o/

YesCT’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
    @@ -238,6 +238,28 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
    +                // User description first to avoid screen reader users to skip.
    

    can improve the grammar here a bit. (and explain why it might be skipped...? or we could assume people would git blame and come here and read the comments on the issue. ;)

    If the usual system message is first, screen reader users might skip it and not notice the more likely custom help text. Put the user description first to avoid screen reader users skipping it.

    Or just

    Put the user description first to avoid screen reader users skipping it.

  2. +++ b/core/modules/link/src/Tests/LinkFieldUITest.php
    @@ -62,31 +66,82 @@ function testFieldUI() {
    +    foreach ($cardinalities as $cardinality) {
    +      foreach ($link_types as $link_type) {
    +        // Now, test this with both the title enabled and disabled.
    +        foreach ($title_settings as $title_setting) {
    +          // Both test empty descriptions and not empty descriptions.
    +          foreach ([TRUE, FALSE] as $description_enabled) {
    

    oh! I love these loops and this test set up!

In general this looks great!

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

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.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.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now 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.

pfrenssen’s picture

Assigned: Unassigned » pfrenssen
Issue tags: +Needs reroll

Patch doesn't apply any more.

Assigning to me. I'll first make a patch with a straight reroll to latest 8.4.x, and then a second one to address the remarks from #72.

pfrenssen’s picture

Status: Needs work » Needs review

Setting to needs review for the bot. The tests have been ported to BrowserTestBase in the meantime so there might be subtle changes causing failures now.

Leaving assigned to me to review + address remarks from #65.

Status: Needs review » Needs work

The last submitted patch, 76: 2421001-76-test_only.patch, failed testing.

pfrenssen’s picture

  1. +++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
    @@ -239,6 +239,28 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
    +        // By default the field description is added to the title field. Since
    
    +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
    @@ -52,9 +52,13 @@ function testFieldUI() {
    +    $this->fieldUIAddNewField($type_path, $field_name, $label, 'link', array(), $field_edit);
    

    We can use [] instead of array() to make this line more hipster.

  2. +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
    @@ -62,31 +66,82 @@ function testFieldUI() {
    +            // Output variation being tested for debugging purpose.
    +            $this->verbose("Now testing - cardinality: $cardinality - link_type:
    +            $link_type, title_setting: $title_setting, description_enabled:
    +            $description_enabled");
    

    Let's remove the debugging cruft.

  3. +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
    @@ -62,31 +66,82 @@ function testFieldUI() {
    +            // Log in an admin to set up a content type for this test.
    +            $this->drupalLogin($this->adminUser);
    +
    +            // Add a new content type.
    +            $type = $this->drupalCreateContentType();
    +            $type_path = 'admin/structure/types/manage/' . $type->id();
    +            $add_path = 'node/add/' . $type->id();
    ...
    +            // and link field settings.
    

    Relogging and creating content types are expensive operations. Since these actions are done in the inner loop of the test a lot of time is spent doing this. A bit later in the loop a new test user is also created and logged in for every iteration.

    I think we can save a lot of cycles if we only log in with the admin user once to create the test fields, and then relog once as the test user to verify the expected output.

    I also think creating one single content type with multiple fields would be sufficient. If we give the fields unique machine names we can check that the expected messages are associated with the expected fields.

jofitz’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
5.16 KB
9.36 KB
  1. Used the hipster array syntax. :)
  2. Removed debugging cruft.
  3. Refactored to only log in once as admin & once as user and only create one new content type. Had to remove the test for absence of certain text because, now that all the fields are on the same content type, the text is actually there (but I think the test is still valid).

(and removed Needs Re-roll tag)

pfrenssen’s picture

Great improvement in speed!

[pieter@thinkarch core ((b2c3a31...) $%)]$ SIMPLETEST_BASE_URL=http://drupal.dev/drupal ../vendor/bin/phpunit modules/link/tests/src/Functional/LinkFieldUITest.php 
PHPUnit 4.8.27 by Sebastian Bergmann and contributors.

.

Time: 1.59 minutes, Memory: 4.00Mb

OK (1 test, 176 assertions)
[pieter@thinkarch core (2421001 $%)]$ git checkout 2421001-80 
Switched to branch '2421001-80'
[pieter@thinkarch core (2421001-80 $%)]$ SIMPLETEST_BASE_URL=http://drupal.dev/drupal ../vendor/bin/phpunit modules/link/tests/src/Functional/LinkFieldUITest.php 
PHPUnit 4.8.27 by Sebastian Bergmann and contributors.

.

Time: 1.03 minutes, Memory: 4.00Mb

OK (1 test, 38 assertions)

From 1.59 minutes to 1.03 minutes, it's almost twice as fast!

We can probably shave off some more seconds if we create the fields using the field API instead of through the interface. Since we are not actually testing the field UI there's no need to use the UI for this.

Refactored to only log in once as admin & once as user and only create one new content type. Had to remove the test for absence of certain text because, now that all the fields are on the same content type, the text is actually there (but I think the test is still valid).

I think we can keep this part of the test if we only look inside the field container for checking the absence of the text, instead of checking the entire response page.

pfrenssen’s picture

Assigned: pfrenssen » Unassigned

Used the field API to create the test fields. I also restored the tests for the absence of non-configured help texts by using XPath to pinpoint exact fields in the document.

[pieter@thinkarch core (2421001 $%)]$ SIMPLETEST_BASE_URL=http://drupal.dev/drupal ../vendor/bin/phpunit modules/link/tests/src/Functional/LinkFieldUITest.php 
PHPUnit 4.8.27 by Sebastian Bergmann and contributors.

.

Time: 31.02 seconds, Memory: 4.00Mb

OK (1 test, 65 assertions)

The test runs again almost twice as fast, now down to 31 seconds from the original 1 minute 59 seconds!

pfrenssen’s picture

And here is the patch :D

Status: Needs review » Needs work

The last submitted patch, 83: 2421001-82.patch, failed testing.

pfrenssen’s picture

Status: Needs work » Needs review
FileSize
11.86 KB

Rerolled against latest HEAD.

peterhebert’s picture

Having the description appear after the link text field is a bit confusing IMHO. It is confusing because it appears like it's describing the link text as opposed to the URL itself. I would suggest that it appear after the URL field, before the drupal-supplied text about the requirements (internal/external link). Here is a mock-up of what I'm suggesting:

Only local images are allowed.

geertvd’s picture

rogierbom’s picture

Issue tags: +sprint
John Cook’s picture

Assigned: Unassigned » John Cook
Issue summary: View changes

I've checked used the reproduction instructions to test geertvd's patch from comment #87.

Before:
Only local images are allowed.

After:
Only local images are allowed.

The help text has been added to the field's "help" area.

I'll go through the other variants in the summary before changing the status.

John Cook’s picture

OK. I've run through the the variants mentioned in the summary. Get ready for a load of screenshots.

Before After
Menu
Shortcut
File field
Cardinality: 1
Link text: disabled
Url type: internal
File field
Cardinality: 1
Link text: disabled
Url type: external
File field
Cardinality: 1
Link text: disabled
Url type: both
File field
Cardinality: 1
Link text: required
Url type: internal
File field
Cardinality: 1
Link text: required
Url type: external
File field
Cardinality: 1
Link text: required
Url type: both
File field
Cardinality: Unlimited
Link text: disabled
Url type: internal
File field
Cardinality: Unlimited
Link text: disabled
Url type: external
File field
Cardinality: Unlimited
Link text: disabled
Url type: both
File field
Cardinality: Unlimited
Link text: required
Url type: internal
File field
Cardinality: Unlimited
Link text: required
Url type: external
File field
Cardinality: Unlimited
Link text: required
Url type: both
John Cook’s picture

The help text is now displayed on menu and shortcut link fields as well as link fields where the cardinality is 1 and the link text option is disabled.

It appears that the problem doesn't exist on other setting combinations on link field.

I've also looked at the code. All appears to be OK.

I've now changed the status to RTBC.

idebr’s picture

cilefen’s picture

I skeptically tested with an unordered list within the help text, but that actually looks ok.

Leo Pitt’s picture

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

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now 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.

star-szr’s picture

+++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
@@ -241,6 +241,28 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
+                // User description first to avoid screen reader users to skip.

Minor but this comment is a bit cryptic/terse to me, can this be expanded upon, please?

(leaving at RTBC)

Edit: Also minor, there is one coding standards violation, missing space after foreach: https://www.drupal.org/pift-ci-job/728472

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

andrewmacpherson’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
1.45 KB
11.96 KB

That comment isn't particularly relevant to screen readers IMO - I think it's more accurate to say the custom help text is the most relevant part for everyone.

The link URL input has an aria-describedby attribute, which points to the div.class wrapper around the entire list of descriptions. That is, the list constitutes a single description as far as assistive tech is concerned.

This patch addresses #96 by:

  • updating the comment about why user-specified description comes first
  • fixing the missing space after foreach keyword.
joelpittet’s picture

Status: Needs review » Reviewed & tested by the community

Returning to RTBC glory

joelpittet’s picture

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

Putting back to 8.4.x due to it being a bug fix.

gnuget’s picture

#97 no longer applies because #2864088: Convert web tests to browser tests for shortcut module was commited, so I just rerolled the patch.

xjm’s picture

Status: Reviewed & tested by the community » Needs work

I finally had a chance to sit down and review this patch. I was a bit hesitant about the proposed resolution, but after more than a month I've not thought of a better way to do this, and it definitely resolves the issue. The presentation to the user is also fine; it was just the bit of mucking with the semantics of the element that gave me pause. And @andrewmacpherson has already reviewed and it sounds like we are okay on the accessibility front now.

The very thorough manual testing demonstrates how well the fix works; thank you so much for providing the screenshots.

There's one thing I think we need to change with the tests (which are really thorough which is great to see).

+++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
@@ -62,31 +69,152 @@ public function testFieldUI() {
+    // Test the displaying of help texts for the link field.
+    $test_cases = [];
+
+    // There are many combinations of field settings: where the description
+    // should show: variation on internal, external, both; cardinality (where
+    // the fieldset is hidden or used); and link text shown (required or
+    // optional) or disabled. There are two descriptions: field and URL help
+    // text.
+    $cardinalities = [1, 2];
+    $title_settings = [
+      DRUPAL_DISABLED,
+      DRUPAL_OPTIONAL,
+    ];
+    $link_types = [
+      LinkItemInterface::LINK_EXTERNAL,
+      LinkItemInterface::LINK_GENERIC,
+      LinkItemInterface::LINK_INTERNAL,
+    ];
+
+    // Test all variations of link types on all cardinalities.
+    foreach ($cardinalities as $cardinality) {
+      foreach ($link_types as $link_type) {
+        // Now, test this with both the title enabled and disabled.
+        foreach ($title_settings as $title_setting) {
+          // Test both empty and non-empty labels.
+          foreach ([TRUE, FALSE] as $label_provided) {

So, this sort of thing is what data providers are made for. The good news is that LinkFieldUITest is already a BTB test, so we can use one! So I think we can refactor the test to use a data provider (really they're the first thing that got me excited about PHPUnit a couple years ago), and then we are good to go.

This isn't actually a string change -- the strings are already defined -- it's just a small UI change and a change to a render array. Typically those changes are minor-only, so the branch change in #99 isn't really correct.

However, since it's a clear UX and a11y bugfix with the only disruption being to the link element's render array, I feel comfortable backporting this during the release candidate phase if needed.

Very sorry for the long wait time; I know this one didn't get the feedback it deserved during the alpha and beta phases.

xjm’s picture

Title: Fix regression in the link widget where help text does not show. » Fix regression in the link widget where help text does not show
gnuget’s picture

Status: Needs work » Needs review
FileSize
12.21 KB
6.69 KB

Ok, new patch using a Data Provider, but I have doubts:

  1.     // With the old patch: 
        Testing Drupal\Tests\link\Functional\LinkFieldUITest
        .
        Time: 14.7 seconds, Memory: 8.00MB
    
         OK (1 test, 65 assertions)
    
         // With the new patch:
         Testing Drupal\Tests\link\Functional\LinkFieldUITest
         ........................
         Time: 3.95 minutes, Memory: 8.00MB
    
         OK (24 tests, 352 assertions)
      

    Using the data provider executes the whole test per test_case, making it way slower than before, In my computer it was ~15 seconds with the previous patch and now it takes ~4 minutes, is this expected and ok?

  2.     Testing Drupal\Tests\link\Functional\LinkFieldUITest
        F
    
        Time: 3.38 seconds, Memory: 8.00MB
    
        There was 1 failure:
    
         1) Warning
         The data provider specified for Drupal\Tests\link\Functional\LinkFieldUITest::testFieldUI is invalid.
         Use of undefined constant DRUPAL_DISABLED - assumed 'DRUPAL_DISABLED'
        

    It seems that the data providers are executed before to include all the files, so it fails whenever I use a constant and that is why in my patch I didn't use them in the data provider, this makes me wonder if this is ok or is there a good way to use constants in a Data Provider?

- David

Sinan Erdem’s picture

I have tested the patch (cleared cache etc) but the problem with it is both the default help text and manually entered help text are visible now. Attaching screenshots.

DuaelFr’s picture

@Sinan ErdemThank you for your review!
The thing is that showing the default help text is needed because we cannot ask the site builder to know what this text is and to include its content in they own help text. What you are describing is precisely what we are trying to introduce with this patch, so it's perfectly working ;)

Sinan Erdem’s picture

I didnt know that, sorry.

Anyway, IMO, the help text should be easily overridable, because this default help text aims mostly site builders. Normal users would need better, site-specific descriptions. In my case, I want to write that "The link should resemble https://www.linkedin.com/in/YOURNAME" which already contains the information that the link is external.

Lendude’s picture

@gnuget yeah setup() is run for each item in the dataprovider, so doing this in a BTB test takes a HUGE hit on speed. So unless you need a fresh install for each item, it's probably better not to use it.

But I agree with xjm that it's a great pattern to use, but how about we sorta follow that pattern but skip the setup? Patch does something like that.

gnuget’s picture

Thanks for your help, Lendude.

I just restored the constants in this patch and removed an unused variable.

pfrenssen’s picture

I agree it's not a good idea to use data providers in functional tests due to the enormous slowdown they cause. In unit tests this is not a problem, and also not in kernel tests if there is only little data to test, but if we are doing functional tests with a lot of data we shouldn't use them. Adding multiple minutes to every single test run on the bot is a poor tradeoff for the luxury of being able to use this new feature.

It is an accepted pattern in core to run multiple slow tests in a single setup without data providers to speed up the test runs, see for example EntityTranslationTest and MenuRouterTest.

pfrenssen’s picture

Status: Needs review » Needs work

Reviewed the patch, this is getting very close to being perfect again, found some nitpicks:

  1. +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
    @@ -31,6 +35,27 @@ class LinkFieldUITest extends BrowserTestBase {
    +  /**
    +   * A user that should see the help texts.
    +   *
    +   * @var \Drupal\user\Entity\User
    +   */
    +  protected $helpTextUser;
    

    Maybe move this property underneath the $adminUser property to keep them together.

  2. +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
    @@ -39,22 +64,94 @@ protected function setUp() {
         $this->drupalLogin($this->adminUser);
    

    This call to $this->drupalLogin() is not needed, at the start of the test the user is already logged in.

  3. +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
    @@ -39,22 +64,94 @@ protected function setUp() {
    +    $this->helpTextUser = $this->drupalCreateUser(['create ' . $this->secondContentType->id() . ' content']);
    

    Very minor remark, I would move this up a few lines so it sits underneath the other user that is created.

  4. +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
    @@ -39,22 +64,94 @@ protected function setUp() {
    +            yield [
    +              $cardinality,
    +              $link_type,
    +              $title_setting,
    +              $label_provided ? $label : '',
    +            ];
    

    This yield is very cool!

  5. +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
    @@ -39,22 +64,94 @@ protected function setUp() {
    +   * @param int $cardinality
    +   * @param $link_type
    +   * @param int $title
    +   * @param string $label
    

    This documentation is incomplete. The descriptions are missing, as well as the type hint of the second argument.

  6. +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
    @@ -62,31 +159,94 @@ public function testFieldUI() {
    +    // Also assert that the description we made is here, no matter what the
    +    // cardinality or link setting.
    

    I would rewrite this "no matter what" to "regardless of"

gnuget’s picture

Status: Needs work » Needs review
FileSize
13.56 KB
2.74 KB

New patch, this should address all the points mentioned in #111

I just have a doubt about the $link_type type hint, that argument is an hexadecimal number (see LinkItemInterface) but accord with the Drupal's documentation

Data types can be primitive types (int, string, etc.), complex PHP built-in types (array, object, resource), or PHP classes.

But a hexadecimal number is not a primitive type accord with the php's documentation.

And I think is not a PHP built-in type nor a PHP class... so I'm not so sure what put there, for now, I put int, I can change it if necessary.

patch attached.

Thanks for the reviews!

pfrenssen’s picture

Status: Needs review » Reviewed & tested by the community

Patch looks perfect now, thanks for the quick fix!

But a hexadecimal number is not a primitive type accord with the php's documentation.

And I think is not a PHP built-in type nor a PHP class... so I'm not so sure what put there, for now, I put int, I can change it if necessary.

That's completely correct!

An integer is any "whole" number without a fraction. It doesn't matter in which numeric system it has been defined. When a variable is assigned an integer (or a boolean) PHP stores it internally as a "long" data type, inside a "zval" object. It doesn't matter whether the original value was decimal, hexadecimal, binary or octal. In the end it's just a number that is stored in 64 bits of memory.

Here is how you can see how PHP handles hexadecimal values:

$ php -a
Interactive shell

php > var_dump(gettype(0x0f));
string(7) "integer"

php > var_dump(0x08 === 8);
bool(true)

If you are interested in how PHP deals with numbers I can highly recommend this blog post: Internal value representation in PHP 7.

xjm’s picture

Bummer about the test run time. I thought browser tests were significantly faster than web tests... oh well.

xjm’s picture

Status: Reviewed & tested by the community » Needs review
  1. +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
    @@ -45,16 +72,89 @@ protected function setUp() {
    -    $label = $this->randomMachineName();
    -    $field_name = Unicode::strtolower($label);
    -    $this->fieldUIAddNewField($type_path, $field_name, $label, 'link');
    +    $field_label = $this->randomMachineName();
    
    @@ -62,31 +162,94 @@ public function testFieldUI() {
    +      $this->assertNoFieldContainsRawText($field_name, $expected_help_texts[LinkItemInterface::LINK_EXTERNAL]);
    +      $this->assertNoFieldContainsRawText($field_name, $expected_help_texts[LinkItemInterface::LINK_GENERIC]);
    

    So, the randomMachineName() exists in HEAD. However, we're now adding an assertNoSomething(). That's a combination that can cause random test failures when the random-thing matches the assert-no-thing.

    In this case, none of the texts we're asserting the absence of are eight characters long, so I think it's okay for this to go in as-is, and I don't want to delay this issue further since I already did so with the data provider distraction. However, for future reference, we should be avoid random usage because of the risk of random failures. Edit: That's discussed in #2571183: Deprecate random() usage in tests to avoid random test failures. However, another concern related to that...

  2. +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
    @@ -62,31 +162,94 @@ public function testFieldUI() {
    +  protected function assertFieldContainsRawText($field_name, $text) {
    +    $this->assertTrue((bool) preg_match('/' . preg_quote($text, '/') . '/ui', $this->getFieldHtml($field_name)));
    +  }
    ...
    +  protected function assertNoFieldContainsRawText($field_name, $text) {
    +    $this->assertFalse((bool) preg_match('/' . preg_quote($text, '/') . '/ui', $this->getFieldHtml($field_name)));
    +  }
    ...
    +  protected function getFieldHtml($field_name) {
    +    $css_id = Html::cleanCssIdentifier("edit-$field_name-wrapper");
    +    return $this->xpath("//div[@id='$css_id']")[0]->getHtml();
       }
    

    This is a whole lot of abstraction, plus an xpath, plus coupling the test to CSS and markup that may change in the future. It's also fragile... presumably these texts should exist nowhere on the page, but if we change the markup and use the negative assertions so specifically tied to xpath, they will give false positives if/when the markup changes in the future.

    It looks like this was added in #82 by @pfrenssen:

    Used the field API to create the test fields. I also restored the tests for the absence of non-configured help texts by using XPath to pinpoint exact fields in the document.

    But that's not clear to me why it merits all the extra code nor the risk of false positives in the future.

This issue does not need further manual testing unless the solution also changes; all the recent changes are only to automated tests. :) Thanks!

pfrenssen’s picture

I think testing both the presence and absence of the different messages is worthwhile since we have options to show them or not. If we only test if they are present when they should then we might have a bug in the future where the wrong messages are showing up and we won't know about it.

I agree fully on the random naming, but matching on the field wrappers is fine I think. The base field templates are not likely to change in core because it would break the custom theming and JS of all websites that use forms. The Form system itself uses XPath and the "edit-" prefix in their tests to identify fields and field wrappers, so we should be pretty OK. See for example the tests in \Drupal\Tests\system\Functional\Form\ElementTest, they are very similar.

Would you be OK if we hardcode unique field names in the test instead of using random names? I think this would also mitigate the risk of tests breaking due to collisions with CSS IDs that may be added in the markup in the future.

pfrenssen’s picture

Updated the patch to use predictable machine names, to reduce the chance of random failures. Also updated the XPath call to use an argument for the dynamic part.

pfrenssen’s picture

FileSize
13.67 KB
687 bytes

I just had a final look at the interdiff and I noticed that we are testing if the field is contained in a <div> element. I somehow missed this before. This is brittle and likely to change to a more specific HTML tag in the future. We should only check the ID.

gnuget’s picture

This looks RTBC to me.

Does it need something else?

Thanks for your help pfrenssen.

DuaelFr’s picture

The patch from #118 looks RTBC'able to me. After an extensive review, I have two nitpicks, fixed in the attached patch, though:

  1. +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
    @@ -45,16 +71,91 @@ protected function setUp() {
    +    $field_label = $this->randomMachineName();
    

    As @xjm told above, we should not use random strings to avoid random failures. As I had to work on the patch anyway (see below), I changed this to a predictable string.

  2. +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
    @@ -62,31 +163,94 @@ public function testFieldUI() {
    +    if (!empty($test_case['label'])) {
    +      $this->assertFieldContainsRawText($field_name, $test_case['label']);
    +    }
    

    $test_case is never ever set so I removed this dead code to avoid confusion.

If the bot goes green again, one should mark this issue RTBC, I think.

gnuget’s picture

Status: Needs review » Reviewed & tested by the community

Thanks!

Gábor Hojtsy’s picture

Version: 8.4.x-dev » 8.5.x-dev
Gábor Hojtsy’s picture

Status: Reviewed & tested by the community » Needs work

Reviewed the patch and even more so the discussion above, which was plentiful to say the least. This issue is a whos-who of Drupal :) All the concerns raised recently have been resolved and this approach had signoff and positive feedback from subsystem maintainers above as well.

I found this little issue with the latest changes though:

+++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php
@@ -208,11 +208,6 @@ public function runFieldUIItem($cardinality, $link_type, $title, $label, $field_
     }
-    // Also assert that the description we made is here, regardless of the
-    // cardinality or link setting.
-    if (!empty($test_case['label'])) {
-      $this->assertFieldContainsRawText($field_name, $test_case['label']);
-    }

This seems to be a refactoring artifact, the method does have a $label argument and the method is invoked on multiple test cases. So this was meant to be $label apparently.

gnuget’s picture

Status: Needs work » Needs review
FileSize
858 bytes
13.65 KB

Thanks a lot, Gábor.

New patch attached.

Lendude’s picture

Status: Needs review » Reviewed & tested by the community

@Gábor Hojtsy nice catch!

Feedback has been addressed, back to RTBC.

  • Gábor Hojtsy committed ee5ad87 on 8.4.x
    Issue #2421001 by eiriksm, pfrenssen, YesCT, DuaelFr, gnuget, StryKaizer...
Gábor Hojtsy’s picture

Status: Reviewed & tested by the community » Fixed

I did not identify this before, failed as I wanted to commit it. Fixed before commit.

PHPCS: core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php passed

FILE: ...mmits/core/modules/link/tests/src/Functional/LinkFieldUITest.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 74 | ERROR | [x] Expected 1 space after FOREACH keyword; 0 found
----------------------------------------------------------------------

Thanks all for working on this and trying different approaches!

  • Gábor Hojtsy committed ffb29bb on 8.4.x
    Revert "Issue #2421001 by eiriksm, pfrenssen, YesCT, DuaelFr, gnuget,...

  • Gábor Hojtsy committed 17e2ab9 on 8.5.x
    Issue #2421001 by eiriksm, pfrenssen, YesCT, DuaelFr, gnuget, StryKaizer...

Status: Fixed » Closed (fixed)

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

botanic_spark’s picture

@Gábor Hojtsy Why is this reverted on 8.4?