Vai al contenuto principale

Expect

Quando scrivi test, spesso devi verificare che i valori soddisfino determinate condizioni. expect ti dà accesso a una serie di "matcher" che ti permettono di validare diverse cose sull'oggetto browser, un oggetto element o mock.

Opzioni Predefinite

Queste opzioni predefinite sotto sono collegate alle opzioni waitforTimeout e waitforInterval impostate nella configurazione.

Imposta le opzioni sotto solo se desideri attendere timeout specifici per le tue asserzioni.

{
wait: 2000, // ms di attesa per il successo dell'aspettativa
interval: 100, // intervallo tra i tentativi
}

Se vuoi utilizzare timeout e intervalli diversi, imposta queste opzioni così:

// wdio.conf.js
import { setOptions } from 'expect-webdriverio'

export const config = {
// ...
before () {
setOptions({ wait: 5000 })
},
// ...
}

Opzioni dei Matcher

Ogni matcher può accettare diverse opzioni che ti consentono di modificare l'asserzione:

Opzioni del Comando
NomeTipoDettagli
waitnumbertempo in ms per attendere il successo dell'aspettativa. Predefinito: 3000
intervalnumberintervallo tra i tentativi. Predefinito: 100
beforeAssertionfunctionfunzione da chiamare prima che l'asserzione venga effettuata
afterAssertionfunctionfunzione da chiamare dopo che l'asserzione è stata effettuata contenente i risultati dell'asserzione
messagestringmessaggio utente da anteporre prima dell'errore di asserzione
Opzioni per le Stringhe

Questa opzione può essere applicata in aggiunta alle opzioni di comando quando vengono asserite stringhe.

NomeTipoDettagli
ignoreCasebooleanapplica toLowerCase sia ai valori effettivi che a quelli attesi
trimbooleanapplica trim al valore effettivo
replaceReplacer | Replacer[]sostituisce parti del valore effettivo che corrispondono alla stringa/RegExp. Il replacer può essere una stringa o una funzione.
containingbooleansi aspetta che il valore effettivo contenga il valore atteso, altrimenti uguaglianza stretta.
asStringbooleanpotrebbe essere utile per forzare la conversione del valore della proprietà in stringa
atStartbooleansi aspetta che il valore effettivo inizi con il valore atteso
atEndbooleansi aspetta che il valore effettivo finisca con il valore atteso
atIndexnumbersi aspetta che il valore effettivo abbia il valore atteso all'indice specificato
Opzioni per i Numeri

Questa opzione può essere applicata in aggiunta alle opzioni di comando quando vengono asseriti numeri.

NomeTipoDettagli
eqnumberuguale a
ltenumberminore o uguale a
gtenumbermaggiore o uguale a

Gestione delle Entità HTML

Un'entità HTML è un pezzo di testo ("stringa") che inizia con una e commerciale (&) e termina con un punto e virgola (;). Le entità sono spesso utilizzate per visualizzare caratteri riservati (che altrimenti verrebbero interpretati come codice HTML) e caratteri invisibili (come gli spazi non interrompibili, ad es.  ).

Per trovare o interagire con tali elementi, utilizza l'equivalente unicode dell'entità. ad esempio:

<div data="Some&nbsp;Value">Some&nbsp;Text</div>
const myElem = await $('div[data="Some\u00a0Value"]')
await expect(myElem).toHaveAttribute('data', 'div[Some\u00a0Value')
await expect(myElem).toHaveText('Some\u00a0Text')

Puoi trovare tutti i riferimenti unicode nella specifica HTML.

Nota: l'unicode non fa distinzione tra maiuscole e minuscole, quindi funzionano sia \u00a0 che \u00A0. Per trovare un elemento nell'ispezione del browser, rimuovi u dall'unicode, ad es.: div[data="Some\00a0Value"]

Matcher per il Browser

toHaveUrl

Verifica se il browser si trova su una pagina specifica.

Utilizzo
await browser.url('https://webdriver.io/')
await expect(browser).toHaveUrl('https://webdriver.io')
Utilizzo
await browser.url('https://webdriver.io/')
await expect(browser).toHaveUrl(expect.stringContaining('webdriver'))

toHaveTitle

Verifica se il sito web ha un titolo specifico.

Utilizzo
await browser.url('https://webdriver.io/')
await expect(browser).toHaveTitle('WebdriverIO · Next-gen browser and mobile automation test framework for Node.js')
await expect(browser).toHaveTitle(expect.stringContaining('WebdriverIO'))

toHaveClipboardText

Verifica se il browser ha un testo specifico memorizzato negli appunti.

Utilizzo
import { Key } from 'webdriverio'

await browser.keys([Key.Ctrl, 'a'])
await browser.keys([Key.Ctrl, 'c'])
await expect(browser).toHaveClipboardText('some clipboard text')
await expect(browser).toHaveClipboardText(expect.stringContaining('clipboard text'))

Matcher per gli Elementi

toBeDisplayed

Chiama isDisplayed sull'elemento dato.

Utilizzo
const elem = await $('#someElem')
await expect(elem).toBeDisplayed()

toExist

Chiama isExisting sull'elemento dato.

Utilizzo
const elem = await $('#someElem')
await expect(elem).toExist()

toBePresent

Uguale a toExist.

Utilizzo
const elem = await $('#someElem')
await expect(elem).toBePresent()

toBeExisting

Uguale a toExist.

Utilizzo
const elem = await $('#someElem')
await expect(elem).toBeExisting()

toBeFocused

Verifica se l'elemento ha il focus. Questa asserzione funziona solo in un contesto web.

Utilizzo
const elem = await $('#someElem')
await expect(elem).toBeFocused()

toHaveAttribute

Verifica se un elemento ha un certo attributo con un valore specifico.

Utilizzo
const myInput = await $('input')
await expect(myInput).toHaveAttribute('class', 'form-control')
await expect(myInput).toHaveAttribute('class', expect.stringContaining('control'))

toHaveAttr

Uguale a toHaveAttribute.

Utilizzo
const myInput = await $('input')
await expect(myInput).toHaveAttr('class', 'form-control')
await expect(myInput).toHaveAttr('class', expect.stringContaining('control'))

toHaveElementClass

Verifica se un elemento ha un singolo nome di classe. Può anche essere chiamato con un array come parametro quando l'elemento può avere più nomi di classe.

Utilizzo
const myInput = await $('input')
await expect(myInput).toHaveElementClass('form-control', { message: 'Not a form control!' })
await expect(myInput).toHaveElementClass(['form-control' , 'w-full'], { message: 'not full width' })
await expect(myInput).toHaveElementClass(expect.stringContaining('form'), { message: 'Not a form control!' })

toHaveElementProperty

Verifica se un elemento ha una certa proprietà.

Utilizzo
const elem = await $('#elem')
await expect(elem).toHaveElementProperty('height', 23)
await expect(elem).not.toHaveElementProperty('height', 0)

toHaveValue

Verifica se un elemento di input ha un certo valore.

Utilizzo
const myInput = await $('input')
await expect(myInput).toHaveValue('admin-user', { ignoreCase: true })
await expect(myInput).toHaveValue(expect.stringContaining('user'), { ignoreCase: true })

toBeClickable

Verifica se un elemento può essere cliccato chiamando isClickable sull'elemento.

Utilizzo
const elem = await $('#elem')
await expect(elem).toBeClickable()

toBeDisabled

Verifica se un elemento è disabilitato chiamando isEnabled sull'elemento.

Utilizzo
const elem = await $('#elem')
await expect(elem).toBeDisabled()
// stesso di
await expect(elem).not.toBeEnabled()

toBeEnabled

Verifica se un elemento è abilitato chiamando isEnabled sull'elemento.

Utilizzo
const elem = await $('#elem')
await expect(elem).toBeEnabled()
// stesso di
await expect(elem).not.toBeDisabled()

toBeSelected

Verifica se un elemento è abilitato chiamando isSelected sull'elemento.

Utilizzo
const elem = await $('#elem')
await expect(elem).toBeSelected()

toBeChecked

Uguale a toBeSelected.

Utilizzo
const elem = await $('#elem')
await expect(elem).toBeChecked()

toHaveComputedLabel

Verifica se un elemento ha un'etichetta WAI-ARIA calcolata specifica. Può anche essere chiamato con un array come parametro nel caso in cui l'elemento possa avere diverse etichette.

Utilizzo
await browser.url('https://webdriver.io/')
const elem = await $('a[href="https://github.com/webdriverio/webdriverio"]')
await expect(elem).toHaveComputedLabel('GitHub repository')
await expect(elem).toHaveComputedLabel(expect.stringContaining('repository'))
Utilizzo
await browser.url('https://webdriver.io/')
const elem = await $('a[href="https://github.com/webdriverio/webdriverio"]')
await expect(elem).toHaveComputedLabel(['GitHub repository', 'Private repository'])
await expect(elem).toHaveComputedLabel([expect.stringContaining('GitHub'), expect.stringContaining('Private')])

toHaveComputedRole

Verifica se un elemento ha un ruolo WAI-ARIA calcolato specifico. Può anche essere chiamato con un array come parametro nel caso in cui l'elemento possa avere diverse etichette.

Utilizzo
await browser.url('https://webdriver.io/')
const elem = await $('[aria-label="Skip to main content"]')
await expect(elem).toHaveComputedRole('region')
await expect(elem).toHaveComputedRole(expect.stringContaining('ion'))
Utilizzo
await browser.url('https://webdriver.io/')
const elem = await $('[aria-label="Skip to main content"]')
await expect(elem).toHaveComputedRole(['region', 'section'])
await expect(elem).toHaveComputedRole([expect.stringContaining('reg'), expect.stringContaining('sec')])

toHaveHref

Verifica se un elemento link ha uno specifico target di collegamento.

Utilizzo
const link = await $('a')
await expect(link).toHaveHref('https://webdriver.io')
await expect(link).toHaveHref(expect.stringContaining('webdriver.io'))

Uguale a toHaveHref.

Utilizzo
const link = await $('a')
await expect(link).toHaveLink('https://webdriver.io')
await expect(link).toHaveLink(expect.stringContaining('webdriver.io'))

toHaveId

Verifica se un elemento ha uno specifico attributo id.

Utilizzo
const elem = await $('#elem')
await expect(elem).toHaveId('elem')

toHaveText

Verifica se un elemento ha un testo specifico. Può anche essere chiamato con un array come parametro nel caso in cui l'elemento possa avere testi diversi.

Utilizzo
await browser.url('https://webdriver.io/')
const elem = await $('.container')
await expect(elem).toHaveText('Next-gen browser and mobile automation test framework for Node.js')
await expect(elem).toHaveText(expect.stringContaining('test framework for Node.js'))
await expect(elem).toHaveText(['Next-gen browser and mobile automation test framework for Node.js', 'Get Started'])
await expect(elem).toHaveText([expect.stringContaining('test framework for Node.js'), expect.stringContaining('Started')])

Nel caso ci sia una lista di elementi nel div sottostante:

<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>

Puoi asserirli usando un array:

const elem = await $$('ul > li')
await expect(elem).toHaveText(['Coffee', 'Tea', 'Milk'])

toHaveHTML

Verifica se un elemento ha un HTML specifico. Può anche essere chiamato con un array come parametro nel caso in cui l'elemento possa avere HTML diversi.

Utilizzo
await browser.url('https://webdriver.io/')
const elem = await $('.hero__subtitle')
await expect(elem).toHaveHTML('<p class="hero__subtitle">Next-gen browser and mobile automation test framework for Node.js</p>')
await expect(elem).toHaveHTML(expect.stringContaining('Next-gen browser and mobile automation test framework for Node.js'))
await expect(elem).toHaveHTML('Next-gen browser and mobile automation test framework for Node.js', { includeSelectorTag: false })
Utilizzo
await browser.url('https://webdriver.io/')
const elem = await $('.hero__subtitle')
await expect(elem).toHaveHTML(['Next-gen browser and mobile automation test framework for Node.js', 'Get Started'], { includeSelectorTag: false })
await expect(elem).toHaveHTML([expect.stringContaining('automation test framework for Node.js'), expect.stringContaining('Started')], { includeSelectorTag: false })

toBeDisplayedInViewport

Verifica se un elemento è all'interno del viewport chiamando isDisplayedInViewport sull'elemento.

Utilizzo
const elem = await $('#elem')
await expect(elem).toBeDisplayedInViewport()

toHaveChildren

Verifica il numero di figli dell'elemento recuperato chiamando il comando element.$('./*').

Utilizzo
const list = await $('ul')
await expect(list).toHaveChildren() // la lista ha almeno un elemento
// stesso di
await expect(list).toHaveChildren({ gte: 1 })

await expect(list).toHaveChildren(3) // la lista ha 3 elementi
// stesso di
await expect(list).toHaveChildren({ eq: 3 })

toHaveWidth

Verifica se un elemento ha una larghezza specifica.

Utilizzo
await browser.url('http://github.com')
const logo = await $('.octicon-mark-github')
await expect(logo).toHaveWidth(32)

toHaveHeight

Verifica se un elemento ha un'altezza specifica.

Utilizzo
await browser.url('http://github.com')
const logo = await $('.octicon-mark-github')
await expect(logo).toHaveHeight(32)

toHaveSize

Verifica se un elemento ha una dimensione specifica.

Utilizzo
await browser.url('http://github.com')
const logo = await $('.octicon-mark-github')
await expect(logo).toHaveSize({ width: 32, height: 32 })

toBeElementsArrayOfSize

Verifica la quantità di elementi recuperati utilizzando il comando $$.

Nota: Questo matcher aggiornerà l'array passato con gli ultimi elementi se l'asserzione passa. Tuttavia, se hai riassegnato la variabile, dovrai recuperare nuovamente gli elementi.

Utilizzo
const listItems = await $$('ul>li')
await expect(listItems).toBeElementsArrayOfSize(5) // 5 elementi nella lista

await expect(listItems).toBeElementsArrayOfSize({ lte: 10 })
// stesso di
assert.ok(listItems.length <= 10)

Matcher di Rete

toBeRequested

Verifica che il mock sia stato chiamato

Utilizzo
const mock = browser.mock('**/api/todo*')
await expect(mock).toBeRequested()

toBeRequestedTimes

Verifica che il mock sia stato chiamato per il numero previsto di volte

Utilizzo
const mock = browser.mock('**/api/todo*')
await expect(mock).toBeRequestedTimes(2) // await expect(mock).toBeRequestedTimes({ eq: 2 })

await expect(mock).toBeRequestedTimes({ gte: 5, lte: 10 }) // richiesta chiamata almeno 5 volte ma meno di 11

toBeRequestedWith

Verifica che il mock sia stato chiamato secondo le opzioni previste.

La maggior parte delle opzioni supporta i matcher parziali expect/jasmine come expect.objectContaining

Utilizzo
const mock = browser.mock('**/api/todo*', { method: 'POST' })

await expect(mock).toBeRequestedWith({
url: 'http://localhost:8080/api/todo', // [opzionale] string | function | custom matcher
method: 'POST', // [opzionale] string | array
statusCode: 200, // [opzionale] number | array
requestHeaders: { Authorization: 'foo' }, // [opzionale] object | function | custom matcher
responseHeaders: { Authorization: 'bar' }, // [opzionale] object | function | custom matcher
postData: { title: 'foo', description: 'bar' }, // [opzionale] object | function | custom matcher
response: { success: true }, // [opzionale] object | function | custom matcher
})

await expect(mock).toBeRequestedWith({
url: expect.stringMatching(/.*\/api\/.*/i),
method: ['POST', 'PUT'], // o POST o PUT
statusCode: [401, 403], // o 401 o 403
requestHeaders: headers => headers.Authorization.startsWith('Bearer '),
postData: expect.objectContaining({ released: true, title: expect.stringContaining('foobar') }),
response: r => Array.isArray(r) && r.data.items.length === 20
})

Matcher di Snapshot

WebdriverIO supporta sia test di snapshot di base che test di snapshot del DOM.

toMatchSnapshot

Verifica se un oggetto arbitrario corrisponde a un certo valore. Se passi un WebdriverIO.Element creerà automaticamente uno snapshot dello stato outerHTML.

Utilizzo
// snapshot di oggetti arbitrari (non serve "await" qui)
expect({ foo: 'bar' }).toMatchSnapshot()
// snapshot di `outerHTML` di WebdriverIO.Element (snapshot DOM, richiede "await")
await expect($('elem')).toMatchSnapshot()
// snapshot del risultato del comando dell'elemento
await expect($('elem').getCSSProperty('background-color')).toMatchSnapshot()

toMatchInlineSnapshot

Analogamente, puoi utilizzare toMatchInlineSnapshot() per memorizzare lo snapshot inline all'interno del file di test. Per esempio, dato:

await expect($('img')).toMatchInlineSnapshot()

Invece di creare un file di snapshot, WebdriverIO modificherà direttamente il file di test per aggiornare lo snapshot come stringa:

await expect($('img')).toMatchInlineSnapshot(`"<img src="/public/apple-touch-icon-precomposed.png">"`)

Matcher di Snapshot Visivi

I seguenti matcher sono implementati come parte del plugin @wdio/visual-service e sono disponibili solo quando il servizio è configurato. Assicurati di seguire le istruzioni di configurazione di conseguenza.

toMatchElementSnapshot

Verifica se l'elemento dato corrisponde allo snapshot della linea di base.

Utilizzo
await expect($('.hero__title-logo')).toMatchElementSnapshot('wdioLogo', 0, {
// opzioni
})

Il risultato atteso è per impostazione predefinita 0, quindi puoi scrivere la stessa asserzione come:

await expect($('.hero__title-logo')).toMatchElementSnapshot('wdioLogo', {
// opzioni
})

o non passare alcuna opzione:

await expect($('.hero__title-logo')).toMatchElementSnapshot()

toMatchScreenSnapshot

Verifica se la schermata attuale corrisponde allo snapshot della linea di base.

Utilizzo
await expect(browser).toMatchScreenSnapshot('partialPage', 0, {
// opzioni
})

Il risultato atteso è per impostazione predefinita 0, quindi puoi scrivere la stessa asserzione come:

await expect(browser).toMatchScreenSnapshot('partialPage', {
// opzioni
})

o non passare alcuna opzione:

await expect(browser).toMatchScreenSnapshot('partialPage')

toMatchFullPageSnapshot

Verifica se lo screenshot della pagina intera corrisponde allo snapshot della linea di base.

Utilizzo
await expect(browser).toMatchFullPageSnapshot('fullPage', 0, {
// opzioni
})

Il risultato atteso è per impostazione predefinita 0, quindi puoi scrivere la stessa asserzione come:

await expect(browser).toMatchFullPageSnapshot('fullPage', {
// opzioni
})

o non passare alcuna opzione:

await expect(browser).toMatchFullPageSnapshot('fullPage')

toMatchTabbablePageSnapshot

Verifica se lo screenshot della pagina intera, inclusi i segni di tabulazione, corrisponde allo snapshot della linea di base.

Utilizzo
await expect(browser).toMatchTabbablePageSnapshot('tabbable', 0, {
// opzioni
})

Il risultato atteso è per impostazione predefinita 0, quindi puoi scrivere la stessa asserzione come:

await expect(browser).toMatchTabbablePageSnapshot('tabbable', {
// opzioni
})

o non passare alcuna opzione:

await expect(browser).toMatchTabbablePageSnapshot('tabbable')

Uso delle espressioni regolari

Puoi anche utilizzare direttamente espressioni regolari per tutti i matcher che fanno confronti di testo.

Utilizzo
await browser.url('https://webdriver.io/')
const elem = await $('.container')
await expect(elem).toHaveText(/node\.js/i)
await expect(elem).toHaveText([/node\.js/i, 'Get Started'])
await expect(browser).toHaveTitle(/webdriverio/i)
await expect(browser).toHaveUrl(/webdriver\.io/)
await expect(elem).toHaveElementClass(/Container/i)

Matcher Predefiniti

Oltre ai matcher di expect-webdriverio, puoi utilizzare le asserzioni expect integrate di Jest o expect/expectAsync per Jasmine.

Matcher Asimmetrici

WebdriverIO supporta l'uso di matcher asimmetrici ovunque confronti valori di testo, ad esempio:

await expect(browser).toHaveTitle(expect.stringContaining('some title'))

o

await expect(browser).toHaveTitle(expect.not.stringContaining('some title'))

TypeScript

Se stai utilizzando WDIO Testrunner, tutto sarà configurato automaticamente. Segui semplicemente la guida alla configurazione dalla documentazione. Tuttavia, se esegui WebdriverIO con un testrunner diverso o in un semplice script Node.js, dovrai aggiungere expect-webdriverio a types nel tsconfig.json.

  • "expect-webdriverio" per tutti tranne gli utenti di Jasmine/Jest.
  • "expect-webdriverio/jasmine" per Jasmine
  • "expect-webdriverio/jest" per Jest

JavaScript (VSCode)

È necessario creare jsconfig.json nella radice del progetto e fare riferimento alle definizioni di tipo per far funzionare l'autocompletamento in JavaScript vanilla.

{
"include": [
"**/*.js",
"**/*.json",
"node_modules/expect-webdriverio"
]
}

Aggiungere i tuoi matcher

Simile a come expect-webdriverio estende i matcher di Jasmine/Jest, è possibile aggiungere matcher personalizzati.

I matcher personalizzati dovrebbero essere aggiunti nell'hook before di wdio

// wdio.conf.js
{
async before () {
const { addCustomMatchers } = await import('./myMatchers')
addCustomMatchers()
}
}
// myMatchers.js - esempio Jest
export function addCustomMatchers () {
if (global.expect.expect !== undefined) { // Workaround temporaneo. Vedi https://github.com/webdriverio/expect-webdriverio/issues/835
global.expect = global.expect.expect;
}

expect.extend({
myMatcher (actual, expected) {
return { pass: actual === expected, message: () => 'some message' }
}
})
}

Welcome! How can I help?

WebdriverIO AI Copilot