Cypress intercept() fails when the network call has parameters with '/' - cypress

I need to add cy.wait() for some network call which has parameters having forward slashes in it.
eg: http://example.com/myPage1?id=598dccc6&startDate=10/01/2023&endDate=11/01/2023
For this, I've added the following intercept,
cy.intercept('http://example.com/myPage1**').as('myPage1');
However, cy.wait('#myPage1').its('response.statusCode').should('eq',200); is getting timed out and the test case fails.
What should I do?
Thanks.
Reply to #agoff
Somehow this doesn't work. My baseUrl is like http://192.168.43.82/font-end/#/ and api calls are made to http://192.168.43.82/rest/api/myPage with query parameters.
I've tried
cy.intercept(
{
pathname:'/rest/api/myPage',
method:'POST'
}).as('myPage');
what's wrong with this?

It's possible to catch it with a regex expression for the URL.
You don't need to specify the base part http://example.com.
Chars / and ? are operators in regex, so preceed them with \ to indicate the literal character.
cy.intercept(/\/myPage1\?/).as('myPage1')
Alternatively,
cy.intercept({pathname: '**/myPage1'}, {}).as('myPage1')
Tested with baseUrl:
const { defineConfig } = require("cypress");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
baseUrl: 'http://192.168.43.82/font-end/#/'
},
});
and the app fetching
fetch('http://192.168.43.82/rest/api/myPage1?id=598dccc6&startDate=10/01/2023&endDate=11/01/2023')

Related

cy.visit() doesn't work for pages of my baseUrl domain

I want my test to visit any other pages of my website by giving it a direct link ( = Cypress.config().baseUrl + '/explore/search/models')
cy.url().then((url) => {
cy.visit('/explore/search/models');
});
It doesn't work for me. It gives 404 Not found error although any other website inside the current tests opens without any problems. What am I doing wrong?
visit() command is automatically prefixed with baseUrl, if you've configured.
cypress.config.js:-
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost:3000/#/',
},
})
then,
cy.visit('dashboard') //Visits http://localhost:3000/#/dashboard
Refer: https://docs.cypress.io/api/commands/visit#Prefixes
Why the cy.url call? Just use cy.visit. Also, delete the slash at the beginning of your url.
This is not the Cypress issue. The problem was on the side of my application. So the code is correct, of course without slash.

How do I log a specific field in API requests within Cypress

I want to cypress.log() out a specific field in the request header whenever my webapp makes requests that way when it fails and adds screenshots/logs I can grab that that requestId that failed.
Is there a way to setup cypress so that for all network requests it checks for this field and log it?
I can add a cy.intercept within each individual file but I want a more generic way to handle this.
Cypress.log is the synchronous version of cy.log().
Add middleware: true to the intercept to pass request to other intercepts.
cy.intercept({ url: '*', middleware: true }, (req) => {
const headerValue = req.headers?['x-custom-headers']
if (headerValue) {
Cypress.log({
name: 'x-custom-header',
message: headerValue
})
}
})
You'll get an Cypress promise error if you try to use cy.log() to log out every request header in an cy.intercept() within a routeHandler callback. This would also make it kind of tough to log to a CI terminal as well.
Instead you can console.log to dev tools. To make it apply to all tests, you can wrap it in a beforeEach() and place it in the support/index.js file.
// support/index.js
beforeEach(() => {
cy.intercept('*', (req) => {
req.continue((res) => {
console.log(JSON.stringify(req.headers))
})
})
})

Svelte Proxy with rollup?

I'm trying to proxy requests from a Svelte app to a different port, where my backend API runs. I want to use a rollup proxy in the dev environment.
I read the alternative of using a webpack proxy here, but I want to give rollup proxy a try.
This is not an issue in production.
As suggested, I tried configuring rollup-plugin-dev However, whenever I make a request to weatherforecast I still get an CORS error. Below is my configuration and the call:
import dev from 'rollup-plugin-dev'
// other code
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/bundle.js'
},
plugins: [
dev({
proxy: [{ from: '/weatherforecast', to: 'https://localhost:7262' }]
}),
// other code
];
and App.svelte looks like this:
<script>
import { onMount } from "svelte";
const endpoint = "/weatherforecast";
onMount(async function () {
try {
const response = await fetch(endpoint);
const data = await response.json();
console.log(data);
} catch (error) {
console.log(error);
}
});
</script>
Any help in solving this issue is appreciated.
What's happening is the proxy is passing through the CORS headers un-touched, so you're basically interacting with the API as though the proxy wasn't even there, with respect to CORS.
I'll note that you can get around this in dev, but keep in mind this problem will come up in production too, so you may just need to rethink how you're getting this data.
For development though, you can use something like cors-anywhere. This is a middleware that you can run through your dev server that can rewrite the headers for you.
To configure rollup-proxy on dev environment, you need to remove the call to the serve method, call the dev method and move the proxy calls inside the dev method:
import dev from 'rollup-plugin-dev'
// other code
export default {
input: 'src/main.js',
output: {
// other code
commonjs(),
// enable the rollup-plugin-dev proxy
// call `npm run start` to start the server
// still supports hot reloading
!production && dev({
dirs: ['public'],
spa: 'public/index.html',
port: 5000,
proxy: [
{ from: '/weatherforecast', to: 'https://localhost:7262/weatherforecast' },
],
}),
// line below is no longer required
// !production && serve(),
// other code
];

Nuxt Axios Dynamic url

I manage to learn nuxt by using following tutorial
https://scotch.io/tutorials/implementing-authentication-in-nuxtjs-app
In the tutorial, it show that
axios: {
baseURL: 'http://127.0.0.1:3000/api'
},
it is point to localhost, it is not a problem for my development,
but when come to deployment, how do I change the URL based on the browser URL,
if the system use in LAN, it will be 192.168.8.1:3000/api
if the system use at outside, it will be example.com:3000/api
On the other hand, Currently i using adonuxt (adonis + nuxt), both listen on same port (3000).
In future, I might separate it to server(3333) and client(3000)
Therefore the api links will be
localhost:3333/api
192.168.8.1:3333/api
example.com:3333/api
How do I achieve dynamic api url based on browser and switch port?
You don't need baseURL in nuxt.config.js.
Create a plugins/axios.js file first (Look here) and write like this.
export default function({ $axios }) {
if (process.client) {
const protocol = window.location.protocol
const hostname = window.location.hostname
const port = 8000
const url = `${protocol}//${hostname}:${port}`
$axios.defaults.baseURL = url
}
A late contribution, but this question and answers were helpful for getting to this more concise approach. I've tested it for localhost and deploying to a branch url at Netlify. Tested only with Windows Chrome.
In client mode, windows.location.origin contains what we need for the baseURL.
# /plugins/axios-host.js
export default function ({$axios}) {
if (process.client) {
$axios.defaults.baseURL = window.location.origin
}
}
Add the plugin to nuxt.config.js.
# /nuxt.config.js
...
plugins: [
...,
"~/plugins/axios-host.js",
],
...
This question is a year and a half old now, but I wanted to answer the second part for anyone that would find it helpful, which is doing it on the server-side.
I stored a reference to the server URL that I wanted to call as a Cookie so that the server can determine which URL to use as well. I use cookie-universal-nuxt and just do something simple like $cookies.set('api-server', 'some-server') and then pull the cookie value with $cookies.get('api-server') .. map that cookie value to a URL then you can do something like this using an Axios interceptor:
// plguins/axios.js
const axiosPlugin = ({ store, app: { $axios, $cookies } }) => {
$axios.onRequest ((config) => {
const server = $cookies.get('api-server')
if (server && server === 'some-server') {
config.baseURL = 'https://some-server.com'
}
return config
})
}
Of course you could also store the URL in the cookie itself, but it's probably best to have a whitelist of allowed URLs.
Don't forget to enable the plugin as well.
// nuxt.config.js
plugins: [
'~/plugins/axios',
This covers both the client-side and server-side since the cookie is "universal"

Zapier CLI how to use trigger_fields

How do I replace the path param template in the url of a trigger ?
This is my current code, but I get an error saying that the
"The client {{client_id}} doesn't exist."
I take it that the {{client_id}} template is not being replaced, here's my code:
const listEvents = (z, bundle) => {
console.log('listing events.. ');
const requestOpts = {
url: 'https://wccqa.on24.com/wcc/api/v2/client/{{client_id}}/event',
params: {
client_id: bundle.inputData.client_id
}
};
var eventResults = z.request(requestOpts)
.then((response) => z.JSON.parse(response.content));
z.console.log(eventResults);
return eventResults;
};
module.exports = {
//config ...
}
Does the params: {client_id: bundle.inputData.client_id} not replace this template ?
Also, sometimes I get the following error when running zapier test:
1) GetEvents trigger testing should load latest Event created:
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
David here, from the Zapier Platform team.
You're correct, as written the curlies aren't being replaced. They're only replaced when you use the shorthand notation, which might work for you here.
Otherwise, you can use regular requests.
The easiest thing is to build your url with template strings:
const url = `https://wccqa.on24.com/wcc/api/v2/client/${bundle.inputData.client_id}/event`
Everything else looks like it'll work as you intend.

Resources