Skip to content

Commit 8666096

Browse files
committed
[js] The FirefoxDriver should clean-up after itself on quit
Fixes issue 8380.
1 parent 09b7101 commit 8666096

File tree

6 files changed

+129
-33
lines changed

6 files changed

+129
-33
lines changed

javascript/node/selenium-webdriver/CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Promise rejections are now always coerced to Error-like objects (an object
44
with a string `message` property). We do not guarantee `instanceof Error`
55
since the rejection value may come from another context.
6+
* FIXED: 8380: `firefox.Driver` will delete its temporary profile on `quit`.
67
* FIXED: 8221: Added support for defining custom command mappings. Includes
78
support for PhantomJS's `executePhantomJS` (requires PhantomJS 1.9.7 or
89
GhostDriver 1.1.0).

javascript/node/selenium-webdriver/firefox/index.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ var Binary = require('./binary').Binary,
2424
webdriver = require('..'),
2525
executors = require('../executors'),
2626
httpUtil = require('../http/util'),
27+
io = require('../io'),
2728
net = require('../net'),
2829
portprober = require('../net/portprober');
2930

@@ -156,6 +157,10 @@ var Driver = function(opt_config, opt_flow) {
156157
caps.set('firefox_binary', null);
157158
caps.set('firefox_profile', null);
158159

160+
/** @private {?string} */
161+
this.profilePath_ = null;
162+
163+
var self = this;
159164
var serverUrl = portprober.findFreePort().then(function(port) {
160165
var prepareProfile;
161166
if (typeof profile === 'string') {
@@ -170,6 +175,7 @@ var Driver = function(opt_config, opt_flow) {
170175
}
171176

172177
return prepareProfile.then(function(dir) {
178+
self.profilePath_ = dir;
173179
return binary.launch(dir);
174180
}).then(function() {
175181
var serverUrl = url.format({
@@ -193,6 +199,19 @@ var Driver = function(opt_config, opt_flow) {
193199
util.inherits(Driver, webdriver.WebDriver);
194200

195201

202+
/** @override */
203+
Driver.prototype.quit = function() {
204+
return this.call(function() {
205+
var self = this;
206+
return Driver.super_.prototype.quit.call(this).thenFinally(function() {
207+
if (self.profilePath_) {
208+
return io.rmDir(self.profilePath_);
209+
}
210+
});
211+
}, this);
212+
};
213+
214+
196215
// PUBLIC API
197216

198217

javascript/node/selenium-webdriver/io/index.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
var fs = require('fs'),
1717
path = require('path'),
18+
rimraf = require('rimraf'),
1819
tmp = require('tmp');
1920

2021
var promise = require('..').promise;
@@ -27,6 +28,26 @@ var PATH_SEPARATOR = process.platform === 'win32' ? ';' : ':';
2728

2829

2930

31+
/**
32+
* Recursively removes a directory and all of its contents. This is equivalent
33+
* to {@code rm -rf} on a POSIX system.
34+
* @param {string} path Path to the directory to remove.
35+
* @return {!promise.Promise} A promise to be resolved when the operation has
36+
* completed.
37+
*/
38+
exports.rmDir = function(path) {
39+
return new promise.Promise(function(fulfill, reject) {
40+
rimraf(path, function(err) {
41+
if (err) {
42+
reject(err);
43+
} else {
44+
fulfill();
45+
}
46+
});
47+
});
48+
};
49+
50+
3051
/**
3152
* Copies one file to another.
3253
* @param {string} src The source file.
Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,36 @@
11
{
2-
"name": "selenium-webdriver",
3-
"version": "2.45.0-dev",
4-
"description": "The official WebDriver JavaScript bindings from the Selenium project",
5-
"keywords": [
6-
"automation",
7-
"selenium",
8-
"testing",
9-
"webdriver",
10-
"webdriverjs"
11-
],
12-
"homepage": "https://code.google.com/p/selenium/",
13-
"bugs": {
14-
"url": "https://code.google.com/p/selenium/issues/list"
15-
},
16-
"main": "./index",
17-
"repository": {
18-
"type": "git",
19-
"url": "https://code.google.com/p/selenium/"
20-
},
21-
"engines": {
22-
"node": ">= 0.8.x"
23-
},
24-
"dependencies": {
25-
"adm-zip": "0.4.4",
26-
"tmp": "0.0.24",
27-
"xml2js": "0.4.4"
28-
},
29-
"devDependencies" : {
30-
"mocha" : ">= 1.21.x"
31-
},
32-
"scripts": {
33-
"test": "node_modules/.bin/mocha --harmony -t 600000 --recursive test"
34-
}
2+
"name": "selenium-webdriver",
3+
"version": "2.45.0-dev",
4+
"description": "The official WebDriver JavaScript bindings from the Selenium project",
5+
"keywords": [
6+
"automation",
7+
"selenium",
8+
"testing",
9+
"webdriver",
10+
"webdriverjs"
11+
],
12+
"homepage": "https://code.google.com/p/selenium/",
13+
"bugs": {
14+
"url": "https://code.google.com/p/selenium/issues/list"
15+
},
16+
"main": "./index",
17+
"repository": {
18+
"type": "git",
19+
"url": "https://code.google.com/p/selenium/"
20+
},
21+
"engines": {
22+
"node": ">= 0.8.x"
23+
},
24+
"dependencies": {
25+
"adm-zip": "0.4.4",
26+
"rimraf": "^2.2.8",
27+
"tmp": "0.0.24",
28+
"xml2js": "0.4.4"
29+
},
30+
"devDependencies": {
31+
"mocha": ">= 1.21.x"
32+
},
33+
"scripts": {
34+
"test": "node_modules/.bin/mocha --harmony -t 600000 --recursive test"
35+
}
3536
}

javascript/node/selenium-webdriver/test/firefox/firefox_test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
var path = require('path');
1919

2020
var firefox = require('../../firefox'),
21+
io = require('../../io'),
2122
test = require('../../lib/test'),
2223
assert = require('../../testing/assert');
2324

@@ -120,5 +121,36 @@ test.suite(function(env) {
120121
}, 3000);
121122
}
122123
});
124+
125+
describe('profile management', function() {
126+
var driver;
127+
128+
test.beforeEach(function() {
129+
driver = null;
130+
});
131+
132+
test.afterEach(function() {
133+
if (driver) {
134+
driver.quit();
135+
}
136+
});
137+
138+
test.it('deletes the temp profile on quit', function() {
139+
driver = env.builder().build();
140+
141+
var profilePath = driver.call(function() {
142+
var path = driver.profilePath_;
143+
assert(io.exists(path)).isTrue();
144+
return path;
145+
});
146+
147+
return driver.quit().then(function() {
148+
driver = null;
149+
return profilePath;
150+
}).then(function(path) {
151+
assert(io.exists(path)).isFalse();
152+
});
153+
});
154+
});
123155
});
124156
}, {browsers: ['firefox']});

javascript/node/selenium-webdriver/test/io_test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,26 @@ describe('io', function() {
174174
});
175175
});
176176
});
177+
178+
describe('rmDir', function() {
179+
it('succeeds if the designated directory does not exist', function() {
180+
return io.tmpDir().then(function(d) {
181+
return io.rmDir(path.join(d, 'i/do/not/exist'));
182+
});
183+
});
184+
185+
it('deletes recursively', function() {
186+
return io.tmpDir().then(function(dir) {
187+
fs.writeFileSync(path.join(dir, 'file1'), 'hello');
188+
fs.mkdirSync(path.join(dir, 'sub'));
189+
fs.mkdirSync(path.join(dir, 'sub/folder'));
190+
fs.writeFileSync(path.join(dir, 'sub/folder/file2'), 'goodbye');
191+
192+
return io.rmDir(dir).then(function() {
193+
assert.ok(!fs.existsSync(dir));
194+
assert.ok(!fs.existsSync(path.join(dir, 'sub/folder/file2')));
195+
});
196+
});
197+
});
198+
});
177199
});

0 commit comments

Comments
 (0)