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 — develop ( 080777...9cdac9 )
by Stuart
07:21
created

UsingBrowser::waitForOverlay()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 6

Duplication

Lines 13
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 13
loc 13
rs 9.4286
c 1
b 0
f 0
cc 1
eloc 6
nc 1
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/Modules/Browser
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 Storyplayer\SPv2\Modules\Browser;
45
46
use Exception;
47
use Prose\Prose;
48
49
/**
50
 * Do things using the web browser
51
 *
52
 * @category  Libraries
53
 * @package   Storyplayer/Prose
54
 * @author    Stuart Herbert <[email protected]>
55
 * @copyright 2011-present Mediasift Ltd www.datasift.com
56
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
57
 * @link      http://datasift.github.io/storyplayer
58
 */
59
class UsingBrowser extends Prose
60
{
61
    protected function initActions()
62
    {
63
        $this->initDevice();
64
    }
65
66
    // ==================================================================
67
    //
68
    // Input actions go here
69
    //
70
    // ------------------------------------------------------------------
71
72
    /**
73
     * tick a checkbox or radio button if it has not yet been checked
74
     *
75
     * @return \DataSift\Storyplayer\BrowserLib\SingleElementAction
0 ignored issues
show
Documentation introduced by
Should the return type not be SingleElementAction?

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...
76
     */
77 View Code Duplication
    public function check()
78
    {
79
        $action = function($element, $elementName, $elementDesc) {
80
            $log = usingLog()->startAction("check $elementDesc '$elementName'");
81
82
            // does the element need clicking to check it?
83
            if (!$element->selected()) {
84
                // click the element to check it
85
                $element->click();
86
                $log->endAction();
87
            }
88
            else {
89
                $log->endAction("was already checked");
90
            }
91
        };
92
93
        return new SingleElementAction(
94
            $action,
95
            "check",
96
            $this->topElement
97
        );
98
    }
99
100
    /**
101
     * remove any content from an input box, or untick a checkbox or
102
     * radio button
103
     *
104
     * @return \DataSift\Storyplayer\BrowserLib\SingleElementAction
0 ignored issues
show
Documentation introduced by
Should the return type not be SingleElementAction?

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...
105
     */
106
    public function clear()
107
    {
108
        $action = function($element, $elementName, $elementDesc) {
109
            // what are we doing?
110
            $log = usingLog()->startAction("clear $elementDesc '$elementName'");
111
112
            // clear the element if we can
113
            $tag = $element->name();
114
            switch ($tag) {
115
                case "input":
116
                case "textarea":
117
                    $element->clear();
118
                    break;
119
            }
120
121
            // all done
122
            $log->endAction();
123
        };
124
125
        return new SingleElementAction(
126
            $action,
127
            "clear",
128
            $this->topElement
129
        );
130
    }
131
132
    /**
133
     * Send a 'click' to the selected element
134
     *
135
     * @return \DataSift\Storyplayer\BrowserLib\SingleElementAction
0 ignored issues
show
Documentation introduced by
Should the return type not be SingleElementAction?

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...
136
     */
137
    public function click()
138
    {
139
        $action = function($element, $elementName, $elementDesc) {
140
            $log = usingLog()->startAction("click $elementDesc '$elementName'");
141
            $element->click();
142
            $log->endAction();
143
        };
144
145
        return new SingleElementAction(
146
            $action,
147
            "click",
148
            $this->topElement
149
        );
150
    }
151
152
    /**
153
     * choose an option from a <select> box
154
     *
155
     * @param  string $label
156
     *         the human-readable text of the option to select
157
     * @return \DataSift\Storyplayer\BrowserLib\SingleElementAction
0 ignored issues
show
Documentation introduced by
Should the return type not be SingleElementAction?

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...
158
     */
159
    public function select($label)
160
    {
161 View Code Duplication
        $action = function ($element, $elementName, $elementDesc) use ($label) {
162
163
            // what are we doing?
164
            $log = usingLog()->startAction("choose option '$label' from $elementDesc '$elementName'");
165
166
            // get the option to select
167
            $option = $element->getElement('xpath', 'option[normalize-space(text()) = "' . $label . '" ]');
168
169
            // select it
170
            $option->click();
171
172
            // all done
173
            $log->endAction();
174
        };
175
176
        return new SingleElementAction(
177
            $action,
178
            "select",
179
            $this->topElement
180
        );
181
    }
182
183
    /**
184
     * type text into an input field
185
     *
186
     * @param  string $text
187
     *         the text to type
188
     * @return \DataSift\Storyplayer\BrowserLib\SingleElementAction
0 ignored issues
show
Documentation introduced by
Should the return type not be SingleElementAction?

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...
189
     */
190 View Code Duplication
    public function type($text)
191
    {
192
        $action = function($element, $elementName, $elementDesc) use ($text) {
193
194
            // what are we doing?
195
            $log = usingLog()->startAction("type '$text' into $elementDesc '$elementName'");
196
197
            // type the text
198
            $element->type($text);
199
200
            // all done
201
            $log->endAction();
202
        };
203
204
        return new SingleElementAction(
205
            $action,
206
            "type",
207
            $this->topElement
208
        );
209
    }
210
211
    // ==================================================================
212
    //
213
    // Navigation actions go here
214
    //
215
    // ------------------------------------------------------------------
216
217
    public function gotoPage($url)
218
    {
219
        // some shorthand to make things easier to read
220
        $browser = $this->device;
221
222
        // relative, or absolute URL?
223
        if (substr($url, 0, 1) == '/') {
224
            // only absolute URLs are supported
225
            throw new E5xx_ActionFailed(__METHOD__, 'only absolute URLs are supported');
226
        }
227
228
        // parse the URL
229
        $urlParts = parse_url($url);
230
231
        // if we have no host, we cannot continue
232
        if (isset($urlParts['host'])) {
233
            // do we have any HTTP AUTH credentials to merge in?
234
            if (fromBrowser()->hasHttpBasicAuthForHost($urlParts['host'])) {
235
                $adapter = $this->st->getDeviceAdapter();
236
237
                // the adapter *might* embed the authentication details
238
                // into the URL
239
                $url = $adapter->applyHttpBasicAuthForHost($urlParts['host'], $url);
240
            }
241
        }
242
243
        // what are we doing?
244
        $log = usingLog()->startAction("goto URL: $url");
245
246
        // tell the browser to move to the page we want
247
        $browser->open($url);
248
249
        // all done
250
        $log->endAction();
251
    }
252
253 View Code Duplication
    public function waitForOverlay($timeout, $id)
254
    {
255
        // what are we doing?
256
        $log = usingLog()->startAction("wait for the overlay with id '{$id}' to appear");
257
258
        // check for the overlay
259
        usingTimer()->waitFor(function() use($id) {
260
            expectsBrowser()->has()->elementWithId($id);
261
        }, $timeout);
262
263
        // all done
264
        $log->endAction();
265
    }
266
267
    public function waitForTitle($timeout, $title, $failedTitle = null)
268
    {
269
        // what are we doing?
270
        $log = usingLog()->startAction("check that the the right page has loaded");
271
272
        // check the title
273
        usingTimer()->waitFor(function() use($title, $failedTitle) {
274
            // have we already failed?
275
            if ($failedTitle && fromBrowser()->getTitle() == $failedTitle) {
276
                return false;
277
            }
278
279
            // we have not failed yet
280
            expectsBrowser()->hasTitle($title);
281
        }, $timeout);
282
283
        // all done
284
        $log->endAction();
285
    }
286
287 View Code Duplication
    public function waitForTitles($timeout, $titles)
288
    {
289
        // what are we doing?
290
        $log = usingLog()->startAction("check that the the right page has loaded");
291
292
        // check the title
293
        usingTimer()->waitFor(function() use($titles) {
294
            expectsBrowser()->hasTitles($titles);
295
        }, $timeout);
296
297
        // all done
298
        $log->endAction();
299
    }
300
301
    // ==================================================================
302
    //
303
    // Window actions go here
304
    //
305
    // ------------------------------------------------------------------
306
307
    public function resizeCurrentWindow($width, $height)
308
    {
309
        // shorthand
310
        $browser = $this->device;
311
312
        // what are we doing?
313
        $log = usingLog()->startAction("change the current browser window size to be {$width} x {$height} (w x h)");
314
315
        // resize the window
316
        $browser->window()->postSize(array("width" => $width, "height" => $height));
317
318
        // all done
319
        $log->endAction();
320
    }
321
322
    public function switchToWindow($name)
323
    {
324
        // shorthand
325
        $browser = $this->device;
326
327
        // what are we doing?
328
        $log = usingLog()->startAction("switch to browser window called '{$name}'");
329
330
        // get the list of available window handles
331
        $handles = $browser->window_handles();
332
333
        // we have to iterate over them, to find the window that we want
334
        foreach ($handles as $handle) {
335
            // switch to the window
336
            $browser->focusWindow($handle);
337
338
            // is this the window that we want?
339
            $title = $browser->title();
340
            if ($title == $name) {
341
                // all done
342
                $log->endAction();
343
                return;
344
            }
345
        }
346
347
        // if we get here, then we could not find the window we wanted
348
        // the browser might be pointing at ANY of the open windows,
349
        // and it might be pointing at no window at all
350
        throw new E5xx_ActionFailed(__METHOD__, "No such window '{$name}'");
351
    }
352
353
    public function closeCurrentWindow()
354
    {
355
        // shorthand
356
        $browser = $this->device;
357
358
        // what are we doing?
359
        $log = usingLog()->startAction("close the current browser window");
360
361
        // close the current window
362
        $browser->deleteWindow();
363
364
        // all done
365
        $log->endAction();
366
    }
367
368
    // ==================================================================
369
    //
370
    // IFrame actions go here
371
    //
372
    // ------------------------------------------------------------------
373
374 View Code Duplication
    public function switchToIframe($id)
375
    {
376
        // shorthand
377
        $browser = $this->device;
378
379
        // what are we doing?
380
        $log = usingLog()->startAction("switch to working inside the iFrame with the id '{$id}'");
381
382
        // switch to the iFrame
383
        $browser->frame(array('id' => $id));
384
385
        // all done
386
        $log->endAction();
387
    }
388
389 View Code Duplication
    public function switchToMainFrame()
390
    {
391
        // shorthand
392
        $browser = $this->device;
393
394
        // what are we doing?
395
        $log = usingLog()->startAction("switch to working with the main frame");
396
397
        // switch to the iFrame
398
        $browser->frame(array('id' => null));
399
400
        // all done
401
        $log->endAction();
402
    }
403
404
    // ==================================================================
405
    //
406
    // Authentication actions go here
407
    //
408
    // ------------------------------------------------------------------
409
410
    public function setHttpBasicAuthForHost($hostname, $username, $password)
411
    {
412
        // what are we doing?
413
        $log = usingLog()->startAction("set HTTP basic auth for host '{$hostname}': user: '{$username}'; password: '{$password}'");
414
415
        try {
416
            // get the browser adapter
417
            $adapter = $this->st->getDeviceAdapter();
418
419
            // set the details
420
            $adapter->setHttpBasicAuthForHost($hostname, $username, $password);
421
        }
422
        catch (Exception $e)
423
        {
424
            throw new E5xx_ActionFailed(__METHOD__, "unable to set HTTP basic auth; error is: " . $e->getMessage());
425
        }
426
427
        // all done
428
        $log->endAction();
429
    }
430
}
431