avh4 / elm-program-test

Test Elm programs
https://elm-program-test.netlify.com/
MIT License
93 stars 27 forks source link

ProgramTest.clickLink does not work if you have no text #158

Closed allanderek closed 2 years ago

allanderek commented 2 years ago

I have a situation in which I have an image (actually an svg which is the entire link, with no text nodes, corresponding to something like:

Html.a
    [ Attributes.href ... ]
    [ Svg.svg [] [ Svg. ...] ]

If I attempt to use ProgramTest.clickLink "" url it doesn't work because the selector attempts to find a text node containing the empty string and fails because it doesn't find any text node at all.

I can solve this by adding an empty text node, as in:

Html.a
    [ Attributes.href ... ]
    [ Svg.svg [] [ Svg. ...]
    -- Added to satisfy ProgramText.clickLink
    , Html.text ""
    ]

This seems a little unsatisfactory. I guess a way to solve this would be to make the text argument to ProgramTest.clickLink a Maybe String. I guess the same applies to ProgramTest.clickButton. It would make the resulting code for the selector a little awkward, you would have to change this

findLinkTag =
            [ Selector.tag "a"
            , Selector.attribute (Html.Attributes.href href)
            , Selector.containing [ Selector.text linkText ]
            ]

into something like:

commonTagSelectors =
            [ Selector.tag "a"
            , Selector.attribute (Html.Attributes.href href)
             ]

findLinkTag =
      case mLinkText of
           Nothing ->
               commonTagSelectors
           Just linkText ->
                List.append
                      commonTagSelectors
                      [ Selector.containing [ Selector.text linkText ] ]

Or, since there doesn't seem to be a Selector.matchAnything

findLinkTag =
            [ Selector.tag "a"
            , Selector.attribute (Html.Attributes.href href)
            , case mLinkText of
                  Nothing ->
                      Selector.all []
                  Just linkText -> 
                       Selector.containing [ Selector.text linkText ]
            ]

As I say, there is a workaround, it just feels a little unsatisfactory.

avh4 commented 2 years ago

Thanks for the report!

The ideal I'm trying to go for in elm-program-test is that the built-in functions (clickLink, clickButton, etc) should rely on things visible to accessibility tools.

So in this case, the first argument to clickLink would ideally be the alt text for the image/link. I'm a bit rusty on best practices there, but I think both putting a <title> in the <svg>, or putting aria-label on the <a> are accepted ways to make the link accessible.

However, I don't think clickLink currently supports either of those accessibility patterns (though I think I could probably add those pretty quickly if you're open to going that way).

For folks that aren't able to add accessibility, simulateDomEvent is meant to be the fallback. Finding and simulating Test.Html.Event.click on your link element ideally should trigger the link clicking mechanism for <a href> tags, though I think that ideal is also currently unimplemented.

allanderek commented 2 years ago

Thanks for the response. In my particular case, the SVG is actually created from an icon library: https://package.elm-lang.org/packages/feathericons/elm-feather/latest/ So I would struggle to change the actual SVG, but I could certainly place an aria-label on the <a> tag. That probably does seem correct.

If I understand correctly, then simulateDomEvent won't work, because there is no onClick handler attached to the link, so I believe you're correct to say that that ideal is currently unimplemented.

Just to be clear with the workaround I have implemented, this is not at all urgent for me.

avh4 commented 2 years ago

Published in https://package.elm-lang.org/packages/avh4/elm-program-test/3.7.0/ big thanks to @nunntom