What is the best way to made multiple sync ajax request - ajax

I convert xlsx to json and send the lines to backend trought ajax request.
The excel has 5k rows, I performed the requests using concatMap. There is another way to do this ? I readed the browsers has a maximium the 6~12 connections per host name.
When I tested this solution, it performed all requests in 6 minutes using 10 requests per time.
The browser really had 6 max connection per host ?
Anybody already made the same solution ?
--
Above there is a example of my solution
let ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let arrIds = this.chunkArray(ids, 3);
for(let i = 0; i < arrIds.length; i++) {
this.getSomethingFromAnAPI(arrIds[i]).subscribe(response => {
console.log(response.name)
this.data.push({
body: response.name,
title: response.name,
id: response.id
});
}, error => {
console.error(error);
});
}
//Send line to api
public getSomethingFromAnAPI(ids: number[]): any {
return from(ids).pipe(
concatMap(id => <Observable<any>> this.http.post('SEND_LINE_API'))
);
}

Related

How to make cypress wait for a response that depends on another response?

From response A (/list.json) my app receives a list of items. Based on the output of A, my app makes another set of requests B for individual items (/one.txt, /two.txt, ...).
Now in my test I want to make sure that all responses B return HTTP 200.
Waiting (cy.wait) for response A is fine. However, waiting for responses B is more difficult, because I have to start waiting just upon receiving response A where I learn about responses B.
I tried 2 options:
start waiting inside of cy.wait of response A - code,
start waiting outside of cy.wait of response A - code
Neither of those work. With option 1 I get
`cy.wait()` timed out waiting `5000ms` for the 1st request to the route: `one.txt`. No request ever occurred
And with option 2 I get a pass, even though /two.txt doesn't exist. Looks like cy.wait for responses B is added after the responses were received
Since all requests are triggered off the visit, and are dynamic, you need a single intercept that handles all requests.
To me that means adding some javascript and dynamic aliases.
// avoid status code 304, disable browser cache
Cypress.automation('remote:debugger:protocol', {
command: 'Network.clearBrowserCache'
})
describe('spec', () => {
it('test', () => {
let items = [];
cy.intercept('GET', '*', (req) => {
const slug = req.url.substring(req.url.lastIndexOf('/') + 1)
if (slug === 'list.json') {
req.alias = 'list'
}
if (items.includes(slug)) {
req.alias = 'item'
}
req.continue((res) => {
if (slug === 'list.json')) {
items = res.body;
}
})
})
cy.visit('https://demo-cypress.netlify.app');
cy.wait('#list') // wait for list
.then(() => { // now items is populated
for (let item of items) { // really just need the count
cy.wait('#item').then(interception => { // wait n-times
expect(interception.response.statusCode).to.eq(200);
})
}
})
})
})

How would you grab old responses in cypress?

I have been trying to grab an old response to assert it has a certain response.
The issue is that the same call is posted at the same time and I can only grab the second response.
I was just wondering if there was a way to grab both responses so I can read each body to make sure the correct posts are made
I have used the following
public assertMixPanelCall(call: string): void {
cy.intercept('POST', 'https://api-js.mixpanel.com/track/*', (req) => {
if (atob(req.body.replace('data=', '')).includes(`"event": "${call}"`)) {
req.alias = 'correctBody'
}
});
cy.wait('#correctBody');
}
So the response I get is the last response,
But I want to grab the penultimate response
I'm not seeing the complete picture, but I think you can use this pattern Intercepting a response
let responseCount = 0;
cy.intercept('POST', 'https://api-js.mixpanel.com/track/*', (req) => {
if (atob(req.body.replace('data=', '')).includes(`"event": "${call}"`)) {
req.continue((res) => {
responseCount++;
if (responseCount === 1) {
req.alias = 'penultimate'
}
if (responseCount === 2) {
req.alias = 'final'
}
})
}
});
cy.wait('#penultimate')
Not sure if dynamic aliasing works on a per-response basis.
There's also an undocumented alias suffix that lets you access the nth response
cy.wait('#correctBody'); // must wait first
cy.get('#correctBody.1'); // then get to access response history
// - not sure if you need #correctBody.0 or #correctBody.1
But I can't see why cy.wait('#correctBody') doesn't catch the first response, generally you need to issue the wait twice to get both responses. Anyway, there's some things to try out here.
So I found the solution
From wherever I want to start capturing
cy.intercept('POST', 'https://api-js.mixpanel.com/track/*').as('call');
generate array based on the number of calls previously I wish to check
const genArr = Array.from({length:noOfCalls},(v,k)=>k+1);
const calls = [];
cy.wrap(genArr).each(() => {
calls.push(`#${call}`)
})
make the call based on the amount of times I wish to post the response
cy.wait(calls).then(differentRequests => {
differentRequests.forEach(differentRequest => {
if(atob(differentRequest.request.body.replace('data=','')).includes(call)) {
pass = true
}
});
expect(pass).to.be.true
});
}
Got the solution from here
https://medium.com/slido-dev-blog/cypress-io-is-pretty-amazing-and-if-you-havent-used-it-yet-and-need-a-jump-start-i-recommend-my-66ee6ac5f8d9

How create step lad in k6 for websocket

I try to generate step load for performance test on k6 for websocket.
regular settings like
export let options = {
stages: [
{
"duration": "0m30s",
"target": 10
},
{
"duration": "0m30s",
"target": 10
},
{
"duration": "0m30s",
"target": 0
}
],
};
doesn't work for k6. I tried --vus 10 --i 10
but it just go through scenario 10 times and sleep till the end of 10 minutes.
Than I tried k6 run --vus 5 --stage 3m:10,5m:10,10m:35,1m30s:0 but result is almost the same. How create active load with step pattern for websocket testing? to connect every time after flow is done?
Test flow:
import ws from "k6/ws";
import { check } from "k6";
export default function() {
const url = "ws://URL:8000/";
const params = { tags: { my_tag: "hello" } };
const response = ws.connect(url, params, function(socket) {
socket.on("open", function open() {
console.log("connected");
socket.send(Date.now());
var url = "ws://URL:8000/";
var response = ws.connect(url, null, function(socket) {
socket.on('open', function() {
socket.send('Hello');
socket.send('How are you?');
});
socket.on("close", () => console.log("disconnected"));
socket.on("error", (e) => {
if (e.error() != "websocket: close sent") {
console.log("An unexpected error occured: ", e.error());
}
});
check(response, { "status is 101": r => r && r.status === 101 });
})
})
})
}
As mentioned in the documentation ws.connect blocks until the connection is closed either by calling socket.close() or the server closing the connection on the other end (or due to an error while doing something else).
So if you want to just send the 2 messages there you should call socket.close(). You can also close after receiving something on the other side using by using
socket.on("message", function(msg) {
console.log("got: "+ msg);
socket.close();
}
But if you don't need to reconnect but instead want to just send more messages you should probably use a timer:
socket.setInterval(function() {
socket.send('Hello');
socket.send('How are you?');
}, 1500);
will send messages each 1.5s
I don't know why you open another websocket connection inside the other, but that might be a mistake on your part and is likely going to make the code hard to read if you don't use a different variable name from socket
I wasted lots of time trying it with the K6 but it seems not supported till today, k6 does not support socket.io testing, check the links attached.
https://github.com/grafana/k6/issues/667
You can go for artillery, as suggested in the official socket.io docs
https://socket.io/docs/v4/load-testing/

How to send requests to server one after one RxJS?

How to correctly send RxJS requests, when there are 4 different API endpoints, I need to request each endpoint until previous does not return data.
Schema is:
Request 1 -> Return Void
Request 2 -> Returned data, stop working and return data
Request 3 -> Will fail
Result is:
Only one result from one of request.
I tried this:
req1$ = of(response);
req2$ = of(response);
req1$.pipe( flatMap((result) => {
if (result) { return of(result); } else {return of([]);}
}));
I think you need to do a manual chain, something like:
const getValueFromServer$ = req1$.pipe(flatMap => result ? of(result) : firstFallback$);
const firstFallback$ = req2$.pipe(flatMap => result ? of(result) : secondFallback$)
const secondFallback$ = req3$.pipe(flatMap => result ? of(result) : req4$)
getValueFromServer$.subscribe(console.log)

How to use Web worker with AJAX

Is there is any way to call ajax function in web worker.Actually i am directly using ajax function to get the response but data is too much heavy,due to that my window is going to be freeze until the response will come.To overcome this problem now i am using web worker.The data(JSON) is dynamic.So can you please tell me how to call ajax function so that i can use it in my application.Here i am attaching web-worker code.
//Worker.js File
var myCallback = function(data){
self.postMessage(JSON.stringify(data));
};
self.addEventListener('message', function(e) {
importScripts('json.js?callback=myCallback');
}, false);
//JOSN.js File
function getResult(){
var randomNum = (Math.floor(Math.random() * 5) + 1),
cacheBuster = (Math.floor(Math.random() * 10000) + 1);
$.ajax({url:'http://examples.kevinchisholm.com/utils/json/jsonp.php?callback=myCallback&cacheBuster=' + cacheBuster + '&sleep=' + randomNum,
type:'POST',cache:false,data:datas,dataType:"json",async:false,
success:function(xmlResponse){
return xmlResponse;
}});
}
getResult();
Yes you can definitely use ajax in web worker by simply using XML Http Request or fetch API and can post the message using postmessage by using my code hope it helps:->
#Declaring Worker
var worker= new Worker("ajax123.js");
worker.onmessage=function(data){
document.body.innerHTML=data.data;
}
#Web Worker Code
fetch(filename)
.then(response => { return response.text(); })
.then(data => { self.postMessage(data) });

Resources