Laravel Sail + Dusk + Selenium: Connection refused
Asked Answered
A

4

3

I have a Laravel with Sail and I want to make automated test with Laravel Dusk. I followed all the instructions in Dusk Documentation and Sail + Dusk Installation, but when I run the default test I receive this error mensage:

Tests\Browser\ExampleTest::testBasicExample
Facebook\WebDriver\Exception\WebDriverCurlException: Curl error thrown for http POST to /session with params: {"capabilities":{"firstMatch":[{"browserName":"chrome","goog:chromeOptions":{"args":["--disable-gpu","--headless","--no-sandbox","--window-size=1920,1080"]},"acceptInsecureCerts":true}]},"desiredCapabilities":{"browserName":"chrome","platform":"ANY","chromeOptions":{"args":["--disable-gpu","--headless","--no-sandbox","--window-size=1920,1080"]},"acceptInsecureCerts":true}}

Failed to connect to localhost port 4444: Connection refused

/var/www/html/vendor/php-webdriver/webdriver/lib/Remote/HttpCommandExecutor.php:333
/var/www/html/vendor/php-webdriver/webdriver/lib/Remote/RemoteWebDriver.php:136
/var/www/html/tests/DuskTestCase.php:69
/var/www/html/vendor/laravel/dusk/src/Concerns/ProvidesBrowser.php:218
/var/www/html/vendor/laravel/framework/src/Illuminate/Support/helpers.php:234
/var/www/html/vendor/laravel/dusk/src/Concerns/ProvidesBrowser.php:219
/var/www/html/vendor/laravel/dusk/src/Concerns/ProvidesBrowser.php:97
/var/www/html/vendor/laravel/dusk/src/Concerns/ProvidesBrowser.php:65
/var/www/html/tests/Browser/ExampleTest.php:21

But if execute the request in Insomnia it runs without any problem:

Insomnia request

Here is my docker-compose:

# For more information: https://laravel.com/docs/sail
version: '3'
services:
  laravel.test:
    build:
      context: ./vendor/laravel/sail/runtimes/8.0
      dockerfile: Dockerfile
      args:
        WWWGROUP: '${WWWGROUP}'
    image: sail-8.0/app
    ports:
      - '${APP_PORT:-80}:80'
    environment:
      WWWUSER: '${WWWUSER}'
      LARAVEL_SAIL: 1
    volumes:
      - '.:/var/www/html'
    networks:
      - sail
    depends_on:
      - mysql
      - redis
      - selenium
  selenium:
    image: 'selenium/standalone-chrome'
    volumes:
      - '/dev/shm:/dev/shm'
    networks:
      - sail
    ports:
      - 4444:4444
    #depends_on:
    #  - laravel.test
  mysql:
    image: 'mysql:8.0'
    ports:
      - '${DB_PORT}:3306'
    environment:
      MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
      MYSQL_DATABASE: '${DB_DATABASE}'
      MYSQL_USER: '${DB_USERNAME}'
      MYSQL_PASSWORD: '${DB_PASSWORD}'
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
    volumes:
      - 'sailmysql:/var/lib/mysql'
    networks:
      - sail
  redis:
    image: 'redis:alpine'
    ports:
      - '${REDIS_PORT}:6379'
    volumes:
      - 'sailredis:/data'
    networks:
      - sail
  # memcached:
  #     image: 'memcached:alpine'
  #     ports:
  #         - '11211:11211'
  #     networks:
  #         - sail
  mailhog:
    image: 'mailhog/mailhog:latest'
    ports:
      - 1025:1025
      - 8025:8025
    networks:
      - sail
networks:
  sail:
    driver: bridge
volumes:
  sailmysql:
    driver: local
  sailredis:
    driver: local

And my DuskTestCase

<?php

namespace Tests;

use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Laravel\Dusk\TestCase as BaseTestCase;

abstract class DuskTestCase extends BaseTestCase {
    use CreatesApplication;

    /**
     * Prepare for Dusk test execution.
     *
     * @beforeClass
     * @return void
     */
    public static function prepare() {
        if (!static::runningInSail()) {
            static::startChromeDriver();
        }
    }

    /**
     * Create the RemoteWebDriver instance.
     *
     * @return \Facebook\WebDriver\Remote\RemoteWebDriver
     */
    protected function driver() {
        $options = (new ChromeOptions)->addArguments([
            '--disable-gpu',
            '--headless',
            '--no-sandbox',
            '--window-size=1920,1080',
        ]);

        return RemoteWebDriver::create(
            'http://localhost:4444/wd/hub', DesiredCapabilities::chrome()->setCapability(
            ChromeOptions::CAPABILITY, $options
        )->setCapability('acceptInsecureCerts', TRUE)
        );
    }
}

I really don't know what I'm doing wrong. Sorry for my English, I'm brazillian.

Abbey answered 4/1, 2021 at 20:7 Comment(2)
Does uncommenting the #depends_on lines in your docker-compose do anything?Wooley
It returns me an error: ERROR: Circular dependency between laravel.test and selenium and redis ERROR: Circular dependency between selenium and redis and laravel.test ERROR: Circular dependency between redis and selenium and laravel.testAbbey
A
10

After many days I finally managed to solve my problem. Reading the Docker documentation I found that I can use the image name as a URL, so I switched to http://selenium:4444 and the tests worked perfectly!

Here are my new code:

<?php

namespace Tests;

use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Laravel\Dusk\TestCase as BaseTestCase;

abstract class DuskTestCase extends BaseTestCase {
    use CreatesApplication;

    /**
     * Prepare for Dusk test execution.
     *
     * @beforeClass
     * @return void
     */
    public static function prepare() {
        if (!static::runningInSail()) {
            static::startChromeDriver();
        }
    }

    /**
     * Create the RemoteWebDriver instance.
     *
     * @return \Facebook\WebDriver\Remote\RemoteWebDriver
     */
    protected function driver() {
        $options = (new ChromeOptions)->addArguments([
            '--disable-gpu',
            '--headless',
            '--no-sandbox',
            '--window-size=1920,1080',
        ]);

        return RemoteWebDriver::create(
            'http://selenium:4444/wd/hub', DesiredCapabilities::chrome()->setCapability(
            ChromeOptions::CAPABILITY, $options
        )->setCapability('acceptInsecureCerts', TRUE)
        );
    }
}

I hope I can help someone with the same problem!

Abbey answered 5/1, 2021 at 0:1 Comment(2)
Thank you for the hint about port, but hard-coding the value does not seem to be a good approach. I've checked the code for DuskTestCase.php and determined that it uses DUSK_DRIVER_URL by default, with a fallback to some hard-coded value. I've set that variable to http://selenium:4444 and APP_URL variable to http://web:80. Please note that the repository has a special .env.dusk.local file for that.Phalanx
Previous comment uses APP_URL value that does not comply with default one for Laravel Sail generated docker-compose.yml file. Mine has laravel.test replaced with web, which changes APP_SERVICE value and thus the URL. Short version - default APP_URL value should be http://laravel.test:80Phalanx
I
4

The WebDriver used by Dusk is looking for the selenium docker image on port 4444.

be sure to add to the .env file:

DUSK_DRIVER_URL='http://selenium:4444'

and an APP_URL that targets a local host on port 80:

APP_URL="http://laravel.test:80"
Inkerman answered 3/12, 2021 at 22:35 Comment(0)
D
1

I had been struggling with the same issue for hours. It was fixed by running below command

./vendor/bin/sail composer dumpautoload
Dagmardagna answered 24/4 at 12:30 Comment(0)
C
0

I'll tell you what worked for me:

1 - sail composer update

2 - docker system prune -a (to delete)

3- APP_URL=http://localhost:80 in the .env file

4- sail up

I'm not sure why but after I did it it worked

Coeducation answered 5/8, 2021 at 17:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.