symfony / panther

A browser testing and web crawling library for PHP and Symfony
MIT License
2.91k stars 213 forks source link

Allow for a WebServer process to be started in a specific environment #575

Open shadydealer opened 1 year ago

shadydealer commented 1 year ago

I am using symfony 6.1 with the latest version of PHPUnit + Panther and I was trying to setup a test which checks if the RECAPTCHA is setup correctly. So what I needed was an environment in which the RECAPTCHA is enabled, but didn't want to modify the default 'panther' or 'test' environments to have the RECAPTCHA enabled for obvious reasons. So what I did was create a new 'panther_with_recaptcha' environment, which it's own config/packages/panther_with_recaptcha/ directory in which I've enabled RECAPTCHA.

All good so far, until I tried to start the panther client with that environment. I though I could use the following:

        $this->client = static::createPantherClient(
            [
                'env' => [
                    'APP_ENV' => 'panther_with_recaptcha'
                ],
            ]
        );

unfortunetally this didn't work, so I went digging and it turns out it's because the WebServerManager has the following in it's constructor:

        if (isset($_SERVER['PANTHER_APP_ENV'])) {
            if (null === $env) {
                $env = [];
            }
            $env['APP_ENV'] = $_SERVER['PANTHER_APP_ENV'];
        }

Thus, even if I've set the environment variable, it's not actually used. Is this the intended behavior?

The workaround I've used is the following:

    public function testRecaptcha() {
        $old_panther_app_env = $_SERVER["PANTHER_APP_ENV"];

        // NOTE:
        //
        // Stopping the webserver, because
        // if we have multiple panther test cases running
        // once the webserver get's started it persists
        // throughout the whole test suite in order to improve performance.
        //
        // If we don't stop the server, then a previous panther test
        // would've started the server in the 'panther' environment
        // which would mean that this test will fail because
        // recaptcha is not enabled for the basic 'panther' environment
        $this->stopWebServer();

        // NOTE:
        //
        // This is currently the only way to force
        // the panther webserver to be started
        // in the 'panther_with_recaptcha' environment
        // which has recaptcha enabled in it.
        $_SERVER["PANTHER_APP_ENV"] = "panther_with_recaptcha";

        // NOTE:
        // Test has to be run using a webdriver
        // because recaptcha is implemented with javascript
        $this->client = static::createPantherClient();

       .....

        // NOTE:
        // Stopping the webserver, because
        // if we have multiple panther test cases running
        // once the webserver get's started it persists
        // throughout the whole test suite in order to improve performance.
        //
        // If we don't stop the server, then the next panther test
        // will also be running in the 'panther_with_recaptcha' env
        // which is not what we want.
        $this->stopWebServer();
        $_SERVER["PANTHER_APP_ENV"] = $old_panther_app_env;
}

But this seems like a bit of a hack to me.

Would it make sense to change the WebServerManager constructor if statement to:

        if (null === $env) {
            $env = [];
        }

        if (isset($_SERVER['PANTHER_APP_ENV'])) {
            $env['APP_ENV'] = $env['APP_ENV'] ?? $_SERVER['PANTHER_APP_ENV'];
        }

Or something along those lines?