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 🙏

© 2024 – Pkg Stats / Ryan Hefner

cypress-typed-stubs

v5.1.0

Published

Typed Cypress stubs with automatic URL patterns, based on clients generated with Swagger

Downloads

319

Readme

Cypress typed stubs

A Criteo npm package to define typed Cypress stubs with automatic URL patterns, based on clients generated with Swagger.

License

criteo/cypress-typed-stubs introspects your typescript (Angular) clients generated by nswag and helps you define your own Cypress stubs very easily, where:

  • HTTP method
  • URL pattern
  • name

...are automatically generated.

And the fixture used to stub your API is type checked.

Installation

Compatibility table:

| Angular version | Cypress version | cypress-typed-stubs version | | --------------- | --------------- | --------------------------- | | 11 | <9 | 2 | | 11 | 9+ | 3 | | 13 | 9+ | 4 | | 15 | 9+ | 5 |

npm install --save-dev cypress-typed-stubs

Usage

Have a look at the example-app code in this repository.

Let's assume that you have an AdSetsClient that was generated by nswag, which contains a getById endpoint and returns a GetAdSetDetailsResponse object, or null.

export class AdSetsClient extends GeneratedClient {
  getById(adSetId: number): Observable<GetAdSetDetailsResponse | null> {
    let url_ = this.baseUrl + '/campaign-api/ad-sets/{adSetId}';
    // ...
  }
}

Without cypress-typed-stubs 😕

If you want to stub this endpoint in your Cypress tests, you might want to do something like:

cy.intercept(
  'GET', // Need to know the HTTP method
  /.*\/campaign-api\/ad-sets\/.*/, // Need to "guess" the appropriate URL regex
  {
    // Need to maintain a JSON object that matches the proper interface
    adSet: {
      id: 5,
      // ...
      // No type checking!
      audienceType: 'invalid type',
    },
  }
).as('getAdSet'); // Need to define a name that makes sense and that is reused throughout the tests

// Can't easily reuse stubs

and wait on the call with:

cy.wait('@getAdSet');

👎 Issues

  • the HTTP method and URL pattern have to be "guessed" and maintained if they happen to change in the generated client
  • the provided fixture is not type checked
  • a name has to be chosen and duplicated in the tests (prepended with @). No naming convention

With cypress-typed-stubs 🤩

Create stubs

Define

  • a stub that matches the generated client (ex: AdSetsStub)
  • stub endpoints that match the generated client endpoint
    • the provided fixture is type checked
    • URL pattern and HTTP method are provided automatically
export class AdSetsStub extends ClientStub<AdSetsClient> {
  constructor() {
    super(AdSetsClient);
  }

  endpoints = {
    getById: this.createEndpoint(
      this.client.getById,
      200,
      // Everything is typed!
      {
        adSet: {
          id: 5,
          // ... other properties
          audienceType: AudienceType.Custom,
        },
      }
    ),
  };
}

Instead of a fixture, you can provide a fixture builder: it is a function that takes a cypress request object (CyHttpMessages.IncomingHttpRequest) as parameter and returns a fixture. It is useful to adapt the fixture depending on the request (for example, request body or query parameters):

export class AdSetsStub extends ClientStub<AdSetsClient> {
  constructor() {
    super(AdSetsClient);
  }

  endpoints = {
    getById: this.createEndpoint(
      this.client.getById,
      200,
      // Fixture builder function -> builds the fixture depending on the request
      // (here depending on 'language' query parameter). The function is typed.
      (req) =>
        req.query['language'] === 'fr-FR'
          ? {
              adSet: {
                name: "Ceci est mon ensemble d'annonce",
                // ... other properties
              },
            }
          : {
              adSet: {
                name: 'This is my ad set',
                // ... other properties
              },
            }
    ),
  };
}

Intercept

These endpoints can then be used in any Cypress test for intercept.

// Create the stub _and initialize it_
const stub = new AdSetsStub().init();

// Endpoints
const getById = stub.endpoints.getById;

// Stub default config
EndpointHelper.stub(getById.defaultConfig());

Note that the usage of EndpointHelper is optional, you can use cy.intercept directly

The endpoint is now stubbed by Cypress with a name automatically generated (prefixed with client name for consistency):

routes

Adjust

The stub can be adapted based on the default configuration:

  • change HTTP status:
EndpointHelper.stub(getById.defaultConfig().withStatusCode(500));
  • adapt the fixture (mapping is type checked):
EndpointHelper.stub(
  getById.defaultConfig().mappingFixture((fixture) => ({
    adSet: {
      ...fixture.adSet,
      id: 7, // Simply change the id
    },
  }))
);

If the endpoint was initially stubbed with a fixture builder, the provided mapping function is applied to the result of the fixture builder function.

  • replace the fixture entirely (override object is type checked):
EndpointHelper.stub(
  getById.defaultConfig().withOverride({
    // Everything is typed!
    adSet: {
      id: 6,
      // ... other properties
      audienceType: AudienceType.Commerce,
    },
  })
);

If the endpoint was initially stubbed with a fixture builder, the provided object overrides the result of the fixture builder function.

  • set HTTP headers:
EndpointHelper.stub(
  getById.defaultConfig().withHeaders({
    myHeader: 'myValue',
  })
);
  • adaptations can be combined with fluent syntax:
EndpointHelper.stub(getById.defaultConfig().withStatusCode(500).withOverride({}).withHeaders({ traceId: '12345' }));

Wait

Endpoints have a default alias that can be used to wait calls:

cy.wait(getById.alias);

👍 Advantages

  • stub name, HTTP method, URL pattern are provided automatically
  • stub alias is a property
  • fixture is type checked (which enables code assistance)
  • helper methods

Contributions

Please use Node v16 and npm v8.

Testing within a "host" project

From this project:

npm run prepare
# This will break the local build, but don't worry this is temporary
npm uninstall @angular/common
npm link

It is useful to temporarily uninstall @angular/common peer dependency to avoid incompatible errors in the "host" project.

From the project using the library:

npm link cypress-typed-stubs

After you are done with your tests, make sure to not commit your changes to package.json (the removal of dev dependencies)