Completed
Push — master ( adf918...e49e9a )
by Kevin
04:28 queued 02:18
created

Initializer::initialize()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 12
nc 2
nop 2
1
<?php
2
3
namespace Magium\TestCase;
4
5
use Magium\AbstractTestCase;
6
use Magium\InvalidConfigurationException;
7
use Magium\TestCaseConfiguration;
8
use Magium\Util\Api\Clairvoyant\Clairvoyant;
9
use Magium\Util\Api\Request;
10
use Magium\Util\Configuration\ClassConfigurationReader;
11
use Magium\Util\Configuration\ConfigurationCollector\DefaultPropertyCollector;
12
use Magium\Util\Configuration\ConfigurationProviderInterface;
13
use Magium\Util\Configuration\ConfigurationReader;
14
use Magium\Util\Configuration\EnvironmentConfigurationReader;
15
use Magium\Util\Configuration\StandardConfigurationProvider;
16
use Magium\Util\Log\Logger;
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
23
class Initializer
24
{
25
26
    protected $testCaseConfiguration = 'Magium\TestCaseConfiguration';
27
    protected $testCaseConfigurationObject;
28
    protected $initialized;
29
    protected $configurationProvider;
30
31
    public function __construct(
32
        $testCaseConfigurationType = null,
33
        TestCaseConfiguration $object = null,
34
        ConfigurationProviderInterface $configurationProvider = null
35
    )
36
    {
37
        if ($testCaseConfigurationType !== null) {
38
            $this->testCaseConfiguration = $testCaseConfigurationType;
39
        }
40
        if ($object instanceof TestCaseConfiguration) {
41
            $this->testCaseConfigurationObject = $object;
42
        }
43
44
        $this->configurationProvider = $configurationProvider;
45
        if (!$this->configurationProvider instanceof ConfigurationProviderInterface) {
46
            $this->configurationProvider = new StandardConfigurationProvider(
47
                new ConfigurationReader(),
48
                new ClassConfigurationReader(),
49
                new EnvironmentConfigurationReader()
50
            );
51
        }
52
53
    }
54
55
    protected function injectTestCaseHierarchy(AbstractTestCase $testCase)
56
    {
57
        $rc = new \ReflectionClass($testCase);
58
        while ($rc->getParentClass()) {
59
            $class = $rc->getParentClass()->getName();
60
            $testCase->getDi()->instanceManager()->addSharedInstance($testCase, $class);
61
            $rc = new \ReflectionClass($class);
62
        }
63
    }
64
65
    protected function configureWebDriver(AbstractTestCase $testCase)
66
    {
67
        $webDriver = $testCase->getDi()->get('Magium\WebDriver\WebDriver');
68
        if ($webDriver instanceof WebDriver) {
69
            $testCase->setWebdriver($webDriver);
70
            $testCase->setTypePreference(
71
                'Facebook\WebDriver\WebDriver',
72
                'Magium\WebDriver\WebDriver'
73
            );
74
            $testCase->setTypePreference(
75
                'Facebook\WebDriver\RemoteWebDriver',
76
                'Magium\WebDriver\WebDriver'
77
            );
78
        } else {
79
            throw new InvalidConfigurationException('DIC has misconfigured WebDriver object');
80
        }
81
    }
82
83
    protected function initLoggingExecutor(AbstractTestCase $testCase)
84
    {
85
        $remote = $testCase->getDi()->get('Magium\WebDriver\LoggingRemoteExecuteMethod');
86
        if ($remote instanceof LoggingRemoteExecuteMethod) {
87
            $testCase->getWebdriver()->setRemoteExecuteMethod($remote);
88
        } else {
89
            throw new InvalidConfigurationException('DIC has invalid logger configured');
90
        }
91
    }
92
93
    protected function configureClairvoyant(AbstractTestCase $testCase)
94
    {
95
        // This is going to be refactored in a completely backwards compatible way.  Currently, because the DiC is
96
        // rebuilt for each request it doesn't maintain state between tests.  This is a good thing... except when
97
        // something that understands it (the MasterListener) does retain state.
98
99
        $clairvoyant = $this->initClairvoyant($testCase);
100
101
        /* @var $clairvoyant \Magium\Util\Api\Clairvoyant\Clairvoyant */
102
        $request = $testCase->get('Magium\Util\Api\Request');
103
        if ($request instanceof Request) {
104
            $clairvoyant->setApiRequest($request);
105
        }
106
        $clairvoyant->reset();
107
        $clairvoyant->setSessionId($testCase->getWebdriver()->getSessionID());
108
        $clairvoyant->setCapability($this->testCaseConfigurationObject->getCapabilities());
109
        $testCase->getLogger()->addWriter($clairvoyant);
110
    }
111
112
    protected function executeCallbacks(AbstractTestCase $testCase)
113
    {
114
        RegistrationListener::executeCallbacks($testCase);
115
    }
116
117
    protected function setCharacteristics(AbstractTestCase $testCase)
118
    {
119
        $testCase->getLogger()->addCharacteristic(Logger::CHARACTERISTIC_BROWSER, $testCase->getWebdriver()->getBrowser());
120
        $testCase->getLogger()->addCharacteristic(Logger::CHARACTERISTIC_OPERATING_SYSTEM, $testCase->getWebdriver()->getPlatform());
121
    }
122
123
    protected function attachMasterListener(AbstractTestCase $testCase)
124
    {
125
        $testCase->getDi()->instanceManager()->addSharedInstance(AbstractTestCase::getMasterListener(), 'Magium\Util\Phpunit\MasterListener');
126
    }
127
128
    public function initialize(AbstractTestCase $testCase, $force = false)
129
    {
130
        if ($this->initialized === $testCase && !$force) {
131
            return;
132
        }
133
        $this->configureDi($testCase);
134
        $this->attachMasterListener($testCase);
135
        $this->injectTestCaseHierarchy($testCase);
136
        $this->configureWebDriver($testCase);
137
        $this->initLoggingExecutor($testCase);
138
        $this->configureClairvoyant($testCase);
139
        $this->setCharacteristics($testCase);
140
        $this->executeCallbacks($testCase);
141
        $this->initialized = $testCase;
142
    }
143
144
145
    protected function initClairvoyant(AbstractTestCase $testCase)
146
    {
147
        $clairvoyant = AbstractTestCase::getMasterListener()->getListener('Magium\Util\Api\Clairvoyant\Clairvoyant');
148
        if ($clairvoyant instanceof Clairvoyant) {
149
            $testCase->getDi()->instanceManager()->addSharedInstance($clairvoyant, get_class($clairvoyant));
150
        } else {
151
            $clairvoyant = $testCase->get('Magium\Util\Api\Clairvoyant\Clairvoyant');
152
            if ($clairvoyant instanceof Clairvoyant) {
153
                AbstractTestCase::getMasterListener()->addListener($clairvoyant);
154
            } else {
155
                throw new InvalidConfigurationException('Invalid Clairvoyant preference');
156
            }
157
        }
158
        return $clairvoyant;
159
    }
160
161
    protected function getDefaultConfiguration()
162
    {
163
        return [
164
            'definition' => [
165
                'class' => [
166
                    'Magium\WebDriver\WebDriver' => [
167
                        'instantiator' => 'Magium\WebDriver\WebDriverFactory::create'
168
                    ],
169
170
                    'Magium\WebDriver\WebDriverFactory' => [
171
                        'create'       => $this->testCaseConfigurationObject->getWebDriverConfiguration()
172
                    ]
173
                ]
174
            ],
175
            'instance'  => [
176
                'preference' => [
177
                    'Zend\I18n\Translator\Translator' => ['Magium\Util\Translator\Translator']
178
                ],
179
                'Magium\Util\Translator\Translator' => [
180
                    'parameters'    => [
181
                        'locale'    => 'en_US'
182
                    ]
183
                ],
184
                'Magium\Util\Log\Logger'   => [
185
                    'parameters'    => [
186
                        'options'   => [
187
                            'writers' => [
188
                                [
189
                                    'name' => 'Zend\Log\Writer\Noop',
190
                                    'options' => []
191
                                ]
192
                            ]
193
                        ]
194
                    ]
195
                ]
196
            ]
197
        ];
198
    }
199
200
    public function configureDi(AbstractTestCase $testCase)
201
    {
202
203
        if (!$this->testCaseConfigurationObject instanceof TestCaseConfiguration) {
204
            if ($testCase->getDi() instanceof Di) {
205
206
                $testCaseConfiguration = $testCase->get($this->testCaseConfiguration);
207
                if ($testCaseConfiguration instanceof TestCaseConfiguration) {
208
                    $this->testCaseConfigurationObject = $testCaseConfiguration;
209
                }
210
            } else {
211
                $this->testCaseConfigurationObject = new $this->testCaseConfiguration(
212
                    $this->configurationProvider
213
                    , new DefaultPropertyCollector()
214
                );
215
            }
216
        }
217
        if ($testCase->getDi() instanceof Di) {
218
            return;
219
        }
220
        /* @var $configuration TestCaseConfiguration */
221
        $configArray = $this->getDefaultConfiguration();
222
223
        $count = 0;
224
225
        $path = realpath(__DIR__ . '/../');
226
227
        while ($count++ < 5) {
228
            $dir = "{$path}/configuration/";
229
            if (is_dir($dir)) {
230
                foreach (glob($dir . '*.php') as $file) {
231
                    $configArray = array_merge_recursive($configArray, include $file);
232
                }
233
                break;
234
            }
235
            $path .= '/../';
236
        }
237
238
239
        $configArray = $this->testCaseConfigurationObject->reprocessConfiguration($configArray);
240
        $configuration = new Config($configArray);
241
242
        $di = new Di();
243
        $configuration->configure($di);
244
        $testCase->setDi($di);
245
        $di->instanceManager()->addSharedInstance($di, Di::class);
246
247
        $this->setConfigurationProvider($testCase);
248
    }
249
250
    public function setConfigurationProvider(AbstractTestCase $testCase)
251
    {
252
        $testCase->setTypePreference(
253
            'Magium\Util\Configuration\ConfigurationProviderInterface',
254
            'Magium\Util\Configuration\StandardConfigurationProvider'
255
        );
256
        $this->configurationProvider->configureDi($testCase->getDi());
257
258
    }
259
260
}
261