DebugContext   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 10
dl 0
loc 127
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A iPutABreakpoint() 0 9 2
A iSaveAScreenshotIn() 0 5 1
A failScreenshots() 0 21 3
A displayProfilerLink() 0 9 2
A getScenario() 0 17 3
A getBackground() 0 18 3
A saveScreenshot() 0 8 2
1
<?php
2
3
namespace Behatch\Context;
4
5
use Behat\Gherkin\Node\StepNode;
6
use Behat\Behat\Hook\Scope\AfterStepScope;
7
use Behat\Mink\Exception\UnsupportedDriverActionException;
8
9
class DebugContext extends BaseContext
10
{
11
    /**
12
     * @var string
13
     */
14
    private $screenshotDir;
15
16
    public function __construct($screenshotDir = '.')
17
    {
18
        $this->screenshotDir = $screenshotDir;
19
    }
20
21
    /**
22
     * Pauses the scenario until the user presses a key. Useful when debugging a scenario.
23
     *
24
     * @Then (I )put a breakpoint
25
     */
26
    public function iPutABreakpoint()
27
    {
28
        fwrite(STDOUT, "\033[s    \033[93m[Breakpoint] Press \033[1;93m[RETURN]\033[0;93m to continue...\033[0m");
29
        while (fgets(STDIN, 1024) == '') {
30
        }
31
        fwrite(STDOUT, "\033[u");
32
33
        return;
34
    }
35
36
    /**
37
     * Saving a screenshot
38
     *
39
     * @When I save a screenshot in :filename
40
     */
41
    public function iSaveAScreenshotIn($filename)
42
    {
43
        sleep(1);
44
        $this->saveScreenshot($filename, $this->screenshotDir);
45
    }
46
47
    /**
48
     * @AfterStep
49
     */
50
    public function failScreenshots(AfterStepScope $scope)
51
    {
52
        if ($scope->getTestResult()->isPassed()) {
53
            return;
54
        }
55
56
        $this->displayProfilerLink();
57
58
        $suiteName      = urlencode(str_replace(' ', '_', $scope->getSuite()->getName()));
59
        $featureName    = urlencode(str_replace(' ', '_', $scope->getFeature()->getTitle()));
60
61
        if ($this->getBackground($scope)) {
62
            $scenarioName   = 'background';
63
        } else {
64
            $scenario       = $this->getScenario($scope);
65
            $scenarioName   = urlencode(str_replace(' ', '_', $scenario->getTitle()));
66
        }
67
68
        $filename = sprintf('fail_%s_%s_%s_%s.png', time(), $suiteName, $featureName, $scenarioName);
69
        $this->saveScreenshot($filename, $this->screenshotDir);
70
    }
71
72
    private function displayProfilerLink()
73
    {
74
        try {
75
            $headers = $this->getMink()->getSession()->getResponseHeaders();
76
            echo "The debug profile URL {$headers['X-Debug-Token-Link'][0]}";
77
        } catch (\Exception $e) {
78
            /* Intentionally leave blank */
79
        }
80
    }
81
82
    /**
83
     * @param AfterStepScope $scope
84
     * @return \Behat\Gherkin\Node\ScenarioInterface
85
     */
86
    private function getScenario(AfterStepScope $scope)
87
    {
88
        $scenarios = $scope->getFeature()->getScenarios();
89
        foreach ($scenarios as $scenario) {
90
            $stepLinesInScenario = array_map(
91
                function (StepNode $step) {
92
                    return $step->getLine();
93
                },
94
                $scenario->getSteps()
95
            );
96
            if (in_array($scope->getStep()->getLine(), $stepLinesInScenario)) {
97
                return $scenario;
98
            }
99
        }
100
101
        throw new \LogicException('Unable to find the scenario');
102
    }
103
104
    /**
105
     * @param AfterStepScope $scope
106
     * @return \Behat\Gherkin\Node\BackgroundNode|bool
107
     */
108
    private function getBackground(AfterStepScope $scope)
109
    {
110
        $background = $scope->getFeature()->getBackground();
111
        if(!$background){
112
            return false;
113
        }
114
        $stepLinesInBackground = array_map(
115
            function (StepNode $step) {
116
                return $step->getLine();
117
            },
118
            $background->getSteps()
119
        );
120
        if (in_array($scope->getStep()->getLine(), $stepLinesInBackground)) {
121
            return $background;
122
        }
123
124
        return false;
125
    }
126
127
    public function saveScreenshot($filename = null, $filepath = null)
128
    {
129
        try {
130
            parent::saveScreenshot($filename, $filepath);
131
        } catch (UnsupportedDriverActionException $e) {
132
            return;
133
        }
134
    }
135
}
136