selenium-webdriver 4.0.0-alpha.7 → 4.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.md +56 -0
- package/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +2 -0
- package/chrome.js +69 -79
- package/chromium.js +231 -164
- package/{lib/atoms/make-atoms-module.js → devtools/CDPConnection.js} +15 -9
- package/edge.js +104 -146
- package/example/chrome_android.js +45 -0
- package/example/chrome_mobile_emulation.js +46 -0
- package/example/firefox_channels.js +84 -0
- package/example/google_search.js +50 -0
- package/example/google_search_test.js +70 -0
- package/example/headless.js +63 -0
- package/example/logging.js +64 -0
- package/firefox.js +199 -200
- package/http/index.js +128 -116
- package/http/util.js +56 -64
- package/ie.js +180 -104
- package/index.js +246 -199
- package/io/exec.js +35 -40
- package/io/index.js +146 -157
- package/io/zip.js +75 -66
- package/lib/atoms/find-elements.js +123 -0
- package/lib/atoms/get-attribute.js +75 -59
- package/lib/atoms/is-displayed.js +72 -72
- package/lib/atoms/mutation-listener.js +55 -0
- package/lib/by.js +192 -65
- package/lib/capabilities.js +76 -86
- package/lib/command.js +19 -35
- package/lib/error.js +134 -168
- package/lib/http.js +308 -232
- package/lib/input.js +192 -453
- package/lib/logging.js +126 -137
- package/lib/promise.js +53 -71
- package/lib/proxy.js +31 -41
- package/lib/session.js +12 -15
- package/lib/symbols.js +3 -4
- package/lib/until.js +162 -160
- package/lib/webdriver.js +1014 -549
- package/net/index.js +30 -36
- package/net/portprober.js +30 -143
- package/opera.js +406 -0
- package/package.json +15 -7
- package/proxy.js +2 -2
- package/remote/index.js +189 -187
- package/safari.js +40 -49
- package/testing/index.js +504 -0
- package/lib/README +0 -5
- package/lib/actions.js +0 -609
package/net/index.js
CHANGED
|
@@ -15,22 +15,20 @@
|
|
|
15
15
|
// specific language governing permissions and limitations
|
|
16
16
|
// under the License.
|
|
17
17
|
|
|
18
|
-
'use strict'
|
|
19
|
-
|
|
20
|
-
const os = require('os');
|
|
18
|
+
'use strict'
|
|
21
19
|
|
|
20
|
+
const os = require('os')
|
|
22
21
|
|
|
23
22
|
function getLoInterface() {
|
|
24
|
-
let name
|
|
23
|
+
let name
|
|
25
24
|
if (process.platform === 'darwin') {
|
|
26
|
-
name = 'lo0'
|
|
25
|
+
name = 'lo0'
|
|
27
26
|
} else if (process.platform === 'linux') {
|
|
28
|
-
name = 'lo'
|
|
27
|
+
name = 'lo'
|
|
29
28
|
}
|
|
30
|
-
return name ? os.networkInterfaces()[name] : null
|
|
29
|
+
return name ? os.networkInterfaces()[name] : null
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
|
|
34
32
|
/**
|
|
35
33
|
* Queries the system network interfaces for an IP address.
|
|
36
34
|
* @param {boolean} loopback Whether to find a loopback address.
|
|
@@ -38,49 +36,45 @@ function getLoInterface() {
|
|
|
38
36
|
* @return {(string|undefined)} The located IP address or undefined.
|
|
39
37
|
*/
|
|
40
38
|
function getAddress(loopback, family) {
|
|
41
|
-
let interfaces
|
|
39
|
+
let interfaces
|
|
42
40
|
if (loopback) {
|
|
43
|
-
let lo = getLoInterface()
|
|
44
|
-
interfaces = lo ? [lo] : null
|
|
41
|
+
let lo = getLoInterface()
|
|
42
|
+
interfaces = lo ? [lo] : null
|
|
45
43
|
}
|
|
46
|
-
interfaces = interfaces || os.networkInterfaces()
|
|
44
|
+
interfaces = interfaces || os.networkInterfaces()
|
|
47
45
|
for (let key in interfaces) {
|
|
48
|
-
if (!
|
|
49
|
-
continue
|
|
46
|
+
if (!Object.prototype.hasOwnProperty.call(interfaces, key)) {
|
|
47
|
+
continue
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
for (let ipAddress of interfaces[key]) {
|
|
53
51
|
if (ipAddress.family === family && ipAddress.internal === loopback) {
|
|
54
|
-
return ipAddress.address
|
|
52
|
+
return ipAddress.address
|
|
55
53
|
}
|
|
56
54
|
}
|
|
57
55
|
}
|
|
58
|
-
return undefined
|
|
56
|
+
return undefined
|
|
59
57
|
}
|
|
60
58
|
|
|
61
|
-
|
|
62
59
|
// PUBLIC API
|
|
63
60
|
|
|
64
|
-
|
|
65
61
|
/**
|
|
66
62
|
* Retrieves the external IP address for this host.
|
|
67
63
|
* @param {string=} family The IP family to retrieve. Defaults to "IPv4".
|
|
68
64
|
* @return {(string|undefined)} The IP address or undefined if not available.
|
|
69
65
|
*/
|
|
70
|
-
exports.getAddress = function(family = 'IPv4') {
|
|
71
|
-
return getAddress(false, family)
|
|
72
|
-
}
|
|
73
|
-
|
|
66
|
+
exports.getAddress = function (family = 'IPv4') {
|
|
67
|
+
return getAddress(false, family)
|
|
68
|
+
}
|
|
74
69
|
|
|
75
70
|
/**
|
|
76
71
|
* Retrieves a loopback address for this machine.
|
|
77
72
|
* @param {string=} family The IP family to retrieve. Defaults to "IPv4".
|
|
78
73
|
* @return {(string|undefined)} The IP address or undefined if not available.
|
|
79
74
|
*/
|
|
80
|
-
exports.getLoopbackAddress = function(family = 'IPv4') {
|
|
81
|
-
return getAddress(true, family)
|
|
82
|
-
}
|
|
83
|
-
|
|
75
|
+
exports.getLoopbackAddress = function (family = 'IPv4') {
|
|
76
|
+
return getAddress(true, family)
|
|
77
|
+
}
|
|
84
78
|
|
|
85
79
|
/**
|
|
86
80
|
* Splits a hostport string, e.g. "www.example.com:80", into its component
|
|
@@ -90,24 +84,24 @@ exports.getLoopbackAddress = function(family = 'IPv4') {
|
|
|
90
84
|
* @return {{host: string, port: ?number}} A host and port. If no port is
|
|
91
85
|
* present in the argument `hostport`, port is null.
|
|
92
86
|
*/
|
|
93
|
-
exports.splitHostAndPort = function(hostport) {
|
|
94
|
-
let lastIndex = hostport.lastIndexOf(':')
|
|
87
|
+
exports.splitHostAndPort = function (hostport) {
|
|
88
|
+
let lastIndex = hostport.lastIndexOf(':')
|
|
95
89
|
if (lastIndex < 0) {
|
|
96
|
-
return {host: hostport, port: null}
|
|
90
|
+
return { host: hostport, port: null }
|
|
97
91
|
}
|
|
98
92
|
|
|
99
|
-
let firstIndex = hostport.indexOf(':')
|
|
93
|
+
let firstIndex = hostport.indexOf(':')
|
|
100
94
|
if (firstIndex != lastIndex && !hostport.includes('[')) {
|
|
101
95
|
// Multiple colons but no brackets, so assume the string is an IPv6 address
|
|
102
96
|
// with no port (e.g. "1234:5678:9:0:1234:5678:9:0").
|
|
103
|
-
return {host: hostport, port: null}
|
|
97
|
+
return { host: hostport, port: null }
|
|
104
98
|
}
|
|
105
99
|
|
|
106
|
-
let host = hostport.slice(0, lastIndex)
|
|
100
|
+
let host = hostport.slice(0, lastIndex)
|
|
107
101
|
if (host.startsWith('[') && host.endsWith(']')) {
|
|
108
|
-
host = host.slice(1, -1)
|
|
102
|
+
host = host.slice(1, -1)
|
|
109
103
|
}
|
|
110
104
|
|
|
111
|
-
let port = parseInt(hostport.slice(lastIndex + 1), 10)
|
|
112
|
-
return {host, port}
|
|
113
|
-
}
|
|
105
|
+
let port = parseInt(hostport.slice(lastIndex + 1), 10)
|
|
106
|
+
return { host, port }
|
|
107
|
+
}
|
package/net/portprober.js
CHANGED
|
@@ -15,128 +15,9 @@
|
|
|
15
15
|
// specific language governing permissions and limitations
|
|
16
16
|
// under the License.
|
|
17
17
|
|
|
18
|
-
'use strict'
|
|
19
|
-
|
|
20
|
-
const fs = require('fs');
|
|
21
|
-
const net = require('net');
|
|
22
|
-
const {exec} = require('child_process');
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* The IANA suggested ephemeral port range.
|
|
27
|
-
* @type {{min: number, max: number}}
|
|
28
|
-
* @const
|
|
29
|
-
* @see http://en.wikipedia.org/wiki/Ephemeral_ports
|
|
30
|
-
*/
|
|
31
|
-
const DEFAULT_IANA_RANGE = {min: 49152, max: 65535};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* The epheremal port range for the current system. Lazily computed on first
|
|
36
|
-
* access.
|
|
37
|
-
* @type {Promise<{min: number, max: number}>}
|
|
38
|
-
*/
|
|
39
|
-
let systemRange = null;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Computes the ephemeral port range for the current system. This is based on
|
|
44
|
-
* http://stackoverflow.com/a/924337.
|
|
45
|
-
* @return {!Promise<{min: number, max: number}>} A promise that will resolve to
|
|
46
|
-
* the ephemeral port range of the current system.
|
|
47
|
-
*/
|
|
48
|
-
function findSystemPortRange() {
|
|
49
|
-
if (systemRange) {
|
|
50
|
-
return systemRange;
|
|
51
|
-
}
|
|
52
|
-
let range =
|
|
53
|
-
process.platform === 'win32'
|
|
54
|
-
? findWindowsPortRange() : findUnixPortRange();
|
|
55
|
-
return systemRange = range.catch(() => DEFAULT_IANA_RANGE);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Executes a command and returns its output if it succeeds.
|
|
61
|
-
* @param {string} cmd The command to execute.
|
|
62
|
-
* @return {!Promise<string>} A promise that will resolve with the command's
|
|
63
|
-
* stdout data.
|
|
64
|
-
*/
|
|
65
|
-
function execute(cmd) {
|
|
66
|
-
return new Promise((resolve, reject) => {
|
|
67
|
-
exec(cmd, function(err, stdout) {
|
|
68
|
-
if (err) {
|
|
69
|
-
reject(err);
|
|
70
|
-
} else {
|
|
71
|
-
resolve(stdout);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Computes the ephemeral port range for a Unix-like system.
|
|
80
|
-
* @return {!Promise<{min: number, max: number}>} A promise that will resolve
|
|
81
|
-
* with the ephemeral port range on the current system.
|
|
82
|
-
*/
|
|
83
|
-
async function findUnixPortRange() {
|
|
84
|
-
var cmd;
|
|
85
|
-
if (process.platform === 'sunos') {
|
|
86
|
-
cmd =
|
|
87
|
-
'/usr/sbin/ndd /dev/tcp tcp_smallest_anon_port tcp_largest_anon_port';
|
|
88
|
-
} else if (fs.existsSync('/proc/sys/net/ipv4/ip_local_port_range')) {
|
|
89
|
-
// Linux
|
|
90
|
-
cmd = 'cat /proc/sys/net/ipv4/ip_local_port_range';
|
|
91
|
-
} else {
|
|
92
|
-
cmd = 'sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last' +
|
|
93
|
-
' | sed -e "s/.*:\\s*//"';
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
let stdout = await execute(cmd);
|
|
97
|
-
if (!stdout || !stdout.length) {
|
|
98
|
-
return DEFAULT_IANA_RANGE;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
let range = stdout.trim().split(/\s+/).map(Number);
|
|
102
|
-
if (range.some(isNaN)) {
|
|
103
|
-
return DEFAULT_IANA_RANGE;
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
return {min: range[0], max: range[1]};
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Computes the ephemeral port range for a Windows system.
|
|
112
|
-
* @return {!Promise<{min: number, max: number}>} A promise that will resolve
|
|
113
|
-
* with the ephemeral port range on the current system.
|
|
114
|
-
*/
|
|
115
|
-
async function findWindowsPortRange() {
|
|
116
|
-
// First, check if we're running on XP. If this initial command fails,
|
|
117
|
-
// we just fallback on the default IANA range.
|
|
118
|
-
let stdout = await execute('cmd.exe /c ver');
|
|
119
|
-
if (/Windows XP/.test(stdout)) {
|
|
120
|
-
// TODO: Try to read these values from the registry.
|
|
121
|
-
return {min: 1025, max: 5000};
|
|
122
|
-
} else {
|
|
123
|
-
stdout = await execute('netsh int ipv4 show dynamicport tcp');
|
|
124
|
-
/* > netsh int ipv4 show dynamicport tcp
|
|
125
|
-
Protocol tcp Dynamic Port Range
|
|
126
|
-
---------------------------------
|
|
127
|
-
Start Port : 49152
|
|
128
|
-
Number of Ports : 16384
|
|
129
|
-
*/
|
|
130
|
-
let range = stdout.split(/\n/)
|
|
131
|
-
.filter((line) => /.*:\s*\d+/.test(line))
|
|
132
|
-
.map((line) => Number(line.split(/:\s*/)[1]));
|
|
133
|
-
return {
|
|
134
|
-
min: range[0],
|
|
135
|
-
max: range[0] + range[1]
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
}
|
|
18
|
+
'use strict'
|
|
139
19
|
|
|
20
|
+
const net = require('net')
|
|
140
21
|
|
|
141
22
|
/**
|
|
142
23
|
* Tests if a port is free.
|
|
@@ -148,41 +29,47 @@ async function findWindowsPortRange() {
|
|
|
148
29
|
*/
|
|
149
30
|
function isFree(port, opt_host) {
|
|
150
31
|
return new Promise((resolve, reject) => {
|
|
151
|
-
let server = net.createServer().on('error', function(e) {
|
|
32
|
+
let server = net.createServer().on('error', function (e) {
|
|
152
33
|
if (e.code === 'EADDRINUSE' || e.code === 'EACCES') {
|
|
153
|
-
resolve(false)
|
|
34
|
+
resolve(false)
|
|
154
35
|
} else {
|
|
155
|
-
reject(e)
|
|
36
|
+
reject(e)
|
|
156
37
|
}
|
|
157
|
-
})
|
|
38
|
+
})
|
|
158
39
|
|
|
159
|
-
server.listen(port, opt_host, function() {
|
|
160
|
-
server.close(() => resolve(true))
|
|
161
|
-
})
|
|
162
|
-
})
|
|
40
|
+
server.listen(port, opt_host, function () {
|
|
41
|
+
server.close(() => resolve(true))
|
|
42
|
+
})
|
|
43
|
+
})
|
|
163
44
|
}
|
|
164
45
|
|
|
165
|
-
|
|
166
46
|
/**
|
|
167
47
|
* @param {string=} opt_host The bound host to test the {@code port} against.
|
|
168
48
|
* Defaults to {@code INADDR_ANY}.
|
|
169
49
|
* @return {!Promise<number>} A promise that will resolve to a free port. If a
|
|
170
50
|
* port cannot be found, the promise will be rejected.
|
|
171
51
|
*/
|
|
172
|
-
async function findFreePort(opt_host) {
|
|
173
|
-
let range = await findSystemPortRange();
|
|
174
|
-
for (let i = 0; i < 100; i++) {
|
|
175
|
-
let port = Math.floor(Math.random() * (range.max - range.min) + range.min);
|
|
176
|
-
if (await isFree(port, opt_host)) {
|
|
177
|
-
return port;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
throw Error('Unable to find a free port');
|
|
181
|
-
}
|
|
182
52
|
|
|
53
|
+
function findFreePort(opt_host) {
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
const server = net.createServer()
|
|
56
|
+
server.on('listening', function () {
|
|
57
|
+
resolve(server.address().port)
|
|
58
|
+
server.close()
|
|
59
|
+
})
|
|
60
|
+
server.on('error', (e) => {
|
|
61
|
+
if (e.code === 'EADDRINUSE' || e.code === 'EACCES') {
|
|
62
|
+
resolve('Unable to find a free port')
|
|
63
|
+
} else {
|
|
64
|
+
reject(e)
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
// By providing 0 we let the operative system find an arbitrary port
|
|
68
|
+
server.listen(0, opt_host)
|
|
69
|
+
})
|
|
70
|
+
}
|
|
183
71
|
|
|
184
72
|
// PUBLIC API
|
|
185
73
|
|
|
186
|
-
|
|
187
|
-
exports.
|
|
188
|
-
exports.isFree = isFree;
|
|
74
|
+
exports.findFreePort = findFreePort
|
|
75
|
+
exports.isFree = isFree
|