Aller au contenu principal

Test d'Extensions Web

WebdriverIO est l'outil idéal pour automatiser un navigateur. Les extensions web font partie du navigateur et peuvent être automatisées de la même manière. Chaque fois que votre extension web utilise des scripts de contenu pour exécuter JavaScript sur des sites web ou offre une fenêtre popup, vous pouvez exécuter un test e2e pour cela en utilisant WebdriverIO.

Charger une Extension Web dans le Navigateur

La première étape consiste à charger l'extension à tester dans le navigateur dans le cadre de notre session. Cela fonctionne différemment pour Chrome et Firefox.

info

Cette documentation ne traite pas des extensions web Safari car leur support est bien en retard et la demande des utilisateurs n'est pas élevée. Si vous développez une extension web pour Safari, veuillez ouvrir un ticket et collaborer pour l'inclure ici également.

Chrome

Le chargement d'une extension web dans Chrome peut se faire en fournissant une chaîne encodée en base64 du fichier crx ou en fournissant un chemin vers le dossier de l'extension web. Le plus simple est de faire cette dernière en définissant vos capacités Chrome comme suit :

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': {
// étant donné que votre wdio.conf.js est dans le répertoire racine et que vos fichiers
// d'extension web compilés sont situés dans le dossier `./dist`
args: [`--load-extension=${path.join(__dirname, '..', '..', 'dist')}`]
}
}]
}
info

Si vous automatisez un navigateur autre que Chrome, par exemple Brave, Edge ou Opera, il est probable que l'option du navigateur corresponde à l'exemple ci-dessus, en utilisant simplement un nom de capacité différent, par exemple ms:edgeOptions.

Si vous compilez votre extension en fichier .crx en utilisant par exemple le package NPM crx, vous pouvez également injecter l'extension groupée via :

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

Pour créer un profil Firefox qui inclut des extensions, vous pouvez utiliser le Service de Profil Firefox pour configurer votre session en conséquence. Cependant, vous pourriez rencontrer des problèmes où votre extension développée localement ne peut pas être chargée en raison de problèmes de signature. Dans ce cas, vous pouvez également charger une extension dans le hook before via la commande installAddOn, par exemple :

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)
}
}
}

Pour générer un fichier .xpi, il est recommandé d'utiliser le package NPM web-ext. Vous pouvez regrouper votre extension en utilisant l'exemple de commande suivant :

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

Astuces et Conseils

La section suivante contient un ensemble d'astuces et de conseils utiles qui peuvent être utiles lors du test d'une extension web.

Tester la Fenêtre Popup dans Chrome

Si vous définissez une entrée d'action de navigateur default_popup dans votre manifeste d'extension, vous pouvez tester cette page HTML directement, car cliquer sur l'icône d'extension dans la barre supérieure du navigateur ne fonctionnera pas. Au lieu de cela, vous devez ouvrir directement le fichier HTML popup.

Dans Chrome, cela fonctionne en récupérant l'ID de l'extension et en ouvrant la page popup via browser.url('...'). Le comportement sur cette page sera le même que dans le popup. Pour ce faire, nous recommandons d'écrire la commande personnalisée suivante :

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
}
}
}

Dans votre wdio.conf.js, vous pouvez importer ce fichier et enregistrer la commande personnalisée dans votre hook before, par exemple :

import { browser } from '@wdio/globals'

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

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

Maintenant, dans votre test, vous pouvez accéder à la page popup via :

await browser.openExtensionPopup('Mon Extension Web')

Welcome! How can I help?

WebdriverIO AI Copilot