Git Product home page Git Product logo

laravel-dusk-firefox's Introduction

Geckodriver support for Laravel Dusk

This package will make Laravel Dusk browser tests run in Mozilla Firefox. Instead of using Chromedriver, Laravel application tests are sent to Firefox's Geckodriver proxy server.

Features

  1. Downloads the latest stable Geckodriver binary for your operating system.
  2. Handles automating startup and shutdown of the Geckodriver proxy server process.
  3. Captures Mozilla Firefox browser screenshots when tests fail.
  4. Generates a debugging log file when JavaScript console errors occur.

Requirements

  • PHP 7.2+
  • Laravel Framework 6.0+
  • Laravel Dusk 6.0+
  • Latest version of Mozilla Firefox installed locally

Installation

First ensure Laravel Dusk command php artisan dusk:install has been run. This will copy files into your application and generate required subdirectories.

composer require --dev derekmd/laravel-dusk-firefox
php artisan dusk:install-firefox

This will overwrite file tests/DuskTestCase.php in your application to support running Mozilla Firefox. Your browser test suite will now open in Mozilla Firefox rather than Google Chrome:

php artisan dusk

Updating Geckodriver

To download the latest stable Geckodriver binary for your current operating system:

php artisan dusk:firefox-driver

Use the --all option to install all three binaries for Linux, macOS, and Windows.

php artisan dusk:firefox-driver --all

If you wish to download older binaries, pass the GitHub release tag version as the first command line argument. Keep in mind Geckodriver's versioning schema does not relate to Mozilla Firefox's release version.

php artisan dusk:firefox-driver v0.19.1

The command can also download the binaries through a local proxy server:

php artisan dusk:firefox-driver --proxy=tcp://127.0.0.1:9000 --ssl-no-verify

Configuring Geckodriver

After tests/DuskTestCase.php is copied into your application, you may update the class as you please.

namespace Tests;

use Derekmd\Dusk\Concerns\TogglesHeadlessMode;
use Derekmd\Dusk\Firefox\SupportsFirefox;
use Facebook\WebDriver\Firefox\FirefoxOptions;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Laravel\Dusk\TestCase as BaseTestCase;

abstract class DuskTestCase extends BaseTestCase
{
    // ...

    protected function driver()
    {
        $capabilities = DesiredCapabilities::firefox();

        $capabilities->getCapability(FirefoxOptions::CAPABILITY)
            ->addArguments($this->filterHeadlessArguments([
                '--headless',
                '--window-size=1920,1080',
            ]))
            ->setPreference('devtools.console.stdout.content', true);

        return RemoteWebDriver::create('http://localhost:4444', $capabilities);
    }
}
  • Mozilla Firefox profile boolean flag devtools.console.stdout.content must be turned on to generate logs for debugging JavaScript errors.
  • --headless runs tests without opening any windows which is useful for continuous integrations. Remove this option to see the browser viewport while the test runs.
  • --window-size controls the width and height of the browser viewport. If your UI assertions are failing from elements being off-screen, you may need to change this setting.
  • The $this->filterHeadlessArguments() call allows the --headless argument to be removed when the command php artisan dusk --browse is run during local dev. This allows the Mozilla Firefox browser window to be displayed while Laravel Dusk tests run. Headless mode is still enabled when the command line argument --browse isn't used.

Read the Geckodriver usage documentation to see which options are available.

Running both Mozilla Firefox & Google Chrome

You may wish to run tests in both Mozilla Firefox and Google Chrome to check for feature parity in your application. This package supports a --with-chrome option to generate tests/DuskTestCase.php so it may run in both browsers.

php artisan dusk:install-firefox --with-chrome

Selecting desired browser in local environment

The Laravel Dusk command will default to running tests in Mozilla Firefox:

php artisan dusk

A new command has been added to make tests run in Google Chrome:

php artisan dusk:chrome

You may also pass PHPUnit arguments to the command:

php artisan dusk:chrome tests/Browser/HomepageTest.php --filter testFooter

This command will append environment variable DUSK_CHROME=1 to your .env.dusk file and remove it after tests complete.

If Laravel Dusk crashes or you have cancelled the test suite process using CTRL+C, you may need to manually remove leftover line DUSK_CHROME=1 from your .env.dusk file.

Selecting desired browser in continuous integration

When running automated test flows through tools such as Chipper CI, CircleCI, Travis CI, or Github Actions, you can setup one job to run Google Chrome and a second job for Mozilla Firefox. The custom Artisan commands can be skipped and you can instead just set the environment variable. The job configured with DUSK_CHROME=1 will run Google Chrome. The second job missing the environment variable defaults to Mozilla Firefox.

Running with Laravel Sail

Laravel Sail is a command-line interface for interacting with your Laravel application's Docker development environment. Laravel Dusk tests can run in Mozilla Firefox once an additional Docker image is added to Sail's configuration file.

You must uncomment and edit the "selenium" service in the docker-compose.yml file to install standalone Mozilla Firefox for Selenium.

version: '3'
services:
    laravel.test:
        # ....
        depends_on:
            - mysql
            - redis
            - selenium
    selenium:
        image: 'selenium/standalone-firefox'
        volumes:
            - '/dev/shm:/dev/shm'
        networks:
            - sail

Developing only with Laraval Sail

You may not require this package if you exclusively use Laravel Sail for development.

Over 90% of this package's solution is focused on managing a local Geckodriver process through PHPUnit's event hooks. Laravel Sail replaces Chromedriver/Geckodriver with a Selenium server so the only custom code you'll require in your application is a WebDriver configuration for Mozilla Firefox. Copy this driver() method into your application's tests/DuskTestCase.php file. Then use the above docker-compose.yml instructions to install Docker image "selenium/standalone-firefox".

Mixing other development environments with Laravel Sail

For projects that have a team of developers across many environments (local native development, Laravel Valet, Laravel Homestead, Laravel Sail) or use a Docker-less continuous integration, this package will allow Laravel Dusk to run Mozilla Firefox in any of those environments.

Install the package using the sail commands:

./vendor/bin/sail composer require --dev derekmd/laravel-dusk-firefox
./vendor/bin/sail artisan dusk:install-firefox

This will copy a tests/DuskTestCase.php file into your application that is configured to recognize Laravel Sail's environment variables. When Sail isn't installed, Laravel Dusk will behave as normal.

Run Laravel Dusk tests in Mozilla Firefox by executing the command:

./vendor/bin/sail dusk

Other developers not using Laravel Sail can execute the usual Dusk command:

php artisan dusk

This configuration only allows running Dusk test with Mozilla Firefox. To make the command php artisan dusk:chrome work with a "selenium/standalone-chrome" image, additional service and sail.sh file changes are required that fall outside the 80% use case of Laravel Sail.

Development

To run the test suite, Geckodriver binaries for each 64-bit operating systems will need to be downloaded:

composer download

or call the PHP script. Yes, using PHPUnit to run an Artisan command is a hack. Package development!

./vendor/phpunit/phpunit/phpunit tests/DownloadBinaries.php

Run the tests in the command line through Composer:

composer test

or call PHPUnit directly:

./vendor/phpunit/phpunit/phpunit

FAQ

  1. How do I fix error "Failed to connect to localhost port 4444: Connection refused"?

    By default Geckodriver runs locally on port 4444. The process may have failed to start.

    • Run php artisan dusk:firefox-driver to ensure the Geckodriver binary is downloaded.
    • The Geckodriver proxy server may already be running which can happen after a crash. Kill the conflicting process ("End Task" in Windows) and try running php artisan dusk again.
    • If another service is using port 4444, open tests/DuskTestCase.php and change the driver() method to configure another port number.
  2. My test suite that passed 100% using Chromedriver now fails in Mozilla Firefox. How do I fix my tests?

    You may find Mozilla Firefox is more temperamental when calling Laravel Dusk method visit() or navigating between web pages. For HTTP redirects and form submissions, you may wish to avoid first calling methods assertPathIs() assertPathIsNot() or assertPathBeginsWith(). Waiting for elements methods such as the waitForText() method are the best fit to delay the test until the next web page has finished loading. When all else fails, add trial-and-error pause($milliseconds) calls to make the test determinstic in all environments.

  3. Can you help me get my tests running in Mozilla Firefox?

    Sorry, no. That would be outside of the scope of support for this package. You can try Laravel community support channels such as the https://laracasts.com/ and https://laravel.io/ forums.

  4. Why doesn't the saved browser error log show scripting warnings, such as a .js file failing to load due to CORS (cross-origin resource sharing) restrictions?

    Chromedriver implements Selenium's commands.GetLog endpoint which provides a wider range of testing feedback. Unfortunately this endpoint is not currently part of the W3C WebDriver API so Geckodriver does not support it.

    This limitation is one of the reasons that Mozilla Firefox support isn't built into the official Laravel Dusk package.

  5. Why does running command php artisan dusk:install-firefox or php artisan dusk:firefox-driver return this error message?

    cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)

    The PHP environment may not be configured for handling SSL certificates.

    a. These two commands support options --proxy and --ssl-no-verify to control the cURL configuration when downloading Geckodriver binaries. --ssl-no-verify will skip checking the certificate, however: b. To ensure SSL certificate verification passes for domain https://github.com, php.ini should be configured with PHP extension openssl enabled. If an OS-managed cert store cannot be found, file php.ini can be updated to configure a .crt file using https://curl.se/docs/caextract.html.

    [openssl]
    # Mac, Linux
    openssl.cafile="~/ca-bundle.crt"
    # Windows
    # openssl.cafile="C:\xampp\apache\bin\curl-ca-bundle.crt"
    
  6. Why is every test case failing with this error message?

    cUrl error (#28): Operation timed out after ... milliseconds with 0 bytes received`?
    

    Xdebug may be awaiting a user interaction to continue from a code breakpoint. PHP extension Xdebug should be disabled in php.ini for running browser tests.

Contributing

When submitting a pull request:

  1. Write new PHP code and docblock in the same style as the Laravel ecoystem. #NoTimeForTypehints
    • Running command ./vendor/friendsofphp/php-cs-fixer/php-cs-fixer fix will auto-correct the code styling.
  2. Add cases to the test suite to ensure code coverage is never reduced.
  3. Please do not try to support more browsers stubs beyond Chrome & Mozilla Firefox.

I'll complete a contribution guide when this package warrants it. However I expect this codebase to have a small footprint given its narrow focus.

Credits

License

The MIT License (MIT). Please see License File for more information.

laravel-dusk-firefox's People

Contributors

derekmd avatar owenvoke avatar spresnac avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

laravel-dusk-firefox's Issues

Please help in taking screenshot of full screen

Hello. Thanks for this module.

Screenshots are cut and not taking the whole page. Here's a sample screenshot of my app. You may see that it does not show the whole page.

failure-Modules_Enrollment_Tests_Browser_EnrollmentTest_testModifyEnrollmentStudentCanDropAndAdd-0

Thank you for your help.

Error: Call to a member function setPreference() on null

I've got laradock container with Firefox installed

firefox --version
Mozilla Firefox 90.0

php artisan dusk:install-firefox
also ran with

Firefox scaffolding installed successfully.
Downloading Geckodriver binaries...
Geckodriver binary successfully installed for version v0.29.1.

however I'm getting

Error: Call to a member function setPreference() on null
from the following code

        $capabilities->getCapability(FirefoxDriver::PROFILE)
            ->setPreference('devtools.console.stdout.content', true);

Firefox 99 causes error

The program 'firefox' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadValue (integer parameter out of range for operation)'.
  (Details: serial 1063 error_code 2 request_code 53 (core protocol) minor_code 0)
Exiting due to channel error.
Tried to run command without establishing a connection
#0 vendor/php-webdriver/webdriver/lib/Remote/HttpCommandExecutor.php(371): Facebook\WebDriver\Exception\WebDriverException::throwException()

I did update geckodriver to 0.31

Solution for me was to downgrade firefox to 96.0.3

I work under ubuntu

https://askubuntu.com/a/661193

PhpStorm/Xdebug - `Listening for PHP debug connections` causes cURL TimeOut exception

Been stuck the whole day today on this issue.

All my Pest/Dusk browser tests ran fine under Chrome,
however the FireFox tests where all failing with cURL TimeOut exception, 0 bytes received.

Having Listening for PHP debug connections enabled, while using the FireFox driver,
was the culprit behind this.

Since the work-around is as simple as toggling off the Listening for PHP debug connections button in the PyCharm IDE,
I'd say that fixing this issue is low priority.

However, it would be nice to have it mentioned in the FAQ,
because this can save others a lot of hair-pulling / time ๐Ÿ™‚

removing --headless causes

image

Your firefox profile cannot be loaded. It may be missing or inaccessible.

as a result, firefox doesn't open, nor does the test run

any fixes to this you know of?

Running out of memory when using Homestead

@derekmd thank you for this package

I'm finding I'm not able to install this package due to memory size exceeding:

PHP Fatal error:  Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/local/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223

I'm running this inside Homestead... Any ideas?

Impossible to pass arguments to startChromeDriver function

Hello,

it's impossible to pass arguments to chrome driver function, without loosing dusk:chrome driver,
because it triggers the following message :

It looks like you must configure your application for Chromedriver.
Run "php artisan dusk:install-firefox --with-chrome" to install new scaffolding.

it's because of this function :

protected function hasChromedriverSetup()
{
    return Str::contains($this->duskTestCaseContents(), 'startChromeDriver()');
}

which check for the string startChromeDriver()

it's possible to bypass the check by doing :

static::startChromeDriver(['--port=9515']);//startChromeDriver()

but it's not very clean

How to increase timeout?

I'm getting:

Facebook\WebDriver\Exception\TimeoutException: Timeout loading page after 300000ms

in my slow work from home machine, but I already increased the timeout via ::create:

        return RemoteWebDriver::create(
            $_ENV['DUSK_DRIVER_URL'] ?? 'http://localhost:4444',
            $capabilities,
            9000000, 9000000
        );

Thanks for your work on this package. I switched to it since chrome has a bug where rendering timeouts occur.

Geckodrivers Missing for Mac and Linux

I ran the following in my Laravel 6/PHP 7.3 project on Mac OS:

% php artisan dusk:install-firefox
Overwrite file /Users/jrquick/development/uabshp/r3/laravel/tests/DuskTestCase.php? (yes/no) [no]:

yes

Firefox scaffolding installed successfully.
Downloading Geckodriver binaries...
Geckodriver binary successfully installed for version v0.29.0.

% php artisan dusk:firefox-driver --all
x geckodriver
Unable to find executable in downloaded file /Users/jrquick/development/uabshp/r3/laravel/vendor/derekmd/laravel-dusk-firefox/src/Console/../../bin/geckodriver-v0.29.0-linux64.tar.gz
x geckodriver
Unable to find executable in downloaded file /Users/jrquick/development/uabshp/r3/laravel/vendor/derekmd/laravel-dusk-firefox/src/Console/../../bin/geckodriver-v0.29.0-macos.tar.gz

Seems to be missing linux and max geckodrivers

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.