I have a single endpoint in the application. We hit the same api for each request with different action in the params.
URL
/application/api
Sample Request Payload 1:
{
"action":"CARD_TRANSACTION_HISTORY",
"data":{"date_from":"2018-12-01","date_to":"2018-12-31","total":5},
"meta":{}
}
Sample Request Payload 2:
{
"action":"CARD_BALANCE",
"data":{"date_from":"2018-12-01","date_to":"2018-12-31","total":5},
"meta":{}
}
Sample Request Payload 3:
{
"action":"CURRENCY_RATES",
"data":{"date_from":"2018-12-01","date_to":"2018-12-31","total":5},
"meta":{}
}
the action in above request changes for different requests.
When the dashboard page is loaded, we trigger 3 concurrent AJAX POST requests with different actions.
Problem with cypress is you can only specify one response for a route, and other way to handle this is make sequential requests (which we can't do)
Even if we write response as a function it gets called only once.
Any ideas on how we can mock data on the basis of payload?
I had the exact same problem and found @Richard Matsen's answer very useful, however when using the whitelist
option it isn't possible to access proxy.request
, which returns undefined
. But if you use onRequest
instead of whitelist
, you can access the request and thus implement any action depending on that request's body.
So this should work:
cy.server({
onRequest: (xhr) => {
xhr.url = xhr.url +
xhr.request.body.action == 'CARD_TRANSACTION_HISTORY' ? '?transactionHistory'
: xhr.request.body.action == 'CARD_BALANCE' ? '?balance'
: xhr.request.body.action == 'CURRENCY_RATES' ? '?currencyRates'
: ''
}
})
I did one dirty work around that worked, I didn't like it but I am out of options.
I simply combined all the responses in the same response.
My Mock Response
{
balance: {..},
transactionHistory: {..},
currencyRates: {..}
}
The each response handler simply processes part it is interested in, if one of the response is array, we'll need to change it to an object.
I'll be on a lookout for a better work around.
Here is another hack. It relies on your api ignoring url parameters and that the cy.server whitelist function is called before the request is made.
cy.server({
whitelist: (proxy) => {
proxy.url = proxy.url +
proxy.request.body.action == 'CARD_TRANSACTION_HISTORY' ? '?transactionHistory'
: proxy.request.body.action == 'CARD_BALANCE' ? '?balance'
: proxy.request.body.action == 'CURRENCY_RATES' ? '?currencyRates'
: ''
}
})
const apiMocks = {
balance: {..},
transactionHistory: {..},
currencyRates: {..}
}
cy.route('/application/api?balance', apiMocks.balance).as('balance')
cy.route('/application/api?transactionHistory', apiMocks.transactionHistory)
.as('transactionHistory')
cy.route('/application/api?currencyRates', apiMocks.currencyRates).as('currencyRates')
cy.visit(...)
cy.wait('@balance').then(xhr => //should see correct mock here )