laravel / dusk

Laravel Dusk provides simple end-to-end testing and browser automation.
https://laravel.com/docs/dusk
MIT License
1.87k stars 320 forks source link

Failed to load assets in Sail #1091

Closed damms005 closed 5 months ago

damms005 commented 5 months ago

Dusk Version

8.0.0

Laravel Version

10.48.2

PHP Version

8.2.8

PHPUnit Version

10.5.12

Database Driver & Version

mysql Ver 8.0.32 for Linux on x86_64 (MySQL Community Server - GPL)

Description

Assets are not loaded when running Dusk tests.

test('homepage', function () {
    $student = addStudent();

    $this->browse(function (Browser $browser) use ($student) {
        $browser->visit(route('homepage'))
            ->loginAs($student->userModel->id)
            ->storeConsoleLog('error-log') // --> debug purposes
            ->assertSee('Something');
    });
});

Console log output

[
    {
        "level": "SEVERE",
        "message": "http:\/\/tims.local\/build\/assets\/app-931911db.css - Failed to load resource: net::ERR_CONNECTION_REFUSED",
        "source": "network",
        "timestamp": 1710742000259
    },
    {
        "level": "SEVERE",
        "message": "http:\/\/tims.local\/new-frontend\/assets\/js\/jquery.min.js - Failed to load resource: net::ERR_CONNECTION_REFUSED",
        "source": "network",
        "timestamp": 1710742000259
    },
    {
        "level": "SEVERE",
        "message": "http:\/\/tims.local\/build\/assets\/main-f5d540ec.js - Failed to load resource: net::ERR_CONNECTION_REFUSED",
        "source": "network",
        "timestamp": 1710742000259
    },
    {
        "level": "SEVERE",
        "message": "http:\/\/tims.local\/build\/assets\/main-97df0a5b.js - Failed to load resource: net::ERR_CONNECTION_REFUSED",
        "source": "network",
        "timestamp": 1710742000259
    },
    {
        "level": "SEVERE",
        "message": "http:\/\/tims.local\/favicon-32x32.png - Failed to load resource: net::ERR_CONNECTION_REFUSED",
        "source": "network",
        "timestamp": 1710742000774
    },
    {
        "level": "SEVERE",
        "message": "http:\/\/tims.local\/favicon-16x16.png - Failed to load resource: net::ERR_CONNECTION_REFUSED",
        "source": "network",
        "timestamp": 1710742000774
    }
]

docker-compose.yml

# For more information: https://laravel.com/docs/sail
version: '3'
services:
    laravel.test:
        build:
            context: ./docker/8.2
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: tims-laravel-sail-php8.2/app
        extra_hosts:
            - 'host.docker.internal:host-gateway'
        ports:
            - '${APP_PORT:-80}:80'
        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
            XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
            XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
            PHP_CLI_SERVER_WORKERS: 10
        volumes:
            - '.:/var/www/html'
        networks:
            - sail
        depends_on:
            - mysql
            - selenium
    mysql:
        image: 'mysql/mysql-server:8.0'
        ports:
            - '${FORWARD_DB_PORT:-3306}:3306'
        environment:
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ROOT_HOST: "%"
            MYSQL_DATABASE: '${DB_DATABASE}'
            MYSQL_USER: '${DB_USERNAME}'
            MYSQL_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ALLOW_EMPTY_PASSWORD: 1
        volumes:
            - 'sail-mysql:/var/lib/mysql'
            - './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
        networks:
            - sail
        healthcheck:
            test: ["CMD", "mysqladmin", "ping", "-p${DB_PASSWORD}"]
            retries: 3
            timeout: 5s
    selenium:
      image: 'selenium/standalone-chrome'
      extra_hosts:
        - 'host.docker.internal:host-gateway'
      volumes:
          - '/dev/shm:/dev/shm'
      networks:
          - sail
networks:
    sail:
        driver: bridge
volumes:
    sail-mysql:
        driver: local

Steps To Reproduce

driesvints commented 5 months ago

Heya, thanks for reporting.

We'll need more info and/or code to debug this further. Can you please create a repository with the command below, commit the code that reproduces the issue as one separate commit on the main/master branch and share the repository here? Please make sure that you have the latest version of the Laravel installer in order to run this command. Please also make sure you have both Git & the GitHub CLI tool properly set up.

laravel new bug-report --github="--public"

Please do not amend and create a separate commit with your custom changes. After you've posted the repository, we'll try to reproduce the issue.

Thanks!

damms005 commented 5 months ago

Thank you. I am on it.

However, I should mention that when I ran laravel new bug-report --github="--public"

I got the following warning in the command output

WARN  Make sure the "gh" CLI tool is installed and that you're authenticated to GitHub. Skipping...

However, running gh --version outputs gh version 2.45.0 (2024-03-04), confirming that I have gh installed, as shown in the screenshot below.

image

driesvints commented 5 months ago

@damms005 can't help you with that I'm afraid.. please just create the repo manually in this case and commit any custom things separately.

damms005 commented 5 months ago

Thanks @driesvints

Having tried to unsuccessfully reproduce it in Laravel v11 and latest v10, I am now convinced that this is a problem with my local Docker setup. I think I've got my Docker environment messed up somehow, and it somehow only affects this project.

I am no Docker expert, so I'll pass on this. However, I managed to get a workaround, and sharing here should an alien from space hit this issue, too:

Workaround

Lary of Laracast gave me a hint that helped me with a temporary fix:

  1. Check Network Access: Verify that the Selenium service can access the laravel.test service. Since they are both in the same network (sail), they should be able to communicate without any issues.

With this nudge, I swapped APP_URL manually because no other solution I could think of worked. I tried:

So the below hot-swap monkey-patch is my workaround: tests/DuskTestCase.php:

protected static function ensureLaravelServiceIsAppUrl()
{
    $appEnvFilePath = __DIR__  . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '.env';
    $duskEnvFilePath = __DIR__  . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '.env.dusk.local';

    $laravelServiceName = 'laravel.test'; // -> service name in docker-compose.yml
    $appUrlForDusk = "http://{$laravelServiceName}";

    $contentOfEnv = file_get_contents($appEnvFilePath);
    $contentOfDuskEnv = file_exists($duskEnvFilePath)
        ? file_get_contents($duskEnvFilePath)
        : '';

    $appUrlInContentOfDuskEnv = preg_match('/APP_URL=(.*)/', $contentOfDuskEnv, $duskEnvMatches);

    if (!$appUrlInContentOfDuskEnv) {
        return self::copyEnvAndWriteLaravelServiceNameToDuskEnv($duskEnvFilePath,  $appUrlForDusk,  $contentOfEnv);
    }

    if ($duskEnvMatches[1] !== $appUrlForDusk) {
        return self::copyEnvAndWriteLaravelServiceNameToDuskEnv($duskEnvFilePath,  $appUrlForDusk,  $contentOfEnv);
    }
}

protected static function copyEnvAndWriteLaravelServiceNameToDuskEnv(string $duskEnvFilePath, string $appUrlForDusk, string $contentOfEnv)
{
    $updatedContentOfEnv = preg_replace('/APP_URL=(.*)/', "APP_URL={$appUrlForDusk}", $contentOfEnv);
    file_put_contents($duskEnvFilePath, $updatedContentOfEnv);
}

The finally, call it if running sail:

/**
 * Prepare for Dusk test execution.
 */
#[BeforeClass]
public static function prepare(): void
{
    if (!static::runningInSail()) {
        static::startChromeDriver();
    }

    if (static::runningInSail()) {
        self::ensureLaravelServiceIsAppUrl();
    }
}