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.
Completed
Push — hotfix/2.3.5 ( 6cc8bd )
by Stuart
10:01 queued 10s
created

StoryTeller::__call()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 6

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 17
rs 9.4286
cc 2
eloc 6
nc 2
nop 2
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
59
/**
60
 * our main facilitation class
61
 *
62
 * all actions and tests inside a story are executed through an instance
63
 * of this class, making this class the StoryTeller :)
64
 *
65
 * @method Prose\AssertsArray assertsArray(array $expected)
66
 * @method Prose\AssertsBoolean assertsBoolean(boolean $expected)
67
 * @method Prose\AssertsDouble assertsDouble(float $expected)
68
 * @method Prose\AssertsInteger assertsInteger(integer $expected)
69
 * @method Prose\AssertsObject assertsObject(object $expected)
70
 * @method Prose\AssertsString assertsString(string $expected)
71
 * @method Prose\ExpectsBrowser expectsBrowser()
72
 * @method Prose\ExpectsEc2Image expectsEc2Image(string $amiId)
73
 * @method Prose\ExpectsFailure expectsFailure()
74
 * @method Prose\ExpectsForm expectsForm(string $formId)
75
 * @method Prose\ExpectsGraphite expectsGraphite()
76
 * @method Prose\ExpectsHost expectsHost($hostDetails)
77
 * @method Prose\ExpectsHostsTable expectsHostsTable()
78
 * @method Prose\ExpectsHttpResponse expectsHttpResponse(HttpClientResponse $response)
79
 * @method Prose\ExpectsIframe expectsIframe(string $id)
80
 * @method Prose\ExpectsProcessesTable expectsProcessesTable()
81
 * @method Prose\ExpectsRuntimeTable expectsRuntimeTable(string $tableName)
82
 * @method Prose\ExpectsShell expectsShell()
83
 * @method Prose\ExpectsUuid expectsUuid()
84
 * @method Prose\ExpectsZmq expectsZmq()
85
 * @method Prose\FromAws fromAws()
86
 * @method Prose\FromBrowser fromBrowser()
87
 * @method Prose\FromCheckpoint fromCheckpoint()
88
 * @method Prose\FromConfig fromConfig()
89
 * @method Prose\FromCurl fromCurl()
90
 * @method Prose\FromEc2 fromEc2()
91
 * @method Prose\FromEc2Instance fromEc2Instance(string $hostname)
92
 * @method Prose\FromEnvironment fromEnvironment()
93
 * @method Prose\FromFacebook fromFacebook()
94
 * @method Prose\FromFile fromFile()
95
 * @method Prose\FromForm fromForm(string $formId)
96
 * @method Prose\FromGraphite fromGraphite()
97
 * @method Prose\FromHost fromHost(string $hostId)
98
 * @method Prose\FromHostsTable fromHostsTable()
99
 * @method Prose\FromHttp fromHttp()
100
 * @method Prose\FromIframe fromIframe(string $id)
101
 * @method Prose\FromProcessesTable fromProcessesTable()
102
 * @method Prose\FromRolesTable fromRolesTable()
103
 * @method Prose\FromRuntimeTable fromRuntimeTable(string $tableName)
104
 * @method Prose\FromRuntimeTableForTargetEnvironment fromRuntimeTableForTargetEnvironment()
105
 * @method Prose\FromSauceLabs fromSauceLabs()
106
 * @method Prose\FromShell fromShell()
107
 * @method Prose\FromStoryplayer fromStoryplayer()
108
 * @method Prose\FromSupervisor fromSupervisor()
109
 * @method Prose\FromTargetsTable fromTargetsTable()
110
 * @method Prose\FromTestEnvironment fromTestEnvironment()
111
 * @method Prose\FromUuid fromUuid()
112
 * @method Prose\UsingBrowser usingBrowser()
113
 * @method Prose\UsingCheckpoint usingCheckpoint()
114
 * @method Prose\UsingDoppeld usingDoppeld()
115
 * @method Prose\UsingEc2 usingEc2()
116
 * @method Prose\UsingEc2Instance usingEc2Instance(string $hostname)
117
 * @method Prose\UsingFacebookGraphApi usingFacebookGraphApi()
118
 * @method Prose\UsingFile usingFile()
119
 * @method Prose\UsingForm usingForm(string $formId)
120
 * @method Prose\UsingHornet usingHornet()
121
 * @method Prose\UsingHost usingHost(string $hostId)
122
 * @method Prose\UsingHostsTable usingHostsTable()
123
 * @method Prose\UsingHttp usingHttp()
124
 * @method Prose\UsingIframe usingIframe(string $id)
125
 * @method Prose\UsingLog usingLog()
126
 * @method Prose\UsingProcessesTable usingProcessesTable()
127
 * @method Prose\UsingProvisioning usingProvisioning()
128
 * @method Prose\UsingProvisioningDefinition usingProvisioningDefinition(ProvisioningDefinition $definition)
129
 * @method Prose\UsingProvisioningEngine usingProvisioningEngine(string $engine)
130
 * @method Prose\UsingReporting usingReporting()
131
 * @method Prose\UsingRolesTable usingRolesTable()
132
 * @method Prose\UsingRuntimeTable usingRuntimeTable(string $tableName)
133
 * @method Prose\UsingRuntimeTableForTargetEnvironment usingRuntimeTableForTargetEnvironment()
134
 * @method Prose\UsingSauceLabs usingSauceLabs()
135
 * @method Prose\UsingSavageD usingSavageD()
136
 * @method Prose\UsingShell usingShell()
137
 * @method Prose\UsingTargetsTable usingTargetsTable()
138
 * @method Prose\UsingTimer usingTimer()
139
 * @method Prose\UsingVagrant usingVagrant()
140
 * @method Prose\UsingYamlFile usingYamlFile(string $filename)
141
 * @method Prose\UsingZmq usingZmq()
142
 * @method Prose\UsingZookeeper usingZookeeper(string $hostname)
143
 *
144
 * @category  Libraries
145
 * @package   Storyplayer/PlayerLib
146
 * @author    Stuart Herbert <[email protected]>
147
 * @copyright 2011-present Mediasift Ltd www.datasift.com
148
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
149
 * @link      http://datasift.github.io/storyplayer
150
 */
151
class StoryTeller
152
{
153
    /**
154
     * singleton instance of StoryTeller
155
     * @var StoryTeller
156
     */
157
    static protected $self = null;
158
159
    /**
160
     * the story that is being played
161
     * @var Story
162
     */
163
    private $story = null;
164
165
    private $pageContext = null;
166
    private $checkpoint = null;
167
168
    /**
169
     * the script that is being played
170
     */
171
    private $scriptFilename = null;
172
173
    /**
174
     *
175
     * @var PhaseLoader
176
     */
177
    private $phaseLoader = null;
178
179
    /**
180
     *
181
     * @var Prose_Loader
182
     */
183
    private $proseLoader = null;
184
185
    // support for the current runtime config
186
    private $runtimeConfig = null;
187
    private $runtimeConfigManager = null;
188
189
    // our output
190
    private $output = null;
191
192
    /**
193
     *
194
     * @var \Datasift\Storyplayer\PlayerLib\Action_Logger
195
     */
196
    private $actionLogger;
197
198
    /**
199
     * which of the steps is currently being executed?
200
     * @var \DataSift\Storyplayer\Phases\Phase
201
     */
202
    private $currentPhase = null;
203
204
    // test device support
205
    private $deviceDetails = null;
206
    private $deviceName = null;
207
    private $deviceAdapter = null;
208
    private $persistDevice = false;
209
210
    // the config that Storyplayer is running with
211
    private $config = null;
212
213
    // the environment we are testing
214
    private $persistTestEnvironment = false;
215
216
    // story / template params
217
    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...
218
219
    // our data formatter
220
    private $dataFormatter = null;
221
222
    // process support
223
    private $persistProcesses = false;
224
225
    public function __construct(Injectables $injectables)
226
    {
227
        // remember our output object
228
        $this->setOutput($injectables->output);
229
230
        // our data formatter
231
        $this->setDataFormatter($injectables->dataFormatter);
232
233
        // set a default page context
234
        $this->setPageContext(new PageContext);
235
236
        // create the actionlog
237
        $this->setActionLogger(new Action_Logger($injectables));
238
239
        // create an empty checkpoint
240
        $this->setCheckpoint(new Story_Checkpoint($this));
241
242
        // create our Prose Loader
243
        $this->setProseLoader($injectables->proseLoader);
244
245
        // create our Phase Loader
246
        $this->setPhaseLoader($injectables->phaseLoader);
247
248
        // remember the device we are testing with
249
        $this->setDevice($injectables->activeDeviceName, $injectables->activeDevice);
250
251
        // the config that we have loaded
252
        $this->setConfig($injectables->activeConfig);
253
254
        // our runtime config
255
        $this->setRuntimeConfig($injectables->getRuntimeConfig());
256
        $this->setRuntimeConfigManager($injectables->getRuntimeConfigManager());
257
258
        self::$self = $this;
259
    }
260
261
    public static function instance()
262
    {
263
        return self::$self;
264
    }
265
266
    // ==================================================================
267
    //
268
    // Getters and setters go here
269
    //
270
    // ------------------------------------------------------------------
271
272
    /**
273
     *
274
     *
275
     * @return Action_Logger
276
     */
277
    public function getActionLogger() {
278
        return $this->actionLogger;
279
    }
280
281
    /**
282
     *
283
     *
284
     * @param Action_Logger $actionLogger
285
     * @return StoryTeller
286
     */
287
    public function setActionLogger(Action_Logger $actionLogger) {
288
        $this->actionLogger = $actionLogger;
289
290
        return $this;
291
    }
292
293
    /**
294
     *
295
     *
296
     * @return Story_Checkpoint
297
     */
298
    public function getCheckpoint() {
299
        return $this->checkpoint;
300
    }
301
302
    /**
303
     *
304
     *
305
     * @param Story_Checkpoint $checkpoint
306
     * @return StoryTeller
307
     */
308
    public function setCheckpoint(Story_Checkpoint $checkpoint) {
309
        $this->checkpoint = $checkpoint;
310
311
        return $this;
312
    }
313
314
    /**
315
     *
316
     *
317
     * @return PageContext
318
     */
319
    public function getPageContext() {
320
        return $this->pageContext;
321
    }
322
323
    /**
324
     *
325
     *
326
     * @param PageContext $pageContext
327
     * @return StoryTeller
328
     */
329
    public function setPageContext(PageContext $pageContext) {
330
        $this->pageContext = $pageContext;
331
332
        return $this;
333
    }
334
335
    /**
336
     *
337
     *
338
     * @return Story
339
     */
340
    public function getStory()
341
    {
342
        return $this->story;
343
    }
344
345
    /**
346
     * track the story that we are testing
347
     *
348
     * NOTE: setting the story also creates a new Story_Result object
349
     *       so that we can track how the story is getting on
350
     *
351
     * @param Story $story
352
     * @return StoryTeller
353
     */
354
    public function setStory(Story $story)
355
    {
356
        // are we already tracking this story?
357
        if ($this->story == $story) {
358
            return $this;
359
        }
360
361
        // we're now tracking this story
362
        $this->story = $story;
363
364
        // all done
365
        return $this;
366
    }
367
368
    /**
369
     * @return string
370
     */
371
    public function getScriptFilename()
372
    {
373
        return $this->scriptFilename;
374
    }
375
376
    /**
377
     * @return void
378
     */
379
    public function setScriptFilename($filename)
380
    {
381
        $this->scriptFilename = $filename;
382
    }
383
384
    /**
385
     *
386
     *
387
     * @return RuntimeConfigManager
388
     */
389
    public function getRuntimeConfigManager() {
390
        return $this->runtimeConfigManager;
391
    }
392
393
    /**
394
     *
395
     *
396
     * @param RuntimeConfigManager $runtimeConfigManager
397
     * @return StoryTeller
398
     */
399
    public function setRuntimeConfigManager(RuntimeConfigManager $runtimeConfigManager) {
400
        $this->runtimeConfigManager = $runtimeConfigManager;
401
402
        return $this;
403
    }
404
405
    /**
406
     *
407
     * @return Phase
408
     */
409
    public function getCurrentPhase()
410
    {
411
        return $this->currentPhase;
412
    }
413
414
    /**
415
     *
416
     * @return string
417
     */
418
    public function getCurrentPhaseName()
419
    {
420
        return $this->currentPhase->getPhaseName();
421
    }
422
423
    /**
424
     *
425
     * @param Phase $newPhase
426
     * @return void
427
     */
428
    public function setCurrentPhase(Phase $newPhase)
429
    {
430
        $this->currentPhase = $newPhase;
431
    }
432
433
    /**
434
     * @return void
435
     */
436
    public function setProseLoader($proseLoader)
437
    {
438
        $this->proseLoader = $proseLoader;
439
    }
440
441
    /**
442
     *
443
     * @return PhaseLoader
444
     */
445
    public function getPhaseLoader()
446
    {
447
        return $this->phaseLoader;
448
    }
449
450
    public function setPhaseLoader($phaseLoader)
451
    {
452
        $this->phaseLoader = $phaseLoader;
453
    }
454
455
    /**
456
     *
457
     * @return Output
458
     */
459
    public function getOutput()
460
    {
461
        return $this->output;
462
    }
463
464
    /**
465
     *
466
     * @param Output $output
467
     * @return void
468
     */
469
    public function setOutput(Output $output)
470
    {
471
        $this->output = $output;
472
    }
473
474
    public function setDataFormatter($dataFormatter)
475
    {
476
        $this->dataFormatter = $dataFormatter;
477
    }
478
479
    // ====================================================================
480
    //
481
    // Helpers to get parts of the story's context go here
482
    //
483
    // --------------------------------------------------------------------
484
485
    /**
486
     * @return object
487
     */
488
    public function getConfig()
489
    {
490
        // get our config
491
        $return = $this->config->getExpandedConfig();
492
493
        // all done
494
        return $return;
495
    }
496
497
    /**
498
     * @return \DataSift\Storyplayer\ConfigLib\ActiveConfig
499
     */
500
    public function getActiveConfig()
501
    {
502
        return $this->config;
503
    }
504
505
    /**
506
     * @return void
507
     */
508
    public function setConfig($config)
509
    {
510
        $this->config = $config;
511
    }
512
513
    /**
514
     * @return object
515
     */
516
    public function getRuntimeConfig()
517
    {
518
        return $this->runtimeConfig;
519
    }
520
521
    /**
522
     * @return void
523
     */
524
    public function setRuntimeConfig($runtimeConfig)
525
    {
526
        $this->runtimeConfig = $runtimeConfig;
527
    }
528
529
    /**
530
     * @return void
531
     */
532
    public function saveRuntimeConfig()
533
    {
534
        if (!isset($this->runtimeConfigManager)) {
535
            throw new E5xx_ActionFailed(__METHOD__, "no runtimeConfigManager available");
536
        }
537
538
        $this->runtimeConfigManager->saveRuntimeConfig($this->runtimeConfig, $this->output);
539
    }
540
541
    // ==================================================================
542
    //
543
    // System under test support
544
    //
545
    // ------------------------------------------------------------------
546
547
    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...
548
    {
549
        return $this->config->getExpandedConfig('systemundertest');
550
    }
551
552
    // ==================================================================
553
    //
554
    // Test environment support
555
    //
556
    // ------------------------------------------------------------------
557
558
    /**
559
     * @return object
560
     */
561
    public function getTestEnvironmentConfig()
562
    {
563
        $retval = $this->config->getExpandedConfig();
564
        return $retval->target;
565
    }
566
567
    /**
568
     * @return string
569
     */
570
    public function getTestEnvironmentName()
571
    {
572
        $envConfig = $this->getTestEnvironmentConfig();
573
        return $envConfig->name;
574
    }
575
576
    /**
577
     * @return string
578
     */
579
    public function getTestEnvironmentSignature()
580
    {
581
        return md5(json_encode($this->getTestEnvironmentConfig()));
582
    }
583
584
    /**
585
     * @return bool
586
     */
587
    public function getPersistTestEnvironment()
588
    {
589
        return $this->persistTestEnvironment;
590
    }
591
592
    /**
593
     * @return void
594
     */
595
    public function setPersistTestEnvironment()
596
    {
597
        $this->persistTestEnvironment = true;
598
    }
599
600
    // ==================================================================
601
    //
602
    // Test user support
603
    //
604
    // ------------------------------------------------------------------
605
606
    /**
607
     * have we loaded test users off disk at all?
608
     *
609
     * @var boolean
610
     */
611
    private $hasTestUsers = false;
612
613
    /**
614
     * our list of test users
615
     *
616
     * @var null|\DataSift\Stone\ObjectLib\BaseObject
617
     */
618
    private $testUsers = null;
619
620
    /**
621
     * should we treat the file we loaded test users from as read-only?
622
     *
623
     * @var boolean
624
     */
625
    private $testUsersFileIsReadOnly = false;
626
627
    /**
628
     * which file did we load the test users from?
629
     *
630
     * @var string
631
     */
632
    private $testUsersFilename = null;
633
634
    /**
635
     * return the list of test users
636
     *
637
     * @return \DataSift\Stone\ObjectLib\BaseObject
638
     */
639
    public function getTestUsers()
640
    {
641
        // make sure we have an object to return
642
        if (!isset($this->testUsers)) {
643
            $this->testUsers = new BaseObject;
644
        }
645
646
        return $this->testUsers;
647
    }
648
649
    /**
650
     * have we loaded any test users from disk?
651
     *
652
     * @return boolean
653
     *         TRUE if we have
654
     */
655
    public function hasTestUsers()
656
    {
657
        return $this->hasTestUsers;
658
    }
659
660
    /**
661
     * remember the test users that we have
662
     *
663
     * @param \DataSift\Stone\ObjectLib\BaseObject $users
664
     *        our test users
665
     */
666
    public function setTestUsers($users)
667
    {
668
        $this->testUsers = $users;
669
        $this->hasTestUsers = true;
670
    }
671
672
    /**
673
     * retrieve the filename we loaded test users from
674
     *
675
     * @return string
676
     */
677
    public function getTestUsersFilename()
678
    {
679
        return $this->testUsersFilename;
680
    }
681
682
    /**
683
     * remember the filename we loaded test users from
684
     *
685
     * we'll re-use this filename later on when it is time to save
686
     * the test users back to disk
687
     *
688
     * @param string $filename
689
     *        the filename to remember
690
     */
691
    public function setTestUsersFilename($filename)
692
    {
693
        $this->testUsersFilename = $filename;
694
        $this->hasTestUsers = true;
695
    }
696
697
    /**
698
     * should we treat the file on disk where we loaded test user
699
     * data from as read-only?
700
     *
701
     * NOTE:
702
     *
703
     * we never treat the loaded data as read-only. Stories are
704
     * free to change this data, and these changes will persist
705
     * between stories. We just won't save any changes back to
706
     * disk if this method call returns TRUE.
707
     *
708
     * @return boolean
709
     */
710
    public function getTestUsersFileIsReadOnly()
711
    {
712
        return $this->testUsersFileIsReadOnly;
713
    }
714
715
    /**
716
     * set whether or not we treat the file on disk were we loaded
717
     * test user data from as read-only
718
     *
719
     * NOTE:
720
     *
721
     * we never treat the loaded data as read-only. Stories are
722
     * free to change this data, and these changes will persist
723
     * between stories. We just won't save any changes back to
724
     * disk if you set this to TRUE.
725
     *
726
     * @param boolean $readOnly
727
     *        TRUE if we should not save data back to this file
728
     */
729
    public function setTestUsersFileIsReadOnly($readOnly = true)
730
    {
731
        $this->testUsersFileIsReadOnly = $readOnly;
732
    }
733
734
    // ==================================================================
735
    //
736
    // Per-story parameter support
737
    //
738
    // ------------------------------------------------------------------
739
740
    /**
741
     * @return array
742
     */
743
    public function getParams()
744
    {
745
        // get the current parameters from the story
746
        //
747
        // NOTE that we deliberately don't cache $return in here, as
748
        // the parameters storied in the story can (in theory) change
749
        // at any moment
750
        //
751
        // NOTE that these are (deliberately) completely independent
752
        // from anything set using -D on the command-line
753
        //
754
        // parameters are now simply a way for stories to pass settings
755
        // into StoryTemplates that they are based upon, nothing more
756
        return $this->getStory()->getParams();
757
    }
758
759
    // ==================================================================
760
    //
761
    // Accessors of other containers go here
762
    //
763
    // ------------------------------------------------------------------
764
765
    /**
766
     *
767
     * @param  string $methodName
768
     * @param  array  $methodArgs
769
     * @return mixed
770
     */
771
    public function __call($methodName, $methodArgs)
772
    {
773
        // what class do we want?
774
        $className = $this->proseLoader->determineProseClassFor($methodName);
775
776
        // use the Prose Loader to create the object to call
777
        $obj = $this->proseLoader->loadProse($this, $className, $methodArgs);
778
779
        // did we find something?
780
        if (!is_object($obj)) {
781
            // alas, no
782
            throw new E5xx_NoMatchingActions($methodName);
783
        }
784
785
        // all done
786
        return $obj;
787
    }
788
789
    // ==================================================================
790
    //
791
    // Logging support
792
    //
793
    // ------------------------------------------------------------------
794
795
    /**
796
     * @return Action_LogItem
797
     */
798
    public function startAction($text)
799
    {
800
        return $this->actionLogger->startAction($text);
801
    }
802
803
    /**
804
     * @return void
805
     */
806
    public function closeAllOpenActions()
807
    {
808
        return $this->actionLogger->closeAllOpenActions();
809
    }
810
811
    /**
812
     * @return void
813
     */
814
    public function convertDataForOutput($data)
815
    {
816
        return $this->dataFormatter->convertData($data);
817
    }
818
819
    // ==================================================================
820
    //
821
    // Device support
822
    //
823
    // ------------------------------------------------------------------
824
825
    /**
826
     * @return bool
827
     */
828
    public function getPersistDevice()
829
    {
830
        return $this->persistDevice;
831
    }
832
833
    /**
834
     * @return void
835
     */
836
    public function setPersistDevice()
837
    {
838
        $this->persistDevice = true;
839
    }
840
841
    /**
842
     * @return BaseObject
843
     */
844
    public function getDeviceDetails()
845
    {
846
        return $this->deviceDetails;
847
    }
848
849
    /**
850
     * @return \DataSift\Storyplayer\DeviceLib\DeviceAdapter
851
     */
852
    public function getDeviceAdapter()
853
    {
854
        if (!isset($this->deviceAdapter)) {
855
            return null;
856
        }
857
858
        return $this->deviceAdapter;
859
    }
860
861
    /**
862
     * @param DeviceLib\DeviceAdapter|null $adapter
863
     */
864
    public function setDeviceAdapter($adapter)
865
    {
866
        $this->deviceAdapter = $adapter;
867
868
        return $this;
869
    }
870
871
    /**
872
     * @return string
873
     */
874
    public function getDeviceName()
875
    {
876
        return $this->deviceName;
877
    }
878
879
    /**
880
     * @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...
881
     */
882
    public function getRunningDevice()
883
    {
884
        if (!is_object($this->deviceAdapter))
885
        {
886
            $this->startDevice();
887
        }
888
889
        if (!is_object($this->deviceAdapter))
890
        {
891
            throw new E5xx_CannotStartDevice();
892
        }
893
894
        return $this->deviceAdapter->getDevice();
895
    }
896
897
    /**
898
     * @param string $deviceName
899
     * @param BaseObject $deviceDetails
900
     */
901
    public function setDevice($deviceName, $deviceDetails)
902
    {
903
        $this->deviceName    = $deviceName;
904
        $this->deviceDetails = $deviceDetails;
905
    }
906
907
    /**
908
     * @return void
909
     */
910
    public function startDevice()
911
    {
912
        // what are we doing?
913
        $log = $this->startAction('start the test device');
914
915
        // what sort of browser are we starting?
916
        $deviceDetails = $this->getDeviceDetails();
917
918
        // get the adapter
919
        $adapter = DeviceLib::getDeviceAdapter($deviceDetails);
920
921
        // initialise the adapter
922
        $adapter->init($deviceDetails);
923
924
        // start the browser
925
        $adapter->start($this);
926
927
        // remember the adapter
928
        $this->setDeviceAdapter($adapter);
929
930
        // do we have a deviceSetup() phase?
931
        if (isset($this->story) && $this->story->hasDeviceSetup()) {
932
            // get the callbacks to call
933
            $callbacks = $this->story->getDeviceSetup();
934
935
            // make the call
936
            //
937
            // we do not need to wrap these in a TRY/CATCH block,
938
            // as we are already running inside one of the story's
939
            // phases
940
            foreach ($callbacks as $callback){
941
                call_user_func($callback, $this);
942
            }
943
        }
944
945
        // all done
946
        $log->endAction();
947
    }
948
949
    /**
950
     * @return void
951
     */
952
    public function stopDevice()
953
    {
954
        // get the browser adapter
955
        $adapter = $this->getDeviceAdapter();
956
957
        // stop the web browser
958
        if (!$adapter) {
959
            // nothing to do
960
            return;
961
        }
962
963
        // what are we doing?
964
        $log = $this->startAction('stop the test device');
965
966
        // do we have a deviceTeardown() phase?
967
        //
968
        // we need to run this BEFORE we stop the device, otherwise
969
        // the deviceTeardown() phase has no device to work with
970
        if (isset($this->story) && $this->story->hasDeviceTeardown()) {
971
            // get the callbacks to call
972
            $callbacks = $this->story->getDeviceTeardown();
973
974
            // make the call
975
            //
976
            // we do not need to wrap these in a TRY/CATCH block,
977
            // as we are already running inside one of the story's
978
            // phases
979
            foreach ($callbacks as $callback){
980
                call_user_func($callback, $this);
981
            }
982
        }
983
984
        // stop the browser
985
        $adapter->stop();
986
987
        // destroy the adapter
988
        $this->setDeviceAdapter(null);
989
990
        // all done
991
        $log->endAction();
992
    }
993
994
    // ==================================================================
995
    //
996
    // Processes support
997
    //
998
    // ------------------------------------------------------------------
999
1000
    /**
1001
     * @return bool
1002
     */
1003
    public function getPersistProcesses()
1004
    {
1005
        return $this->persistProcesses;
1006
    }
1007
1008
    /**
1009
     * @return void
1010
     */
1011
    public function setPersistProcesses()
1012
    {
1013
        $this->persistProcesses = true;
1014
    }
1015
1016
    // ==================================================================
1017
    //
1018
    // Helpful methods that we can use to help with testing
1019
    //
1020
    // ------------------------------------------------------------------
1021
1022
    /**
1023
     * @return CommandRunner
1024
     */
1025
    public function getNewCommandRunner()
1026
    {
1027
        return new CommandRunner();
1028
    }
1029
1030
    // ==================================================================
1031
    //
1032
    // Features from v1 that we no longer support
1033
    //
1034
    // ------------------------------------------------------------------
1035
1036
    /**
1037
     * @return \Prose\FromEnvironment
1038
     */
1039
    public function getEnvironment()
1040
    {
1041
        return new \Prose\FromEnvironment($this);
1042
    }
1043
1044
    /**
1045
     * @return void
1046
     */
1047
    public function getEnvironmentName()
1048
    {
1049
        throw new E4xx_ObsoleteProse(
1050
            '$st->getEnvironmentName()',
1051
            '$st->fromTestEnvironment()->getName()'
1052
        );
1053
    }
1054
}
1055