Skip to content

Commit 111941b

Browse files
committed
[JS] Implement fullPageScreenshot functionality for Firefox (#13301)
1 parent b49ae75 commit 111941b

File tree

5 files changed

+296
-138
lines changed

5 files changed

+296
-138
lines changed

javascript/node/selenium-webdriver/firefox.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ const ExtensionCommand = {
444444
SET_CONTEXT: 'setContext',
445445
INSTALL_ADDON: 'install addon',
446446
UNINSTALL_ADDON: 'uninstall addon',
447+
FULL_PAGE_SCREENSHOT: 'fullPage screenshot',
447448
}
448449

449450
/**
@@ -470,6 +471,8 @@ function configureExecutor(executor) {
470471
executor.defineCommand(ExtensionCommand.INSTALL_ADDON, 'POST', '/session/:sessionId/moz/addon/install')
471472

472473
executor.defineCommand(ExtensionCommand.UNINSTALL_ADDON, 'POST', '/session/:sessionId/moz/addon/uninstall')
474+
475+
executor.defineCommand(ExtensionCommand.FULL_PAGE_SCREENSHOT, 'GET', '/session/:sessionId/moz/screenshot/full')
473476
}
474477

475478
/**
@@ -645,6 +648,16 @@ class Driver extends webdriver.WebDriver {
645648
id = await Promise.resolve(id)
646649
return this.execute(new command.Command(ExtensionCommand.UNINSTALL_ADDON).setParameter('id', id))
647650
}
651+
652+
/**
653+
* Take full page screenshot of the visible region
654+
*
655+
* @return {!Promise<string>} A promise that will be
656+
* resolved to the screenshot as a base-64 encoded PNG.
657+
*/
658+
takeFullPageScreenshot() {
659+
return this.execute(new command.Command(ExtensionCommand.FULL_PAGE_SCREENSHOT))
660+
}
648661
}
649662

650663
/**
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*
2+
* Licensed to the Software Freedom Conservancy (SFC) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The SFC licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
'use strict'
21+
22+
const assert = require('assert')
23+
const { Browser } = require('../../index')
24+
const { Pages, suite } = require('../../lib/test')
25+
const { locate } = require('../../lib/test/resources')
26+
const { until, By } = require('../../index')
27+
28+
const EXT_XPI = locate('common/extensions/webextensions-selenium-example.xpi')
29+
const EXT_UNSIGNED_ZIP = locate('common/extensions/webextensions-selenium-example-unsigned.zip')
30+
const EXT_SIGNED_ZIP = locate('common/extensions/webextensions-selenium-example.zip')
31+
const EXT_UNSIGNED_DIR = locate('common/extensions/webextensions-selenium-example')
32+
const EXT_SIGNED_DIR = locate('common/extensions/webextensions-selenium-example')
33+
34+
suite(
35+
function (env) {
36+
describe('firefox', function () {
37+
let driver
38+
39+
beforeEach(function () {
40+
driver = null
41+
})
42+
43+
afterEach(function () {
44+
return driver && driver.quit()
45+
})
46+
47+
describe('installAddon', function () {
48+
beforeEach(function () {
49+
driver = env.builder().build()
50+
})
51+
52+
it('installs and uninstalls by xpi file', async function () {
53+
await driver.get(Pages.blankPage)
54+
await verifyWebExtensionNotInstalled()
55+
56+
let id = await driver.installAddon(EXT_XPI)
57+
58+
await driver.navigate().refresh()
59+
await verifyWebExtensionWasInstalled()
60+
61+
await driver.uninstallAddon(id)
62+
await driver.navigate().refresh()
63+
await verifyWebExtensionNotInstalled()
64+
})
65+
66+
it('installs and uninstalls by unsigned zip file', async function () {
67+
await driver.get(Pages.blankPage)
68+
await verifyWebExtensionNotInstalled()
69+
70+
let id = await driver.installAddon(EXT_UNSIGNED_ZIP, true)
71+
72+
await driver.navigate().refresh()
73+
await verifyWebExtensionWasInstalled()
74+
75+
await driver.uninstallAddon(id)
76+
await driver.navigate().refresh()
77+
await verifyWebExtensionNotInstalled()
78+
})
79+
80+
it('installs and uninstalls by signed zip file', async function () {
81+
await driver.get(Pages.blankPage)
82+
await verifyWebExtensionNotInstalled()
83+
84+
let id = await driver.installAddon(EXT_SIGNED_ZIP)
85+
86+
await driver.navigate().refresh()
87+
await verifyWebExtensionWasInstalled()
88+
89+
await driver.uninstallAddon(id)
90+
await driver.navigate().refresh()
91+
await verifyWebExtensionNotInstalled()
92+
})
93+
94+
it('installs and uninstalls by unsigned directory', async function () {
95+
await driver.get(Pages.blankPage)
96+
await verifyWebExtensionNotInstalled()
97+
98+
let id = await driver.installAddon(EXT_UNSIGNED_DIR, true)
99+
100+
await driver.navigate().refresh()
101+
await verifyWebExtensionWasInstalled()
102+
103+
await driver.uninstallAddon(id)
104+
await driver.navigate().refresh()
105+
await verifyWebExtensionNotInstalled()
106+
})
107+
108+
it('installs and uninstalls by signed directory', async function () {
109+
await driver.get(Pages.blankPage)
110+
await verifyWebExtensionNotInstalled()
111+
112+
let id = await driver.installAddon(EXT_SIGNED_DIR, true)
113+
114+
await driver.navigate().refresh()
115+
await verifyWebExtensionWasInstalled()
116+
117+
await driver.uninstallAddon(id)
118+
await driver.navigate().refresh()
119+
await verifyWebExtensionNotInstalled()
120+
})
121+
})
122+
123+
async function verifyWebExtensionNotInstalled() {
124+
let found = await driver.findElements({
125+
id: 'webextensions-selenium-example',
126+
})
127+
assert.strictEqual(found.length, 0)
128+
}
129+
130+
async function verifyWebExtensionWasInstalled() {
131+
let footer = await driver.wait(until.elementLocated(By.id('webextensions-selenium-example')), 5000)
132+
133+
let text = await footer.getText()
134+
assert.strictEqual(text, 'Content injected by webextensions-selenium-example')
135+
}
136+
})
137+
},
138+
{ browsers: [Browser.FIREFOX] },
139+
)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Licensed to the Software Freedom Conservancy (SFC) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The SFC licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
'use strict'
21+
22+
const assert = require('assert')
23+
const error = require('../../lib/error')
24+
const { Browser } = require('../../index')
25+
const { Context } = require('../../firefox')
26+
const { suite } = require('../../lib/test')
27+
28+
suite(
29+
function (env) {
30+
describe('firefox', function () {
31+
let driver
32+
33+
beforeEach(function () {
34+
driver = null
35+
})
36+
37+
afterEach(function () {
38+
return driver && driver.quit()
39+
})
40+
41+
describe('context switching', function () {
42+
beforeEach(async function () {
43+
driver = await env.builder().build()
44+
})
45+
46+
it('can get context', async function () {
47+
assert.strictEqual(await driver.getContext(), Context.CONTENT)
48+
})
49+
50+
it('can set context', async function () {
51+
await driver.setContext(Context.CHROME)
52+
let ctxt = await driver.getContext()
53+
assert.strictEqual(ctxt, Context.CHROME)
54+
55+
await driver.setContext(Context.CONTENT)
56+
ctxt = await driver.getContext()
57+
assert.strictEqual(ctxt, Context.CONTENT)
58+
})
59+
60+
it('throws on unknown context', function () {
61+
return driver.setContext('foo').then(assert.fail, function (e) {
62+
assert(e instanceof error.InvalidArgumentError)
63+
})
64+
})
65+
})
66+
})
67+
},
68+
{ browsers: [Browser.FIREFOX] },
69+
)
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Licensed to the Software Freedom Conservancy (SFC) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The SFC licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
'use strict'
21+
22+
const assert = require('assert')
23+
const { Browser } = require('../../index')
24+
const { Pages, suite } = require('../../lib/test')
25+
let startIndex = 0
26+
let endIndex = 5
27+
let pngMagicNumber = 'iVBOR'
28+
suite(
29+
function (env) {
30+
describe('firefox', function () {
31+
let driver
32+
33+
beforeEach(function () {
34+
driver = null
35+
})
36+
37+
afterEach(function () {
38+
return driver && driver.quit()
39+
})
40+
41+
it('Should be able to take full page screenshot', async function () {
42+
driver = env.builder().build()
43+
await driver.get(Pages.simpleTestPage)
44+
let encoding = await driver.takeFullPageScreenshot()
45+
const base64code = encoding.slice(startIndex, endIndex)
46+
assert.equal(base64code, pngMagicNumber)
47+
})
48+
})
49+
},
50+
{ browsers: [Browser.FIREFOX] },
51+
)

0 commit comments

Comments
 (0)