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

E2E tests setup with laravel dusk #234

Merged
merged 50 commits into from
Sep 8, 2023

Conversation

vsergiu93
Copy link
Contributor

@vsergiu93 vsergiu93 commented Aug 30, 2023

This PR does the following:

  1. Sets up Laravel Dusk with Sail
  2. Add E2E tests for home page
  3. Add E2E tests for login
  4. Add E2E tests for register
  5. Add some guidelines on how to get started with this setup in README.md
  6. Sets up github action to run Laravel Dusk tests

Closes #231

@vsergiu93 vsergiu93 marked this pull request as draft August 30, 2023 23:36
@brendt
Copy link
Owner

brendt commented Aug 31, 2023

Wow, this looks great! Anything you want my input on?

@vsergiu93
Copy link
Contributor Author

vsergiu93 commented Aug 31, 2023

@brendt Thanks. Yes feel free to suggest improvements to what I have so far.
Right now there is at least one thing that is problematic with this PR, that is making it work on apple silicon, here is the link to the official sail documentation about Laravel Dusk, as we can see there are two distinct images that need to be used based on what cpu type one has, ideally we would like to make this as seamless as possible, maybe we can make the docker image dynamic with some env variable. I haven't tried the solution.

I am open to solutions on how to solve the selenium docker image issue, not sure if this PR should be blocked by this issue though.

What I would like to do in this PR is the following:

  • setup laravel dusk with sail (partially done, see the issue described above)
  • setup github workflow for laravel dusk ( this is done, ready for some feedback)
  • add e2e tests for homepage (partially done)
  • add e2e tests for login
  • add e2e tests for register
  • add some documentation about running laravel dusk with sail

@joshbonnick
Copy link
Contributor

Can we add an @dusk directive instead of adding id attributes to the HTML just for testing?

Blade::directive('dusk', function ($expression) {
    if ( ! app()->isProduction()) {
        return "<?php echo 'dusk=\"' . $expression . '\"'; ?>";
    }

    return null;
});

Then in the blade files <div class="some-classes" @dusk('main-header')></div>. The directive will add the dusk attribute to elements but not pollute the HTML in production.

@vsergiu93
Copy link
Contributor Author

vsergiu93 commented Aug 31, 2023

@joshbonnick Honestly I'm ok with any suggestion, the way I started to add tests was to use this page objects which also allows you to map some css selectors to some dusk specific selector.

Honestly I'm not sure what would be the best way to handle this. But I can say I didn't think of adding a custom blade directive.

I have to admin that it is the first time writing laravel dusk tests, so not really that up to date with best practices and popular patterns.

@joshbonnick
Copy link
Contributor

Right now there is at least one thing that is problematic with this PR, that is making it work on apple silicon, here is the link to the official sail documentation about Laravel Dusk, as we can see there are two distinct images that need to be used based on what cpu type one has, ideally we would like to make this as seamless as possible, maybe we can make the docker image dynamic with some env variable. I haven't tried the solution.

version: '3'

services:
  selenium:
    image: ${SELENIUM_IMAGE}
    extra_hosts:
      - 'host.docker.internal:host-gateway'
    volumes:
      - '/dev/shm:/dev/shm'
    networks:
      - sail

In the dusk env file

SELENIUM_IMAGE=selenium/standalone-chromium

You should also add BCRYPT_ROUNDS to the Dusk env file. Which will speed up tests which hash passwords, further explanation here in 'Password hash rounds'

BCRYPT_ROUNDS=4

@vsergiu93
Copy link
Contributor Author

vsergiu93 commented Sep 2, 2023

Can we add an @dusk directive instead of adding id attributes to the HTML just for testing?

Blade::directive('dusk', function ($expression) {
    if ( ! app()->isProduction()) {
        return "<?php echo 'dusk=\"' . $expression . '\"'; ?>";
    }

    return null;
});

Then in the blade files <div class="some-classes" @dusk('main-header')></div>. The directive will add the dusk attribute to elements but not pollute the HTML in production.

@joshbonnick I tried to add this, but I don't think this is valid in blade, I mean you can't use the directive in the way you suggested, maybe I'm just not familiar with this. In any case I not sure if we should bother that much with removing the dusk selector in prod.

@brendt do you have any opinions/ideas/suggestions on this?

@vsergiu93
Copy link
Contributor Author

vsergiu93 commented Sep 2, 2023

In the dusk env file

SELENIUM_IMAGE=selenium/standalone-chromium

Thanks, I added this, it is working, but just one thing, it needs to be added to .env file, I think sail looks at .env when you run the commands like sail up -d

You should also add BCRYPT_ROUNDS to the Dusk env file. Which will speed up tests which hash passwords, further explanation here in 'Password hash rounds'

BCRYPT_ROUNDS=4

I added this, indeed I saw some small improvements in test run time, thanks for suggesting it.


namespace PHPSTORM_META {

override(\Laravel\Dusk\Browser::visit(0), type(0));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a weird trick to improve a bit the developer experience with page methods.

Basically with this PhpStorm doesn't complain about undefined method, when doing visit(new SomePage) followed by some methods define in SomePage, here is an example from LoginPageTest:
image

@brendt please let me know how you feel about this, it is a bit unconventional and I wasn't able to find a better way a more general way of improving the page methods.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm totally fine with it. I use the Laravel Idea plugin, which I think supports this out of the box, but I'm fine adding it via phpstorm meta as well 👍

Copy link
Contributor Author

@vsergiu93 vsergiu93 Sep 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use Laravel Idea plugin as well, but I wasn't able to make it work only with that.

@vsergiu93
Copy link
Contributor Author

not really sure what happened with github history, we can try to fix it, I somehow messed up when I tried to sync the fork .

try rebasing your branch from main locally, and push force the branch

I think it is better now thanks, need to be a bit more careful in the future with fork syncing

@vsergiu93
Copy link
Contributor Author

@brendt Do I need to do anything special to get Qodana to pass? :)

<div
class="container flex justify-between text-white gap-4 items-center m-auto relative px-2"
x-data="{ open: false }"
>
<div class="dark:text-gray-200 text-lg md:text-xl font-bold relative z-20">
<div dusk="header-logo" class="dark:text-gray-200 text-lg md:text-xl font-bold relative z-20">
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we use @dusk('header-logo). I kind of thought Laravel had this built-in, but apparently it hasn't? 🤔

The idea would be that @dusk will only write the x-dusk attribute when not in production, so that we don't have additional dusk attributes on the real site.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'll try to look more into this, I haven't found anything here https://laravel.com/docs/10.x/dusk#dusk-selectors

@brendt
Copy link
Owner

brendt commented Sep 6, 2023

I tried to add this, but I don't think this is valid in blade, I mean you can't use the directive in the way you suggested, maybe I'm just not familiar with this. In any case I not sure if we should bother that much with removing the dusk selector in prod.

Maybe we should just do it via a function?

function dusk(string $name): ?HtmlString
{
    if (app()->isProduction()) {
        return null;
    }
    
    return new HtmlString($name);
}
<div {{ dusk('header-logo') }} 

(I didn't test this, it could have syntax errors)

@brendt
Copy link
Owner

brendt commented Sep 6, 2023

Apart from the dusk attribute, this looks all super nice! I'm happy to merge it when the attribute thing has been fixed.

use Illuminate\Support\HtmlString;

if (! function_exists('dusk')) {
function dusk(string $selector): ?HtmlString
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brendt I tried with this helper function, it works on html elements but not on blade components :(.
This is the error I get when I attempt to use this helper on a blade component.

        <x-home.title {{dusk('test')}}>
            {{ __('Open RFCs') }}
        </x-home.title>

image

Not really sure how else to approach this at this point :), I'm willing to work more on this but I would need some ideas/suggestions.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I think the dusk function should be move to the component itself, no? Otherwise you'd have to repeat it every time you add the component.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, but we need to keep this limitation in mind, if that's ok, I can try to use it and see how it goes.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's ok :)

@vsergiu93
Copy link
Contributor Author

@brendt when you have time please have another look

@brendt brendt merged commit 908cb51 into brendt:main Sep 8, 2023
3 checks passed
@brendt
Copy link
Owner

brendt commented Sep 8, 2023

Awesome!

@vsergiu93 vsergiu93 deleted the front-end-tests-setup-dusk branch September 8, 2023 19:44
@SerhiiCho SerhiiCho added the tests Issues and PRs related to adding, removing or modifying tests label Sep 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tests Issues and PRs related to adding, removing or modifying tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Frontend tests/Dusk tests
5 participants