Skip to content

Commit e51997b

Browse files
[Javascript] Ensure correct serialization of extensions in chromium.Options (#9495)
Fixes #6676 Co-authored-by: David Burns <david.burns@theautomatedtester.co.uk>
1 parent 6eff56e commit e51997b

File tree

3 files changed

+93
-29
lines changed

3 files changed

+93
-29
lines changed

javascript/node/selenium-webdriver/chromium.js

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,11 @@ class Options extends Capabilities {
358358
* @return {!Options} A self reference.
359359
*/
360360
addExtensions(...args) {
361-
let current = this.options_.extensions || []
362-
this.options_.extensions = current.concat(...args)
361+
let extensions = this.options_.extensions || new Extensions()
362+
extensions.add(...args)
363+
if (extensions.length) {
364+
this.options_.extensions = extensions
365+
}
363366
return this
364367
}
365368

@@ -584,28 +587,47 @@ class Options extends Capabilities {
584587
}
585588
return this
586589
}
590+
}
591+
592+
/**
593+
* A list of extensions to install when launching the browser.
594+
*/
595+
class Extensions {
596+
constructor() {
597+
this.extensions = []
598+
}
599+
600+
/**
601+
* @return {number} The length of the extensions list.
602+
*/
603+
get length() {
604+
return this.extensions.length
605+
}
587606

588607
/**
589-
* Converts this instance to its JSON wire protocol representation. Note this
590-
* function is an implementation not intended for general use.
608+
* Add additional extensions to install when launching the browser. Each
609+
* extension should be specified as the path to the packed CRX file, or a
610+
* Buffer for an extension.
591611
*
592-
* @return {!Object} The JSON wire protocol representation of this instance.
593-
* @suppress {checkTypes} Suppress [] access on a struct.
612+
* @param {...(string|!Buffer|!Array<(string|!Buffer)>)} args The
613+
* extensions to add.
614+
*/
615+
add(...args) {
616+
this.extensions = this.extensions.concat(...args)
617+
}
618+
619+
/**
620+
* @return {!Object} A serialized representation of this Extensions object.
594621
*/
595622
[Symbols.serialize]() {
596-
if (this.options_.extensions && this.options_.extensions.length) {
597-
this.options_.extensions = this.options_.extensions.map(function (
598-
extension
599-
) {
600-
if (Buffer.isBuffer(extension)) {
601-
return extension.toString('base64')
602-
}
603-
return io
604-
.read(/** @type {string} */ (extension))
605-
.then((buffer) => buffer.toString('base64'))
606-
})
607-
}
608-
return super[Symbols.serialize]()
623+
return this.extensions.map(function (extension) {
624+
if (Buffer.isBuffer(extension)) {
625+
return extension.toString('base64')
626+
}
627+
return io
628+
.read(/** @type {string} */ (extension))
629+
.then((buffer) => buffer.toString('base64'))
630+
})
609631
}
610632
}
611633

Binary file not shown.

javascript/node/selenium-webdriver/test/chrome/options_test.js

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,17 @@
1919

2020
const assert = require('assert')
2121
const fs = require('fs')
22+
const path = require('path')
2223

2324
const chrome = require('../../chrome')
2425
const symbols = require('../../lib/symbols')
2526
const test = require('../../lib/test')
2627

28+
const WEBEXTENSION_CRX = path.join(
29+
__dirname,
30+
'../../lib/test/data/chrome/webextension.crx'
31+
)
32+
2733
describe('chrome.Options', function () {
2834
describe('addArguments', function () {
2935
it('takes var_args', function () {
@@ -65,15 +71,16 @@ describe('chrome.Options', function () {
6571
assert.strictEqual(options.options_.extensions, undefined)
6672

6773
options.addExtensions('a', 'b')
68-
assert.deepStrictEqual(options.options_.extensions, ['a', 'b'])
74+
assert.deepStrictEqual(options.options_.extensions.extensions,
75+
['a', 'b'])
6976
})
7077

7178
it('flattens input arrays', function () {
7279
let options = new chrome.Options()
7380
assert.strictEqual(options.options_.extensions, undefined)
7481

7582
options.addExtensions(['a', 'b'], 'c', [1, 2], 3)
76-
assert.deepStrictEqual(options.options_.extensions, [
83+
assert.deepStrictEqual(options.options_.extensions.extensions, [
7784
'a',
7885
'b',
7986
'c',
@@ -86,16 +93,15 @@ describe('chrome.Options', function () {
8693

8794
describe('serialize', function () {
8895
it('base64 encodes extensions', async function () {
89-
let expected = fs.readFileSync(__filename, 'base64')
96+
let expected = fs.readFileSync(WEBEXTENSION_CRX, 'base64')
9097
let wire = new chrome.Options()
91-
.addExtensions(__filename)
98+
.addExtensions(WEBEXTENSION_CRX)
9299
[symbols.serialize]()
93100

94-
assert.strictEqual(wire['goog:chromeOptions'].extensions.length, 1)
95-
assert.strictEqual(
96-
await wire['goog:chromeOptions'].extensions[0],
97-
expected
98-
)
101+
let extensions = wire['goog:chromeOptions'].extensions
102+
[symbols.serialize]()
103+
assert.strictEqual(extensions.length, 1)
104+
assert.strictEqual(await extensions[0], expected)
99105
})
100106
})
101107

@@ -129,8 +135,12 @@ test.suite(
129135
function (env) {
130136
var driver
131137

138+
beforeEach(function () {
139+
driver = null
140+
})
141+
132142
afterEach(function () {
133-
return driver.quit()
143+
return driver && driver.quit()
134144
})
135145

136146
describe('Chrome options', function () {
@@ -146,6 +156,38 @@ test.suite(
146156
)
147157
assert.strictEqual(userAgent, 'foo;bar')
148158
})
159+
160+
it('can install an extension from path', async function () {
161+
let options = new chrome.Options().addExtensions(WEBEXTENSION_CRX)
162+
163+
driver = await env.builder().forBrowser('chrome')
164+
.setChromeOptions(options).build()
165+
166+
await driver.get(test.Pages.echoPage)
167+
await verifyWebExtensionWasInstalled()
168+
})
169+
170+
it('can install an extension from Buffer', async function () {
171+
let options = new chrome.Options()
172+
.addExtensions(fs.readFileSync(WEBEXTENSION_CRX))
173+
174+
driver = await env.builder().forBrowser('chrome')
175+
.setChromeOptions(options).build()
176+
177+
await driver.get(test.Pages.echoPage)
178+
await verifyWebExtensionWasInstalled()
179+
})
180+
181+
async function verifyWebExtensionWasInstalled() {
182+
let footer = await driver.findElement({
183+
id: 'webextensions-selenium-example',
184+
})
185+
let text = await footer.getText()
186+
assert.strictEqual(
187+
text,
188+
'Content injected by webextensions-selenium-example'
189+
)
190+
}
149191
})
150192
},
151193
{ browsers: ['chrome'] }

0 commit comments

Comments
 (0)