Expect
Al escribir pruebas, a menudo necesitas verificar que los valores cumplan ciertas condiciones. expect
te da acceso a una serie de "matchers" que te permiten validar diferentes cosas en el objeto browser
, un objeto element
o mock
.
Opciones predeterminadas
Estas opciones predeterminadas a continuación están conectadas a las opciones waitforTimeout
y waitforInterval
establecidas en la configuración.
Solo configura las opciones a continuación si deseas esperar tiempos específicos para tus aserciones.
{
wait: 2000, // ms para esperar a que la expectativa tenga éxito
interval: 100, // intervalo entre intentos
}
Si deseas elegir diferentes tiempos de espera e intervalos, configura estas opciones de la siguiente manera:
// wdio.conf.js
import { setOptions } from 'expect-webdriverio'
export const config = {
// ...
before () {
setOptions({ wait: 5000 })
},
// ...
}
Opciones de Matcher
Cada matcher puede tomar varias opciones que te permiten modificar la aserción:
Opciones de comando
Nombre | Tipo | Detalles |
---|---|---|
wait | number | tiempo en ms para esperar a que la expectativa tenga éxito. Predeterminado: 3000 |
interval | number | intervalo entre intentos. Predeterminado: 100 |
beforeAssertion | function | función que se llamará antes de que se haga la aserción |
afterAssertion | function | función que se llamará después de que se haga la aserción conteniendo los resultados de la aserción |
message | string | mensaje de usuario para anteponer antes del error de aserción |
Opciones de cadena
Esta opción se puede aplicar además de las opciones de comando cuando se están afirmando cadenas.
Nombre | Tipo | Detalles |
---|---|---|
ignoreCase | boolean | aplicar toLowerCase a los valores real y esperado |
trim | boolean | aplicar trim al valor real |
replace | Replacer | Replacer[] | reemplazar partes del valor real que coincidan con la cadena/RegExp. El reemplazo puede ser una cadena o una función. |
containing | boolean | esperar que el valor real contenga el valor esperado, de lo contrario igual estricto. |
asString | boolean | puede ser útil para forzar la conversión del valor de propiedad a cadena |
atStart | boolean | esperar que el valor real comience con el valor esperado |
atEnd | boolean | esperar que el valor real termine con el valor esperado |
atIndex | number | esperar que el valor real tenga el valor esperado en el índice dado |
Opciones de número
Esta opción se puede aplicar además de las opciones de comando cuando se están afirmando números.
Nombre | Tipo | Detalles |
---|---|---|
eq | number | igual a |
lte | number | menor o igual que |
gte | number | mayor o igual que |
Manejo de entidades HTML
Una entidad HTML es un fragmento de texto ("cadena") que comienza con un ampersand (&
) y termina con un punto y coma (;
). Las entidades se utilizan frecuentemente para mostrar caracteres reservados (que de otro modo se interpretarían como código HTML) y caracteres invisibles (como espacios sin romper, por ejemplo,
).
Para encontrar o interactuar con dicho elemento, usa el equivalente unicode de la entidad. por ejemplo:
<div data="Some Value">Some Text</div>
const myElem = await $('div[data="Some\u00a0Value"]')
await expect(myElem).toHaveAttribute('data', 'div[Some\u00a0Value')
await expect(myElem).toHaveText('Some\u00a0Text')
Puedes encontrar todas las referencias unicode en la especificación HTML.
Nota: unicode no distingue entre mayúsculas y minúsculas, por lo que tanto \u00a0
como \u00A0
funcionan. Para encontrar elementos en la inspección del navegador, quita u
del unicode, por ejemplo: div[data="Some\00a0Value"]
Matchers de navegador
toHaveUrl
Comprueba si el navegador está en una página específica.
Uso
await browser.url('https://webdriver.io/')
await expect(browser).toHaveUrl('https://webdriver.io')
Uso
await browser.url('https://webdriver.io/')
await expect(browser).toHaveUrl(expect.stringContaining('webdriver'))
toHaveTitle
Comprueba si el sitio web tiene un título específico.
Uso
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
Comprueba si el navegador tiene un texto específico almacenado en su portapapeles.
Uso
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'))
Matchers de elemento
toBeDisplayed
Llama a isDisplayed
en el elemento dado.
Uso
const elem = await $('#someElem')
await expect(elem).toBeDisplayed()
toExist
Llama a isExisting
en el elemento dado.
Uso
const elem = await $('#someElem')
await expect(elem).toExist()
toBePresent
Igual que toExist
.
Uso
const elem = await $('#someElem')
await expect(elem).toBePresent()
toBeExisting
Igual que toExist
.
Uso
const elem = await $('#someElem')
await expect(elem).toBeExisting()
toBeFocused
Comprueba si el elemento tiene foco. Esta aserción solo funciona en un contexto web.
Uso
const elem = await $('#someElem')
await expect(elem).toBeFocused()
toHaveAttribute
Comprueba si un elemento tiene un cierto atributo con un valor específico.
Uso
const myInput = await $('input')
await expect(myInput).toHaveAttribute('class', 'form-control')
await expect(myInput).toHaveAttribute('class', expect.stringContaining('control'))
toHaveAttr
Igual que toHaveAttribute
.
Uso
const myInput = await $('input')
await expect(myInput).toHaveAttr('class', 'form-control')
await expect(myInput).toHaveAttr('class', expect.stringContaining('control'))
toHaveElementClass
Comprueba si un elemento tiene un solo nombre de clase. También se puede llamar con un array como parámetro cuando el elemento puede tener múltiples nombres de clase.
Uso
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
Comprueba si un elemento tiene una cierta propiedad.
Uso
const elem = await $('#elem')
await expect(elem).toHaveElementProperty('height', 23)
await expect(elem).not.toHaveElementProperty('height', 0)
toHaveValue
Comprueba si un elemento de entrada tiene un cierto valor.
Uso
const myInput = await $('input')
await expect(myInput).toHaveValue('admin-user', { ignoreCase: true })
await expect(myInput).toHaveValue(expect.stringContaining('user'), { ignoreCase: true })
toBeClickable
Comprueba si un elemento puede ser clickeado llamando a isClickable
en el elemento.
Uso
const elem = await $('#elem')
await expect(elem).toBeClickable()
toBeDisabled
Comprueba si un elemento está deshabilitado llamando a isEnabled
en el elemento.
Uso
const elem = await $('#elem')
await expect(elem).toBeDisabled()
// same as
await expect(elem).not.toBeEnabled()
toBeEnabled
Comprueba si un elemento está habilitado llamando a isEnabled
en el elemento.
Uso
const elem = await $('#elem')
await expect(elem).toBeEnabled()
// same as
await expect(elem).not.toBeDisabled()
toBeSelected
Comprueba si un elemento está habilitado llamando a isSelected
en el elemento.
Uso
const elem = await $('#elem')
await expect(elem).toBeSelected()
toBeChecked
Igual que toBeSelected
.
Uso
const elem = await $('#elem')
await expect(elem).toBeChecked()
toHaveComputedLabel
Comprueba si el elemento tiene una etiqueta WAI-ARIA computada específica. También se puede llamar con un array como parámetro en el caso donde el elemento puede tener diferentes etiquetas.
Uso
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'))
Uso
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
Comprueba si el elemento tiene un rol WAI-ARIA calculado específico. También se puede llamar con un array como parámetro en el caso donde el elemento puede tener diferentes etiquetas.
Uso
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'))
Uso
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
Comprueba si el elemento de enlace tiene un objetivo de enlace específico.
Uso
const link = await $('a')
await expect(link).toHaveHref('https://webdriver.io')
await expect(link).toHaveHref(expect.stringContaining('webdriver.io'))
toHaveLink
Igual que toHaveHref
.
Uso
const link = await $('a')
await expect(link).toHaveLink('https://webdriver.io')
await expect(link).toHaveLink(expect.stringContaining('webdriver.io'))
toHaveId
Comprueba si el elemento tiene un atributo id
específico.
Uso
const elem = await $('#elem')
await expect(elem).toHaveId('elem')
toHaveText
Comprueba si el elemento tiene un texto específico. También se puede llamar con un array como parámetro en el caso donde el elemento puede tener diferentes textos.
Uso
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')])
En caso de que haya una lista de elementos en el div a continuación:
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
Puedes afirmarlos usando un array:
const elem = await $$('ul > li')
await expect(elem).toHaveText(['Coffee', 'Tea', 'Milk'])
toHaveHTML
Comprueba si el elemento tiene un texto específico. También se puede llamar con un array como parámetro en el caso donde el elemento puede tener diferentes textos.
Uso
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 })
Uso
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
Comprueba si un elemento está dentro del viewport llamando a isDisplayedInViewport
en el elemento.
Uso
const elem = await $('#elem')
await expect(elem).toBeDisplayedInViewport()
toHaveChildren
Comprueba la cantidad de hijos del elemento fetcheado llamando al comando element.$('./*')
.
Uso
const list = await $('ul')
await expect(list).toHaveChildren() // la lista tiene al menos un elemento
// mismo que
await expect(list).toHaveChildren({ gte: 1 })
await expect(list).toHaveChildren(3) // la lista tiene 3 elementos
// mismo que
await expect(list).toHaveChildren({ eq: 3 })
toHaveWidth
Comprueba si el elemento tiene un ancho específico.
Uso
await browser.url('http://github.com')
const logo = await $('.octicon-mark-github')
await expect(logo).toHaveWidth(32)
toHaveHeight
Comprueba si el elemento tiene una altura específica.
Uso
await browser.url('http://github.com')
const logo = await $('.octicon-mark-github')
await expect(logo).toHaveHeight(32)
toHaveSize
Comprueba si el elemento tiene un tamaño específico.
Uso
await browser.url('http://github.com')
const logo = await $('.octicon-mark-github')
await expect(logo).toHaveSize({ width: 32, height: 32 })
toBeElementsArrayOfSize
Comprueba la cantidad de elementos obtenidos usando el comando $$
.
Nota: Este matcher actualizará el array pasado con los últimos elementos si la aserción pasa. Sin embargo, si has reasignado la variable, tendrás que buscar los elementos de nuevo.
Uso
const listItems = await $$('ul>li')
await expect(listItems).toBeElementsArrayOfSize(5) // 5 elementos en la lista
await expect(listItems).toBeElementsArrayOfSize({ lte: 10 })
// mismo que
assert.ok(listItems.length <= 10)
Matchers de red
toBeRequested
Comprueba que el mock fue llamado
Uso
const mock = browser.mock('**/api/todo*')
await expect(mock).toBeRequested()
toBeRequestedTimes
Comprueba que el mock fue llamado por la cantidad esperada de veces
Uso
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 }) // petición llamada al menos 5 veces pero menos de 11
toBeRequestedWith
Comprueba que el mock fue llamado de acuerdo con las opciones esperadas.
La mayoría de las opciones admiten matchers parciales de expect/jasmine como expect.objectContaining
Uso
const mock = browser.mock('**/api/todo*', { method: 'POST' })
await expect(mock).toBeRequestedWith({
url: 'http://localhost:8080/api/todo', // [opcional] string | function | custom matcher
method: 'POST', // [opcional] string | array
statusCode: 200, // [opcional] number | array
requestHeaders: { Authorization: 'foo' }, // [opcional] object | function | custom matcher
responseHeaders: { Authorization: 'bar' }, // [opcional] object | function | custom matcher
postData: { title: 'foo', description: 'bar' }, // [opcional] object | function | custom matcher
response: { success: true }, // [opcional] object | function | custom matcher
})
await expect(mock).toBeRequestedWith({
url: expect.stringMatching(/.*\/api\/.*/i),
method: ['POST', 'PUT'], // ya sea POST o PUT
statusCode: [401, 403], // ya sea 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 de instantánea
WebdriverIO admite pruebas básicas de instantáneas así como pruebas de instantáneas DOM.
toMatchSnapshot
Comprueba si cualquier objeto arbitrario coincide con un valor determinado. Si pasas un WebdriverIO.Element
, automáticamente capturará el estado outerHTML
del mismo.
Uso
// instantánea de objetos arbitrarios (no se necesita "await" aquí)
expect({ foo: 'bar' }).toMatchSnapshot()
// instantánea de `outerHTML` de WebdriverIO.Element (instantánea DOM, requiere "await")
await expect($('elem')).toMatchSnapshot()
// instantánea del resultado del comando de elemento
await expect($('elem').getCSSProperty('background-color')).toMatchSnapshot()
toMatchInlineSnapshot
De manera similar, puedes usar toMatchInlineSnapshot()
para almacenar la instantánea en línea dentro del archivo de prueba. Por ejemplo, dado:
await expect($('img')).toMatchInlineSnapshot()
En lugar de crear un archivo de instantánea, WebdriverIO modificará el archivo de prueba directamente para actualizar la instantánea como una cadena:
await expect($('img')).toMatchInlineSnapshot(`"<img src="/public/apple-touch-icon-precomposed.png">"`)