GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

StoryTeller   F
last analyzed

Complexity

Total Complexity 78

Size/Duplication

Total Lines 929
Duplicated Lines 0 %

Coupling/Cohesion

Components 9
Dependencies 16

Importance

Changes 3
Bugs 2 Features 0
Metric Value
wmc 78
c 3
b 2
f 0
lcom 9
cbo 16
dl 0
loc 929
rs 1.6901

64 Methods

Rating   Name   Duplication   Size   Complexity  
A instance() 0 4 1
A getActionLogger() 0 3 1
A getCheckpoint() 0 3 1
A getPageContext() 0 3 1
A getStory() 0 4 1
A getScriptFilename() 0 4 1
A setScriptFilename() 0 4 1
A getRuntimeConfigManager() 0 3 1
A getCurrentPhase() 0 4 1
A getCurrentPhaseName() 0 4 1
A setCurrentPhase() 0 4 1
A setProseLoader() 0 4 1
A getPhaseLoader() 0 4 1
A setPhaseLoader() 0 4 1
A getOutput() 0 4 1
A setOutput() 0 4 1
A setDataFormatter() 0 4 1
A getActiveConfig() 0 4 1
A setConfig() 0 4 1
A getRuntimeConfig() 0 4 1
A setRuntimeConfig() 0 4 1
A getSystemUnderTestConfig() 0 4 1
A getTestEnvironmentSignature() 0 4 1
A getPersistTestEnvironment() 0 4 1
A setPersistTestEnvironment() 0 4 1
A hasTestUsers() 0 4 1
A getTestUsersFilename() 0 4 1
A getTestUsersFileIsReadOnly() 0 4 1
A setTestUsersFileIsReadOnly() 0 4 1
A startAction() 0 4 1
A closeAllOpenActions() 0 4 1
A convertDataForOutput() 0 4 1
A getPersistDevice() 0 4 1
A setPersistDevice() 0 4 1
A getDeviceDetails() 0 4 1
A getDeviceName() 0 4 1
A getPersistProcesses() 0 4 1
A setPersistProcesses() 0 4 1
A getEventStream() 0 4 1
A setEventStream() 0 4 1
A getNewCommandRunner() 0 4 1
A getEnvironment() 0 4 1
B __construct() 0 38 1
A setActionLogger() 0 5 1
A setCheckpoint() 0 5 1
A setPageContext() 0 5 1
A setStory() 0 13 2
A setRuntimeConfigManager() 0 5 1
A getConfig() 0 8 1
A saveRuntimeConfig() 0 8 2
A getTestEnvironmentConfig() 0 5 1
A getTestEnvironmentName() 0 5 1
A getTestUsers() 0 9 2
A setTestUsers() 0 5 1
A setTestUsersFilename() 0 5 1
A getParams() 0 15 1
A __call() 0 17 2
A getDeviceAdapter() 0 8 2
A setDeviceAdapter() 0 6 1
A getRunningDevice() 0 14 3
A setDevice() 0 5 1
B startDevice() 0 38 4
B stopDevice() 0 42 5
A getEnvironmentName() 0 7 1

How to fix   Complexity   

Complex Class

Complex classes like StoryTeller often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use StoryTeller, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Copyright (c) 2011-present Mediasift Ltd
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 *
11
 *   * Redistributions of source code must retain the above copyright
12
 *     notice, this list of conditions and the following disclaimer.
13
 *
14
 *   * Redistributions in binary form must reproduce the above copyright
15
 *     notice, this list of conditions and the following disclaimer in
16
 *     the documentation and/or other materials provided with the
17
 *     distribution.
18
 *
19
 *   * Neither the names of the copyright holders nor the names of his
20
 *     contributors may be used to endorse or promote products derived
21
 *     from this software without specific prior written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
 * POSSIBILITY OF SUCH DAMAGE.
35
 *
36
 * @category  Libraries
37
 * @package   Storyplayer/PlayerLib
38
 * @author    Stuart Herbert <[email protected]>
39
 * @copyright 2011-present Mediasift Ltd www.datasift.com
40
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
41
 * @link      http://datasift.github.io/storyplayer
42
 */
43
44
namespace DataSift\Storyplayer\PlayerLib;
45
46
use DataSift\Storyplayer\Injectables;
47
use DataSift\Storyplayer\Cli\RuntimeConfigManager;
48
use DataSift\Storyplayer\CommandLib\CommandRunner;
49
use DataSift\Storyplayer\Output;
50
use DataSift\Storyplayer\Phases\Phase;
51
use DataSift\Storyplayer\DeviceLib;
52
use DataSift\Storyplayer\OutputLib\CodeFormatter;
53
use Prose\E4xx_ObsoleteProse;
54
use Prose\E5xx_NoMatchingActions;
55
use Prose\PageContext;
56
57
use DataSift\Stone\ObjectLib\BaseObject;
58
use Storyplayer\SPv2\Modules\Exceptions;
59
use StoryplayerInternals\SPv2\Modules\Events;
60
use StoryplayerInternals\SPv2\Modules\Events\EventStream;
61
62
/**
63
 * our main facilitation class
64
 *
65
 * all actions and tests inside a story are executed through an instance
66
 * of this class, making this class the StoryTeller :)
67
 *
68
 * @method Prose\AssertsArray assertsArray(array $expected)
69
 * @method Prose\AssertsBoolean assertsBoolean(boolean $expected)
70
 * @method Prose\AssertsDouble assertsDouble(float $expected)
71
 * @method Prose\AssertsInteger assertsInteger(integer $expected)
72
 * @method Prose\AssertsObject assertsObject(object $expected)
73
 * @method Prose\AssertsString assertsString(string $expected)
74
 * @method Prose\ExpectsBrowser expectsBrowser()
75
 * @method Prose\ExpectsEc2Image expectsEc2Image(string $amiId)
76
 * @method Prose\ExpectsFailure expectsFailure()
77
 * @method Prose\ExpectsForm expectsForm(string $formId)
78
 * @method Prose\ExpectsGraphite expectsGraphite()
79
 * @method Prose\ExpectsHost expectsHost($hostDetails)
80
 * @method Prose\ExpectsHostsTable expectsHostsTable()
81
 * @method Prose\ExpectsHttpResponse expectsHttpResponse(HttpClientResponse $response)
82
 * @method Prose\ExpectsIframe expectsIframe(string $id)
83
 * @method Prose\ExpectsProcessesTable expectsProcessesTable()
84
 * @method Prose\ExpectsRuntimeTable expectsRuntimeTable(string $tableName)
85
 * @method Prose\ExpectsShell expectsShell()
86
 * @method Prose\ExpectsUuid expectsUuid()
87
 * @method Prose\ExpectsZmq expectsZmq()
88
 * @method Prose\FromAws fromAws()
89
 * @method Prose\FromBrowser fromBrowser()
90
 * @method Prose\FromCheckpoint fromCheckpoint()
91
 * @method Prose\FromConfig fromConfig()
92
 * @method Prose\FromCurl fromCurl()
93
 * @method Prose\FromEc2 fromEc2()
94
 * @method Prose\FromEc2Instance fromEc2Instance(string $hostname)
95
 * @method Prose\FromEnvironment fromEnvironment()
96
 * @method Prose\FromFacebook fromFacebook()
97
 * @method Prose\FromFile fromFile()
98
 * @method Prose\FromForm fromForm(string $formId)
99
 * @method Prose\FromGraphite fromGraphite()
100
 * @method Prose\FromHost fromHost(string $hostId)
101
 * @method Prose\FromHostsTable fromHostsTable()
102
 * @method Prose\FromHttp fromHttp()
103
 * @method Prose\FromIframe fromIframe(string $id)
104
 * @method Prose\FromProcessesTable fromProcessesTable()
105
 * @method Prose\FromRolesTable fromRolesTable()
106
 * @method Prose\FromRuntimeTable fromRuntimeTable(string $tableName)
107
 * @method Prose\FromSauceLabs fromSauceLabs()
108
 * @method Prose\FromShell fromShell()
109
 * @method Prose\FromStoryplayer fromStoryplayer()
110
 * @method Prose\FromSupervisor fromSupervisor()
111
 * @method Prose\FromTargetsTable fromTargetsTable()
112
 * @method Prose\FromTestEnvironment fromTestEnvironment()
113
 * @method Prose\FromUuid fromUuid()
114
 * @method Prose\UsingBrowser usingBrowser()
115
 * @method Prose\UsingCheckpoint usingCheckpoint()
116
 * @method Prose\UsingDoppeld usingDoppeld()
117
 * @method Prose\UsingEc2 usingEc2()
118
 * @method Prose\UsingEc2Instance usingEc2Instance(string $hostname)
119
 * @method Prose\UsingFacebookGraphApi usingFacebookGraphApi()
120
 * @method Prose\UsingFile usingFile()
121
 * @method Prose\UsingForm usingForm(string $formId)
122
 * @method Prose\UsingHornet usingHornet()
123
 * @method Prose\UsingHost usingHost(string $hostId)
124
 * @method Prose\UsingHostsTable usingHostsTable()
125
 * @method Prose\UsingHttp usingHttp()
126
 * @method Prose\UsingIframe usingIframe(string $id)
127
 * @method Prose\UsingLog usingLog()
128
 * @method Prose\UsingProcessesTable usingProcessesTable()
129
 * @method Prose\UsingProvisioning usingProvisioning()
130
 * @method Prose\UsingProvisioningDefinition usingProvisioningDefinition(ProvisioningDefinition $definition)
131
 * @method Prose\UsingProvisioningEngine usingProvisioningEngine(string $engine)
132
 * @method Prose\UsingReporting usingReporting()
133
 * @method Prose\UsingRolesTable usingRolesTable()
134
 * @method Prose\UsingRuntimeTable usingRuntimeTable(string $tableName)
135
 * @method Prose\UsingSauceLabs usingSauceLabs()
136
 * @method Prose\UsingSavageD usingSavageD()
137
 * @method Prose\UsingShell usingShell()
138
 * @method Prose\UsingTargetsTable usingTargetsTable()
139
 * @method Prose\UsingTimer usingTimer()
140
 * @method Prose\UsingVagrant usingVagrant()
141
 * @method Prose\UsingYamlFile usingYamlFile(string $filename)
142
 * @method Prose\UsingZmq usingZmq()
143
 * @method Prose\UsingZookeeper usingZookeeper(string $hostname)
144
 *
145
 * @category  Libraries
146
 * @package   Storyplayer/PlayerLib
147
 * @author    Stuart Herbert <[email protected]>
148
 * @copyright 2011-present Mediasift Ltd www.datasift.com
149
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
150
 * @link      http://datasift.github.io/storyplayer
151
 */
152
class StoryTeller
153
{
154
    /**
155
     * singleton instance of StoryTeller
156
     * @var StoryTeller
157
     */
158
    static protected $self = null;
159
160
    /**
161
     * the story that is being played
162
     * @var Story
163
     */
164
    private $story = null;
165
166
    private $pageContext = null;
167
    private $checkpoint = null;
168
169
    /**
170
     * the script that is being played
171
     */
172
    private $scriptFilename = null;
173
174
    /**
175
     *
176
     * @var PhaseLoader
177
     */
178
    private $phaseLoader = null;
179
180
    /**
181
     *
182
     * @var Prose_Loader
183
     */
184
    private $proseLoader = null;
185
186
    // support for the current runtime config
187
    private $runtimeConfig = null;
188
    private $runtimeConfigManager = null;
189
190
    // our output
191
    private $output = null;
192
193
    /**
194
     *
195
     * @var \Datasift\Storyplayer\PlayerLib\Action_Logger
196
     */
197
    private $actionLogger;
198
199
    /**
200
     * which of the steps is currently being executed?
201
     * @var \DataSift\Storyplayer\Phases\Phase
202
     */
203
    private $currentPhase = null;
204
205
    // test device support
206
    private $deviceDetails = null;
207
    private $deviceName = null;
208
    private $deviceAdapter = null;
209
    private $persistDevice = false;
210
211
    // the config that Storyplayer is running with
212
    private $config = null;
213
214
    // the environment we are testing
215
    private $persistTestEnvironment = false;
216
217
    // story / template params
218
    private $defines = [];
0 ignored issues
show
Unused Code introduced by
The property $defines is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
219
220
    // our data formatter
221
    private $dataFormatter = null;
222
223
    // process support
224
    private $persistProcesses = false;
225
226
    // event support
227
    private $eventStream;
228
229
    public function __construct(Injectables $injectables)
230
    {
231
        // remember our output object
232
        $this->setOutput($injectables->output);
233
234
        // our data formatter
235
        $this->setDataFormatter($injectables->dataFormatter);
236
237
        // set a default page context
238
        $this->setPageContext(new PageContext);
239
240
        // create the actionlog
241
        $this->setActionLogger(new Action_Logger($injectables));
242
243
        // create an empty checkpoint
244
        $this->setCheckpoint(new Story_Checkpoint($this));
245
246
        // create our Prose Loader
247
        $this->setProseLoader($injectables->proseLoader);
248
249
        // create our Phase Loader
250
        $this->setPhaseLoader($injectables->phaseLoader);
251
252
        // remember the device we are testing with
253
        $this->setDevice($injectables->activeDeviceName, $injectables->activeDevice);
254
255
        // the config that we have loaded
256
        $this->setConfig($injectables->activeConfig);
257
258
        // our runtime config
259
        $this->setRuntimeConfig($injectables->getRuntimeConfig());
260
        $this->setRuntimeConfigManager($injectables->getRuntimeConfigManager());
261
262
        // our event support
263
        $this->setEventStream(new EventStream);
264
265
        self::$self = $this;
266
    }
267
268
    public static function instance()
269
    {
270
        return self::$self;
271
    }
272
273
    // ==================================================================
274
    //
275
    // Getters and setters go here
276
    //
277
    // ------------------------------------------------------------------
278
279
    /**
280
     *
281
     *
282
     * @return Action_Logger
283
     */
284
    public function getActionLogger() {
285
        return $this->actionLogger;
286
    }
287
288
    /**
289
     *
290
     *
291
     * @param Action_Logger $actionLogger
292
     * @return StoryTeller
293
     */
294
    public function setActionLogger(Action_Logger $actionLogger) {
295
        $this->actionLogger = $actionLogger;
296
297
        return $this;
298
    }
299
300
    /**
301
     *
302
     *
303
     * @return Story_Checkpoint
304
     */
305
    public function getCheckpoint() {
306
        return $this->checkpoint;
307
    }
308
309
    /**
310
     *
311
     *
312
     * @param Story_Checkpoint $checkpoint
313
     * @return StoryTeller
314
     */
315
    public function setCheckpoint(Story_Checkpoint $checkpoint) {
316
        $this->checkpoint = $checkpoint;
317
318
        return $this;
319
    }
320
321
    /**
322
     *
323
     *
324
     * @return PageContext
325
     */
326
    public function getPageContext() {
327
        return $this->pageContext;
328
    }
329
330
    /**
331
     *
332
     *
333
     * @param PageContext $pageContext
334
     * @return StoryTeller
335
     */
336
    public function setPageContext(PageContext $pageContext) {
337
        $this->pageContext = $pageContext;
338
339
        return $this;
340
    }
341
342
    /**
343
     *
344
     *
345
     * @return Story
346
     */
347
    public function getStory()
348
    {
349
        return $this->story;
350
    }
351
352
    /**
353
     * track the story that we are testing
354
     *
355
     * NOTE: setting the story also creates a new Story_Result object
356
     *       so that we can track how the story is getting on
357
     *
358
     * @param Story $story
359
     * @return StoryTeller
360
     */
361
    public function setStory(Story $story)
362
    {
363
        // are we already tracking this story?
364
        if ($this->story === $story) {
365
            return $this;
366
        }
367
368
        // we're now tracking this story
369
        $this->story = $story;
370
371
        // all done
372
        return $this;
373
    }
374
375
    /**
376
     * @return string
377
     */
378
    public function getScriptFilename()
379
    {
380
        return $this->scriptFilename;
381
    }
382
383
    /**
384
     * @return void
385
     */
386
    public function setScriptFilename($filename)
387
    {
388
        $this->scriptFilename = $filename;
389
    }
390
391
    /**
392
     *
393
     *
394
     * @return RuntimeConfigManager
395
     */
396
    public function getRuntimeConfigManager() {
397
        return $this->runtimeConfigManager;
398
    }
399
400
    /**
401
     *
402
     *
403
     * @param RuntimeConfigManager $runtimeConfigManager
404
     * @return StoryTeller
405
     */
406
    public function setRuntimeConfigManager(RuntimeConfigManager $runtimeConfigManager) {
407
        $this->runtimeConfigManager = $runtimeConfigManager;
408
409
        return $this;
410
    }
411
412
    /**
413
     *
414
     * @return Phase
415
     */
416
    public function getCurrentPhase()
417
    {
418
        return $this->currentPhase;
419
    }
420
421
    /**
422
     *
423
     * @return string
424
     */
425
    public function getCurrentPhaseName()
426
    {
427
        return $this->currentPhase->getPhaseName();
428
    }
429
430
    /**
431
     *
432
     * @param Phase $newPhase
433
     * @return void
434
     */
435
    public function setCurrentPhase(Phase $newPhase)
436
    {
437
        $this->currentPhase = $newPhase;
438
    }
439
440
    /**
441
     * @return void
442
     */
443
    public function setProseLoader($proseLoader)
444
    {
445
        $this->proseLoader = $proseLoader;
446
    }
447
448
    /**
449
     *
450
     * @return PhaseLoader
451
     */
452
    public function getPhaseLoader()
453
    {
454
        return $this->phaseLoader;
455
    }
456
457
    public function setPhaseLoader($phaseLoader)
458
    {
459
        $this->phaseLoader = $phaseLoader;
460
    }
461
462
    /**
463
     *
464
     * @return Output
465
     */
466
    public function getOutput()
467
    {
468
        return $this->output;
469
    }
470
471
    /**
472
     *
473
     * @param Output $output
474
     * @return void
475
     */
476
    public function setOutput(Output $output)
477
    {
478
        $this->output = $output;
479
    }
480
481
    public function setDataFormatter($dataFormatter)
482
    {
483
        $this->dataFormatter = $dataFormatter;
484
    }
485
486
    // ====================================================================
487
    //
488
    // Helpers to get parts of the story's context go here
489
    //
490
    // --------------------------------------------------------------------
491
492
    /**
493
     * @return object
494
     */
495
    public function getConfig()
496
    {
497
        // get our config
498
        $return = $this->config->getExpandedConfig();
499
500
        // all done
501
        return $return;
502
    }
503
504
    /**
505
     * @return \DataSift\Storyplayer\ConfigLib\ActiveConfig
506
     */
507
    public function getActiveConfig()
508
    {
509
        return $this->config;
510
    }
511
512
    /**
513
     * @return void
514
     */
515
    public function setConfig($config)
516
    {
517
        $this->config = $config;
518
    }
519
520
    /**
521
     * @return object
522
     */
523
    public function getRuntimeConfig()
524
    {
525
        return $this->runtimeConfig;
526
    }
527
528
    /**
529
     * @return void
530
     */
531
    public function setRuntimeConfig($runtimeConfig)
532
    {
533
        $this->runtimeConfig = $runtimeConfig;
534
    }
535
536
    /**
537
     * @return void
538
     */
539
    public function saveRuntimeConfig()
540
    {
541
        if (!isset($this->runtimeConfigManager)) {
542
            throw Exceptions::newActionFailedException(__METHOD__, "no runtimeConfigManager available");
543
        }
544
545
        $this->runtimeConfigManager->saveRuntimeConfig($this->runtimeConfig, $this->output);
546
    }
547
548
    // ==================================================================
549
    //
550
    // System under test support
551
    //
552
    // ------------------------------------------------------------------
553
554
    public function getSystemUnderTestConfig()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
555
    {
556
        return $this->config->getExpandedConfig('systemundertest');
557
    }
558
559
    // ==================================================================
560
    //
561
    // Test environment support
562
    //
563
    // ------------------------------------------------------------------
564
565
    /**
566
     * @return object
567
     */
568
    public function getTestEnvironmentConfig()
569
    {
570
        $retval = $this->config->getExpandedConfig();
571
        return $retval->target;
572
    }
573
574
    /**
575
     * @return string
576
     */
577
    public function getTestEnvironmentName()
578
    {
579
        $envConfig = $this->getTestEnvironmentConfig();
580
        return $envConfig->name;
581
    }
582
583
    /**
584
     * @return string
585
     */
586
    public function getTestEnvironmentSignature()
587
    {
588
        return md5(json_encode($this->getTestEnvironmentConfig()));
589
    }
590
591
    /**
592
     * @return bool
593
     */
594
    public function getPersistTestEnvironment()
595
    {
596
        return $this->persistTestEnvironment;
597
    }
598
599
    /**
600
     * @return void
601
     */
602
    public function setPersistTestEnvironment()
603
    {
604
        $this->persistTestEnvironment = true;
605
    }
606
607
    // ==================================================================
608
    //
609
    // Test user support
610
    //
611
    // ------------------------------------------------------------------
612
613
    /**
614
     * have we loaded test users off disk at all?
615
     *
616
     * @var boolean
617
     */
618
    private $hasTestUsers = false;
619
620
    /**
621
     * our list of test users
622
     *
623
     * @var null|\DataSift\Stone\ObjectLib\BaseObject
624
     */
625
    private $testUsers = null;
626
627
    /**
628
     * should we treat the file we loaded test users from as read-only?
629
     *
630
     * @var boolean
631
     */
632
    private $testUsersFileIsReadOnly = false;
633
634
    /**
635
     * which file did we load the test users from?
636
     *
637
     * @var string
638
     */
639
    private $testUsersFilename = null;
640
641
    /**
642
     * return the list of test users
643
     *
644
     * @return \DataSift\Stone\ObjectLib\BaseObject
645
     */
646
    public function getTestUsers()
647
    {
648
        // make sure we have an object to return
649
        if (!isset($this->testUsers)) {
650
            $this->testUsers = new BaseObject;
651
        }
652
653
        return $this->testUsers;
654
    }
655
656
    /**
657
     * have we loaded any test users from disk?
658
     *
659
     * @return boolean
660
     *         TRUE if we have
661
     */
662
    public function hasTestUsers()
663
    {
664
        return $this->hasTestUsers;
665
    }
666
667
    /**
668
     * remember the test users that we have
669
     *
670
     * @param \DataSift\Stone\ObjectLib\BaseObject $users
671
     *        our test users
672
     */
673
    public function setTestUsers($users)
674
    {
675
        $this->testUsers = $users;
676
        $this->hasTestUsers = true;
677
    }
678
679
    /**
680
     * retrieve the filename we loaded test users from
681
     *
682
     * @return string
683
     */
684
    public function getTestUsersFilename()
685
    {
686
        return $this->testUsersFilename;
687
    }
688
689
    /**
690
     * remember the filename we loaded test users from
691
     *
692
     * we'll re-use this filename later on when it is time to save
693
     * the test users back to disk
694
     *
695
     * @param string $filename
696
     *        the filename to remember
697
     */
698
    public function setTestUsersFilename($filename)
699
    {
700
        $this->testUsersFilename = $filename;
701
        $this->hasTestUsers = true;
702
    }
703
704
    /**
705
     * should we treat the file on disk where we loaded test user
706
     * data from as read-only?
707
     *
708
     * NOTE:
709
     *
710
     * we never treat the loaded data as read-only. Stories are
711
     * free to change this data, and these changes will persist
712
     * between stories. We just won't save any changes back to
713
     * disk if this method call returns TRUE.
714
     *
715
     * @return boolean
716
     */
717
    public function getTestUsersFileIsReadOnly()
718
    {
719
        return $this->testUsersFileIsReadOnly;
720
    }
721
722
    /**
723
     * set whether or not we treat the file on disk were we loaded
724
     * test user data from as read-only
725
     *
726
     * NOTE:
727
     *
728
     * we never treat the loaded data as read-only. Stories are
729
     * free to change this data, and these changes will persist
730
     * between stories. We just won't save any changes back to
731
     * disk if you set this to TRUE.
732
     *
733
     * @param boolean $readOnly
734
     *        TRUE if we should not save data back to this file
735
     */
736
    public function setTestUsersFileIsReadOnly($readOnly = true)
737
    {
738
        $this->testUsersFileIsReadOnly = $readOnly;
739
    }
740
741
    // ==================================================================
742
    //
743
    // Per-story parameter support
744
    //
745
    // ------------------------------------------------------------------
746
747
    /**
748
     * @return array
749
     */
750
    public function getParams()
751
    {
752
        // get the current parameters from the story
753
        //
754
        // NOTE that we deliberately don't cache $return in here, as
755
        // the parameters storied in the story can (in theory) change
756
        // at any moment
757
        //
758
        // NOTE that these are (deliberately) completely independent
759
        // from anything set using -D on the command-line
760
        //
761
        // parameters are now simply a way for stories to pass settings
762
        // into StoryTemplates that they are based upon, nothing more
763
        return $this->getStory()->getParams();
764
    }
765
766
    // ==================================================================
767
    //
768
    // Accessors of other containers go here
769
    //
770
    // ------------------------------------------------------------------
771
772
    /**
773
     *
774
     * @param  string $methodName
775
     * @param  array  $methodArgs
776
     * @return mixed
777
     */
778
    public function __call($methodName, $methodArgs)
779
    {
780
        // what class do we want?
781
        $className = $this->proseLoader->determineProseClassFor($methodName);
782
783
        // use the Prose Loader to create the object to call
784
        $obj = $this->proseLoader->loadProse($this, $className, $methodArgs);
785
786
        // did we find something?
787
        if (!is_object($obj)) {
788
            // alas, no
789
            throw new E5xx_NoMatchingActions($methodName);
790
        }
791
792
        // all done
793
        return $obj;
794
    }
795
796
    // ==================================================================
797
    //
798
    // Logging support
799
    //
800
    // ------------------------------------------------------------------
801
802
    /**
803
     * @return Action_LogItem
804
     */
805
    public function startAction($text)
806
    {
807
        return $this->actionLogger->startAction($text);
808
    }
809
810
    /**
811
     * @return void
812
     */
813
    public function closeAllOpenActions()
814
    {
815
        return $this->actionLogger->closeAllOpenActions();
816
    }
817
818
    /**
819
     * @return void
820
     */
821
    public function convertDataForOutput($data)
822
    {
823
        return $this->dataFormatter->convertData($data);
824
    }
825
826
    // ==================================================================
827
    //
828
    // Device support
829
    //
830
    // ------------------------------------------------------------------
831
832
    /**
833
     * @return bool
834
     */
835
    public function getPersistDevice()
836
    {
837
        return $this->persistDevice;
838
    }
839
840
    /**
841
     * @return void
842
     */
843
    public function setPersistDevice()
844
    {
845
        $this->persistDevice = true;
846
    }
847
848
    /**
849
     * @return BaseObject
850
     */
851
    public function getDeviceDetails()
852
    {
853
        return $this->deviceDetails;
854
    }
855
856
    /**
857
     * @return \DataSift\Storyplayer\DeviceLib\DeviceAdapter
858
     */
859
    public function getDeviceAdapter()
860
    {
861
        if (!isset($this->deviceAdapter)) {
862
            return null;
863
        }
864
865
        return $this->deviceAdapter;
866
    }
867
868
    /**
869
     * @param DeviceLib\DeviceAdapter|null $adapter
870
     */
871
    public function setDeviceAdapter($adapter)
872
    {
873
        $this->deviceAdapter = $adapter;
874
875
        return $this;
876
    }
877
878
    /**
879
     * @return string
880
     */
881
    public function getDeviceName()
882
    {
883
        return $this->deviceName;
884
    }
885
886
    /**
887
     * @return \DataSift\WebDriver\WebDriverSession
0 ignored issues
show
Documentation introduced by
Should the return type not be \DataSift\WebDriver\WebDriverSession|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
888
     */
889
    public function getRunningDevice()
890
    {
891
        if (!is_object($this->deviceAdapter))
892
        {
893
            $this->startDevice();
894
        }
895
896
        if (!is_object($this->deviceAdapter))
897
        {
898
            throw new E5xx_CannotStartDevice();
899
        }
900
901
        return $this->deviceAdapter->getDevice();
902
    }
903
904
    /**
905
     * @param string $deviceName
906
     * @param BaseObject $deviceDetails
907
     */
908
    public function setDevice($deviceName, $deviceDetails)
909
    {
910
        $this->deviceName    = $deviceName;
911
        $this->deviceDetails = $deviceDetails;
912
    }
913
914
    /**
915
     * @return void
916
     */
917
    public function startDevice()
918
    {
919
        // what are we doing?
920
        $log = $this->startAction('start the test device');
921
922
        // what sort of browser are we starting?
923
        $deviceDetails = $this->getDeviceDetails();
924
925
        // get the adapter
926
        $adapter = DeviceLib::getDeviceAdapter($deviceDetails);
927
928
        // initialise the adapter
929
        $adapter->init($deviceDetails);
930
931
        // start the browser
932
        $adapter->start($this);
933
934
        // remember the adapter
935
        $this->setDeviceAdapter($adapter);
936
937
        // do we have a deviceSetup() phase?
938
        if (isset($this->story) && $this->story->hasDeviceSetup()) {
939
            // get the callbacks to call
940
            $callbacks = $this->story->getDeviceSetup();
941
942
            // make the call
943
            //
944
            // we do not need to wrap these in a TRY/CATCH block,
945
            // as we are already running inside one of the story's
946
            // phases
947
            foreach ($callbacks as $callback){
948
                call_user_func($callback, $this);
949
            }
950
        }
951
952
        // all done
953
        $log->endAction();
954
    }
955
956
    /**
957
     * @return void
958
     */
959
    public function stopDevice()
960
    {
961
        // get the browser adapter
962
        $adapter = $this->getDeviceAdapter();
963
964
        // stop the web browser
965
        if (!$adapter) {
966
            // nothing to do
967
            // silently return
968
            return;
969
        }
970
971
        // what are we doing?
972
        $log = $this->startAction('stop the test device');
973
974
        // do we have a deviceTeardown() phase?
975
        //
976
        // we need to run this BEFORE we stop the device, otherwise
977
        // the deviceTeardown() phase has no device to work with
978
        if (isset($this->story) && $this->story->hasDeviceTeardown()) {
979
            // get the callbacks to call
980
            $callbacks = $this->story->getDeviceTeardown();
981
982
            // make the call
983
            //
984
            // we do not need to wrap these in a TRY/CATCH block,
985
            // as we are already running inside one of the story's
986
            // phases
987
            foreach ($callbacks as $callback){
988
                call_user_func($callback, $this);
989
            }
990
        }
991
992
        // stop the browser
993
        $adapter->stop();
994
995
        // destroy the adapter
996
        $this->setDeviceAdapter(null);
997
998
        // all done
999
        $log->endAction();
1000
    }
1001
1002
    // ==================================================================
1003
    //
1004
    // Processes support
1005
    //
1006
    // ------------------------------------------------------------------
1007
1008
    /**
1009
     * @return bool
1010
     */
1011
    public function getPersistProcesses()
1012
    {
1013
        return $this->persistProcesses;
1014
    }
1015
1016
    /**
1017
     * @return void
1018
     */
1019
    public function setPersistProcesses()
1020
    {
1021
        $this->persistProcesses = true;
1022
    }
1023
1024
    // ==================================================================
1025
    //
1026
    // Event support
1027
    //
1028
    // Events are used to decouple our code a little.
1029
    //
1030
    // ------------------------------------------------------------------
1031
1032
    public function getEventStream()
1033
    {
1034
        return $this->eventStream;
1035
    }
1036
1037
    public function setEventStream(EventStream $eventStream)
1038
    {
1039
        $this->eventStream = $eventStream;
1040
    }
1041
1042
    // ==================================================================
1043
    //
1044
    // Helpful methods that we can use to help with testing
1045
    //
1046
    // ------------------------------------------------------------------
1047
1048
    /**
1049
     * @return CommandRunner
1050
     */
1051
    public function getNewCommandRunner()
1052
    {
1053
        return new CommandRunner();
1054
    }
1055
1056
    // ==================================================================
1057
    //
1058
    // Features from v1 that we no longer support
1059
    //
1060
    // ------------------------------------------------------------------
1061
1062
    /**
1063
     * @return \Prose\FromEnvironment
1064
     */
1065
    public function getEnvironment()
1066
    {
1067
        return new \Prose\FromEnvironment($this);
1068
    }
1069
1070
    /**
1071
     * @return void
1072
     */
1073
    public function getEnvironmentName()
1074
    {
1075
        throw new E4xx_ObsoleteProse(
1076
            '$st->getEnvironmentName()',
1077
            '$st->fromTestEnvironment()->getName()'
1078
        );
1079
    }
1080
}
1081