npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@healify/webdriverio-plugin

v2.4.0

Published

Self-healing wrapper for WebdriverIO: heuristic, local-first, no AI, no server.

Readme

@healify/webdriverio-plugin

Wrapper de auto-sanado para WebdriverIO. Cuando una interacción con un elemento (click, setValue, etc.) falla porque el selector ya no existe en la página, este plugin intenta curarlo en vivo con una heurística de pattern-matching (no es IA, no hay red ni servidor). Es el mismo motor que usan @healify/test-runner (Playwright), @healify/cypress-plugin (Cypress) y @healify/selenium-plugin (Selenium): analyzeAndHeal().

Verifica contra la página real. En el momento exacto en que la interacción falla, el plugin todavía tiene el browser en la mano — consulta el DOM real ahí mismo (browser.execute) antes de proponer nada. Las sugerencias se confrontan contra lo que había de verdad en pantalla: se descarta lo que no existe, y los nombres se leen de la página en vez de deducirse por diccionario. Si execute no está disponible (sesión rara, browser sin soporte de JS), degrada limpio a la heurística sin verificar.

Instalación

npm install --save-dev @healify/webdriverio-plugin

Uso

import { remote } from 'webdriverio'
import { HealifyWebdriverIOPlugin } from '@healify/webdriverio-plugin'

const raw = await remote({ capabilities: { browserName: 'chrome' } })
const healify = new HealifyWebdriverIOPlugin({ onEvent: console.log })
const browser = healify.wrap(raw)

// Si '#add-to-cart-btn' se rompió, el plugin intenta un selector alternativo
// antes de dejar que el error se propague.
await browser.$('#add-to-cart-btn').click()

WebdriverIO es lazy: $() no falla hasta que interactuás con el elemento devuelto. El proxy envuelve los métodos de interacción (click, setValue, addValue, getText, getAttribute, waitForExist, waitForDisplayed, waitForClickable, isExisting, isDisplayed, getHTML, getLocation, getSize) para capturar el error en el momento correcto, no en $() mismo.

Opciones

new HealifyWebdriverIOPlugin({
  confidenceThreshold: 0.9,       // default: mismo piso que reporter-core (HEALED_THRESHOLD, auto-aplicado sin revisión)
  dryRun: false,                  // default: true = cura pero nunca aplica el fix, solo emite el evento
  onEvent: (e) => {},             // opcional: se llama en cada intento de curado
  projectName: 'mi-proyecto',     // opcional: nombre que va a healify-report.json al llamar flush()
})

Generar un reporte con flush()

Igual que Selenium, WebdriverIO no tiene un hook nativo de "fin de corrida" en este plugin, así que no genera healify-report.html/.json solo. Llamando flush() al final de tu suite (ej. en un after/afterAll global) se escribe healify-report.json con todos los eventos acumulados desde la última llamada, mismo formato que Playwright/Cypress/Selenium:

const healify = new HealifyWebdriverIOPlugin({ projectName: 'mi-proyecto' })
const browser = healify.wrap(raw)

// ... corré tu suite normalmente ...

const cantidad = healify.flush()   // escribe healify-report.json, devuelve cuántos casos escribió

healify-report.html no se genera acá (no hay renderer HTML en este paquete), pero podés correr npx @healify/cli fix sobre el healify-report.json resultante igual que con Playwright/Cypress.

Qué selectores soporta

WebdriverIO usa strings directos, no una clase de locators como By en Selenium: selectores CSS (.clase, #id, [attr=x], tag), XPath (//div, (//div)[1]).

Estrategias de string de WebdriverIO (linkText=, partialText=, xpath= explícito con prefijo, etc.) no están soportadas: no tienen equivalente limpio en el motor de heurística. Si se usan, el plugin no intenta curar y deja pasar el error original tal cual.

Fuera de alcance (a propósito, en esta versión)

  • Modo cloud: no existe. Healify es 100% local, sin apiKey, sin servidor.
  • Reporte HTML: flush() (arriba) escribe healify-report.json, pero este paquete no tiene un renderer de healify-report.html propio como test-runner/cypress-plugin.
  • Memoria entre tests ("si otro test ya usa un selector estable, sugerirlo acá también"): el motor de heurística no tiene esta capacidad hoy, en ningún paquete de Healify. No se agregó solo para WebdriverIO.
  • Sugerencias role(...) con nombre: se convierten a un XPath real ($() de WebdriverIO autodetecta XPath por el // inicial) que busca por texto visible, aria-label, placeholder o value según el rol — reconoce button, link, textbox, checkbox, radio y searchbox. Sin nombre (role('button'), típico de la estrategia XPath del motor) no hay con qué armar un XPath confiable, y se reporta como 'no-suggestion'.
  • :has-text(...)/visible=.../getBy*(...): siguen siendo sintaxis de Playwright sin equivalente CSS/XPath directo — se reportan como 'no-suggestion'.

Licencia

MIT