Completed
Push — develop ( 411d31...981d0d )
by Carlo
10s
created

Spinner::spin()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 16
rs 9.2
nc 4
cc 4
eloc 8
nop 2
1
<?php
2
3
namespace Magefix\Plugin;
4
5
/**
6
 * Class Spinner
7
 *
8
 * Provide "waiting" functionality to contexts
9
 *
10
 * @package Magefix\Plugin
11
 * @author  Carlo Tasca <[email protected]>
12
 */
13
trait Spinner
14
{
15
    /**
16
     * @param $lambda
17
     * @param int $wait
18
     * @return bool
19
     * @throws \Exception
20
     */
21
    public function spin($lambda, $wait = 60)
22
    {
23
        for ($i = 0; $i < $wait; $i++) {
24
            try {
25
                if ($lambda($this)) {
26
                    return true;
27
                }
28
            } catch (\Exception $e) {
29
                // do nothing
30
            }
31
32
            sleep(1);
33
        }
34
35
        $this->_throwBacktraceException();
36
    }
37
38
    /**
39
     * Spin until element is visible. Default timeout is 60 seconds.
40
     *
41
     * @param string|Object $element
42
     * @param int $wait
43
     */
44
    public function spinUntilVisible($element, $wait = 60)
45
    {
46
        $this->spin(function ($context) use ($element) {
47
            return $this->_spinnerAction($context, $element, 'isVisible', true);
48
        }, $wait);
49
    }
50
51
    /**
52
     * Spin until element is not visible. Default timeout is 60 seconds.
53
     *
54
     * @param string|Object $element
55
     * @param int $wait
56
     */
57
    public function spinUntilInvisible($element, $wait = 60)
58
    {
59
        $this->spin(function ($context) use ($element) {
60
            return $this->_spinnerAction($context, $element, 'isVisible', false);
61
        }, $wait);
62
    }
63
64
    /**
65
     * Spin and click element. Default timeout is 60 seconds.
66
     *
67
     * @param string|Object $element
68
     * @param int $wait
69
     */
70
    public function spinAndClick($element, $wait = 60)
71
    {
72
        $this->spin(function ($context) use ($element) {
73
            return $this->_spinnerAction($context, $element, 'click');
74
        }, $wait);
75
    }
76
77
    /**
78
     * Spin and press element. Default timeout is 60 seconds.
79
     *
80
     * @param string|Object $element
81
     * @param int $wait
82
     */
83
    public function spinAndPress($element, $wait = 60)
84
    {
85
        $this->spin(function ($context) use ($element) {
86
            return $this->_spinnerAction($context, $element, 'press');
87
        }, $wait);
88
    }
89
90
    /**
91
     * @throws \Exception
92
     */
93
    protected function _throwBacktraceException()
94
    {
95
        $backtrace = debug_backtrace();
96
97
        throw new \Exception(
98
            "Timeout thrown by " . $backtrace[1]['class'] . "::" . $backtrace[1]['function'] . "()\n" .
99
            $backtrace[1]['file'] . ", line " . $backtrace[1]['line']
100
        );
101
    }
102
103
    /**
104
     * @param $context
105
     * @param $element
106
     * @param $action
107
     * @param null $condition
108
     * @return bool
109
     */
110
    private function _spinnerAction($context, $element, $action, $condition = null)
111
    {
112
        if (is_object($element)) {
113
            if (!is_null($condition)) {
114
                return $element->$action() === $condition;
115
            }
116
            $element->$action();
117
        } else {
118
            if (!is_null($condition)) {
119
                return  $context->getElement($element)->$action() === $condition;
120
            }
121
            $context->getElement($element)->$action();
122
        }
123
124
        return true;
125
    }
126
}
127