Behat / MinkExtension

Mink extension (tight integration and configuration) for Behat
MIT License
636 stars 279 forks source link

use of whole extension-config-array within the driver-factories #206

Open miertschink opened 9 years ago

miertschink commented 9 years ago

What I want to do:

What I did:

Now behat.yml looks like this:

...
default:
  extension:
    My\Extension:
      mySelenium2: ~
      myGoutte: ~

      MyValueOne: foo
      MyValuTwo: bar
...   

No problems so far. But then I tried to use the configuration-array of the extension inside the driver-factories to use "MyValueOne" and "MyValueTwo". There is no way to it directly, isn`t it?

The only way to use values from behat.yml inside the driver-factories is to write them down for each driver separately as the config-array which is passed to the buildDriver method isnt the "full" one. Only the subset for the driver is passed. I didnt want to overwrite the whole method "load" of the mink extension.

What I now did was to "store" the DriverFactories inside my extension in the constructor to configure them during the load method before calling the MinkExtension load method:

clss MyOwnExtension  extends MinkExtension
{
    public function __construct()
    {
        parent::__construct();

        $seleniumDriverFactory = new MyOwnSelenium2DriverFactory($config);
        $this->MyOwnDriverFactories[$seleniumDriverFactory->getDriverName()] =
        $seleniumDriverFactory;

        $goutteDriverFactory = new MyOwnGoutteDriverFactory($config);
        $this->MyOwnDriverFactories[$goutteDriverFactory->getDriverName()] =
        $goutteDriverFactory;

        $this->registerDriverFactory($seleniumDriverFactory);
        $this->registerDriverFactory($goutteDriverFactory);
    }

    public function load(ContainerBuilder $container, array $config)
    {
        foreach ($this->MyOwnDriverFactories as $driverFactory) {
            $driverFactory->setExtensionConfig($config);
        }

        parent::load($container, $config);
    }

    ...
}

This way doesn`t feel right. Is there a better solution? Maybe change the source of the MinkExtension in a way that provides this functionality? Passing the whole config-array to the buildDriver - maybe as a second parameter?

miertschink commented 9 years ago

Anybody?

Why not do a simple array_merge($config, $session[$driver]) in src/Behat/MinkExtension/ServiceContainer/MinkExtension.php ~231 ???

private function loadSessions(ContainerBuilder $container, array $config)
{
    ...

    foreach ($config['sessions'] as $name => $session) {
        $driver = key($session);
        $factory = $this->driverFactories[$driver];
        $driverConfig = array_merge($config, $session[$driver]);
        $definition = new Definition('Behat\Mink\Session', array(
            $factory->buildDriver($driverConfig),
            new Reference(self::SELECTORS_HANDLER_ID),
        ));
        $minkDefinition->addMethodCall('registerSession', array($name, $definition));
        if ($factory->supportsJavascript()) {
            $javascriptSessions[] = $name;
        } else {
            $nonJavascriptSessions[] = $name;
        }

     ...
    }

Now the whole config would be available in the build-Driver method.

stof commented 9 years ago

I'm -1 on this. Factories should expose configuration settings for the settings they need. Merging the whole MinkExtension config with the driver config is totally unclean (and it could even break assumptions for some factories assuming the get a clean config). So I'm -1 on this.

can you describe a real use case for your feature request, so that I can think about what would be the right way to achieve it ? And note that I need the use case, not the description of the way you tried to solve your use case for now. So the question to ask is Why do I need this ? and What do I want to solve?, not How can I read this value (which forces part of the solution to be based on a value provided in a particular place)

miertschink commented 9 years ago

As I mentioned I want to use Config-Values from the extension within the drivers to avoid blowing up the config and write them for each driver separately. It's about cookie values and user-agent config which I am using in the goutte- AND the selenium2-driver.

Maybe the best way here is to make use of yamls "Repeated nodes" and define the values somewhere in the yaml and re-use them. http://www.yaml.org/spec/1.2/spec.html#id2760395

I will check if this is suitable for me. Thank you