:wave: I'm having some issues with an interceptor ...
# pact-js
b
šŸ‘‹ I'm having some issues with an interceptor in Cypress. Route matcher
Copy code
POST	**/api/v2/login	(stubbed) Yes	(alias) login	(count) -
The request
Copy code
POST    https://<our domain>.<http://pactflow.io/pacts/provider/<our|pactflow.io/pacts/provider/<our> provider>/consumer/<our consumer>/latest/stub/api/v2/login
The Cypress test
Copy code
const loginResponse = require(`../../../fixtures/login.json`);

describe(`Login API`, () => {
    Cypress.config({ defaultCommandTimeout: 120000 });

    beforeEach(() => {
        cy.intercept(
            {
                method: `POST`,
                url: `**/api/v2/login`
            },
            {
                statusCode: 200,
                body: { ...loginResponse },
                headers: {
                    "access-control-allow-origin": `*`
                }
            }
        ).as(`login`);      <----- The alias

        cy.visit(`/`);

        cy.setupPact(`<our consumer>`, Cypress.env(`PACT_PROVIDER`));
    });

    it(`should log into Studio Frontend`, () => {
        cy.login(
            `/api/v2/login`,
            `user`,
            `password`
        );
    });

    after(() => {
        cy.usePactWait(`login`);   <---- This doesn't match the route 
    });
});
The error
Copy code
Error:    CypressError: Timed out retrying after 5000ms: `cy.wait()` timed out waiting `5000ms` for the 1st request to the route: `login`. No request ever occurred.
y
Hey @Bernard Baker! Thanks for trying out the adapter. What does your
cy.login
method look like? Are you making a a
cy.request
call via your customer
cy.login
method? If so, you would wish to use
cy.usePactRequest
https://github.com/pactflow/pact-cypress-adapter#cyusepactrequestoption-alias-and-cyusepactgetalias--alias
b
@Yousaf Nabi (pactflow.io) My
login
command looks like...
Copy code
Cypress.Commands.add(`login`, (api, user, passphrase) => {
    cy.request({
        method: `POST`,
        url: `${Cypress.env(`PACT_PROVIDER_STUB_URL`)}${api}`,
        body: {
            user,
            passphrase
        },
        headers: {
            Authorization: `Bearer ${Cypress.env(`PACT_PROVIDER_TOKEN`)}`,
            Accept: `application/json, text/plain, */*`
        }
    });
});
@Yousaf Nabi (pactflow.io) refactored it based on the document you sent over. It's working now. The Pact file is being written. Thanks šŸ™
šŸŽ‰ 2
y
Saweeeeet!
šŸ™Œ 1
Props to the author @Shuying Lin and her documentation chefkiss
šŸ™Œ 1
āœ… 2
b
Hi @Yousaf Nabi (pactflow.io) apologies for wrangling your handle. But I have a question. In Cypress can I make a request to the latest stub URL of my integration? And get the OAS schema example for the path back in my response?
y
Is there 2 separate questions there? ā€¢ In Cypress can I make a request to the latest stub URL of my integration? ā—¦ Yes, @Lewis Prescott made a post recently https://www.pactman.co.uk/post/end-to-end-testing-in-microservices-with-api-contracts ā—¦ You can read in also read in a Pact file directly, and strip off the matchers and feed into to cy.route https://gist.github.com/bethesque/a4b117ebb09488c101f88320cac678a4 ā€¢ And get the OAS schema example for the path back in my response? ā—¦ Not sure I fully understand this? As a response from what?
Some more info on the first point in our docs https://docs.pact.io/consumer/using_pact_to_support_ui_testing
b
If the provider uses an OAS document which has examples, is it possible to use the latest stub URL as my consumers endpoint. And not have to write Cypress interceptors that make use of fixtures? Instead of using the fixture, I'd like to assert that the response fits the pattern of the OAS response example.
y
I don't believe we allow for generating stubs from OAS/Provider Contracts. Sounds like a cool idea though!
b
It would be helpful. SmartBear through their Swagger Editor provide a stub URL which sends back examples, which I previously used to assert against in my responses.
y
Ahh yeah, I can see here https://github.com/OpenAPITools/openapi-generator available in all kinds of flavours of languages
Ada, C# (ASP.NET Core, Azure Functions), C++ (Pistache, Restbed, Qt5 QHTTPEngine), Erlang, F# (Giraffe), Go (net/http, Gin, Echo), Haskell (Servant, Yesod), Java (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, Jersey, RestEasy, Play Framework, PKMST, Vert.x, Apache Camel), Kotlin (Spring Boot, Ktor, Vertx), PHP (Laravel, Lumen, Mezzio (fka Zend Expressive), Slim, Silex, Symfony), Python (FastAPI, Flask), NodeJS, Ruby (Sinatra, Rails5), Rust (rust-server), Scala (Akka, Finch, Lagom, Play, Scalatra)
I previously created one for serverless-offline that you could feed a pact file into and spin up a stub server, and have also hosted stub servers in ECS via a docker container.
where would this fit on the consumer side, in terms of their testing pyramid/pipeline?
Feel free to raise an issue on the Pactflow Roadmap buddy https://github.com/pactflow/roadmap#contributing-to-the-roadmap
b
Sorry for the late reply....
More questions, sorry.....
The interactions in a Pact that I just queried using CURL responded with the responses crafted by interactions created during Unit Tests.
šŸ‘ 1
Would you recommend that the responses to an interaction be crafted based on the OAS in Pactflow?
So I create interactions in my unit tests. And in my e2e Cypress tests use the stubs?
šŸ‘Œ 1
y
An OAS is just a design spec, so doesn't represent the subset of interactions any one consumer may have with it. I think the stubs made from Pact servers work fine for the most part, however for some e2e cases, I needed more granular control over my mocks, which tools like Wiremock etc provide (response templating). We also used our stubs in a hosted environment (basically a dev environment where our main services lived, but third party dependencies were mocked out) so the PO's could play around with it, without being reliant on everything being up an integrated test env
I could see value in standing up a OAS stub server from a spec, especially in Pactflow land as you would have confidence that it was tied to a particular build, or environment. Good for for thought anyway
I used to create pacts in my consumer code, and prior to uploading them, I would run swagger-mock-validator to ensure we didn't upload any Pacts that were garbage. If consumers or providers wanted to make API changes, they would propose it on a feature branch for the docs, and then when a Pact was generated on the same feature branch, it would pull the corresponding openapi spec, and if not one on the branch it would fall back to master. Our providers used the API specs in their AWS API gateways as request/response validators as well, and we weren't overly confident on their test coverage, but testing it against the spec which they used for the validator made sense to us