Initializer   A
last analyzed

Complexity

Total Complexity 34

Size/Duplication

Total Lines 237
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 34
lcom 1
cbo 7
dl 0
loc 237
rs 9.2
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 24 6
A setInitializationDependencyInjectionContainer() 0 4 1
A getInitializationDependencyInjectionContainer() 0 8 2
A injectTestCaseHierarchy() 0 9 2
A configureWebDriver() 0 17 2
A initLoggingExecutor() 0 9 2
A executeCallbacks() 0 4 1
A setCharacteristics() 0 7 1
A attachMasterListener() 0 5 1
A initialize() 0 14 3
B getDefaultConfiguration() 0 43 2
C configureDi() 0 49 8
A setConfigurationProvider() 0 15 3
1
<?php
2
3
namespace Magium\TestCase;
4
5
use Facebook\WebDriver\Remote\RemoteWebDriver;
6
use Interop\Container\ContainerInterface;
7
use Magium\AbstractTestCase;
8
use Magium\InvalidConfigurationException;
9
use Magium\TestCaseConfiguration;
10
use Magium\Util\Configuration\ConfigurationCollector\DefaultPropertyCollector;
11
use Magium\Util\Configuration\ConfigurationProviderInterface;
12
use Magium\Util\Configuration\StandardConfigurationProvider;
13
use Magium\Util\Log\Logger;
14
use Magium\Util\Log\LoggerInterface;
15
use Magium\Util\Log\LoggerPHPUnit5;
16
use Magium\Util\Phpunit\MasterListenerInterface;
17
use Magium\Util\TestCase\RegistrationListener;
18
use Magium\WebDriver\LoggingRemoteExecuteMethod;
19
use Magium\WebDriver\WebDriver;
20
use Zend\Di\Config;
21
use Zend\Di\Di;
22
use Zend\I18n\Translator\Translator;
23
use Zend\Log\Writer\Noop;
24
25
class Initializer
26
{
27
28
    protected $testCaseConfiguration = 'Magium\TestCaseConfiguration';
29
    protected $testCaseConfigurationObject;
30
    protected $initialized;
31
    protected $configurationProvider;
32
    protected static $initDi;
33
34
    public function __construct(
35
        $testCaseConfigurationType = null,
36
        TestCaseConfiguration $object = null,
37
        ConfigurationProviderInterface $configurationProvider = null
38
    )
39
    {
40
        if ($testCaseConfigurationType !== null) {
41
            $this->testCaseConfiguration = $testCaseConfigurationType;
42
        }
43
        if ($object instanceof TestCaseConfiguration) {
44
            $this->testCaseConfigurationObject = $object;
45
        }
46
47
        $this->configurationProvider = $configurationProvider;
48
        if (!$this->configurationProvider instanceof ConfigurationProviderInterface) {
49
            $preference = self::getInitializationDependencyInjectionContainer()->instanceManager()->getTypePreferences(ConfigurationProviderInterface::class);
50
            if (is_array($preference) && count($preference)) {
51
                $preference = array_shift($preference);
52
            } else {
53
                $preference = StandardConfigurationProvider::class;
54
            }
55
            $this->configurationProvider = self::getInitializationDependencyInjectionContainer()->get($preference);
56
        }
57
    }
58
59
    public static function setInitializationDependencyInjectionContainer(ContainerInterface $container)
60
    {
61
        self::$initDi = $container;
62
    }
63
64
    /**
65
     * This method returns a DI container that will ONLY be used to initialize this class
66
     *
67
     * @return Di
68
     */
69
70
    public static function getInitializationDependencyInjectionContainer()
71
    {
72
        if (!self::$initDi instanceof Di) {
73
            self::$initDi = new Di();
74
            self::$initDi->instanceManager()->addTypePreference(ConfigurationProviderInterface::class, StandardConfigurationProvider::class);
75
        }
76
        return self::$initDi;
77
    }
78
79
    protected function injectTestCaseHierarchy(AbstractTestCase $testCase)
80
    {
81
        $rc = new \ReflectionClass($testCase);
82
        while ($rc->getParentClass()) {
83
            $class = $rc->getParentClass()->getName();
84
            $testCase->getDi()->instanceManager()->addSharedInstance($testCase, $class);
85
            $rc = new \ReflectionClass($class);
86
        }
87
    }
88
89
    protected function configureWebDriver(AbstractTestCase $testCase)
90
    {
91
        $webDriver = $testCase->getDi()->get('Magium\WebDriver\WebDriver');
92
        if ($webDriver instanceof WebDriver) {
93
            $testCase->setWebdriver($webDriver);
94
            $testCase->setTypePreference(
95
                \Facebook\WebDriver\WebDriver::class,
96
                \Magium\WebDriver\WebDriver::class
97
            );
98
            $testCase->setTypePreference(
99
                RemoteWebDriver::class,
100
                \Magium\WebDriver\WebDriver::class
101
            );
102
        } else {
103
            throw new InvalidConfigurationException('DIC has misconfigured WebDriver object');
104
        }
105
    }
106
107
    protected function initLoggingExecutor(AbstractTestCase $testCase)
108
    {
109
        $remote = $testCase->getDi()->get(LoggingRemoteExecuteMethod::class);
110
        if ($remote instanceof LoggingRemoteExecuteMethod) {
111
            $testCase->getWebdriver()->setRemoteExecuteMethod($remote);
112
        } else {
113
            throw new InvalidConfigurationException('DIC has invalid logger configured');
114
        }
115
    }
116
117
    protected function executeCallbacks(AbstractTestCase $testCase)
118
    {
119
        RegistrationListener::executeCallbacks($testCase);
120
    }
121
122
    protected function setCharacteristics(AbstractTestCase $testCase)
123
    {
124
        $capabilities = $testCase->getWebdriver()->getCapabilities();
125
        $testCase->getLogger()->addCharacteristic(LoggerInterface::CHARACTERISTIC_BROWSER, $capabilities->getBrowserName());
126
        $testCase->getLogger()->addCharacteristic(LoggerInterface::CHARACTERISTIC_BROWSER_VERSION, $capabilities->getVersion());
127
        $testCase->getLogger()->addCharacteristic(LoggerInterface::CHARACTERISTIC_OPERATING_SYSTEM, $capabilities->getPlatform());
128
    }
129
130
    protected function attachMasterListener(AbstractTestCase $testCase)
131
    {
132
        $masterListener = AbstractTestCase::getMasterListener();
133
        $testCase->getDi()->instanceManager()->addSharedInstance($masterListener, MasterListenerInterface::class);
134
    }
135
136
    public function initialize(AbstractTestCase $testCase, $force = false)
137
    {
138
        if ($this->initialized === $testCase && !$force) {
139
            return;
140
        }
141
        $this->configureDi($testCase);
142
        $this->attachMasterListener($testCase);
143
        $this->injectTestCaseHierarchy($testCase);
144
        $this->configureWebDriver($testCase);
145
        $this->initLoggingExecutor($testCase);
146
        $this->executeCallbacks($testCase);
147
        $this->setCharacteristics($testCase);
148
        $this->initialized = $testCase;
149
    }
150
151
    protected function getDefaultConfiguration()
152
    {
153
        // Choose the correct logger/listener for the version of PHPUnit being used
154
        $loggerClass = class_exists('PHPUnit_Framework_TestCase')?LoggerPHPUnit5::class:Logger::class;
155
156
        return [
157
            'definition' => [
158
                'class' => [
159
                    'Magium\WebDriver\WebDriver' => [
160
                        'instantiator' => 'Magium\WebDriver\WebDriverFactory::create'
161
                    ],
162
163
                    'Magium\WebDriver\WebDriverFactory' => [
164
                        'create'       => $this->testCaseConfigurationObject->getWebDriverConfiguration()
165
                    ]
166
                ]
167
            ],
168
            'instance'  => [
169
                'preference' => [
170
                    Translator::class => [\Magium\Util\Translator\Translator::class],
171
                    \Zend\Log\LoggerInterface::class => [$loggerClass],
172
                    LoggerInterface::class => [$loggerClass],
173
                ],
174
                'Magium\Util\Translator\Translator' => [
175
                    'parameters'    => [
176
                        'locale'    => 'en_US'
177
                    ]
178
                ],
179
                $loggerClass   => [
180
                    'parameters'    => [
181
                        'options'   => [
182
                            'writers' => [
183
                                [
184
                                    'name' => Noop::class,
185
                                    'options' => []
186
                                ]
187
                            ]
188
                        ]
189
                    ]
190
                ]
191
            ]
192
        ];
193
    }
194
195
    public function configureDi(AbstractTestCase $testCase)
196
    {
197
198
        if (!$this->testCaseConfigurationObject instanceof TestCaseConfiguration) {
199
            if ($testCase->getDi() instanceof Di) {
200
201
                $testCaseConfiguration = $testCase->get($this->testCaseConfiguration);
202
                if ($testCaseConfiguration instanceof TestCaseConfiguration) {
203
                    $this->testCaseConfigurationObject = $testCaseConfiguration;
204
                }
205
            } else {
206
                $this->testCaseConfigurationObject = new $this->testCaseConfiguration(
207
                    $this->configurationProvider
208
                    , new DefaultPropertyCollector()
209
                );
210
            }
211
        }
212
        if ($testCase->getDi() instanceof Di) {
213
            return;
214
        }
215
        /* @var $configuration TestCaseConfiguration */
216
        $configArray = $this->getDefaultConfiguration();
217
218
        $count = 0;
219
220
        $path = realpath(__DIR__ . '/../');
221
222
        while ($count++ < 5) {
223
            $dir = "{$path}/configuration/";
224
            if (is_dir($dir)) {
225
                foreach (glob($dir . '*.php') as $file) {
226
                    $configArray = array_merge_recursive($configArray, include $file);
227
                }
228
                break;
229
            }
230
            $path .= '/../';
231
        }
232
233
234
        $configArray = $this->testCaseConfigurationObject->reprocessConfiguration($configArray);
235
        $configuration = new Config($configArray);
236
237
        $di = new Di();
238
        $configuration->configure($di);
239
        $testCase->setDi($di);
240
        $di->instanceManager()->addSharedInstance($di, Di::class);
241
242
        $this->setConfigurationProvider($testCase);
243
    }
244
245
    public function setConfigurationProvider(AbstractTestCase $testCase)
246
    {
247
        $configuredProvider = self::getInitializationDependencyInjectionContainer()->instanceManager()->getTypePreferences(ConfigurationProviderInterface::class);
248
        if (is_array($configuredProvider) && count($configuredProvider)) {
249
            $configuredProvider = array_shift($configuredProvider);
250
        } else {
251
            $configuredProvider = StandardConfigurationProvider::class;
252
        }
253
        $testCase->setTypePreference(
254
            ConfigurationProviderInterface::class,
255
            $configuredProvider
256
        );
257
        $this->configurationProvider->configureDi($testCase->getDi());
258
259
    }
260
261
}
262