Completed
Push — master ( 200256...2dbcc8 )
by Haralan
02:22
created

Driver_Selenium   B

Complexity

Total Complexity 49

Size/Duplication

Total Lines 421
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 97.84%

Importance

Changes 6
Bugs 1 Features 3
Metric Value
wmc 49
c 6
b 1
f 3
lcom 1
cbo 2
dl 0
loc 421
ccs 136
cts 139
cp 0.9784
rs 8.5454

28 Methods

Rating   Name   Duplication   Size   Complexity  
A base_url() 0 9 2
A clear() 0 4 1
A connection() 0 16 3
A tag_name() 0 4 1
A html() 0 7 2
A text() 0 6 1
B value() 0 20 5
A is_checked() 0 4 1
C set() 0 30 7
A alert_text() 0 4 1
A click() 0 4 1
A visit() 0 17 3
A current_path() 0 6 2
A current_url() 0 4 1
A all() 0 6 2
A next_query() 0 5 1
A execute() 0 7 2
A is_page_active() 0 4 1
A screenshot() 0 6 1
A cookies() 0 4 1
A cookie() 0 10 1
A content() 0 4 1
A attribute() 0 4 1
A is_visible() 0 4 1
A is_selected() 0 4 1
A select_option() 0 4 1
A confirm() 0 11 2
A move_to() 0 11 2

How to fix   Complexity   

Complex Class

Complex classes like Driver_Selenium often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Driver_Selenium, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Openbuildings\Spiderling;
4
5
/**
6
 * Use Selenium to load pages.
7
 * Has Javascript
8
 *
9
 * @package    Openbuildings\Spiderling
10
 * @author     Ivan Kerin
11
 * @copyright  (c) 2013 OpenBuildings Ltd.
12
 * @license    http://spdx.org/licenses/BSD-3-Clause
13
 */
14
class Driver_Selenium extends Driver {
15
16
	/**
17
	 * Driver name
18
	 * @var string
19
	 */
20
	public $name = 'selenium';
21
22
	/**
23
	 * Array containing parameters to be added on the next request
24
	 * @var array
25
	 */
26
	protected $_next_query = array();
27
28
	/**
29
	 * Variable holding the current Driver_Selenium_Connection
30
	 * @var Driver_Selenium_Connection
31
	 */
32
	protected $_connection;
33
34
	/**
35
	 * The base URL, to be prefixed on each request
36
	 * @var string
37
	 */
38
	protected $_base_url = '';
39
40
	/**
41
	 * As selenium might be a bit slow to respond, we increase the default wait time.
42
	 * @var integer
43
	 */
44
	public $default_wait_time = 4000;
45
46
	/**
47
	 * Getter / Setter of the base_url, that will be prefixed on each request
48
	 * @param  string $base_url
49
	 * @return string|Driver_PHantomjs
50
	 */
51 4
	public function base_url($base_url = NULL)
52
	{
53 4
		if ($base_url !== NULL)
54 4
		{
55 1
			$this->_base_url = $base_url;
56 1
			return $this;
57
		}
58 4
		return $this->_base_url;
59
	}
60
61
	/**
62
	 * Clear the connection by deleting all cookies
63
	 */
64 1
	public function clear()
65
	{
66 1
		$this->connection()->delete('cookie');
0 ignored issues
show
Bug introduced by
The method delete does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
67 1
	}
68
69
	/**
70
	 * Getter of the raw content html, this driver does not allow "setting"
71
	 *
72
	 * @param  string $content
73
	 * @return string
74
	 */
75 1
	public function content($content = NULL)
76
	{
77 1
		return $this->connection()->get('source');
0 ignored issues
show
Bug introduced by
The method get does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
78
	}
79
80
	/**
81
	 * Getter / Setter of the Driver_Selenium_Connection object.
82
	 * Use this to customize the connection, otherwise a default one on a random port will be used
83
	 *
84
	 * @param  Driver_Selenium_Connection $connection
85
	 * @return Driver_Selenium_Connection|Driver_Selenium
86
	 */
87 12
	public function connection(Driver_Selenium_Connection $connection = NULL)
88
	{
89 12
		if ($connection !== NULL)
90 12
		{
91 1
			$this->_connection = $connection;
92 1
			return $this;
93
		}
94
95 12
		if ( ! $this->_connection)
96 12
		{
97 1
			$this->_connection = new Driver_Selenium_Connection();
98 1
			$this->_connection->start(array('browserName' => 'firefox', 'acceptSslCerts' => FALSE));
99 1
		}
100
101 12
		return $this->_connection;
102
	}
103
104
	/**
105
	 * NODE GETTERS
106
	 * =====================================
107
	 */
108
109
	/**
110
	 * Get the tag name of a Node with id. e.g. DIV, SPAN ...
111
	 * @param  string $id
112
	 * @return string
113
	 */
114 2
	public function tag_name($id)
115
	{
116 2
		return $this->connection()->get("element/$id/name");
0 ignored issues
show
Bug introduced by
The method get does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
117
	}
118
119
	/**
120
	 * Get the attribute of a Node with id. If the attribute does not exist, returns NULL
121
	 * @param  string $id
122
	 * @param  string $name
123
	 * @return string
124
	 */
125 2
	public function attribute($id, $name)
126
	{
127 2
		return $this->connection()->get("element/$id/attribute/$name");
0 ignored issues
show
Bug introduced by
The method get does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
128
	}
129
130
	/**
131
	 * Return the raw html of a Node with id, along with all of its children.
132
	 * @param  string $id
133
	 * @return string
134
	 */
135 1
	public function html($id)
136
	{
137 1
		if ($id === NULL)
138 1
			return $this->content();
139
140 1
		return $this->execute($id, 'return arguments[0].outerHTML');
141
	}
142
143
	/**
144
	 * Return the text of a Node with id, with all the spaces collapsed, similar to browser rendering.
145
	 * @param  string $id
146
	 * @return string
147
	 */
148 2
	public function text($id)
149
	{
150 2
		$text = $this->connection()->get("element/$id/text");
0 ignored issues
show
Bug introduced by
The method get does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
151 2
		$text = preg_replace('/[ \s\f\n\r\t\v ]+/u', ' ', $text);
152 2
		return trim($text);
153
	}
154
155
	/**
156
	 * Return the value of a Node of a form element, e.g. INPUT, TEXTAREA or SELECT
157
	 * @param  string $id
158
	 * @return string
159
	 */
160 2
	public function value($id)
161
	{
162 2
		if ($this->tag_name($id) == 'select' AND $this->attribute($id, 'multiple'))
163 2
		{
164 2
			$self = $this;
0 ignored issues
show
Unused Code introduced by
$self is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
165 2
			$values = array();
166 2
			foreach ($this->all('//option', $id) as $option_id)
167
			{
168 2
				if ($this->is_selected($option_id))
169 2
				{
170 2
					$values []= $this->value($option_id);
171 2
				}
172 2
			}
173 2
			return $values;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $values; (array) is incompatible with the return type documented by Openbuildings\Spiderling\Driver_Selenium::value of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
174
		}
175
		else
176
		{
177 2
			return $this->connection()->get("element/$id/value");
0 ignored issues
show
Bug introduced by
The method get does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
178
		}
179
	}
180
181
	/**
182
	 * Check if a Node with id is visible.
183
	 * @param  string  $id
184
	 * @return boolean
185
	 */
186 1
	public function is_visible($id)
187
	{
188 1
		return $this->connection()->get("element/$id/displayed");
0 ignored issues
show
Bug introduced by
The method get does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
189
	}
190
191
	/**
192
	 * Check if a Node with id of an option element is selected
193
	 * @param  string  $id
194
	 * @return boolean
195
	 */
196 2
	public function is_selected($id)
197
	{
198 2
		return $this->connection()->get("element/$id/selected");
0 ignored issues
show
Bug introduced by
The method get does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
199
	}
200
201
	/**
202
	 * Check if a Node with id of an input element (radio or checkbox) is checked
203
	 * @param  string  $id
204
	 * @return boolean
205
	 */
206 1
	public function is_checked($id)
207
	{
208 1
		return $this->connection()->get("element/$id/selected");
0 ignored issues
show
Bug introduced by
The method get does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
209
	}
210
211
	/**
212
	 * Set the value of a Node with id of a form element
213
	 * @param string $id
214
	 * @param string $value
215
	 */
216 1
	public function set($id, $value)
217
	{
218 1
		$tag_name = $this->tag_name($id);
219
220 1
		if ($tag_name == 'textarea')
221 1
		{
222 1
			$this->connection()->post("element/$id/clear", array());
0 ignored issues
show
Bug introduced by
The method post does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
223 1
			$this->connection()->post("element/$id/value", array('value' => str_split($value)));
224 1
		}
225 1
		elseif ($tag_name == 'input')
226
		{
227 1
			$type = $this->attribute($id, 'type');
228 1
			if ($type == 'checkbox' OR $type == 'radio')
229 1
			{
230 1
				$this->connection()->post("element/$id/click", array());
231 1
			}
232
			else
233
			{
234 1
				if ($type !== 'file')
235 1
				{
236 1
					$this->connection()->post("element/$id/clear", array());
237 1
				}
238 1
				$this->connection()->post("element/$id/value", array('value' => str_split($value)));
239
			}
240 1
		}
241 1
		elseif ($tag_name == 'option')
242
		{
243 1
			$this->connection()->post("element/$id/click", array());
244 1
		}
245 1
	}
246
247
	/**
248
	 * Set the option value that is selected of a Node of a select element
249
	 * @param  string $id
250
	 * @param  string $value
251
	 */
252 1
	public function select_option($id, $value)
253
	{
254 1
		$this->connection()->post("element/$id/click", array());
0 ignored issues
show
Bug introduced by
The method post does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
255 1
	}
256
257
	/**
258
	 * Confirm or cancel for the next confirmation dialog
259
	 * @param  bool $confirm
260
	 */
261 2
	public function confirm($confirm)
262
	{
263
		if ($confirm)
264 2
		{
265 1
			$this->connection()->post('accept_alert', array());
0 ignored issues
show
Bug introduced by
The method post does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
266 1
		}
267
		else
268
		{
269 2
			$this->connection()->post('dismiss_alert', array());
270
		}
271 2
	}
272
273
	/**
274
	 * Get the text of the currently displayed alert / confirm /prompt dialog
275
	 * @param  bool $confirm
0 ignored issues
show
Bug introduced by
There is no parameter named $confirm. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
276
	 */
277 2
	public function alert_text()
278
	{
279 2
		return $this->connection()->get("alert_text");
0 ignored issues
show
Bug introduced by
The method get does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
280
	}
281
282
	/**
283
	 * Click on a Node with id, triggering a link or form submit
284
	 * @param  string $id
285
	 */
286 1
	public function click($id)
287
	{
288 1
		$this->connection()->post("element/$id/click", array());
0 ignored issues
show
Bug introduced by
The method post does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
289 1
	}
290
291
	/**
292
	 * Go to a given url address, use next_query along with the provided query array
293
	 * @param  string $uri
294
	 * @param  array  $query
295
	 */
296 3
	public function visit($uri, array $query = NULL)
297
	{
298 3
		$query = array_merge((array) $this->_next_query, (array) $query);
299
300 3
		$this->_next_query = NULL;
0 ignored issues
show
Documentation Bug introduced by
It seems like NULL of type null is incompatible with the declared type array of property $_next_query.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
301
302
		// Check for implicit query string
303 3
		if (strpos($uri, '?') !== FALSE)
304 3
		{
305
			$query = array_merge(self::extract_query_from_uri($uri), $query);
306
			$uri = substr($uri, 0, strpos($uri, '?'));
307
		}
308
309 3
		$url = $this->base_url().$uri.($query ? '?'.http_build_query($query) : '');
310
311 3
		$this->connection()->post('url', array('url' => $url));
0 ignored issues
show
Bug introduced by
The method post does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
312 3
	}
313
314
	/**
315
	 * Get the current path (without host and protocol)
316
	 * @return string
317
	 */
318 1
	public function current_path()
319
	{
320 1
		$url = parse_url($this->connection()->get('url'));
0 ignored issues
show
Bug introduced by
The method get does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
321
322 1
		return $url['path'].(isset($url['query']) ? '?'.$url['query'] : '');
323
	}
324
325
	/**
326
	 * Get the current url
327
	 * @return string
328
	 */
329 2
	public function current_url()
330
	{
331 2
		return urldecode($this->connection()->get('url'));
0 ignored issues
show
Bug introduced by
The method get does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
332
	}
333
334
	/**
335
	 * Find all ids of a given XPath
336
	 * @param  string $xpath
337
	 * @param  string $parent id of the parent node
338
	 * @return array
339
	 */
340 6
	public function all($xpath, $parent = NULL)
341
	{
342 6
		$elements = $this->connection()->post(($parent === NULL ? '' : 'element/'.$parent.'/').'elements', array('using' => 'xpath', 'value' => '.'.$xpath));
0 ignored issues
show
Bug introduced by
The method post does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
343
344
		return array_map(function($item){ return $item['ELEMENT'];}, $elements);
345
	}
346
347
	/**
348
	 * Setter for the next_query variable, to be added to the next visit's query
349
	 * @param  array  $query
350
	 */
351 1
	public function next_query(array $query)
352
	{
353 1
		$this->_next_query = $query;
354 1
		return $this;
355
	}
356
357
	/**
358
	 * Execute raw javascript. it will be executed in the context of a given node ('this' will point to the node) and the return of the script will be the return of this method
359
	 * @param  string $id
360
	 * @param  string $script
361
	 * @return mixed
362
	 */
363 3
	public function execute($id, $script)
364
	{
365 3
		return $this->connection()->post('execute', array(
0 ignored issues
show
Bug introduced by
The method post does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
366 3
			'script' => $script,
367 3
			'args' => $id ? array(array('ELEMENT' => $id)) : array()
368 3
		));
369
	}
370
371
	/**
372
	 * Check if a connection is active
373
	 * @return boolean
374
	 */
375 1
	public function is_page_active()
376
	{
377 1
		return (bool) $this->_connection;
378
	}
379
380
	/**
381
	 * Move the mouse to a given element, or coordinates, or coordinates relative to a given element
382
	 * @param  string $id
383
	 * @param  integer $x
384
	 * @param  integer $y
385
	 */
386 1
	public function move_to($id = NULL, $x = NULL, $y = NULL)
387
	{
388 1
		$this->connection()->post('moveto', array_filter(array(
0 ignored issues
show
Bug introduced by
The method post does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
389 1
			'element' => $id,
390 1
			'xoffset' => $x,
391
			'yoffset' => $y
392 1
		), function($param)
393
		{
394 1
			return ($param OR $param === 0);
395 1
		}));
396 1
	}
397
398
	/**
399
	 * Do a screenshot of the current page into a file
400
	 * @param  string $file
401
	 */
402 1
	public function screenshot($file)
403
	{
404 1
		$data = $this->connection()->get('screenshot');
0 ignored issues
show
Bug introduced by
The method get does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
405
406 1
		file_put_contents($file, base64_decode($data));
407 1
	}
408
409
	/**
410
	 * Return all the current cookies
411
	 * @return array
412
	 */
413 1
	public function cookies()
414
	{
415 1
		return $this->connection()->get('cookie');
0 ignored issues
show
Bug introduced by
The method get does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
416
	}
417
418
	/**
419
	 * Set a cookie. Use parameters to set "expiry", "path", "domain" and "secure"
420
	 * @param  string $name
421
	 * @param  mixed $value
422
	 * @param  array  $parameters
423
	 */
424 1
	public function cookie($name, $value, array $parameters = array())
425
	{
426 1
		$parameters = array_merge(array(
427 1
			'name' => $name,
428 1
			'value' => $value,
429 1
			'expiry' => time() + 86400,
430 1
		), $parameters);
431
432 1
		return $this->connection()->post('cookie', array('cookie' => $parameters));
0 ignored issues
show
Bug introduced by
The method post does only exist in Openbuildings\Spiderling...ver_Selenium_Connection, but not in Openbuildings\Spiderling\Driver_Selenium.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
433
	}
434
}
435