Vai al contenuto principale

Multiremote

WebdriverIO consente di eseguire più sessioni automatizzate in un singolo test. Questo diventa utile quando si testano funzionalità che richiedono più utenti (ad esempio, applicazioni di chat o WebRTC).

Invece di creare diverse istanze remote dove è necessario eseguire comandi comuni come newSession o url su ciascuna istanza, puoi semplicemente creare un'istanza multiremote e controllare tutti i browser contemporaneamente.

Per farlo, usa la funzione multiremote() e passa un oggetto con nomi associati a capabilities come valori. Assegnando un nome a ciascuna capability, puoi facilmente selezionare e accedere a quella singola istanza quando esegui comandi su un'istanza specifica.

info

Multiremote non è destinato a eseguire tutti i tuoi test in parallelo. È pensato per aiutare a coordinare più browser e/o dispositivi mobili per test di integrazione speciali (ad esempio applicazioni di chat).

Tutte le istanze multiremote restituiscono un array di risultati. Il primo risultato rappresenta la capability definita per prima nell'oggetto capability, il secondo risultato la seconda capability e così via.

Utilizzo in modalità Standalone

Ecco un esempio di come creare un'istanza multiremote in modalità standalone:

import { multiremote } from 'webdriverio'

(async () => {
const browser = await multiremote({
myChromeBrowser: {
capabilities: {
browserName: 'chrome'
}
},
myFirefoxBrowser: {
capabilities: {
browserName: 'firefox'
}
}
})

// open url with both browser at the same time
await browser.url('http://json.org')

// call commands at the same time
const title = await browser.getTitle()
expect(title).toEqual(['JSON', 'JSON'])

// click on an element at the same time
const elem = await browser.$('#someElem')
await elem.click()

// only click with one browser (Firefox)
await elem.getInstance('myFirefoxBrowser').click()
})()

Utilizzo con WDIO Testrunner

Per utilizzare multiremote nel testrunner WDIO, definisci semplicemente l'oggetto capabilities nel tuo wdio.conf.js come un oggetto con i nomi dei browser come chiavi (invece di un elenco di capabilities):

export const config = {
// ...
capabilities: {
myChromeBrowser: {
capabilities: {
browserName: 'chrome'
}
},
myFirefoxBrowser: {
capabilities: {
browserName: 'firefox'
}
}
}
// ...
}

Questo creerà due sessioni WebDriver con Chrome e Firefox. Al posto di Chrome e Firefox, puoi anche avviare due dispositivi mobili utilizzando Appium o un dispositivo mobile e un browser.

Puoi anche eseguire multiremote in parallelo mettendo l'oggetto delle capabilities dei browser in un array. Assicurati di includere il campo capabilities in ciascun browser, poiché questo è il modo in cui distinguiamo ogni modalità.

export const config = {
// ...
capabilities: [{
myChromeBrowser0: {
capabilities: {
browserName: 'chrome'
}
},
myFirefoxBrowser0: {
capabilities: {
browserName: 'firefox'
}
}
}, {
myChromeBrowser1: {
capabilities: {
browserName: 'chrome'
}
},
myFirefoxBrowser1: {
capabilities: {
browserName: 'firefox'
}
}
}]
// ...
}

Puoi anche avviare uno dei backend di servizi cloud insieme a istanze locali di Webdriver/Appium o Selenium Standalone. WebdriverIO rileva automaticamente le capabilities del backend cloud se hai specificato bstack:options (Browserstack), sauce:options (SauceLabs) o tb:options (TestingBot) nelle capabilities del browser.

export const config = {
// ...
user: process.env.BROWSERSTACK_USERNAME,
key: process.env.BROWSERSTACK_ACCESS_KEY,
capabilities: {
myChromeBrowser: {
capabilities: {
browserName: 'chrome'
}
},
myBrowserStackFirefoxBrowser: {
capabilities: {
browserName: 'firefox',
'bstack:options': {
// ...
}
}
}
},
services: [
['browserstack', 'selenium-standalone']
],
// ...
}

Qui è possibile qualsiasi combinazione di OS/browser (inclusi browser mobili e desktop). Tutti i comandi che i tuoi test chiamano tramite la variabile browser vengono eseguiti in parallelo con ogni istanza. Questo aiuta a ottimizzare i tuoi test di integrazione e a velocizzarne l'esecuzione.

Ad esempio, se apri un URL:

browser.url('https://socketio-chat-h9jt.herokuapp.com/')

Il risultato di ogni comando sarà un oggetto con i nomi dei browser come chiave e il risultato del comando come valore, così:

// wdio testrunner example
await browser.url('https://www.whatismybrowser.com')

const elem = await $('.string-major')
const result = await elem.getText()

console.log(result[0]) // returns: 'Chrome 40 on Mac OS X (Yosemite)'
console.log(result[1]) // returns: 'Firefox 35 on Mac OS X (Yosemite)'

Nota che ogni comando viene eseguito uno dopo l'altro. Ciò significa che il comando termina una volta che tutti i browser lo hanno eseguito. Questo è utile perché mantiene sincronizzate le azioni del browser, il che rende più facile capire cosa sta attualmente accadendo.

A volte è necessario fare cose diverse in ogni browser per testare qualcosa. Ad esempio, se vogliamo testare un'applicazione di chat, ci deve essere un browser che invia un messaggio di testo mentre un altro browser attende di riceverlo, e poi esegue un'asserzione su di esso.

Quando si utilizza il testrunner WDIO, esso registra i nomi dei browser con le loro istanze nello scope globale:

const myChromeBrowser = browser.getInstance('myChromeBrowser')
await myChromeBrowser.$('#message').setValue('Hi, I am Chrome')
await myChromeBrowser.$('#send').click()

// wait until messages arrive
await $('.messages').waitForExist()
// check if one of the messages contain the Chrome message
assert.true(
(
await $$('.messages').map((m) => m.getText())
).includes('Hi, I am Chrome')
)

In questo esempio, l'istanza myFirefoxBrowser inizierà ad attendere un messaggio una volta che l'istanza myChromeBrowser ha cliccato sul pulsante #send.

Multiremote rende facile e conveniente controllare più browser, sia che tu voglia fargli fare la stessa cosa in parallelo, sia che debbano fare cose diverse in concerto.

Accesso alle istanze del browser tramite stringhe via l'oggetto browser

Oltre ad accedere all'istanza del browser tramite le loro variabili globali (ad esempio myChromeBrowser, myFirefoxBrowser), puoi anche accedervi tramite l'oggetto browser, ad esempio browser["myChromeBrowser"] o browser["myFirefoxBrowser"]. Puoi ottenere un elenco di tutte le tue istanze tramite browser.instances. Questo è particolarmente utile quando si scrivono passaggi di test riutilizzabili che possono essere eseguiti in entrambi i browser, ad esempio:

wdio.conf.js:

    capabilities: {
userA: {
capabilities: {
browserName: 'chrome'
}
},
userB: {
capabilities: {
browserName: 'chrome'
}
}
}

File Cucumber:

When User A types a message into the chat

File di definizione dei passaggi:

When(/^User (.) types a message into the chat/, async (userId) => {
await browser.getInstance(`user${userId}`).$('#message').setValue('Hi, I am Chrome')
await browser.getInstance(`user${userId}`).$('#send').click()
})

Estendere i tipi TypeScript

Se stai utilizzando TypeScript e desideri accedere direttamente all'istanza del driver dall'oggetto multiremote, puoi anche estendere i tipi multiremote per farlo. Ad esempio, date le seguenti capabilities:

export const config: WebdriverIO.MultiremoteConfig = {
// ...
capabilities: {
myAppiumDriver: {
// ...
},
myChromeDriver: {
// ...
}
}
// ...
}

Puoi estendere l'istanza multiremote aggiungendo i tuoi nomi di driver personalizzati, ad esempio:

declare namespace WebdriverIO {
interface MultiRemoteBrowser {
myAppiumDriver: WebdriverIO.Browser
myChromeDriver: WebdriverIO.Browser
}
}

Ora puoi accedere ai driver direttamente, ad esempio:

multiRemoteBrowser.myAppiumDriver.$$(...)
multiRemoteBrowser.myChromeDriver.$(...)

Welcome! How can I help?

WebdriverIO AI Copilot