How to pass query params of a request url while mocking with Request Hooks in Testcafe? - testing

My request url has multiple query params. I want to mock the response of the external API while writing my tests in Testcafe. I want to mock the data in E2E testing because my data will expire in every 15days.
Please suggest some ways to handle mocking the request with query param. I am able to mock the request not having any query param and I am using Request Hooks for that.

There shouldn't be a difference between a mocking response from URL with parameters and without them. You can mock a response by using RequestMock API:
...
const getDataMock = RequestMock()
.onRequestTo(/.*getData\?param=param_1/)
.respond((req, res) => {
res.setBody({...});
});
...
If this doesn't work for you, please provide us with the code where you define RequestMock or RequestHook.

Related

Playwright intercept server side network request

Can't see to find any good docs on how to mock/stub the server Sider side requests with playwright.
An example would be to intercept the getServerSideProps in nextjs: hitting the routes makes the server do a request (db API etc). Then it can do some business logic (which should also be covered by testing) before it is passed to the component as props which is sent to the client (being server side rendered).
Mocking that db API request without having some test logic mixed into the business logic is what I am hoping to find an answer for.
Playwright allows you to do interception and mocking/stubbing.
UI action can triger the API call, and without sending request you can intercept
the response.
And you can use moks and stubs as well.
const mock = { animals: [] }
await page.route('**/Zoo/v1/books', (animals) =>
route.fulfill({
status: 304,
body: JSON.stringify(mock),
})),
);
await page.goto('https://www.demoqa/animals');
See more https://github.com/microsoft/playwright/issues/1774#issuecomment-769247500
And https://playwright.dev/docs/next/network#modify-responses

Is it possible to create mock api on this cypress to prevent the actual api call

We have an vue js application which contains the component, On this component, there is an api call to update database records. We are doing unit test for this component.
Is it possible to create mock api on this cypress to prevent the actual api call? So database will not be modified during the unit test and can keep actual data as it is on database.
You can mock it indeed. For example this mocks a server and a specific API-call:
cy.server()
cy.route('POST', '**/oauth/v2/token', 'fixture:/oauth/agent-token.json')
More information about route is available on the cypress site: https://docs.cypress.io/api/commands/route.html
To make sure every request is mocked, use the force404 option with cy.server:
cy.server({force404: true})
cy.route('**/user/jake', {user:{name:'Jake'})
cy.visit('/')
// your test code here
Then any XHR request to /user/jake will work, but /user/jane and /login for example, will 404

How to see if nock is matching the request or not?

How to see if nock is matching the request or not? Is there a way one can log information on console regarding nock is matching or not to the requests being made?
The log function is no more available on newer versions of nock e.g. v13.0.0 but you can set the DEBUG environment variable to nock.* as described here https://github.com/nock/nock#debugging to log each step of the matching process. For example:
export DEBUG=nock.* && yarn test
if you're using yarn to run your tests.
It is very simple.
Just add .log(console.log) to your nock object!
nock('https://github.com')
.log(console.log)
.get('/')
Basically, nock checks all the interceptors it has active until a match is found for your request (in case you have multiple nock interceptors mocking a variety of requests). So what will be logged using .log(console.log) is,
a whole url to which the request is being made.
a url from the interceptor
true or false, depending upon the match scenario.
Hope this will help you resolve mysteries of nock :)
You can log requests to the console using:
nock.recorder.rec();
You can also listen to nock's event emitters to create a callback for whenever a request is intercepted. For example:
const requestCallback = () => {
console.log('Request was called');
}
nock('https://example.org')
.persist()
.get('/')
.on('request', requestCallback);

How to wait for XHR to 3rd party API in Cypress?

I have a SPA application that talks with API that deployed on another server. For example, when I click a Submit button it sends XHR request to it API, and I need to wait for a response to check it. How can I do this?
Put this in cypress/support/commands.js:
Cypress.Commands.add('manageMyApiRequests', () => {
cy.route('/URL/Of/api/I/Want/To/wait/For').as('myApi')
});
Then in your test or before each call:
cy.server();
cy.manageMyApiRequests();
Then where-ever you want to wait for that api response just do:
cy.wait('#myApi');
The same can also be acheived without the first cypress command manageMyApiRequests but I suggest you use this for better organization of your tests and then later you can also add more apis to the same function.
FYI you can also use .then() it if you want to check something within the response:
cy.wait('#myApi').then((xhr) => {
// we can now access the low level xhr
// that contains the request body,
// response body, status, etc
});

How to distinguish between GET and POST

I'm writing a simple api for training using express. Here's my testing code:
var express = require('express');
var app = express();
app.post("/api/:var_name", function(req, res) {
res.send(req.params.var_name);
});
is simply testing to see if POST is working. When I call http://localhost:3000/api/1 I get Cannot GET /api/1, so the server is obviously interpreting the POST request as GET, what do I need to do to call POST instead?
Anything you call in the address bar of your browser will be sent via get. This is due to the fact that post-messages (and almost all other methods) do have a body-part. But there is no way for your browser to send additional information inside the body of the http packet.
If you want to test your routes for any method other than GET I would suggest you download a tool like postman.
https://www.getpostman.com/
BEWARE: This is my preference. You can of curse also use text based browsers like curl to test it.
The server interprets the request according to the verb you set in the HTTP request. If no method/verb is specified it is interpreted as GET(not sure about this part).
When you call that URL, you need to use the method as well. For example if you use the fetch API, you can call it like:
fetch(url, {method:"POST"})
If you're entering it in your browser and expect it to be interpreted as a post request, it's not. All browser url requests are GET. Use a tool like Postman to call different HTTP verbs. It's really useful when creating such APIs.
You can check out this answer on details of how to add body and headers to a post request: Fetch: POST json data