selenium-webdriver 3.4.0 → 3.5.0

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.
@@ -0,0 +1,34 @@
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <title>Testing Key Events</title>
6
+ <script type="text/javascript">
7
+ function appendMessage(message) {
8
+ document.getElementById('resultParagraph').innerHTML += message + " ";
9
+ }
10
+ </script>
11
+ </head>
12
+ <body>
13
+ <div id="resultContainer" height="30">&nbsp;
14
+ <div id="result" style="width:300;height:60">
15
+ <p id="resultParagraph">&nbsp;</p>
16
+ </div>
17
+ </div>
18
+
19
+ <div>
20
+ <form action="resultPage.html" id="on-form">
21
+ <input id="theworks"
22
+ onfocus="appendMessage('focus')"
23
+ onkeydown="appendMessage('keydown')"
24
+ onkeypress="appendMessage('keypress')"
25
+ onkeyup="appendMessage('keyup')"
26
+ onblur="appendMessage('blur')"
27
+ onchange="appendMessage('change')"
28
+ />
29
+ </form>
30
+ </div>
31
+ </body>
32
+ </html>
33
+
34
+
@@ -0,0 +1,12 @@
1
+ <html>
2
+ <head>
3
+ <title>BasicKeyboardInterfaceTest</title>
4
+ </head>
5
+ <body>
6
+ <form action="#">
7
+ <input type="text" id="textInput" />
8
+ </form>
9
+ </body>
10
+ </html>
11
+
12
+
package/lib/test/index.js CHANGED
@@ -31,9 +31,6 @@ var build = require('./build'),
31
31
  fileserver = require('./fileserver');
32
32
 
33
33
 
34
- const LEGACY_FIREFOX = 'legacy-' + webdriver.Browser.FIREFOX;
35
-
36
-
37
34
  /**
38
35
  * Browsers with native support.
39
36
  * @type {!Array.<webdriver.Browser>}
@@ -42,7 +39,6 @@ var NATIVE_BROWSERS = [
42
39
  webdriver.Browser.CHROME,
43
40
  webdriver.Browser.EDGE,
44
41
  webdriver.Browser.FIREFOX,
45
- LEGACY_FIREFOX,
46
42
  webdriver.Browser.IE,
47
43
  webdriver.Browser.OPERA,
48
44
  webdriver.Browser.PHANTOM_JS,
@@ -54,7 +50,6 @@ var noBuild = /^1|true$/i.test(process.env['SELENIUM_NO_BUILD']);
54
50
  var serverJar = process.env['SELENIUM_SERVER_JAR'];
55
51
  var remoteUrl = process.env['SELENIUM_REMOTE_URL'];
56
52
  var useLoopback = process.env['SELENIUM_USE_LOOP_BACK'] == '1';
57
- var noMarionette = /^0|false$/i.test(process.env['SELENIUM_GECKODRIVER']);
58
53
  var startServer = !!serverJar && !remoteUrl;
59
54
  var nativeRun = !serverJar && !remoteUrl;
60
55
 
@@ -76,9 +71,6 @@ var browsersToTest = (function() {
76
71
  if (parts[0] === 'edge') {
77
72
  parts[0] = webdriver.Browser.EDGE;
78
73
  }
79
- if (noMarionette && parts[0] === webdriver.Browser.FIREFOX) {
80
- parts[0] = LEGACY_FIREFOX;
81
- }
82
74
  return parts.join(':');
83
75
  });
84
76
 
@@ -88,10 +80,6 @@ var browsersToTest = (function() {
88
80
  parts[0] = webdriver.Browser.IE;
89
81
  }
90
82
 
91
- if (parts[0] === LEGACY_FIREFOX) {
92
- return;
93
- }
94
-
95
83
  if (NATIVE_BROWSERS.indexOf(parts[0]) == -1 && !permitRemoteBrowsers) {
96
84
  throw Error('Browser ' + parts[0] + ' requires a WebDriver server and ' +
97
85
  'neither the SELENIUM_REMOTE_URL nor the SELENIUM_SERVER_JAR ' +
@@ -157,10 +145,6 @@ function TestEnvironment(browserName, server) {
157
145
  return server || remoteUrl;
158
146
  };
159
147
 
160
- this.isMarionette = function() {
161
- return !noMarionette;
162
- };
163
-
164
148
  this.browsers = function(var_args) {
165
149
  var browsersToIgnore = Array.prototype.slice.apply(arguments, [0]);
166
150
  return browsers(browserName, browsersToIgnore);
@@ -171,15 +155,7 @@ function TestEnvironment(browserName, server) {
171
155
  var realBuild = builder.build;
172
156
 
173
157
  builder.build = function() {
174
- var parts = browserName.split(/:/, 3);
175
-
176
- if (parts[0] === LEGACY_FIREFOX) {
177
- var options = builder.getFirefoxOptions() || new firefox.Options();
178
- options.useGeckoDriver(false);
179
- builder.setFirefoxOptions(options);
180
-
181
- parts[0] = webdriver.Browser.FIREFOX;
182
- }
158
+ let parts = browserName.split(/:/, 3);
183
159
 
184
160
  builder.forBrowser(parts[0], parts[1], parts[2]);
185
161
  if (server) {
@@ -244,15 +220,6 @@ function suite(fn, opt_options) {
244
220
  browsers.forEach(function(browser) {
245
221
  describe('[' + browser + ']', function() {
246
222
 
247
- if (isDevMode && nativeRun) {
248
- if (browser === LEGACY_FIREFOX) {
249
- before(function() {
250
- return build.of('//javascript/firefox-driver:webdriver')
251
- .onlyOnce().go();
252
- });
253
- }
254
- }
255
-
256
223
  var serverToUse = null;
257
224
 
258
225
  if (!!serverJar && !remoteUrl) {
package/lib/webdriver.js CHANGED
@@ -750,20 +750,12 @@ class WebDriver {
750
750
  * commands should execute under, including the initial session creation.
751
751
  * Defaults to the {@link promise.controlFlow() currently active}
752
752
  * control flow.
753
- * @param {(function(new: WebDriver,
754
- * !IThenable<!Session>,
755
- * !command.Executor,
756
- * promise.ControlFlow=))=} opt_ctor
757
- * A reference to the constructor of the specific type of WebDriver client
758
- * to instantiate. Will create a vanilla {@linkplain WebDriver} instance
759
- * if a constructor is not provided.
760
753
  * @param {(function(this: void): ?)=} opt_onQuit A callback to invoke when
761
754
  * the newly created session is terminated. This should be used to clean
762
755
  * up any resources associated with the session.
763
756
  * @return {!WebDriver} The driver for the newly created session.
764
757
  */
765
- static createSession(
766
- executor, capabilities, opt_flow, opt_ctor, opt_onQuit) {
758
+ static createSession(executor, capabilities, opt_flow, opt_onQuit) {
767
759
  let flow = opt_flow || promise.controlFlow();
768
760
  let cmd = new command.Command(command.Name.NEW_SESSION);
769
761
 
@@ -782,8 +774,7 @@ class WebDriver {
782
774
  return Promise.resolve(opt_onQuit.call(void 0)).then(_ => {throw err;});
783
775
  });
784
776
  }
785
- const ctor = opt_ctor || WebDriver;
786
- return new ctor(session, executor, flow, opt_onQuit);
777
+ return new this(session, executor, flow, opt_onQuit);
787
778
  }
788
779
 
789
780
  /** @override */
@@ -2186,7 +2177,7 @@ class WebElement {
2186
2177
  if (!this.driver_.fileDetector_) {
2187
2178
  return this.schedule_(
2188
2179
  new command.Command(command.Name.SEND_KEYS_TO_ELEMENT).
2189
- setParameter('text', keys).
2180
+ setParameter('text', keys.then(keys => keys.join(''))).
2190
2181
  setParameter('value', keys),
2191
2182
  'WebElement.sendKeys()');
2192
2183
  }
package/opera.js CHANGED
@@ -383,7 +383,7 @@ class Driver extends webdriver.WebDriver {
383
383
  }
384
384
 
385
385
  return /** @type {!Driver} */(
386
- webdriver.WebDriver.createSession(executor, caps, opt_flow, this));
386
+ super.createSession(executor, caps, opt_flow));
387
387
  }
388
388
 
389
389
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "selenium-webdriver",
3
- "version": "3.4.0",
3
+ "version": "3.5.0",
4
4
  "description": "The official WebDriver JavaScript bindings from the Selenium project",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -23,7 +23,7 @@
23
23
  "node": ">= 6.9.0"
24
24
  },
25
25
  "dependencies": {
26
- "adm-zip": "^0.4.7",
26
+ "jszip": "^3.1.3",
27
27
  "rimraf": "^2.5.4",
28
28
  "tmp": "0.0.30",
29
29
  "xml2js": "^0.4.17"
package/phantomjs.js CHANGED
@@ -217,8 +217,8 @@ class Driver extends webdriver.WebDriver {
217
217
  });
218
218
 
219
219
  var executor = createExecutor(service.start());
220
- return /** @type {!Driver} */(webdriver.WebDriver.createSession(
221
- executor, caps, opt_flow, this, () => service.kill()));
220
+ return /** @type {!Driver} */(super.createSession(
221
+ executor, caps, opt_flow, () => service.kill()));
222
222
  }
223
223
 
224
224
  /**
package/remote/index.js CHANGED
@@ -17,7 +17,6 @@
17
17
 
18
18
  'use strict';
19
19
 
20
- const AdmZip = require('adm-zip');
21
20
  const fs = require('fs');
22
21
  const path = require('path');
23
22
  const url = require('url');
@@ -26,6 +25,7 @@ const util = require('util');
26
25
  const httpUtil = require('../http/util');
27
26
  const io = require('../io');
28
27
  const exec = require('../io/exec');
28
+ const {Zip} = require('../io/zip');
29
29
  const cmd = require('../lib/command');
30
30
  const input = require('../lib/input');
31
31
  const promise = require('../lib/promise');
@@ -575,15 +575,16 @@ class FileDetector extends input.FileDetector {
575
575
  return file; // Not a valid file, return original input.
576
576
  }
577
577
 
578
- var zip = new AdmZip();
579
- zip.addLocalFile(file);
580
- // Stored compression, see https://en.wikipedia.org/wiki/Zip_(file_format)
581
- zip.getEntries()[0].header.method = 0;
582
-
583
- var command = new cmd.Command(cmd.Name.UPLOAD_FILE)
584
- .setParameter('file', zip.toBuffer().toString('base64'));
585
- return driver.schedule(command,
586
- 'remote.FileDetector.handleFile(' + file + ')');
578
+ let zip = new Zip;
579
+ return zip.addFile(file)
580
+ .then(() => zip.toBuffer())
581
+ .then(buf => buf.toString('base64'))
582
+ .then(encodedZip => {
583
+ let command = new cmd.Command(cmd.Name.UPLOAD_FILE)
584
+ .setParameter('file', encodedZip);
585
+ return driver.schedule(command,
586
+ 'remote.FileDetector.handleFile(' + file + ')');
587
+ });
587
588
  }, function(err) {
588
589
  if (err.code === 'ENOENT') {
589
590
  return file; // Not a file; return original input.
package/safari.js CHANGED
@@ -250,8 +250,8 @@ class Driver extends webdriver.WebDriver {
250
250
  let executor = new http.Executor(
251
251
  service.start().then(url => new http.HttpClient(url)));
252
252
 
253
- return /** @type {!Driver} */(webdriver.WebDriver.createSession(
254
- executor, caps, opt_flow, this, () => service.kill()));
253
+ return /** @type {!Driver} */(super.createSession(
254
+ executor, caps, opt_flow, () => service.kill()));
255
255
  }
256
256
  }
257
257
 
@@ -17,24 +17,27 @@
17
17
 
18
18
  'use strict';
19
19
 
20
- var AdmZip = require('adm-zip'),
21
- assert = require('assert'),
20
+ var assert = require('assert'),
22
21
  crypto = require('crypto'),
23
22
  fs = require('fs'),
24
23
  path = require('path');
25
24
 
26
25
  var extension = require('../../firefox/extension'),
27
26
  io = require('../../io'),
27
+ zip = require('../../io/zip'),
28
28
  it = require('../../testing').it;
29
29
 
30
30
 
31
31
  var JETPACK_EXTENSION = path.join(__dirname,
32
32
  '../../lib/test/data/firefox/jetpack-sample.xpi');
33
33
  var NORMAL_EXTENSION = path.join(__dirname,
34
- '../../lib/test/data/firefox/sample.xpi');
34
+ '../../lib/test/data/firefox/sample.xpi');
35
+ var WEBEXTENSION_EXTENSION = path.join(__dirname,
36
+ '../../lib/test/data/firefox/webextension.xpi');
35
37
 
36
38
  var JETPACK_EXTENSION_ID = 'jid1-EaXX7k0wwiZR7w@jetpack';
37
39
  var NORMAL_EXTENSION_ID = 'sample@seleniumhq.org';
40
+ var WEBEXTENSION_EXTENSION_ID = 'webextensions-selenium-example@example.com';
38
41
 
39
42
 
40
43
  describe('extension', function() {
@@ -75,22 +78,43 @@ describe('extension', function() {
75
78
  });
76
79
  });
77
80
 
81
+ it('can install a webextension xpi file', function() {
82
+ return io.tmpDir().then(function(dir) {
83
+ return extension.install(WEBEXTENSION_EXTENSION, dir).then(function(id) {
84
+ assert.equal(WEBEXTENSION_EXTENSION_ID, id);
85
+ var file = path.join(dir, id + '.xpi');
86
+ assert.ok(fs.existsSync(file), 'no such file: ' + file);
87
+ assert.ok(!fs.statSync(file).isDirectory());
88
+
89
+ var copiedSha1 = crypto.createHash('sha1')
90
+ .update(fs.readFileSync(file))
91
+ .digest('hex');
92
+
93
+ var goldenSha1 = crypto.createHash('sha1')
94
+ .update(fs.readFileSync(WEBEXTENSION_EXTENSION))
95
+ .digest('hex');
96
+
97
+ assert.equal(copiedSha1, goldenSha1);
98
+ });
99
+ });
100
+ });
101
+
78
102
  it('can install an extension from a directory', function() {
79
103
  return io.tmpDir().then(function(srcDir) {
80
- var buf = fs.readFileSync(NORMAL_EXTENSION);
81
- new AdmZip(buf).extractAllTo(srcDir, true);
82
- return io.tmpDir().then(function(dstDir) {
83
- return extension.install(srcDir, dstDir).then(function(id) {
84
- assert.equal(NORMAL_EXTENSION_ID, id);
85
-
86
- var dir = path.join(dstDir, NORMAL_EXTENSION_ID);
87
-
88
- assert.ok(fs.existsSync(path.join(dir, 'chrome.manifest')));
89
- assert.ok(fs.existsSync(path.join(dir, 'content/overlay.xul')));
90
- assert.ok(fs.existsSync(path.join(dir, 'content/overlay.js')));
91
- assert.ok(fs.existsSync(path.join(dir, 'install.rdf')));
92
- });
93
- });
104
+ return zip.unzip(NORMAL_EXTENSION, srcDir)
105
+ .then(() => io.tmpDir())
106
+ .then(dstDir => {
107
+ return extension.install(srcDir, dstDir).then(function(id) {
108
+ assert.equal(NORMAL_EXTENSION_ID, id);
109
+
110
+ var dir = path.join(dstDir, NORMAL_EXTENSION_ID);
111
+
112
+ assert.ok(fs.existsSync(path.join(dir, 'chrome.manifest')));
113
+ assert.ok(fs.existsSync(path.join(dir, 'content/overlay.xul')));
114
+ assert.ok(fs.existsSync(path.join(dir, 'content/overlay.js')));
115
+ assert.ok(fs.existsSync(path.join(dir, 'install.rdf')));
116
+ });
117
+ });
94
118
  });
95
119
  });
96
120
  });
@@ -33,18 +33,20 @@ var JETPACK_EXTENSION = path.join(__dirname,
33
33
  '../../lib/test/data/firefox/jetpack-sample.xpi');
34
34
  var NORMAL_EXTENSION = path.join(__dirname,
35
35
  '../../lib/test/data/firefox/sample.xpi');
36
+ var WEBEXTENSION_EXTENSION = path.join(__dirname,
37
+ '../../lib/test/data/firefox/webextension.xpi');
36
38
 
37
39
 
38
40
  test.suite(function(env) {
39
41
  describe('firefox', function() {
40
42
  describe('Options', function() {
41
- var driver;
43
+ let driver;
42
44
 
43
- test.beforeEach(function() {
45
+ beforeEach(function() {
44
46
  driver = null;
45
47
  });
46
48
 
47
- test.afterEach(function() {
49
+ afterEach(function() {
48
50
  if (driver) {
49
51
  return driver.quit();
50
52
  }
@@ -128,6 +130,22 @@ test.suite(function(env) {
128
130
  });
129
131
  });
130
132
 
133
+ test.it('can start Firefox with a webextension extension', function() {
134
+ let profile = new firefox.Profile();
135
+ profile.addExtension(WEBEXTENSION_EXTENSION);
136
+
137
+ let options = new firefox.Options().setProfile(profile);
138
+
139
+ return runWithFirefoxDev(options, function*() {
140
+ yield driver.get(test.Pages.echoPage);
141
+
142
+ let footer =
143
+ yield driver.findElement({id: 'webextensions-selenium-example'});
144
+ let text = yield footer.getText();
145
+ assert(text).equalTo('Content injected by webextensions-selenium-example');
146
+ });
147
+ });
148
+
131
149
  test.it('can start Firefox with multiple extensions', function() {
132
150
  let profile = new firefox.Profile();
133
151
  profile.addExtension(JETPACK_EXTENSION);
@@ -150,6 +168,26 @@ test.suite(function(env) {
150
168
  });
151
169
  });
152
170
 
171
+ test.it('can be used alongside preset capabilities', function*() {
172
+ let binary = yield firefox.Channel.AURORA.locate();
173
+
174
+ let profile = new firefox.Profile();
175
+ profile.addExtension(JETPACK_EXTENSION);
176
+ profile.setPreference('general.useragent.override', 'foo;bar');
177
+
178
+ driver = yield env.builder()
179
+ .withCapabilities({'moz:firefoxOptions': {binary}})
180
+ .setFirefoxOptions(new firefox.Options().setProfile(profile))
181
+ .build();
182
+
183
+ yield loadJetpackPage(driver,
184
+ 'data:text/html;charset=UTF-8,<html><div>content</div></html>');
185
+
186
+ let text =
187
+ yield driver.findElement({id: 'jetpack-sample-banner'}).getText();
188
+ assert(text).equalTo('Hello, world!');
189
+ });
190
+
153
191
  function loadJetpackPage(driver, url) {
154
192
  // On linux the jetpack extension does not always run the first time
155
193
  // we load a page. If this happens, just reload the page (a simple
@@ -198,13 +236,11 @@ test.suite(function(env) {
198
236
  }
199
237
  });
200
238
 
201
- test.ignore(() => !env.isMarionette).
202
- it('can get context', function() {
239
+ test.it('can get context', function() {
203
240
  return assert(driver.getContext()).equalTo(Context.CONTENT);
204
241
  });
205
242
 
206
- test.ignore(() => !env.isMarionette).
207
- it('can set context', function*() {
243
+ test.it('can set context', function*() {
208
244
  yield driver.setContext(Context.CHROME);
209
245
  let ctxt = yield driver.getContext();
210
246
  assert(ctxt).equalTo(Context.CHROME);
@@ -214,8 +250,7 @@ test.suite(function(env) {
214
250
  assert(ctxt).equalTo(Context.CONTENT);
215
251
  });
216
252
 
217
- test.ignore(() => !env.isMarionette).
218
- it('throws on unknown context', function() {
253
+ test.it('throws on unknown context', function() {
219
254
  return driver.setContext("foo").then(assert.fail, function(e) {
220
255
  assert(e).instanceOf(error.InvalidArgumentError);
221
256
  });
@@ -17,8 +17,7 @@
17
17
 
18
18
  'use strict';
19
19
 
20
- var AdmZip = require('adm-zip'),
21
- assert = require('assert'),
20
+ var assert = require('assert'),
22
21
  fs = require('fs'),
23
22
  path = require('path');
24
23
 
@@ -33,10 +32,12 @@ var JETPACK_EXTENSION = path.join(__dirname,
33
32
  '../../lib/test/data/firefox/jetpack-sample.xpi');
34
33
  var NORMAL_EXTENSION = path.join(__dirname,
35
34
  '../../lib/test/data/firefox/sample.xpi');
35
+ var WEBEXTENSION_EXTENSION = path.join(__dirname,
36
+ '../../lib/test/data/firefox/webextension.xpi');
36
37
 
37
38
  var JETPACK_EXTENSION_ID = 'jid1-EaXX7k0wwiZR7w@jetpack.xpi';
38
39
  var NORMAL_EXTENSION_ID = 'sample@seleniumhq.org';
39
- var WEBDRIVER_EXTENSION_ID = 'fxdriver@googlecode.com';
40
+ var WEBEXTENSION_EXTENSION_ID = 'webextensions-selenium-example@example.com';
40
41
 
41
42
 
42
43
 
@@ -57,13 +58,6 @@ describe('Profile', function() {
57
58
  assert.equal('http://www.example.com',
58
59
  profile.getPreference('browser.newtab.url'));
59
60
  });
60
-
61
- it('throws if setting a frozen preference', function() {
62
- var profile = new Profile();
63
- assert.throws(function() {
64
- profile.setPreference('app.update.auto', true);
65
- });
66
- });
67
61
  });
68
62
 
69
63
  describe('writeToDisk', function() {
@@ -104,20 +98,6 @@ describe('Profile', function() {
104
98
  });
105
99
 
106
100
  describe('user.js', function() {
107
-
108
- it('writes defaults', function() {
109
- return new Profile().writeToDisk().then(function(dir) {
110
- return loadUserPrefs(path.join(dir, 'user.js'));
111
- }).then(function(prefs) {
112
- // Just check a few.
113
- assert.equal(false, prefs['app.update.auto']);
114
- assert.equal(true, prefs['browser.EULA.override']);
115
- assert.equal(false, prefs['extensions.update.enabled']);
116
- assert.equal('about:blank', prefs['browser.newtab.url']);
117
- assert.equal(30, prefs['dom.max_script_run_time']);
118
- });
119
- });
120
-
121
101
  it('merges template user.js into preferences', function() {
122
102
  return io.tmpDir().then(function(dir) {
123
103
  fs.writeFileSync(path.join(dir, 'user.js'), [
@@ -133,19 +113,6 @@ describe('Profile', function() {
133
113
  assert.equal(1234, prefs['dom.max_script_run_time']);
134
114
  });
135
115
  });
136
-
137
- it('ignores frozen preferences when merging template user.js',
138
- function() {
139
- return io.tmpDir().then(function(dir) {
140
- fs.writeFileSync(path.join(dir, 'user.js'),
141
- 'user_pref("app.update.auto", true)');
142
- return new Profile(dir).writeToDisk();
143
- }).then(function(profile) {
144
- return loadUserPrefs(path.join(profile, 'user.js'));
145
- }).then(function(prefs) {
146
- assert.equal(false, prefs['app.update.auto']);
147
- });
148
- });
149
116
  });
150
117
 
151
118
  describe('extensions', function() {
@@ -153,33 +120,21 @@ describe('Profile', function() {
153
120
  var profile = new Profile();
154
121
  profile.addExtension(JETPACK_EXTENSION);
155
122
  profile.addExtension(NORMAL_EXTENSION);
123
+ profile.addExtension(WEBEXTENSION_EXTENSION);
156
124
 
157
125
  return profile.writeToDisk().then(function(dir) {
158
126
  dir = path.join(dir, 'extensions');
159
- assert.ok(fs.existsSync(path.join(dir, JETPACK_EXTENSION_ID)));
160
- assert.ok(fs.existsSync(path.join(dir, NORMAL_EXTENSION_ID)));
161
- assert.ok(fs.existsSync(path.join(dir, WEBDRIVER_EXTENSION_ID)));
127
+ assertExists(JETPACK_EXTENSION_ID);
128
+ assertExists(NORMAL_EXTENSION_ID);
129
+ assertExists(WEBEXTENSION_EXTENSION_ID + '.xpi');
130
+
131
+ function assertExists(file) {
132
+ assert.ok(
133
+ fs.existsSync(path.join(dir, file)),
134
+ `expected ${file} to exist`);
135
+ }
162
136
  });
163
137
  });
164
138
  });
165
139
  });
166
-
167
- describe('encode', function() {
168
- it('excludes the bundled WebDriver extension', function() {
169
- return new Profile().encode().then(function(data) {
170
- return decode(data);
171
- }).then(function(dir) {
172
- assert.ok(fs.existsSync(path.join(dir, 'user.js')));
173
- assert.ok(fs.existsSync(path.join(dir, 'extensions')));
174
- return loadUserPrefs(path.join(dir, 'user.js'));
175
- }).then(function(prefs) {
176
- // Just check a few.
177
- assert.equal(false, prefs['app.update.auto']);
178
- assert.equal(true, prefs['browser.EULA.override']);
179
- assert.equal(false, prefs['extensions.update.enabled']);
180
- assert.equal('about:blank', prefs['browser.newtab.url']);
181
- assert.equal(30, prefs['dom.max_script_run_time']);
182
- });
183
- });
184
- });
185
140
  });
@@ -44,6 +44,14 @@ describe('HttpClient', function() {
44
44
  res.writeHead(200, {'content-type': 'text/plain'});
45
45
  res.end('hello, world!');
46
46
 
47
+ } else if (req.method == 'GET' && req.url == '/chunked') {
48
+ res.writeHead(200, {
49
+ 'content-type': 'text/html; charset=utf-8',
50
+ 'transfer-encoding': 'chunked'
51
+ });
52
+ res.write('<!DOCTYPE html>');
53
+ setTimeout(() => res.end('<h1>Hello, world!</h1>'), 20);
54
+
47
55
  } else if (req.method == 'GET' && req.url == '/badredirect') {
48
56
  res.writeHead(303, {});
49
57
  res.end();
@@ -121,6 +129,16 @@ describe('HttpClient', function() {
121
129
  });
122
130
  });
123
131
 
132
+ it('handles chunked responses', function() {
133
+ let request = new HttpRequest('GET', '/chunked');
134
+
135
+ let client = new HttpClient(server.url());
136
+ return client.send(request).then(response => {
137
+ assert.equal(200, response.status);
138
+ assert.equal(response.body, '<!DOCTYPE html><h1>Hello, world!</h1>');
139
+ });
140
+ });
141
+
124
142
  it('can use basic auth', function() {
125
143
  var parsed = url.parse(server.url());
126
144
  parsed.auth = 'genie:bottle';
@@ -22,7 +22,7 @@ var assert = require('assert'),
22
22
  path = require('path'),
23
23
  tmp = require('tmp');
24
24
 
25
- var io = require('../io');
25
+ var io = require('../../io');
26
26
 
27
27
 
28
28
  describe('io', function() {
@@ -318,4 +318,43 @@ describe('io', function() {
318
318
  (e) => assert.equal('ENOENT', e.code));
319
319
  });
320
320
  });
321
+
322
+ describe('mkdirp', function() {
323
+ it('recursively creates entire directory path', function() {
324
+ return io.tmpDir().then(root => {
325
+ let dst = path.join(root, 'foo/bar/baz');
326
+ return io.mkdirp(dst).then(d => {
327
+ assert.strictEqual(d, dst);
328
+ return io.stat(d).then(stats => {
329
+ assert.ok(stats.isDirectory());
330
+ });
331
+ });
332
+ });
333
+ });
334
+
335
+ it('does nothing if the directory already exists', function() {
336
+ return io.tmpDir()
337
+ .then(dir => io.mkdirp(dir).then(d => assert.strictEqual(d, dir)));
338
+ });
339
+ });
340
+
341
+ describe('walkDir', function() {
342
+ it('walk directory', function() {
343
+ return io.tmpDir().then(dir => {
344
+ fs.writeFileSync(path.join(dir, 'file1'), 'hello');
345
+ fs.mkdirSync(path.join(dir, 'sub'));
346
+ fs.mkdirSync(path.join(dir, 'sub/folder'));
347
+ fs.writeFileSync(path.join(dir, 'sub/folder/file2'), 'goodbye');
348
+
349
+ return io.walkDir(dir).then(seen => {
350
+ assert.deepStrictEqual(
351
+ seen,
352
+ [{path: 'file1', dir: false},
353
+ {path: 'sub', dir: true},
354
+ {path: 'sub/folder', dir: true},
355
+ {path: 'sub/folder/file2', dir: false}]);
356
+ });
357
+ });
358
+ });
359
+ })
321
360
  });