Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add data-dusk DOM hooks (for less brittle tests) #343

Merged
merged 2 commits into from
Aug 28, 2017

Conversation

calebporzio
Copy link
Contributor

TL;DR;

// before
<div class="post-panel m-b-lg"><p>Some Post Title</p></div>
$browser->click('.post-panel.m-b-lg p');

// after
<div class="post-panel m-b-lg"><p data-dusk="post-title">Some Post Title</p></div>
$browser->click('@post-title');

Depending on prone-to-change ui classes in Dusk tests like div div div.campaign-panel--large ul li can make for really brittle acceptance tests.

There is a slightly better solution from the jquery days: .js-campaign-title

Something like .dusk-campaign-title would do the trick, but I personally don't like muddying up my class lists.

I've come up with a solution that I think is pretty BA: <li class="active" data-dusk="campaign-title">...

My selectors in dusk now look like: $browser->click('[data-dusk="campaign-title"]') - which works but makes me a little sad. I've used macros like $browser->hook('campaign-title') in the past, but things like that always feel hidden to me.

I propose leveraging the existing '@campaign-title' => 'div div.campaign-panel...' idiom in Dusk and creating a fallback for data-dusk

Now, anywhere in your DOM you can add data-dusk="something", and it is immediately available via $browser->click('@something')

It's ballsy, I know - but people seem to really dig it.

@mattstauffer
Copy link
Member

I don't have it in front of me but I think modern browsers may not need the data- prefix, which means you could simplify this to duskhook="title" or something simpler. Not at my computer but worth checking out. Love this idea though!

@calebporzio
Copy link
Contributor Author

Interesting @mattstauffer - that scares me a little - but less if you wrap these data-dusk hooks in something that hides them from production (I think that was Adam's suggestion a while back) - like a blade directive:

<li class="campaign__name" @dusk('campaign-name')></li>

@jakebathman
Copy link

I like the @dusk() idea, and generally think cluttering up the class space with these non-fragile test classes is crummy. This would be great to get that out of the production DOM. 👍

@calebporzio
Copy link
Contributor Author

@jakebathman - thanks for the input Jake. I agree - if this goes through, I'll PR a blade directive, or at least tweet a macro or something.

@jakebathman
Copy link

Core could definitely use a pre-defined directive to close the loop on this kind of testing pattern. Good stuff.

@mattstauffer
Copy link
Member

@calebporzio Curious: What's scaring about dropping the data- prefix? It's basically like Angular or Vue directives.

@calebporzio
Copy link
Contributor Author

calebporzio commented Aug 24, 2017

@mattstauffer - good call - maybe I like data-dusk because people are more familiar with what data attributes are used for? Idk

@damiani
Copy link
Contributor

damiani commented Aug 24, 2017

Particularly if coupled with an optional @dusk Blade directive that hides the value in production, I like @mattstauffer's idea of ditching the data- prefix, but it seems cleaner to just calling it dusk rather than duskhook so there's a parallel between both implementations.

So you'd either have:

<li class="campaign__name" @dusk('campaign-name')></li>

or

<li class="campaign__name" dusk="campaign-name"></li>

both of which could be referenced by

$browser->click('@campaign-name')

@DanielCoulbourne
Copy link

I agree with Keith. @dusk('campaign-name') speaks my language.

@calebporzio
Copy link
Contributor Author

I like that: dusk="campaign-name" and @dusk="campaign-name"

@taylorotwell
Copy link
Member

I like it combined with the Blade stuff.

@calebporzio
Copy link
Contributor Author

@taylorotwell - I changed the implementation to look for dusk="something" instead of data-dusk="something"

However, I couldn't think of a way to add a blade directive seeing as how the DuskServiceProvider typically isn't loaded in production. The only options I could think of:

  • separate service provider
  • register the directive in laravel/framework seeing as the directive doesn't actually depend on having laravel/dusk installed
  • Have users always register DuskServiceProvider in 2.0 and conditionally load the "unsafe for production" routes inside the service provider.

The best option IMO is just to ship it with framework 5.5 - I'm interested to hear your thought though, hoping you'll say: "why don't you just..." and I'll go "aha!"

  • Thanks

@jakebathman
Copy link

I had always assumed it’d be part of laravel/framework and just render the dusk=“foo” attributes. Maybe I wasn’t thinking too deeply on it, though?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants