Completed
Push — master ( 73d08a...e108ec )
by Greg
08:17
created

BrowserMob::getProxyPort()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
namespace Codeception\Extension;
3
4
use Codeception\Module;
5
use Codeception\Exception\ModuleException;
6
use Codeception\Exception\ModuleConfigException;
7
use \PHPBrowserMobProxy_Client as BMP;
8
use \Requests;
9
use \RuntimeException;
10
11
/**
12
 * @method void _open()
13
 * @method void _close()
14
 * @method string _newHar(string $label='')
15
 * @method string _newPage(string $label='')
16
 * @method string _blacklist(string $regexp, integer $status_code)
17
 * @method string _whitelist(string $regexp, integer $status_code)
18
 * @method string _basicAuth(string $domain, string[] $options)
19
 * @method string _headers(string[] $options)
20
 * @method string _responseInterceptor(string $js)
21
 * @method string _requestInterceptor(string $js)
22
 * @method Requests_Response _limits(string[] $options)
23
 * @method Requests_Response _timeouts(string[] $options)
24
 * @method string _remapHosts(string $address, string $ip_address)
25
 * @method string _waitForTrafficToStop(integer $quiet_period, integer $timeout)
26
 * @method string _clearDnsCache()
27
 * @method string _rewriteUrl(string $match, string $replace)
28
 * @method string _retry(integer $retry_count)
29
 */
30
class BrowserMob extends Module
31
{
32
33
    protected $config = ['host', 'port', 'autostart', 'blacklist', 'whitelist', 'limits', 'timeouts', 'redirect', 'retry', 'basicAuth', 'littleproxy'];
34
35
    protected $requiredFields = ['host'];
36
37
    protected $lastResponse;
38
39
    private $bmp;
40
41
    /**
42
     * @codeCoverageIgnore
43
     * @ignore Codeception specific
44
     */
45
    public function _initialize()
46
    {
47
        $host = $this->config['host'];
48
        if (isset($this->config['port'])) {
49
            $host = $host.':'.$this->config['port'];
50
        }
51
52
        // test if proxy is available
53
        if (static::__pingProxy($host)) {
54
            $this->bmp = new BMP($host);
55
        } else {
56
            throw new ModuleConfigException(__CLASS__, "Proxy '{$host}' cannot be reached");
57
        }
58
59
        // start a new BrowserMobProxy session
60
        if (isset($this->config['autostart'])) {
61
            if (true === (bool) $this->config['autostart']) {
62
                $this->openProxy();
63
            }
64
        }
65
    }
66
67
    protected static function __pingProxy($url)
68
    {
69
        try {
70
            $response = Requests::get('http://'.$url.'/proxy/');
71
        } catch (\Exception $e) {
72
            throw new ModuleException(__CLASS__, $e->getMessage());
73
        }
74
75
        return $response->success;
76
    }
77
78
    protected function __setProxyCapabilities($capabilities)
79
    {
80
        $response = null;
81
82
        foreach ($capabilities as $config => $data) {
83
            try {
84
                if (false === empty($data)) {
85
                    switch ($config) {
86
                        case 0: // fix a weird PHP behaviour: when $config === 0 then go in 'blacklist'
87
                            break;
88
                        case 'blacklist':
89
                            $response = $this->_blacklist($data);
0 ignored issues
show
Bug introduced by
The call to _blacklist() misses a required argument $status_code.

This check looks for function calls that miss required arguments.

Loading history...
90
                            break;
91
                        case 'whitelist':
92
                            $response = $this->_whitelist($data);
0 ignored issues
show
Bug introduced by
The call to _whitelist() misses a required argument $status_code.

This check looks for function calls that miss required arguments.

Loading history...
93
                            break;
94
                        case 'limits':
95
                            $response = $this->_limits($data);
96
                            break;
97
                        case 'timeouts':
98
                            $response = $this->_timeouts($data);
99
                            break;
100
                        case 'redirect':
101
                            $response = $this->_remapHosts($data);
0 ignored issues
show
Bug introduced by
The call to _remapHosts() misses a required argument $ip_address.

This check looks for function calls that miss required arguments.

Loading history...
102
                            break;
103
                        case 'retry':
104
                            $response = $this->_retry($data);
105
                            break;
106
                        case 'basicAuth':
107
                            $response = $this->_basicAuth($data);
0 ignored issues
show
Bug introduced by
The call to _basicAuth() misses a required argument $options.

This check looks for function calls that miss required arguments.

Loading history...
108
                            break;
109
                        default:
110
                            // do nothing
111
                    }
112
                }
113
            } catch (\Exception $e) {
114
                throw new ModuleConfigException(__CLASS__, $e->getMessage());
115
            }
116
117
            if (get_class($response) === 'Request')
118
            {
119
                if (false === $response->success) {
120
                    throw new ModuleConfigException(__CLASS__, "Proxy response error '{$reponse->status_code}' {$respone->body}");
121
                }
122
            }
123
        }
124
    }
125
126
    public function getProxyPort()
127
    {
128
        return $this->bmp->port;
129
    }
130
131
    public function openProxy($capabilities = null)
132
    {
133
        try {
134
            $this->bmp->open();
135
            if (empty($capabilities)) {
136
                $capabilities = $this->config;
137
            }
138
            $this->__setProxyCapabilities($capabilities);
139
        } catch (\Exception $e) {
140
            throw new ModuleException(__CLASS__, $e->getMessage());
141
        }
142
        return $this->getProxyPort();
143
    }
144
145
    public function closeProxy()
146
    {
147
        try {
148
            $this->bmp->close();
149
        } catch (\Exception $e) {
150
            throw new ModuleException(__CLASS__, $e->getMessage());
151
        }
152
    }
153
154 View Code Duplication
    public function startHar()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
155
    {
156
        try {
157
            $response = $this->bmp->newHar();
158
        } catch (\Exception $e) {
159
            throw new ModuleException(__CLASS__, $e->getMessage());
160
        }
161
        return $response->success;
162
    }
163
164 View Code Duplication
    public function startPage()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
165
    {
166
        try {
167
            $response = $this->bmp->newPage();
168
        } catch (\Exception $e) {
169
            throw new ModuleException(__CLASS__, $e->getMessage());
170
        }
171
        return $response->success;
172
    }
173
174
    public function getHar()
175
    {
176
        try {
177
            return $this->bmp->har;
178
        } catch (\Exception $e) {
0 ignored issues
show
Unused Code introduced by
catch (\Exception $e) { ..._, $e->getMessage()); } does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
179
            throw new ModuleException(__CLASS__, $e->getMessage());
180
        }
181
    }
182
183
    public function getLimit()
184
    {
185
        try {
186
            return $this->bmp->getLimit();
0 ignored issues
show
Bug introduced by
The method getLimit() does not seem to exist on object<PHPBrowserMobProxy_Client>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
187
        } catch(\Exception $e) {
188
            throw new ModuleException(__CLASS__, $e->getMessage());
189
        }
190
    }
191
192
    // magic function that exposes BrowserMobProxy API pulic methods
193
    public function __call($method, $args)
194
    {
195
        // check if is a command call
196
        if (preg_match('/^_[A-z]+$/', $method)) {
197
            // extract standard method name
198
            $method = preg_filter('/_/', '', $method);
199
            // set call array for calling method
200
            $call = array($this, $method);
201
            // check if method is callable
202
            if (is_callable($call)) {
203
                call_user_func_array($call, $args);
204
            } else {
205
                throw new RuntimeException("Method ${method} does not exist or is not callable");
206
            }
207
        } else {
208
            throw new RuntimeException("Method ${method} does not exist or is not callable");
209
        }
210
    }
211
212
}
213