selenium-webdriver 4.0.0-alpha.5 → 4.0.0-beta.1
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 +35 -1
- package/LICENSE +1 -1
- package/NOTICE +1 -1
- package/README.md +4 -4
- package/chrome.js +72 -592
- package/chromium.js +829 -0
- package/devtools/CDPConnection.js +37 -0
- package/edge.js +124 -86
- package/example/chrome_android.js +16 -13
- package/example/chrome_mobile_emulation.js +18 -14
- package/example/firefox_channels.js +35 -28
- package/example/google_search.js +9 -9
- package/example/google_search_test.js +20 -22
- package/example/headless.js +27 -19
- package/example/logging.js +34 -38
- package/firefox.js +200 -200
- package/http/index.js +131 -115
- package/http/util.js +56 -64
- package/ie.js +180 -104
- package/index.js +246 -199
- package/io/exec.js +34 -39
- package/io/index.js +142 -152
- package/io/zip.js +75 -65
- package/lib/actions.js +140 -122
- package/lib/atoms/find-elements.js +124 -0
- package/lib/atoms/get-attribute.js +79 -59
- package/lib/atoms/is-displayed.js +72 -73
- package/lib/atoms/mutation-listener.js +38 -0
- package/lib/by.js +192 -65
- package/lib/capabilities.js +82 -78
- package/lib/command.js +20 -20
- package/lib/error.js +134 -168
- package/lib/http.js +337 -230
- package/lib/input.js +325 -302
- package/lib/logging.js +127 -138
- package/lib/promise.js +60 -66
- 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 +1024 -541
- package/net/index.js +30 -36
- package/net/portprober.js +31 -144
- package/opera.js +406 -0
- package/package.json +19 -12
- package/proxy.js +2 -2
- package/remote/index.js +190 -187
- package/safari.js +40 -49
- package/testing/index.js +166 -155
package/io/exec.js
CHANGED
|
@@ -15,10 +15,9 @@
|
|
|
15
15
|
// specific language governing permissions and limitations
|
|
16
16
|
// under the License.
|
|
17
17
|
|
|
18
|
-
'use strict'
|
|
19
|
-
|
|
20
|
-
const childProcess = require('child_process');
|
|
18
|
+
'use strict'
|
|
21
19
|
|
|
20
|
+
const childProcess = require('child_process')
|
|
22
21
|
|
|
23
22
|
/**
|
|
24
23
|
* Options for configuring an executed command.
|
|
@@ -31,7 +30,7 @@ class Options {
|
|
|
31
30
|
* Command line arguments for the child process, if any.
|
|
32
31
|
* @type (!Array<string>|undefined)
|
|
33
32
|
*/
|
|
34
|
-
this.args
|
|
33
|
+
this.args
|
|
35
34
|
|
|
36
35
|
/**
|
|
37
36
|
* Environment variables for the spawned process. If unspecified, the
|
|
@@ -39,7 +38,7 @@ class Options {
|
|
|
39
38
|
*
|
|
40
39
|
* @type {(!Object<string, string>|undefined)}
|
|
41
40
|
*/
|
|
42
|
-
this.env
|
|
41
|
+
this.env
|
|
43
42
|
|
|
44
43
|
/**
|
|
45
44
|
* IO conifguration for the spawned server child process. If unspecified,
|
|
@@ -49,11 +48,10 @@ class Options {
|
|
|
49
48
|
* undefined)}
|
|
50
49
|
* @see <https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html#child_process_options_stdio>
|
|
51
50
|
*/
|
|
52
|
-
this.stdio
|
|
51
|
+
this.stdio
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
|
|
57
55
|
/**
|
|
58
56
|
* Describes a command's termination conditions.
|
|
59
57
|
*/
|
|
@@ -66,21 +64,20 @@ class Result {
|
|
|
66
64
|
*/
|
|
67
65
|
constructor(code, signal) {
|
|
68
66
|
/** @type {?number} */
|
|
69
|
-
this.code = code
|
|
67
|
+
this.code = code
|
|
70
68
|
|
|
71
69
|
/** @type {?string} */
|
|
72
|
-
this.signal = signal
|
|
70
|
+
this.signal = signal
|
|
73
71
|
}
|
|
74
72
|
|
|
75
73
|
/** @override */
|
|
76
74
|
toString() {
|
|
77
|
-
return `Result(code=${this.code}, signal=${this.signal})
|
|
75
|
+
return `Result(code=${this.code}, signal=${this.signal})`
|
|
78
76
|
}
|
|
79
77
|
}
|
|
80
78
|
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
const KILL_HOOK = /** !WeakMap<!Command, function(string)> */new WeakMap;
|
|
79
|
+
const COMMAND_RESULT = /** !WeakMap<!Command, !Promise<!Result>> */ new WeakMap()
|
|
80
|
+
const KILL_HOOK = /** !WeakMap<!Command, function(string)> */ new WeakMap()
|
|
84
81
|
|
|
85
82
|
/**
|
|
86
83
|
* Represents a command running in a sub-process.
|
|
@@ -92,8 +89,8 @@ class Command {
|
|
|
92
89
|
* is called.
|
|
93
90
|
*/
|
|
94
91
|
constructor(result, onKill) {
|
|
95
|
-
COMMAND_RESULT.set(this, result)
|
|
96
|
-
KILL_HOOK.set(this, onKill)
|
|
92
|
+
COMMAND_RESULT.set(this, result)
|
|
93
|
+
KILL_HOOK.set(this, onKill)
|
|
97
94
|
}
|
|
98
95
|
|
|
99
96
|
/**
|
|
@@ -101,7 +98,7 @@ class Command {
|
|
|
101
98
|
* command.
|
|
102
99
|
*/
|
|
103
100
|
result() {
|
|
104
|
-
return /** @type {!Promise<!Result>} */(COMMAND_RESULT.get(this))
|
|
101
|
+
return /** @type {!Promise<!Result>} */ (COMMAND_RESULT.get(this))
|
|
105
102
|
}
|
|
106
103
|
|
|
107
104
|
/**
|
|
@@ -109,14 +106,12 @@ class Command {
|
|
|
109
106
|
* @param {string=} opt_signal The signal to send; defaults to `SIGTERM`.
|
|
110
107
|
*/
|
|
111
108
|
kill(opt_signal) {
|
|
112
|
-
KILL_HOOK.get(this)(opt_signal || 'SIGTERM')
|
|
109
|
+
KILL_HOOK.get(this)(opt_signal || 'SIGTERM')
|
|
113
110
|
}
|
|
114
111
|
}
|
|
115
112
|
|
|
116
|
-
|
|
117
113
|
// PUBLIC API
|
|
118
114
|
|
|
119
|
-
|
|
120
115
|
/**
|
|
121
116
|
* Spawns a child process. The returned {@link Command} may be used to wait
|
|
122
117
|
* for the process result or to send signals to the process.
|
|
@@ -126,42 +121,42 @@ class Command {
|
|
|
126
121
|
* @return {!Command} The launched command.
|
|
127
122
|
*/
|
|
128
123
|
module.exports = function exec(command, opt_options) {
|
|
129
|
-
var options = opt_options || {}
|
|
124
|
+
var options = opt_options || {}
|
|
130
125
|
|
|
131
126
|
var proc = childProcess.spawn(command, options.args || [], {
|
|
132
127
|
env: options.env || process.env,
|
|
133
|
-
stdio: options.stdio || 'ignore'
|
|
134
|
-
})
|
|
128
|
+
stdio: options.stdio || 'ignore',
|
|
129
|
+
})
|
|
135
130
|
|
|
136
131
|
// This process should not wait on the spawned child, however, we do
|
|
137
132
|
// want to ensure the child is killed when this process exits.
|
|
138
|
-
proc.unref()
|
|
139
|
-
process.once('exit', onProcessExit)
|
|
133
|
+
proc.unref()
|
|
134
|
+
process.once('exit', onProcessExit)
|
|
140
135
|
|
|
141
|
-
let result = new Promise(resolve => {
|
|
136
|
+
let result = new Promise((resolve) => {
|
|
142
137
|
proc.once('exit', (code, signal) => {
|
|
143
|
-
proc = null
|
|
144
|
-
process.removeListener('exit', onProcessExit)
|
|
145
|
-
resolve(new Result(code, signal))
|
|
146
|
-
})
|
|
147
|
-
})
|
|
148
|
-
return new Command(result, killCommand)
|
|
138
|
+
proc = null
|
|
139
|
+
process.removeListener('exit', onProcessExit)
|
|
140
|
+
resolve(new Result(code, signal))
|
|
141
|
+
})
|
|
142
|
+
})
|
|
143
|
+
return new Command(result, killCommand)
|
|
149
144
|
|
|
150
145
|
function onProcessExit() {
|
|
151
|
-
killCommand('SIGTERM')
|
|
146
|
+
killCommand('SIGTERM')
|
|
152
147
|
}
|
|
153
148
|
|
|
154
149
|
function killCommand(signal) {
|
|
155
|
-
process.removeListener('exit', onProcessExit)
|
|
150
|
+
process.removeListener('exit', onProcessExit)
|
|
156
151
|
if (proc) {
|
|
157
|
-
proc.kill(signal)
|
|
158
|
-
proc = null
|
|
152
|
+
proc.kill(signal)
|
|
153
|
+
proc = null
|
|
159
154
|
}
|
|
160
155
|
}
|
|
161
|
-
}
|
|
156
|
+
}
|
|
162
157
|
|
|
163
158
|
// Exported to improve generated API documentation.
|
|
164
159
|
|
|
165
|
-
module.exports.Command = Command
|
|
166
|
-
module.exports.Options = Options
|
|
167
|
-
module.exports.Result = Result
|
|
160
|
+
module.exports.Command = Command
|
|
161
|
+
module.exports.Options = Options
|
|
162
|
+
module.exports.Result = Result
|
package/io/index.js
CHANGED
|
@@ -15,13 +15,12 @@
|
|
|
15
15
|
// specific language governing permissions and limitations
|
|
16
16
|
// under the License.
|
|
17
17
|
|
|
18
|
-
'use strict'
|
|
19
|
-
|
|
20
|
-
var fs = require('fs'),
|
|
21
|
-
path = require('path'),
|
|
22
|
-
rimraf = require('rimraf'),
|
|
23
|
-
tmp = require('tmp');
|
|
18
|
+
'use strict'
|
|
24
19
|
|
|
20
|
+
const fs = require('fs')
|
|
21
|
+
const path = require('path')
|
|
22
|
+
const rimraf = require('rimraf')
|
|
23
|
+
const tmp = require('tmp')
|
|
25
24
|
|
|
26
25
|
/**
|
|
27
26
|
* @param {!Function} fn .
|
|
@@ -33,23 +32,19 @@ function checkedCall(fn) {
|
|
|
33
32
|
try {
|
|
34
33
|
fn((err, value) => {
|
|
35
34
|
if (err) {
|
|
36
|
-
reject(err)
|
|
35
|
+
reject(err)
|
|
37
36
|
} else {
|
|
38
|
-
resolve(value)
|
|
37
|
+
resolve(value)
|
|
39
38
|
}
|
|
40
|
-
})
|
|
39
|
+
})
|
|
41
40
|
} catch (e) {
|
|
42
|
-
reject(e)
|
|
41
|
+
reject(e)
|
|
43
42
|
}
|
|
44
|
-
})
|
|
43
|
+
})
|
|
45
44
|
}
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
|
|
49
46
|
// PUBLIC API
|
|
50
47
|
|
|
51
|
-
|
|
52
|
-
|
|
53
48
|
/**
|
|
54
49
|
* Recursively removes a directory and all of its contents. This is equivalent
|
|
55
50
|
* to {@code rm -rf} on a POSIX system.
|
|
@@ -57,27 +52,26 @@ function checkedCall(fn) {
|
|
|
57
52
|
* @return {!Promise} A promise to be resolved when the operation has
|
|
58
53
|
* completed.
|
|
59
54
|
*/
|
|
60
|
-
exports.rmDir = function(dirPath) {
|
|
61
|
-
return new Promise(function(fulfill, reject) {
|
|
62
|
-
var numAttempts = 0
|
|
63
|
-
attemptRm()
|
|
55
|
+
exports.rmDir = function (dirPath) {
|
|
56
|
+
return new Promise(function (fulfill, reject) {
|
|
57
|
+
var numAttempts = 0
|
|
58
|
+
attemptRm()
|
|
64
59
|
function attemptRm() {
|
|
65
|
-
numAttempts += 1
|
|
66
|
-
rimraf(dirPath, function(err) {
|
|
60
|
+
numAttempts += 1
|
|
61
|
+
rimraf(dirPath, function (err) {
|
|
67
62
|
if (err) {
|
|
68
63
|
if (err.code && err.code === 'ENOTEMPTY' && numAttempts < 2) {
|
|
69
|
-
attemptRm()
|
|
70
|
-
return
|
|
64
|
+
attemptRm()
|
|
65
|
+
return
|
|
71
66
|
}
|
|
72
|
-
reject(err)
|
|
67
|
+
reject(err)
|
|
73
68
|
} else {
|
|
74
|
-
fulfill()
|
|
69
|
+
fulfill()
|
|
75
70
|
}
|
|
76
|
-
})
|
|
71
|
+
})
|
|
77
72
|
}
|
|
78
|
-
})
|
|
79
|
-
}
|
|
80
|
-
|
|
73
|
+
})
|
|
74
|
+
}
|
|
81
75
|
|
|
82
76
|
/**
|
|
83
77
|
* Copies one file to another.
|
|
@@ -85,19 +79,18 @@ exports.rmDir = function(dirPath) {
|
|
|
85
79
|
* @param {string} dst The destination file.
|
|
86
80
|
* @return {!Promise<string>} A promise for the copied file's path.
|
|
87
81
|
*/
|
|
88
|
-
exports.copy = function(src, dst) {
|
|
89
|
-
return new Promise(function(fulfill, reject) {
|
|
90
|
-
var rs = fs.createReadStream(src)
|
|
91
|
-
rs.on('error', reject)
|
|
82
|
+
exports.copy = function (src, dst) {
|
|
83
|
+
return new Promise(function (fulfill, reject) {
|
|
84
|
+
var rs = fs.createReadStream(src)
|
|
85
|
+
rs.on('error', reject)
|
|
92
86
|
|
|
93
|
-
var ws = fs.createWriteStream(dst)
|
|
94
|
-
ws.on('error', reject)
|
|
95
|
-
ws.on('close', () => fulfill(dst))
|
|
96
|
-
|
|
97
|
-
rs.pipe(ws);
|
|
98
|
-
});
|
|
99
|
-
};
|
|
87
|
+
var ws = fs.createWriteStream(dst)
|
|
88
|
+
ws.on('error', reject)
|
|
89
|
+
ws.on('close', () => fulfill(dst))
|
|
100
90
|
|
|
91
|
+
rs.pipe(ws)
|
|
92
|
+
})
|
|
93
|
+
}
|
|
101
94
|
|
|
102
95
|
/**
|
|
103
96
|
* Recursively copies the contents of one directory to another.
|
|
@@ -109,63 +102,62 @@ exports.copy = function(src, dst) {
|
|
|
109
102
|
* @return {!Promise<string>} A promise for the destination
|
|
110
103
|
* directory's path once all files have been copied.
|
|
111
104
|
*/
|
|
112
|
-
exports.copyDir = function(src, dst, opt_exclude) {
|
|
113
|
-
var predicate = opt_exclude
|
|
105
|
+
exports.copyDir = function (src, dst, opt_exclude) {
|
|
106
|
+
var predicate = opt_exclude
|
|
114
107
|
if (opt_exclude && typeof opt_exclude !== 'function') {
|
|
115
|
-
predicate = function(p) {
|
|
116
|
-
return !opt_exclude.test(p)
|
|
117
|
-
}
|
|
108
|
+
predicate = function (p) {
|
|
109
|
+
return !opt_exclude.test(p)
|
|
110
|
+
}
|
|
118
111
|
}
|
|
119
112
|
|
|
120
113
|
// TODO(jleyba): Make this function completely async.
|
|
121
114
|
if (!fs.existsSync(dst)) {
|
|
122
|
-
fs.mkdirSync(dst)
|
|
115
|
+
fs.mkdirSync(dst)
|
|
123
116
|
}
|
|
124
117
|
|
|
125
|
-
var files = fs.readdirSync(src)
|
|
126
|
-
files = files.map(function(file) {
|
|
127
|
-
return path.join(src, file)
|
|
128
|
-
})
|
|
118
|
+
var files = fs.readdirSync(src)
|
|
119
|
+
files = files.map(function (file) {
|
|
120
|
+
return path.join(src, file)
|
|
121
|
+
})
|
|
129
122
|
|
|
130
123
|
if (predicate) {
|
|
131
|
-
files = files.filter(/** @type {function(string): boolean} */(predicate))
|
|
124
|
+
files = files.filter(/** @type {function(string): boolean} */ (predicate))
|
|
132
125
|
}
|
|
133
126
|
|
|
134
|
-
var results = []
|
|
135
|
-
files.forEach(function(file) {
|
|
136
|
-
var stats = fs.statSync(file)
|
|
137
|
-
var target = path.join(dst, path.basename(file))
|
|
127
|
+
var results = []
|
|
128
|
+
files.forEach(function (file) {
|
|
129
|
+
var stats = fs.statSync(file)
|
|
130
|
+
var target = path.join(dst, path.basename(file))
|
|
138
131
|
|
|
139
132
|
if (stats.isDirectory()) {
|
|
140
133
|
if (!fs.existsSync(target)) {
|
|
141
|
-
fs.mkdirSync(target, stats.mode)
|
|
134
|
+
fs.mkdirSync(target, stats.mode)
|
|
142
135
|
}
|
|
143
|
-
results.push(exports.copyDir(file, target, predicate))
|
|
136
|
+
results.push(exports.copyDir(file, target, predicate))
|
|
144
137
|
} else {
|
|
145
|
-
results.push(exports.copy(file, target))
|
|
138
|
+
results.push(exports.copy(file, target))
|
|
146
139
|
}
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
return Promise.all(results).then(() => dst);
|
|
150
|
-
};
|
|
140
|
+
})
|
|
151
141
|
|
|
142
|
+
return Promise.all(results).then(() => dst)
|
|
143
|
+
}
|
|
152
144
|
|
|
153
145
|
/**
|
|
154
146
|
* Tests if a file path exists.
|
|
155
147
|
* @param {string} aPath The path to test.
|
|
156
148
|
* @return {!Promise<boolean>} A promise for whether the file exists.
|
|
157
149
|
*/
|
|
158
|
-
exports.exists = function(aPath) {
|
|
159
|
-
return new Promise(function(fulfill, reject) {
|
|
160
|
-
let type = typeof aPath
|
|
150
|
+
exports.exists = function (aPath) {
|
|
151
|
+
return new Promise(function (fulfill, reject) {
|
|
152
|
+
let type = typeof aPath
|
|
161
153
|
if (type !== 'string') {
|
|
162
|
-
reject(TypeError(`expected string path, but got ${type}`))
|
|
154
|
+
reject(TypeError(`expected string path, but got ${type}`))
|
|
163
155
|
} else {
|
|
164
|
-
|
|
156
|
+
// eslint-disable-next-line node/no-deprecated-api
|
|
157
|
+
fs.exists(aPath, fulfill)
|
|
165
158
|
}
|
|
166
|
-
})
|
|
167
|
-
}
|
|
168
|
-
|
|
159
|
+
})
|
|
160
|
+
}
|
|
169
161
|
|
|
170
162
|
/**
|
|
171
163
|
* Calls `stat(2)`.
|
|
@@ -173,9 +165,8 @@ exports.exists = function(aPath) {
|
|
|
173
165
|
* @return {!Promise<!fs.Stats>} A promise for the file stats.
|
|
174
166
|
*/
|
|
175
167
|
exports.stat = function stat(aPath) {
|
|
176
|
-
return checkedCall(callback => fs.stat(aPath, callback))
|
|
177
|
-
}
|
|
178
|
-
|
|
168
|
+
return checkedCall((callback) => fs.stat(aPath, callback))
|
|
169
|
+
}
|
|
179
170
|
|
|
180
171
|
/**
|
|
181
172
|
* Deletes a name from the filesystem and possibly the file it refers to. Has
|
|
@@ -183,47 +174,45 @@ exports.stat = function stat(aPath) {
|
|
|
183
174
|
* @param {string} aPath The path to remove.
|
|
184
175
|
* @return {!Promise} A promise for when the file has been removed.
|
|
185
176
|
*/
|
|
186
|
-
exports.unlink = function(aPath) {
|
|
187
|
-
return new Promise(function(fulfill, reject) {
|
|
188
|
-
|
|
177
|
+
exports.unlink = function (aPath) {
|
|
178
|
+
return new Promise(function (fulfill, reject) {
|
|
179
|
+
// eslint-disable-next-line node/no-deprecated-api
|
|
180
|
+
fs.exists(aPath, function (exists) {
|
|
189
181
|
if (exists) {
|
|
190
|
-
fs.unlink(aPath, function(err) {
|
|
191
|
-
err && reject(err) || fulfill()
|
|
192
|
-
})
|
|
182
|
+
fs.unlink(aPath, function (err) {
|
|
183
|
+
;(err && reject(err)) || fulfill()
|
|
184
|
+
})
|
|
193
185
|
} else {
|
|
194
|
-
fulfill()
|
|
186
|
+
fulfill()
|
|
195
187
|
}
|
|
196
|
-
})
|
|
197
|
-
})
|
|
198
|
-
}
|
|
199
|
-
|
|
188
|
+
})
|
|
189
|
+
})
|
|
190
|
+
}
|
|
200
191
|
|
|
201
192
|
/**
|
|
202
193
|
* @return {!Promise<string>} A promise for the path to a temporary directory.
|
|
203
194
|
* @see https://www.npmjs.org/package/tmp
|
|
204
195
|
*/
|
|
205
|
-
exports.tmpDir = function() {
|
|
206
|
-
return checkedCall(tmp.dir)
|
|
207
|
-
}
|
|
208
|
-
|
|
196
|
+
exports.tmpDir = function () {
|
|
197
|
+
return checkedCall((callback) => tmp.dir({ unsafeCleanup: true }, callback))
|
|
198
|
+
}
|
|
209
199
|
|
|
210
200
|
/**
|
|
211
201
|
* @param {{postfix: string}=} opt_options Temporary file options.
|
|
212
202
|
* @return {!Promise<string>} A promise for the path to a temporary file.
|
|
213
203
|
* @see https://www.npmjs.org/package/tmp
|
|
214
204
|
*/
|
|
215
|
-
exports.tmpFile = function(opt_options) {
|
|
216
|
-
return checkedCall(callback => {
|
|
205
|
+
exports.tmpFile = function (opt_options) {
|
|
206
|
+
return checkedCall((callback) => {
|
|
217
207
|
// |tmp.file| checks arguments length to detect options rather than doing a
|
|
218
208
|
// truthy check, so we must only pass options if there are some to pass.
|
|
219
209
|
if (opt_options) {
|
|
220
|
-
tmp.file(opt_options, callback)
|
|
210
|
+
tmp.file(opt_options, callback)
|
|
221
211
|
} else {
|
|
222
|
-
tmp.file(callback)
|
|
212
|
+
tmp.file(callback)
|
|
223
213
|
}
|
|
224
|
-
})
|
|
225
|
-
}
|
|
226
|
-
|
|
214
|
+
})
|
|
215
|
+
}
|
|
227
216
|
|
|
228
217
|
/**
|
|
229
218
|
* Searches the {@code PATH} environment variable for the given file.
|
|
@@ -234,26 +223,25 @@ exports.tmpFile = function(opt_options) {
|
|
|
234
223
|
* @return {?string} Path to the located file, or {@code null} if it could
|
|
235
224
|
* not be found.
|
|
236
225
|
*/
|
|
237
|
-
exports.findInPath = function(file, opt_checkCwd) {
|
|
238
|
-
let dirs = []
|
|
226
|
+
exports.findInPath = function (file, opt_checkCwd) {
|
|
227
|
+
let dirs = []
|
|
239
228
|
if (opt_checkCwd) {
|
|
240
|
-
dirs.push(process.cwd())
|
|
229
|
+
dirs.push(process.cwd())
|
|
241
230
|
}
|
|
242
|
-
dirs.push.apply(dirs, process.env['PATH'].split(path.delimiter))
|
|
231
|
+
dirs.push.apply(dirs, process.env['PATH'].split(path.delimiter))
|
|
243
232
|
|
|
244
|
-
let foundInDir = dirs.find(dir => {
|
|
245
|
-
let tmp = path.join(dir, file)
|
|
233
|
+
let foundInDir = dirs.find((dir) => {
|
|
234
|
+
let tmp = path.join(dir, file)
|
|
246
235
|
try {
|
|
247
|
-
let stats = fs.statSync(tmp)
|
|
248
|
-
return stats.isFile() && !stats.isDirectory()
|
|
236
|
+
let stats = fs.statSync(tmp)
|
|
237
|
+
return stats.isFile() && !stats.isDirectory()
|
|
249
238
|
} catch (ex) {
|
|
250
|
-
return false
|
|
239
|
+
return false
|
|
251
240
|
}
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
return foundInDir ? path.join(foundInDir, file) : null;
|
|
255
|
-
};
|
|
241
|
+
})
|
|
256
242
|
|
|
243
|
+
return foundInDir ? path.join(foundInDir, file) : null
|
|
244
|
+
}
|
|
257
245
|
|
|
258
246
|
/**
|
|
259
247
|
* Reads the contents of the given file.
|
|
@@ -262,10 +250,9 @@ exports.findInPath = function(file, opt_checkCwd) {
|
|
|
262
250
|
* @return {!Promise<!Buffer>} A promise that will resolve with a buffer of the
|
|
263
251
|
* file contents.
|
|
264
252
|
*/
|
|
265
|
-
exports.read = function(aPath) {
|
|
266
|
-
return checkedCall(callback => fs.readFile(aPath, callback))
|
|
267
|
-
}
|
|
268
|
-
|
|
253
|
+
exports.read = function (aPath) {
|
|
254
|
+
return checkedCall((callback) => fs.readFile(aPath, callback))
|
|
255
|
+
}
|
|
269
256
|
|
|
270
257
|
/**
|
|
271
258
|
* Writes to a file.
|
|
@@ -275,10 +262,9 @@ exports.read = function(aPath) {
|
|
|
275
262
|
* @return {!Promise} A promise that will resolve when the operation has
|
|
276
263
|
* completed.
|
|
277
264
|
*/
|
|
278
|
-
exports.write = function(aPath, data) {
|
|
279
|
-
return checkedCall(callback => fs.writeFile(aPath, data, callback))
|
|
280
|
-
}
|
|
281
|
-
|
|
265
|
+
exports.write = function (aPath, data) {
|
|
266
|
+
return checkedCall((callback) => fs.writeFile(aPath, data, callback))
|
|
267
|
+
}
|
|
282
268
|
|
|
283
269
|
/**
|
|
284
270
|
* Creates a directory.
|
|
@@ -287,18 +273,17 @@ exports.write = function(aPath, data) {
|
|
|
287
273
|
* @return {!Promise<string>} A promise that will resolve with the path of the
|
|
288
274
|
* created directory.
|
|
289
275
|
*/
|
|
290
|
-
exports.mkdir = function(aPath) {
|
|
291
|
-
return checkedCall(callback => {
|
|
292
|
-
fs.mkdir(aPath, undefined, err => {
|
|
276
|
+
exports.mkdir = function (aPath) {
|
|
277
|
+
return checkedCall((callback) => {
|
|
278
|
+
fs.mkdir(aPath, undefined, (err) => {
|
|
293
279
|
if (err && err.code !== 'EEXIST') {
|
|
294
|
-
callback(err)
|
|
280
|
+
callback(err)
|
|
295
281
|
} else {
|
|
296
|
-
callback(null, aPath)
|
|
282
|
+
callback(null, aPath)
|
|
297
283
|
}
|
|
298
|
-
})
|
|
299
|
-
})
|
|
300
|
-
}
|
|
301
|
-
|
|
284
|
+
})
|
|
285
|
+
})
|
|
286
|
+
}
|
|
302
287
|
|
|
303
288
|
/**
|
|
304
289
|
* Recursively creates a directory and any ancestors that do not yet exist.
|
|
@@ -308,29 +293,31 @@ exports.mkdir = function(aPath) {
|
|
|
308
293
|
* created directory.
|
|
309
294
|
*/
|
|
310
295
|
exports.mkdirp = function mkdirp(dir) {
|
|
311
|
-
return checkedCall(callback => {
|
|
312
|
-
fs.mkdir(dir, undefined, err => {
|
|
296
|
+
return checkedCall((callback) => {
|
|
297
|
+
fs.mkdir(dir, undefined, (err) => {
|
|
313
298
|
if (!err) {
|
|
314
|
-
callback(null, dir)
|
|
315
|
-
return
|
|
299
|
+
callback(null, dir)
|
|
300
|
+
return
|
|
316
301
|
}
|
|
317
302
|
|
|
318
303
|
switch (err.code) {
|
|
319
304
|
case 'EEXIST':
|
|
320
|
-
callback(null, dir)
|
|
321
|
-
return
|
|
305
|
+
callback(null, dir)
|
|
306
|
+
return
|
|
322
307
|
case 'ENOENT':
|
|
323
308
|
return mkdirp(path.dirname(dir))
|
|
324
|
-
|
|
325
|
-
|
|
309
|
+
.then(() => mkdirp(dir))
|
|
310
|
+
.then(
|
|
311
|
+
() => callback(null, dir),
|
|
312
|
+
(err) => callback(err)
|
|
313
|
+
)
|
|
326
314
|
default:
|
|
327
|
-
callback(err)
|
|
328
|
-
return
|
|
315
|
+
callback(err)
|
|
316
|
+
return
|
|
329
317
|
}
|
|
330
|
-
})
|
|
331
|
-
})
|
|
332
|
-
}
|
|
333
|
-
|
|
318
|
+
})
|
|
319
|
+
})
|
|
320
|
+
}
|
|
334
321
|
|
|
335
322
|
/**
|
|
336
323
|
* Recursively walks a directory, returning a promise that will resolve with
|
|
@@ -341,19 +328,22 @@ exports.mkdirp = function mkdirp(dir) {
|
|
|
341
328
|
* resolve with a list of entries seen. For each entry, the recorded path
|
|
342
329
|
* will be relative to `rootPath`.
|
|
343
330
|
*/
|
|
344
|
-
exports.walkDir = function(rootPath) {
|
|
345
|
-
let seen = []
|
|
331
|
+
exports.walkDir = function (rootPath) {
|
|
332
|
+
let seen = []
|
|
346
333
|
return (function walk(dir) {
|
|
347
|
-
return checkedCall(callback => fs.readdir(dir, callback))
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
334
|
+
return checkedCall((callback) => fs.readdir(dir, callback)).then((files) =>
|
|
335
|
+
Promise.all(
|
|
336
|
+
files.map((file) => {
|
|
337
|
+
file = path.join(dir, file)
|
|
338
|
+
return checkedCall((cb) => fs.stat(file, cb)).then((stats) => {
|
|
351
339
|
seen.push({
|
|
352
340
|
path: path.relative(rootPath, file),
|
|
353
|
-
dir: stats.isDirectory()
|
|
354
|
-
})
|
|
355
|
-
return stats.isDirectory() && walk(file)
|
|
356
|
-
})
|
|
357
|
-
})
|
|
358
|
-
|
|
359
|
-
|
|
341
|
+
dir: stats.isDirectory(),
|
|
342
|
+
})
|
|
343
|
+
return stats.isDirectory() && walk(file)
|
|
344
|
+
})
|
|
345
|
+
})
|
|
346
|
+
)
|
|
347
|
+
)
|
|
348
|
+
})(rootPath).then(() => seen)
|
|
349
|
+
}
|