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/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
|
-
|
|
124
|
+
const options = opt_options || {}
|
|
130
125
|
|
|
131
|
-
|
|
126
|
+
let 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
|
-
|
|
136
|
+
const 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,44 @@ 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(callback => tmp.dir({ unsafeCleanup
|
|
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 => {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
};
|
|
226
|
-
|
|
205
|
+
exports.tmpFile = function (opt_options) {
|
|
206
|
+
return checkedCall((callback) => {
|
|
207
|
+
/** check fixed in v > 0.2.1 if
|
|
208
|
+
* (typeof options === 'function') {
|
|
209
|
+
* return [{}, options];
|
|
210
|
+
* }
|
|
211
|
+
*/
|
|
212
|
+
tmp.file(opt_options, callback)
|
|
213
|
+
})
|
|
214
|
+
}
|
|
227
215
|
|
|
228
216
|
/**
|
|
229
217
|
* Searches the {@code PATH} environment variable for the given file.
|
|
@@ -234,26 +222,25 @@ exports.tmpFile = function(opt_options) {
|
|
|
234
222
|
* @return {?string} Path to the located file, or {@code null} if it could
|
|
235
223
|
* not be found.
|
|
236
224
|
*/
|
|
237
|
-
exports.findInPath = function(file, opt_checkCwd) {
|
|
238
|
-
|
|
225
|
+
exports.findInPath = function (file, opt_checkCwd) {
|
|
226
|
+
const dirs = []
|
|
239
227
|
if (opt_checkCwd) {
|
|
240
|
-
dirs.push(process.cwd())
|
|
228
|
+
dirs.push(process.cwd())
|
|
241
229
|
}
|
|
242
|
-
dirs.push.apply(dirs, process.env['PATH'].split(path.delimiter))
|
|
230
|
+
dirs.push.apply(dirs, process.env['PATH'].split(path.delimiter))
|
|
243
231
|
|
|
244
|
-
let foundInDir = dirs.find(dir => {
|
|
245
|
-
let tmp = path.join(dir, file)
|
|
232
|
+
let foundInDir = dirs.find((dir) => {
|
|
233
|
+
let tmp = path.join(dir, file)
|
|
246
234
|
try {
|
|
247
|
-
let stats = fs.statSync(tmp)
|
|
248
|
-
return stats.isFile() && !stats.isDirectory()
|
|
235
|
+
let stats = fs.statSync(tmp)
|
|
236
|
+
return stats.isFile() && !stats.isDirectory()
|
|
249
237
|
} catch (ex) {
|
|
250
|
-
return false
|
|
238
|
+
return false
|
|
251
239
|
}
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
return foundInDir ? path.join(foundInDir, file) : null;
|
|
255
|
-
};
|
|
240
|
+
})
|
|
256
241
|
|
|
242
|
+
return foundInDir ? path.join(foundInDir, file) : null
|
|
243
|
+
}
|
|
257
244
|
|
|
258
245
|
/**
|
|
259
246
|
* Reads the contents of the given file.
|
|
@@ -262,10 +249,9 @@ exports.findInPath = function(file, opt_checkCwd) {
|
|
|
262
249
|
* @return {!Promise<!Buffer>} A promise that will resolve with a buffer of the
|
|
263
250
|
* file contents.
|
|
264
251
|
*/
|
|
265
|
-
exports.read = function(aPath) {
|
|
266
|
-
return checkedCall(callback => fs.readFile(aPath, callback))
|
|
267
|
-
}
|
|
268
|
-
|
|
252
|
+
exports.read = function (aPath) {
|
|
253
|
+
return checkedCall((callback) => fs.readFile(aPath, callback))
|
|
254
|
+
}
|
|
269
255
|
|
|
270
256
|
/**
|
|
271
257
|
* Writes to a file.
|
|
@@ -275,10 +261,9 @@ exports.read = function(aPath) {
|
|
|
275
261
|
* @return {!Promise} A promise that will resolve when the operation has
|
|
276
262
|
* completed.
|
|
277
263
|
*/
|
|
278
|
-
exports.write = function(aPath, data) {
|
|
279
|
-
return checkedCall(callback => fs.writeFile(aPath, data, callback))
|
|
280
|
-
}
|
|
281
|
-
|
|
264
|
+
exports.write = function (aPath, data) {
|
|
265
|
+
return checkedCall((callback) => fs.writeFile(aPath, data, callback))
|
|
266
|
+
}
|
|
282
267
|
|
|
283
268
|
/**
|
|
284
269
|
* Creates a directory.
|
|
@@ -287,18 +272,17 @@ exports.write = function(aPath, data) {
|
|
|
287
272
|
* @return {!Promise<string>} A promise that will resolve with the path of the
|
|
288
273
|
* created directory.
|
|
289
274
|
*/
|
|
290
|
-
exports.mkdir = function(aPath) {
|
|
291
|
-
return checkedCall(callback => {
|
|
292
|
-
fs.mkdir(aPath, undefined, err => {
|
|
275
|
+
exports.mkdir = function (aPath) {
|
|
276
|
+
return checkedCall((callback) => {
|
|
277
|
+
fs.mkdir(aPath, undefined, (err) => {
|
|
293
278
|
if (err && err.code !== 'EEXIST') {
|
|
294
|
-
callback(err)
|
|
279
|
+
callback(err)
|
|
295
280
|
} else {
|
|
296
|
-
callback(null, aPath)
|
|
281
|
+
callback(null, aPath)
|
|
297
282
|
}
|
|
298
|
-
})
|
|
299
|
-
})
|
|
300
|
-
}
|
|
301
|
-
|
|
283
|
+
})
|
|
284
|
+
})
|
|
285
|
+
}
|
|
302
286
|
|
|
303
287
|
/**
|
|
304
288
|
* Recursively creates a directory and any ancestors that do not yet exist.
|
|
@@ -308,29 +292,31 @@ exports.mkdir = function(aPath) {
|
|
|
308
292
|
* created directory.
|
|
309
293
|
*/
|
|
310
294
|
exports.mkdirp = function mkdirp(dir) {
|
|
311
|
-
return checkedCall(callback => {
|
|
312
|
-
fs.mkdir(dir, undefined, err => {
|
|
295
|
+
return checkedCall((callback) => {
|
|
296
|
+
fs.mkdir(dir, undefined, (err) => {
|
|
313
297
|
if (!err) {
|
|
314
|
-
callback(null, dir)
|
|
315
|
-
return
|
|
298
|
+
callback(null, dir)
|
|
299
|
+
return
|
|
316
300
|
}
|
|
317
301
|
|
|
318
302
|
switch (err.code) {
|
|
319
303
|
case 'EEXIST':
|
|
320
|
-
callback(null, dir)
|
|
321
|
-
return
|
|
304
|
+
callback(null, dir)
|
|
305
|
+
return
|
|
322
306
|
case 'ENOENT':
|
|
323
307
|
return mkdirp(path.dirname(dir))
|
|
324
|
-
|
|
325
|
-
|
|
308
|
+
.then(() => mkdirp(dir))
|
|
309
|
+
.then(
|
|
310
|
+
() => callback(null, dir),
|
|
311
|
+
(err) => callback(err)
|
|
312
|
+
)
|
|
326
313
|
default:
|
|
327
|
-
callback(err)
|
|
328
|
-
return
|
|
314
|
+
callback(err)
|
|
315
|
+
return
|
|
329
316
|
}
|
|
330
|
-
})
|
|
331
|
-
})
|
|
332
|
-
}
|
|
333
|
-
|
|
317
|
+
})
|
|
318
|
+
})
|
|
319
|
+
}
|
|
334
320
|
|
|
335
321
|
/**
|
|
336
322
|
* Recursively walks a directory, returning a promise that will resolve with
|
|
@@ -341,19 +327,22 @@ exports.mkdirp = function mkdirp(dir) {
|
|
|
341
327
|
* resolve with a list of entries seen. For each entry, the recorded path
|
|
342
328
|
* will be relative to `rootPath`.
|
|
343
329
|
*/
|
|
344
|
-
exports.walkDir = function(rootPath) {
|
|
345
|
-
|
|
330
|
+
exports.walkDir = function (rootPath) {
|
|
331
|
+
const seen = []
|
|
346
332
|
return (function walk(dir) {
|
|
347
|
-
return checkedCall(callback => fs.readdir(dir, callback))
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
333
|
+
return checkedCall((callback) => fs.readdir(dir, callback)).then((files) =>
|
|
334
|
+
Promise.all(
|
|
335
|
+
files.map((file) => {
|
|
336
|
+
file = path.join(dir, file)
|
|
337
|
+
return checkedCall((cb) => fs.stat(file, cb)).then((stats) => {
|
|
351
338
|
seen.push({
|
|
352
339
|
path: path.relative(rootPath, file),
|
|
353
|
-
dir: stats.isDirectory()
|
|
354
|
-
})
|
|
355
|
-
return stats.isDirectory() && walk(file)
|
|
356
|
-
})
|
|
357
|
-
})
|
|
358
|
-
|
|
359
|
-
|
|
340
|
+
dir: stats.isDirectory(),
|
|
341
|
+
})
|
|
342
|
+
return stats.isDirectory() && walk(file)
|
|
343
|
+
})
|
|
344
|
+
})
|
|
345
|
+
)
|
|
346
|
+
)
|
|
347
|
+
})(rootPath).then(() => seen)
|
|
348
|
+
}
|