Skip to content

Commit

Permalink
[JS] Implement fullPageScreenshot functionality for Firefox (#13301)
Browse files Browse the repository at this point in the history
  • Loading branch information
harsha509 committed Apr 5, 2024
1 parent b49ae75 commit 111941b
Show file tree
Hide file tree
Showing 5 changed files with 296 additions and 138 deletions.
13 changes: 13 additions & 0 deletions javascript/node/selenium-webdriver/firefox.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ const ExtensionCommand = {
SET_CONTEXT: 'setContext',
INSTALL_ADDON: 'install addon',
UNINSTALL_ADDON: 'uninstall addon',
FULL_PAGE_SCREENSHOT: 'fullPage screenshot',
}

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

executor.defineCommand(ExtensionCommand.UNINSTALL_ADDON, 'POST', '/session/:sessionId/moz/addon/uninstall')

executor.defineCommand(ExtensionCommand.FULL_PAGE_SCREENSHOT, 'GET', '/session/:sessionId/moz/screenshot/full')
}

/**
Expand Down Expand Up @@ -645,6 +648,16 @@ class Driver extends webdriver.WebDriver {
id = await Promise.resolve(id)
return this.execute(new command.Command(ExtensionCommand.UNINSTALL_ADDON).setParameter('id', id))
}

/**
* Take full page screenshot of the visible region
*
* @return {!Promise<string>} A promise that will be
* resolved to the screenshot as a base-64 encoded PNG.
*/
takeFullPageScreenshot() {
return this.execute(new command.Command(ExtensionCommand.FULL_PAGE_SCREENSHOT))
}
}

/**
Expand Down
139 changes: 139 additions & 0 deletions javascript/node/selenium-webdriver/test/firefox/addon_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Licensed to the Software Freedom Conservancy (SFC) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The SFC licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

'use strict'

const assert = require('assert')
const { Browser } = require('../../index')
const { Pages, suite } = require('../../lib/test')
const { locate } = require('../../lib/test/resources')
const { until, By } = require('../../index')

const EXT_XPI = locate('common/extensions/webextensions-selenium-example.xpi')
const EXT_UNSIGNED_ZIP = locate('common/extensions/webextensions-selenium-example-unsigned.zip')
const EXT_SIGNED_ZIP = locate('common/extensions/webextensions-selenium-example.zip')
const EXT_UNSIGNED_DIR = locate('common/extensions/webextensions-selenium-example')
const EXT_SIGNED_DIR = locate('common/extensions/webextensions-selenium-example')

suite(
function (env) {
describe('firefox', function () {
let driver

beforeEach(function () {
driver = null
})

afterEach(function () {
return driver && driver.quit()
})

describe('installAddon', function () {
beforeEach(function () {
driver = env.builder().build()
})

it('installs and uninstalls by xpi file', async function () {
await driver.get(Pages.blankPage)
await verifyWebExtensionNotInstalled()

let id = await driver.installAddon(EXT_XPI)

await driver.navigate().refresh()
await verifyWebExtensionWasInstalled()

await driver.uninstallAddon(id)
await driver.navigate().refresh()
await verifyWebExtensionNotInstalled()
})

it('installs and uninstalls by unsigned zip file', async function () {
await driver.get(Pages.blankPage)
await verifyWebExtensionNotInstalled()

let id = await driver.installAddon(EXT_UNSIGNED_ZIP, true)

await driver.navigate().refresh()
await verifyWebExtensionWasInstalled()

await driver.uninstallAddon(id)
await driver.navigate().refresh()
await verifyWebExtensionNotInstalled()
})

it('installs and uninstalls by signed zip file', async function () {
await driver.get(Pages.blankPage)
await verifyWebExtensionNotInstalled()

let id = await driver.installAddon(EXT_SIGNED_ZIP)

await driver.navigate().refresh()
await verifyWebExtensionWasInstalled()

await driver.uninstallAddon(id)
await driver.navigate().refresh()
await verifyWebExtensionNotInstalled()
})

it('installs and uninstalls by unsigned directory', async function () {
await driver.get(Pages.blankPage)
await verifyWebExtensionNotInstalled()

let id = await driver.installAddon(EXT_UNSIGNED_DIR, true)

await driver.navigate().refresh()
await verifyWebExtensionWasInstalled()

await driver.uninstallAddon(id)
await driver.navigate().refresh()
await verifyWebExtensionNotInstalled()
})

it('installs and uninstalls by signed directory', async function () {
await driver.get(Pages.blankPage)
await verifyWebExtensionNotInstalled()

let id = await driver.installAddon(EXT_SIGNED_DIR, true)

await driver.navigate().refresh()
await verifyWebExtensionWasInstalled()

await driver.uninstallAddon(id)
await driver.navigate().refresh()
await verifyWebExtensionNotInstalled()
})
})

async function verifyWebExtensionNotInstalled() {
let found = await driver.findElements({
id: 'webextensions-selenium-example',
})
assert.strictEqual(found.length, 0)
}

async function verifyWebExtensionWasInstalled() {
let footer = await driver.wait(until.elementLocated(By.id('webextensions-selenium-example')), 5000)

let text = await footer.getText()
assert.strictEqual(text, 'Content injected by webextensions-selenium-example')
}
})
},
{ browsers: [Browser.FIREFOX] },
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Licensed to the Software Freedom Conservancy (SFC) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The SFC licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

'use strict'

const assert = require('assert')
const error = require('../../lib/error')
const { Browser } = require('../../index')
const { Context } = require('../../firefox')
const { suite } = require('../../lib/test')

suite(
function (env) {
describe('firefox', function () {
let driver

beforeEach(function () {
driver = null
})

afterEach(function () {
return driver && driver.quit()
})

describe('context switching', function () {
beforeEach(async function () {
driver = await env.builder().build()
})

it('can get context', async function () {
assert.strictEqual(await driver.getContext(), Context.CONTENT)
})

it('can set context', async function () {
await driver.setContext(Context.CHROME)
let ctxt = await driver.getContext()
assert.strictEqual(ctxt, Context.CHROME)

await driver.setContext(Context.CONTENT)
ctxt = await driver.getContext()
assert.strictEqual(ctxt, Context.CONTENT)
})

it('throws on unknown context', function () {
return driver.setContext('foo').then(assert.fail, function (e) {
assert(e instanceof error.InvalidArgumentError)
})
})
})
})
},
{ browsers: [Browser.FIREFOX] },
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Licensed to the Software Freedom Conservancy (SFC) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The SFC licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

'use strict'

const assert = require('assert')
const { Browser } = require('../../index')
const { Pages, suite } = require('../../lib/test')
let startIndex = 0
let endIndex = 5
let pngMagicNumber = 'iVBOR'
suite(
function (env) {
describe('firefox', function () {
let driver

beforeEach(function () {
driver = null
})

afterEach(function () {
return driver && driver.quit()
})

it('Should be able to take full page screenshot', async function () {
driver = env.builder().build()
await driver.get(Pages.simpleTestPage)
let encoding = await driver.takeFullPageScreenshot()
const base64code = encoding.slice(startIndex, endIndex)
assert.equal(base64code, pngMagicNumber)
})
})
},
{ browsers: [Browser.FIREFOX] },
)
Loading

0 comments on commit 111941b

Please sign in to comment.