Spinner::spin()   A
last analyzed

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
     * Spin and carry out given action on an element. Default timeout is 60 seconds.
92
     *
93
     * @param string|Object $element
94
     * @param $action
95
     * @param null $condition
96
     * @param int $wait
97
     */
98
    public function spinAndDo($element, $action, $condition = null, $wait = 60)
99
    {
100
        $this->spin(function ($context) use ($element, $action, $condition) {
101
            return $this->_spinnerAction($context, $element, $action, $condition);
102
        }, $wait);
103
    }
104
105
    /**
106
     * @throws \Exception
107
     */
108
    protected function _throwBacktraceException()
109
    {
110
        $backtrace = debug_backtrace();
111
112
        throw new \Exception(
113
            "Timeout thrown by " . $backtrace[1]['class'] . "::" . $backtrace[1]['function'] . "()\n" .
114
            $backtrace[1]['file'] . ", line " . $backtrace[1]['line']
115
        );
116
    }
117
118
    /**
119
     * @param $context
120
     * @param $element
121
     * @param $action
122
     * @param null $condition
123
     * @return bool
124
     */
125
    private function _spinnerAction($context, $element, $action, $condition = null)
126
    {
127
        if (is_object($element)) {
128
            if (!is_null($condition)) {
129
                return $element->$action() === $condition;
130
            }
131
            $element->$action();
132
        } else {
133
            if (!is_null($condition)) {
134
                return  $context->getElement($element)->$action() === $condition;
135
            }
136
            $context->getElement($element)->$action();
137
        }
138
139
        return true;
140
    }
141
}
142