cypress-typed-stubs
TypeScript icon, indicating that this package has built-in type declarations

5.1.0 • Public • Published

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)

Package Sidebar

Install

npm i cypress-typed-stubs

Weekly Downloads

218

Version

5.1.0

License

Apache-2.0

Unpacked Size

1.32 MB

Total Files

77

Last publish

Collaborators

  • xavierdupessey
  • eguerin_criteo
  • olivier.chirouze