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

@braze/cypress-utils

v4.4.0

Published

Utilities for cypress testing at Braze

Readme

cypress-utils

Utilities for cypress testing at Braze

This package provides a composable interface for re-using cypress selectors. Example declaration of selectors and their possible usage in a test can be found in the examples/ directory

Context definitions are an object containing one of 3 kinds of selectors:

  1. a function that returns a cypress selector
  2. a function that accepts arguments and returns a cypress selectors
  3. a selector with child selectors

All selectors can also define context actions to abstract common actions

Function selector

const context = makeContext("context type", {
  el: () => cy.get(".element");
});

/** use in the test as */
context.el.click();
context.el.should("be.visible");
// and so on - you can interact with context.el as if you were interacting
// with cy.get(".element")

Function selector that accepts arguments

const context = makeContext("context type", {
  row: {
    self: (num: number) => cy.get(`li:nth-child(${num})`);
    needsParams: true,
    children: {}
  }
});

/** use in the test as */
context.row(3).click();
context.row(5).should("be.visible");
// and so on - you can interact with context.row(n) as if you were interacting
// with cy.get("li:nth-child(n)")

// any type or number of arguments is acceptable
const context = makeContext("another example", {
  badge: {
    self: (label: string, num: number) => cy.get(`div:contains("${label}") li:nth-child(${num})`)
    needsParams: true,
    children: {}
});

/** use in the test as */
context.badge("failed", 4).should("be.visible");

Selector with child selectors

// you can declare children inline
const context = makeContext("context type", {
  table: {
    self: () => cy.get("table");
    children: {
      header: {
        self: () => cy.get("thead"),
        row: {
          self: (num: number) => cy.get(`tr:nth-child(${num})`),
          needsParams: true,
          children: {
            th: {
              self: (num: number) => cy.get(`th:nth-child(${num})`),
              needsParams: true,
              children: {}
            }
          }
        }
      }
    }
  }
});

// or define re-usable components to include inside other context declarations
const tableContext = extractDeclaration({
  header: () => cy.get("thead"),
  body: {
    self: () => cy.get("tbody"),
    children: {
      row: {
        self: (num: number) => cy.get(`tr:nth-child(${num})`),
        needsParams: true,
        children: {},
      },
    },
  },
});

const context = makeContext("larger re-usable context", {
  table: {
    self: cy.get("#table-wrapper"),
    children: tableContext,
  },
  // ... other selectors
})

Context actions

Commonly repeated functionality can be abstracted into actions. Actions are functions that accept as their first argument a Cypress chainable, and an arbitrary number of arguments. In the test, The value of self is passed as the first argument, and any arguments passed into the action.

As an example, with the previous example's context, if you find yourself writing a test like this:

context.table.in((table) => {
  table.body.in((body) => {
    body.row(1).realHover().click();
  });
});

cy.findByText("Framulous").should("be.visible");

context.table.in((table) => {
  table.body.in((body) => {
    body.row(2).realHover().click();
  });
});

cy.findByText("Eggsplicious").should("be.visible");

context.table.in((table) => {
  table.body.in((body) => {
    body.row(3).realHover().click();
  });
});

cy.findByText("Otherficious").should("be.visible");

You can define an action clickTableRow:

const context = makeContext("larger re-usable context", {
  table: {
    self: cy.get("#table-wrapper"),
    children: tableContext,
    actions: {
      clickTableRow: (self, table, num: number) => {
        self.within(() => {
          getActionContext(tableContext, table).body.in((body) => {
            body.row(num).realHover().click();
          });
        });
      },
    },
  },
});

and then call it in the test:

context.table.clickTableRow(1);

cy.findByText("Framulous").should("be.visible");

context.table.clickTableRow(2);

cy.findByText("Eggsplicious").should("be.visible");

context.table.clickTableRow(3);

cy.findByText("Otherficious").should("be.visible");

Actions should be used sparingly, and only after it is abundantly clear that they alleviate duplication, or are necessary to avoid gotchas, such as the need to call realHover() prior to click() to avoid flakiness.

Actions appear with intellisense on the chainable returned from a context, and have full type safety for the parameters. In addition, the action will log both its name and user-supplied parameters to allow debugging/inspection in the Cypress command log.

Context actions gotchas

Some context actions should be executed within the parent, as in the clickTableRow example above.

Others, however, should be executed in the parent scope. For those, omit the self.within wrapped around the getActionContext as in the example above.

API

makeContext

makeContext creates a context that can be used directly in a test. It accepts 2 arguments:

  1. a description of the thing that is represented
  2. a context declaration

The description is only used in error messages when accessing a selector that does not exist in the declaratin to make it easier to debug in Cypress's log.

extractDeclaration

extractDeclaration is purely a convenience helper that allows declaring a context with full type safety and inference. Whenever declaring a re-usable context declaration, it should be used

extractSelector

extractSelector is a convenience helper that allows declaring a selector with full type safety and inference. This can be used for standalone selector declaration.

getActionContext

getActionContext is useful to launder a context passed to a context action function to get type safety. It should be passed the children object from which to extract type information, and the context object, and returns the same context object with full type safety.