Перейти к основному содержимому

Тестирование веб-расширений

WebdriverIO — идеальный инструмент для автоматизации браузера. Веб-расширения являются частью браузера и могут быть автоматизированы таким же образом. Когда ваше веб-расширение использует контентные скрипты для запуска JavaScript на веб-сайтах или предлагает всплывающее окно, вы можете провести e2e-тестирование для этого с помощью WebdriverIO.

Загрузка веб-расширения в браузер

В качестве первого шага мы должны загрузить тестируемое расширение в браузер как часть нашей сессии. Это работает по-разному для Chrome и Firefox.

информация

В этой документации не рассматриваются веб-расширения для Safari, так как их поддержка значительно отстаёт, а потребность пользователей невелика. Если вы разрабатываете веб-расширение для Safari, пожалуйста, создайте issue и помогите включить его здесь.

Chrome

Загрузка веб-расширения в Chrome может быть выполнена путем предоставления строки base64 закодированного файла crx или путем указания пути к папке веб-расширения. Проще всего сделать последнее, определив возможности Chrome следующим образом:

import path from 'node:path'
import url from 'node:url'

const __dirname = url.fileURLToPath(new URL('.', import.meta.url))

export const config = {
// ...
capabilities: [{
browserName,
'goog:chromeOptions': {
// учитывая, что ваш wdio.conf.js находится в корневом каталоге, а скомпилированные
// файлы веб-расширения находятся в папке `./dist`
args: [`--load-extension=${path.join(__dirname, '..', '..', 'dist')}`]
}
}]
}
информация

Если вы автоматизируете другой браузер, кроме Chrome, например, Brave, Edge или Opera, возможно, параметры браузера совпадают с приведенным выше примером, но используется другое имя capability, например, ms:edgeOptions.

Если вы компилируете своё расширение как файл .crx, используя, например, NPM-пакет crx, вы также можете внедрить объединенное расширение через:

import path from 'node:path'
import url from 'node:url'

const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
const extPath = path.join(__dirname, `web-extension-chrome.crx`)
const chromeExtension = (await fs.readFile(extPath)).toString('base64')

export const config = {
// ...
capabilities: [{
browserName,
'goog:chromeOptions': {
extensions: [chromeExtension]
}
}]
}

Firefox

Для создания профиля Firefox, включающего расширения, вы можете использовать службу профилей Firefox для соответствующей настройки сессии. Однако вы можете столкнуться с проблемами, когда ваше локально разработанное расширение не может быть загружено из-за проблем с подписью. В этом случае вы также можете загрузить расширение в хуке before с помощью команды installAddOn, например:

import path from 'node:path'
import url from 'node:url'

const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
const extensionPath = path.resolve(__dirname, `web-extension.xpi`)

export const config = {
// ...
before: async (capabilities) => {
const browserName = (capabilities as WebdriverIO.Capabilities).browserName
if (browserName === 'firefox') {
const extension = await fs.readFile(extensionPath)
await browser.installAddOn(extension.toString('base64'), true)
}
}
}

Для генерации файла .xpi рекомендуется использовать NPM-пакет web-ext. Вы можете объединить своё расширение, используя следующую команду:

npx web-ext build -s dist/ -a . -n web-extension-firefox.xpi

Советы и приёмы

В следующем разделе содержится набор полезных советов и приёмов, которые могут быть полезны при тестировании веб-расширения.

Тестирование всплывающего окна в Chrome

Если вы определили запись default_popup в действиях браузера в манифесте расширения, вы можете напрямую тестировать эту HTML-страницу, так как клик по значку расширения в верхней панели браузера не сработает. Вместо этого вам нужно открыть HTML-файл всплывающего окна напрямую.

В Chrome это работает путем получения ID расширения и открытия страницы всплывающего окна через browser.url('...'). Поведение на этой странице будет таким же, как и во всплывающем окне. Для этого мы рекомендуем написать следующую пользовательскую команду:

export async function openExtensionPopup (this: WebdriverIO.Browser, extensionName: string, popupUrl = 'index.html') {
if ((this.capabilities as WebdriverIO.Capabilities).browserName !== 'chrome') {
throw new Error('This command only works with Chrome')
}
await this.url('chrome://extensions/')

const extensions = await this.$$('extensions-item')
const extension = await extensions.find(async (ext) => (
await ext.$('#name').getText()) === extensionName
)

if (!extension) {
const installedExtensions = await extensions.map((ext) => ext.$('#name').getText())
throw new Error(`Couldn't find extension "${extensionName}", available installed extensions are "${installedExtensions.join('", "')}"`)
}

const extId = await extension.getAttribute('id')
await this.url(`chrome-extension://${extId}/popup/${popupUrl}`)
}

declare global {
namespace WebdriverIO {
interface Browser {
openExtensionPopup: typeof openExtensionPopup
}
}
}

В вашем wdio.conf.js вы можете импортировать этот файл и зарегистрировать пользовательскую команду в хуке before, например:

import { browser } from '@wdio/globals'

import { openExtensionPopup } from './support/customCommands'

export const config: WebdriverIO.Config = {
// ...
before: () => {
browser.addCommand('openExtensionPopup', openExtensionPopup)
}
}

Теперь в вашем тесте вы можете получить доступ к странице всплывающего окна через:

await browser.openExtensionPopup('Моё веб-расширение')

Welcome! How can I help?

WebdriverIO AI Copilot