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

@koenvanbelle/cypress-soft-assertions

v2.4.4

Published

A Cypress plugin that provides soft_it() for soft assertions - all assertions continue on failure and are reported together

Readme

Cypress Soft Assertions

A Cypress plugin that provides soft_it() — a drop-in replacement for it() that makes all assertions soft. Assertions continue execution on failure, and all failures are aggregated and reported together at the end of the test.

Why?

Standard Cypress assertions stop test execution at the first failure. With soft_it():

  • All assertions run even if some fail
  • See all failures at once — no need to fix one issue and rerun to find the next
  • Drop-in replacement — just change it() to soft_it()
  • No manual tracking — failures are automatically aggregated and reported

Installation

npm install @koenvanbelle/cypress-soft-assertions --save-dev

Setup

1. Import the plugin

Add the import to your Cypress support file (cypress/support/e2e.ts or cypress/support/e2e.js):

import '@koenvanbelle/cypress-soft-assertions';

Or for JavaScript:

require('@koenvanbelle/cypress-soft-assertions');

2. Add type definitions (TypeScript only)

Add a reference directive at the top of your test files:

/// <reference types="@koenvanbelle/cypress-soft-assertions" />

Or include the types in your tsconfig.json:

{
  "compilerOptions": {
    "types": ["cypress", "@koenvanbelle/cypress-soft-assertions"]
  }
}

Usage

Replace it() with soft_it() in any test where you want soft assertion behavior:

describe('Product Page', () => {
  soft_it('validates all product details', () => {
    cy.visit('/product/123');

    // All assertions run even if some fail
    cy.get('.product-name').should('have.text', 'Awesome Product');
    cy.get('.product-price').should('have.text', '$99.99');
    cy.get('.stock-status').should('have.text', 'In Stock');
    cy.get('.rating').should('have.attr', 'data-stars', '5');
  });
});

Supported assertion styles

soft_it() works with all Cypress assertion styles:

soft_it('supports all assertion types', () => {
  // .should() assertions
  cy.get('.title').should('be.visible');
  cy.get('.title').should('have.text', 'Welcome');

  // expect() in .then()
  cy.get('.price').then(($el) => {
    expect($el.text()).to.equal('$99.99');
  });

  // Chained assertions with .and()
  cy.get('.button')
    .should('be.visible')
    .and('have.class', 'active')
    .and('contain', 'Submit');
});

Mixing soft_it() with regular it()

You can use both in the same suite. Regular it() tests are unaffected:

describe('User Profile', () => {
  // Regular test — stops on first failure
  it('loads the page', () => {
    cy.visit('/profile');
    cy.get('h1').should('be.visible');
  });

  // Soft test — all assertions run
  soft_it('validates profile fields', () => {
    cy.get('.username').should('have.text', 'john_doe');
    cy.get('.email').should('have.text', '[email protected]');
    cy.get('.member-since').should('contain', '2023');
    cy.get('.posts-count').should('have.text', '42');
  });
});

soft_it.only and soft_it.skip

Works just like regular it():

describe('Test Suite', () => {
  soft_it.only('run only this test', () => {
    cy.get('.field1').should('exist');
  });

  soft_it.skip('skip this test', () => {
    cy.get('.optional').should('exist');
  });
});

soft_it.expectFailure

Use soft_it.expectFailure() for browser behavior specs that intentionally trigger soft failures but should still finish green overall.

soft_it.expectFailure('captures a known soft failure without failing the spec', () => {
  cy.get('#title').should('have.text', 'Wrong Title');
  cy.get('#status').should('have.text', 'Ready');
});

This mode still verifies that a final SoftAssertionError was produced. If the test completes without any soft failure, the test fails.

soft_it.expectFailure.only(...) is also available.

How it works

  1. soft_it() patches Chai's assertion mechanism for the duration of the test.
  2. When an assertion fails inside a retriable command (.should(), .and()), the error is staged under a stable token and rethrown so Cypress can retry. If the assertion eventually passes, the staged failure is cleared.
  3. After a bounded number of retries, the assertion is swallowed and the failure is recorded so the test can continue to the next command.
  4. Non-retriable assertion failures (expect() in .then() callbacks) are captured immediately.
  5. Command-level failures (e.g. element-not-found timeouts) are caught by a Cypress.on('fail') handler and recorded as soft failures.
  6. At the end of the test, all recorded failures are aggregated into a single SoftAssertionError.

Error output

When soft assertions fail, you get a single formatted report:

================================================================================
SOFT ASSERTION FAILURES (3 failed):
================================================================================
  1. expected '<h1.title>' to have text 'Wrong Title', but the text was 'Products'
  2. expected '<div.count>' to have text '999', but the text was '42'
  3. expected '<div.missing>' to exist in the DOM
================================================================================

Important notes

  • Retriable assertions are retried: .should() and .and() assertions are retried by Cypress before being captured as soft failures. Assertions that eventually pass are not reported.
  • Non-assertion errors still stop execution: Network errors, visit timeouts, and other command errors are captured as soft failures but may prevent subsequent commands from running.
  • State resets between tests: Each soft_it() test starts with a clean slate — failures from one test never leak into another.
  • Timeout-aware retries: The plugin respects Cypress's defaultCommandTimeout and per-command { timeout } overrides. Retriable assertions (.should(), .and()) are retried until just before the effective timeout expires, using max(timeout - 100ms, timeout * 0.9) as the swallow threshold. For slow applications, increase the timeout to give assertions more time to pass:
    // Global: set in cypress.config.ts
    e2e: { defaultCommandTimeout: 10000 }
    
    // Per-command: override on individual commands
    cy.get('.slow-element', { timeout: 15000 }).should('be.visible');
  • Cypress Studio / Command Log: When a soft assertion fails definitively, the plugin swallows the error so the test can continue. Cypress treats the command as resolved, which means it may not appear as a failed step in the Cypress Studio command log or may look like the assertion was skipped. The assertions do execute and failures are captured — they just don't show visually in the command log. Check the final SoftAssertionError report for the complete list of failures.

Compatibility: cypress-translation-checker

@koenvanbelle/cypress-soft-assertions is compatible with cypress-translation-checker (verified with [email protected] and Cypress 15).

Install

npm install --save-dev @koenvanbelle/cypress-soft-assertions cypress-translation-checker

1. Register translation-checker tasks in Cypress config

cypress-translation-checker uses Cypress tasks to persist collected page results. Add these in setupNodeEvents.

import { defineConfig } from 'cypress';

const translationResults = new Map<string, { url: string; errors: any[]; testContext: string }>();

export default defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('task', {
        storeTranslationResult({
          url,
          errors,
          testContext,
        }: {
          url: string;
          errors: any[];
          testContext: string;
        }) {
          translationResults.set(url, { url, errors, testContext });
          return null;
        },
        getTranslationResults() {
          return Array.from(translationResults.values());
        },
        clearTranslationResults() {
          translationResults.clear();
          return null;
        },
      });

      return config;
    },
  },
});

2. Import both plugins in support file

Enable soft assertions and then enable automatic translation checks.

import '@koenvanbelle/cypress-soft-assertions';
import { enableAutoTranslationCheck } from 'cypress-translation-checker/commands';

enableAutoTranslationCheck({
  waitTime: 500,
});

3. Write tests normally with soft_it

Soft assertion failures are still aggregated into one SoftAssertionError at test end.

soft_it('works with automatic translation checks', () => {
  cy.visit('/');
  cy.get('h1').should('have.text', 'Expected title');
  cy.get('#status').should('have.text', 'Ready');
});

Notes

  • If translation-checker tasks are missing, Cypress will fail with unknown task errors.
  • Both plugins register hooks/events, but they can run together safely with the setup above.
  • Keep translation-checker in non-invasive mode (failOnError: false in auto mode) so functional assertions remain the source of test pass/fail behavior.

License

MIT