-
Notifications
You must be signed in to change notification settings - Fork 169
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to intercept with cypress ? #999
Comments
Personally I'd recommend against asserting on the request itself, and rather focus on asserting that the API responds the way you expect and that your app behaves as you want. This is similar to what Kent C Dodds writes in https://kentcdodds.com/blog/stop-mocking-fetch (although he recommends MSW). As for your direct question, I'm not sure if it's possible, but I kind of doubt it. |
TLDR: You're right, it's not a good idea I started to reply to your message explaining why we're doing this... but in the end I totally agree, it's not maintainable to do this.
So I think that we'll try to setup a test environment we can request to have better tests. However, maybe it could help other people to know if it's possible |
Hi folks. I've been using Mirage for 3 years. It's awesome, thanks! well, I have same question. How we could intercept a requesting using Cypress? I don't want to to mock or assert against a request but I'd like to wait for some requests to have been finished before interacting with UI. Cypress is really fast. |
Do you have some solution? i have the same problem |
Hi @andreLuis1506 . I was able to handle this situation by adding a queue of mocked requests. I am gonna suppose you are using Cypress + Mirage and you've followed this tutorial for adding a Mirage JS Proxy. This is my Cypress.on('window:before:load', (win) => {
win.CYPRESS_REQUESTS = [];
win.handleFromCypress = function(request) {
const {method, url} = request;
const logRequest = {start: true, finished: false, url, method};
win.CYPRESS_REQUESTS.unshift(logRequest);
return fetch(url, {
method,
headers: request.requestHeaders,
body: request.requestBody,
}).then((res) => {
const content = res.headers.get('content-type').includes('application/json') ?
res.json() :
res.text();
return new Promise((resolve) => {
content.then((body) => {
const result = resolve([res.status, res.headers, body]);
logRequest.finished = true;
return result;
});
});
});
};
}); As we can a custom request object is added to array attached to So I've create a function that will look for request given a regex pattern that it's not finished. This function will wait until the target request becomes function waitForRequest(urlPattern: string, method = '') {
const wildcardRegex = new RegExp('\\*', 'g');
const questionMarkRegex = new RegExp('\\?', 'g');
const replacedWildCard = urlPattern.replace(wildcardRegex, '[^ ]*').replace(questionMarkRegex, '\\?');
const regexUrl = new RegExp(replacedWildCard, 'g');
cy.window().then((win) => {
const checkMatches = (r: any) => {
let isMatched = r.url.match(regexUrl);
if (method) {
isMatched = isMatched && r.method === method;
}
return isMatched;
};
const findRequest = () => (win as any).CYPRESS_REQUESTS.find(checkMatches);
const errorMsg = `[Request [${method}] to ${urlPattern} didn't happen`;
cy.waitUntil(findRequest, {errorMsg}).its('finished', {timeout: 10000})
.should('be.true')
.log(`Request [${method}] to ${urlPattern} has been finished`);
});
} With this help i could simulate intercepting a request and wait for it. so I can intercept requests, filter for a regex pattern and HTTP method (GET,POST etc) and wait for it to becomes finished. |
See my previous answer. |
I was excited to come back to this issue and see @albuquerquecesar's solution. I tried to implement it for my usecase and ran into some issues. I'm using MirageJS alongside Cypress in its relatively new Component Testing mode. One difference between it and E2E mode that matters in this case is which Cypress events are accessible. CT mode doesn't have access to the So instead, I just totally skipped the event bit and modified // commands.js
Cypress.Commands.add('waitForRequest', (server, urlPattern, method = '') => {
const wildcardRegex = /\*/g;
const questionMarkRegex = /\?/g;
const replacedWildCard = urlPattern.replace(wildcardRegex, '[^ ]*').replace(questionMarkRegex, '\\?');
const regexUrl = new RegExp(replacedWildCard, 'g');
const checkMatches = (r) => {
let isMatched = r.url.match(regexUrl);
if (method) {
isMatched = isMatched && r.method.toLowerCase() === method.toLowerCase();
}
return isMatched;
};
const requestFound = () => server.pretender.handledRequests.some(checkMatches);
const errorMsg = `[Request [${method}] to ${urlPattern} didn't happen`;
return cy
.waitUntil(requestFound, {errorMsg})
.should('be.true')
.log(`Request [${method}] to ${urlPattern} has been finished`);
}); // some-test-file.cy.js
let server;
beforeEach(() => {
server = createServer();
});
it('a test', () => {
server.post('/api/v1/endpoint/', () => []);
cy.mount(<Component {...props} />, {state});
cy.findByLabelText(/some text/i).select('bar');
cy.waitForRequest(server, '/api/v1/endpoint/', 'POST');
}); Note that this still depends on the Cypress wait-until plugin, so you'll need to include that. |
Description
This is not an issue, this is a discussion.
I set up Mirage on my project which is using Cypress as a testing tool (using your great documentation, thank you for this).
I would like if there's a way to interecept requests with
cy.intercept
to do some assertions on the request body for instance ?More details
When running
cy.intercept('POST', '/api/users').as('createUser')
and thency.wait('@createUser').then(({ request }) => {})
, cypress says that the call is never done, which seems to be normal, because of Mirage.Do you think that there could be a way to make it work?
Thanks
The text was updated successfully, but these errors were encountered: