Completed
Push — master ( d8e283...af2b3d )
by Vitaly
01:42
created

GenericFeatureContext::iFillInTheElementUsingJs()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace samsonframework\behatextension;
6
7
use Behat\Behat\Hook\Scope\AfterStepScope;
8
use Behat\Mink\Driver\Selenium2Driver;
9
use Behat\Mink\Element\NodeElement;
10
use Behat\MinkExtension\Context\MinkContext;
11
12
/**
13
 * Defines generic feature steps.
14
 */
15
class GenericFeatureContext extends MinkContext
16
{
17
    /** @var int UI generic delay duration in milliseconds */
18
    const DELAY = 1000;
19
    /** @var int UI javascript generic delay duration in milliseconds */
20
    const JS_DELAY = self::DELAY / 5;
21
22
    /** @var mixed */
23
    protected $session;
24
25
    /**
26
     * Initializes context.
27
     *
28
     * Every scenario gets its own context instance.
29
     * You can also pass arbitrary arguments to the
30
     * context constructor through behat.yml.
31
     *
32
     * @param mixed $session
33
     */
34
    public function __construct($session = null)
35
    {
36
        $this->session = $session;
37
38
        ini_set('xdebug.max_nesting_level', '1000');
39
    }
40
41
    /**
42
     * @AfterStep
43
     *
44
     * @param AfterStepScope $scope
45
     */
46
    public function takeScreenShotAfterFailedStep(AfterStepScope $scope)
47
    {
48
        if (99 === $scope->getTestResult()->getResultCode()) {
49
            $driver = $this->getSession()->getDriver();
50
51
            if (!($driver instanceof Selenium2Driver)) {
52
                return;
53
            }
54
55
            $step = $scope->getStep();
56
            $fileName = 'Fail.'.preg_replace('/[^a-zA-Z0-9-_\.]/', '_', $scope->getName().'-'.$step->getText()).'.jpg';
57
            file_put_contents($fileName, $driver->getScreenshot());
58
        }
59
    }
60
61
    /**
62
     * Find all elements by CSS selector.
63
     *
64
     * @param string $selector CSS selector
65
     *
66
     * @throws \InvalidArgumentException If element not found
67
     *
68
     * @return \Behat\Mink\Element\NodeElement[]
69
     */
70
    protected function findAllByCssSelector(string $selector)
71
    {
72
        $session = $this->getSession();
73
74
        $elements = $session->getPage()->findAll('css', $this->fixStepArgument($selector));
75
76
        // If element with current selector is not found then print error
77
        if (count($elements) === 0) {
78
            throw new \InvalidArgumentException(sprintf('Could not evaluate CSS selector: "%s"', $selector));
79
        }
80
81
        return $elements;
82
    }
83
84
    /**
85
     * Find element by CSS selector.
86
     *
87
     * @param string $selector CSS selector
88
     *
89
     * @throws \InvalidArgumentException If element not found
90
     *
91
     * @return \Behat\Mink\Element\NodeElement
92
     */
93
    protected function findByCssSelector(string $selector) : NodeElement
94
    {
95
        return $this->findAllByCssSelector($selector)[0];
96
    }
97
98
    /**
99
     * @Given /^I set browser window size to "([^"]*)" x "([^"]*)"$/
100
     *
101
     * @param int $width  Browser window width
102
     * @param int $height Browser window height
103
     */
104
    public function iSetBrowserWindowSizeToX($width, $height)
105
    {
106
        $this->getSession()->resizeWindow((int) $width, (int) $height, 'current');
107
    }
108
109
    /**
110
     * @Given /^I wait "([^"]*)" milliseconds for response$/
111
     *
112
     * @param int $delay Amount of milliseconds to wait
113
     */
114
    public function iWaitMillisecondsForResponse($delay = self::DELAY)
115
    {
116
        $this->getSession()->wait((int) $delay);
117
    }
118
119
    /**
120
     * Click on the element with the provided xpath query.
121
     *
122
     * @When I click on the element :arg1
123
     *
124
     * @param string $selector CSS element selector
125
     *
126
     * @throws \InvalidArgumentException
127
     */
128
    public function iClickOnTheElement(string $selector)
129
    {
130
        // Click on the founded element
131
        $this->findByCssSelector($selector)->click();
132
    }
133
134
    /**
135
     * @When /^I hover over the element "([^"]*)"$/
136
     *
137
     * @param string $selector CSS element selector
138
     *
139
     * @throws \InvalidArgumentException
140
     */
141
    public function iHoverOverTheElement(string $selector)
142
    {
143
        $this->findByCssSelector($selector)->mouseOver();
144
    }
145
146
    /**
147
     * Fill in input with the provided info.
148
     *
149
     * @When I fill in the input :arg1 with :arg2
150
     *
151
     * @param string $selector CSS element selector
152
     * @param string $value    Element value for filling in
153
     *
154
     * @throws \InvalidArgumentException
155
     */
156
    public function iFillInTheElement(string $selector, string $value)
157
    {
158
        $this->findByCssSelector($selector)->setValue($this->fixStepArgument($value));
159
    }
160
161
    /**
162
     * @When I scroll vertically to :arg1 px
163
     *
164
     * @param mixed $yPos Vertical scrolling position in pixels
165
     */
166
    public function iScrollVerticallyToPx($yPos)
167
    {
168
        $this->getSession()->executeScript('window.scrollTo(0, Math.min(document.documentElement.scrollHeight, document.body.scrollHeight, '.((int) $yPos).'));');
169
    }
170
171
    /**
172
     * @When I scroll horizontally to :arg1 px
173
     *
174
     * @param mixed $xPos Horizontal scrolling position in pixels
175
     */
176
    public function iScrollHorizontallyToPx($xPos)
177
    {
178
        $this->getSession()->executeScript('window.scrollTo('.((int) $xPos).', 0);');
179
    }
180
181
    /**
182
     * @Given /^I fill hidden field "([^"]*)" with "([^"]*)"$/
183
     *
184
     * @param string $field Field name
185
     * @param string $value Field value
186
     */
187
    public function iFillHiddenFieldWith(string $field, string $value)
188
    {
189
        // TODO: Change to Mink implementation
190
        $this->getSession()->executeScript("
191
            $('input[name=".$field."]').val('".$value."');
192
        ");
193
    }
194
195
    /**
196
     * @Then I check custom checkbox with :id
197
     *
198
     * @param string $id Checkbox identifier
199
     *
200
     * @throws \InvalidArgumentException If checkbox with provided identifier does not exists
201
     */
202
    public function iCheckCustomCheckboxWith(string $id)
203
    {
204
        // Find label for checkbox by chekbox identifier
205
        $element = null;
206
        foreach ($this->findAllByCssSelector('label') as $label) {
207
            if ($label->getAttribute('for') === $id) {
208
                $element = $label;
209
            }
210
        }
211
212
        // Imitate checkbox checking by clicking its label
213
        $element->click();
214
    }
215
216
    /**
217
     * @Then I drag element :selector to :target
218
     *
219
     * @param string $selector Source element for dragging
220
     * @param string $target   Target element to drag to
221
     *
222
     * @throws \InvalidArgumentException
223
     */
224
    public function dragElementTo(string $selector, string $target)
225
    {
226
        $this->findByCssSelector($selector)->dragTo($this->findByCssSelector($target));
227
228
        $this->iWaitMillisecondsForResponse(self::JS_DELAY);
229
    }
230
231
    /**
232
     * Fill in input with the provided info
233
     *
234
     * @When I fill in the element :arg1 with value :arg2 using js
235
     *
236
     * @param string $selector CSS element selector
237
     * @param string $value    Element value for filling in
238
     */
239
    public function iFillInTheElementUsingJs(string $selector, string $value)
240
    {
241
        $this->getSession()->executeScript('document.querySelectorAll("' . $selector . '")[0].value="' . $value . '";');
242
    }
243
}
244