faking xmlhttprequests with casperjs [closed] - javascript

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm writing end-to-end tests with casperjs and would like to fake ajax server responses
I've came up with the idea of including a simple script that mocks the xmlhttprequest object and would always return my expected results, like the following
var ajax_requests = [
['GET', '/jobs', JSON.stringify(jobs)]
], stubs = stubs || {};
function setup_ajax(){
stubs.server = sinon.fakeServer.create();
_.each(ajax_requests, function(r){
//r[1] = "http://localhost:8000" + r[1]
r[2] = [200, { "Content-Type": "application/json" }, r[2]]
stubs.server.respondWith.apply(stubs.server, r)
})
stubs.server.autoRespond = true;
stubs.server.autoRespondAfter = 2;
}
Then I call setup_ajax in my casper test like
casper.then(function(){
this.evaluate(setup_ajax)
}
but seemingly future ajax requests still avoid my xmlhttprequest implementation.
I've tried running setup_ajax on the fly, using $.ready() and having it called from casper too, but neither of these worked
More interestingly, checking for objects' existence strangely fails.
function setup_ajax(){
return typeof(sinon)
}
casper.then(function(){
var x = this.evaluate(setup_ajax)
casper.log(x) // logs 'null'
}
But sinon is properly included, at least casper did not cause any errors when I've made some calls to it outside the setup_ajax function, but caused error when I deliberately had sinon excluded.
Do you have any ideas on mocking xmlhttprequests under casperjs?

You can use sinon.js to fake XmlHttpRequest.

PhantomXHR wraps the XHR mocking of SinonJS for casperjs.
First you need to initialize PhantomXHR:
var xhr = require('phantomxhr');
casper.on('page.initialized', function () {
xhr.init(casper.page, {
libraryRoot: '/path/to/node_modules/phantomxhr/'
});
});
Than you can fake the XHR request:
var fake = xhr.fake({
url: '/jobs',
responseBody: jobs
});
Take care of waiting for the XHR request to finish before evaluating the page. You can check if the request completed by looking for
fake.count() === 1

Related

How to recreate Chrome Waterfall column (Network tab) that documents time required for different stages of network request for jQuery AJAX call?

This question is similar but not helpful.
To provide more feedback to users, we want to mimic the Waterfall column in the Network tab of Chrome, which deconstructs network requests into different stages and times them.
An example is included below.
In the particular, we want to indicate three stages:
Time uploading a file
Time processing a file on the server
Time download results
From the jQuery AJAX docs, it seems like beforeSend could be used to time file uploads. How about download time and time on server (TTFB in screenshot)?
Here's how we implement AJAX calls:
async function doRequest() {
// Set server URL.
let serverUrl = 'https://test.com/test';
// Set form data
let imageFile = imageFile
// Create request form.
let formData = new FormData();
formData.append('imageFile', imageFile);
// Set request settings.
let settings = {
url: serverUrl,
method: 'POST',
timeout: 0,
contentType: false,
processData: false,
data: formData,
xhr: function() {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 2) {
if (xhr.status == 200) {
xhr.responseType = 'blob';
} else {
xhr.responseType = 'text';
}
}
};
return xhr;
},
};
// Make request.
try {
let result = await $.ajax(settings);
// Handle success
} catch (error) {
// Handle failure
}
}
Resource Loading and Timing
As usual, someone had the same idea and has provided a pre-coded solution. I discovered these resources in an attempt to help you with this very complicated task. You can use the code as written or place it into a bookmarklet.
I found a detailed article that describes how to use both the Navigation Timing API & the Resource Timing API The article I came across is titled (and found at):
Assessing Loading Performance in Real Life with Navigation and Resource Timing
The two prebuilt solutions provided by that article take completely different approaches to visualizing the data you seek.
To use them without any effort, create a book mark for each of the following URLs:
More Detailed Analysis <-- copy this link to your bookmarks collection
Performance Waterfall <-- copy this link to your bookmarks collection
As mentioned, these are bookmarklets. They contain JavaScript code that can be executed directly on the page you have loaded. To use them,
Load the page in Chrome that you want performance data
Open you bookmarks and click on one of the two bookmarklets provided here
The result will be the waterfall or other detailed data you are seeking.
Note: The script can be blocked by content-security-policy and may not
work on all sites.
Source Code
The waterfall chart like you originally asked about can be found at the following link. Note I am hosting this file for your answer. I can't guarantee it will be available forever. Please download and host the file. (Open License)
Waterfall by Andy Davies
The more detailed version is found here: (MIT License)
Performance-Bookmarklet by Michael Mrowetz.
File Upload
You'll see the Resource Timing API provides this data. If you prefer to use the XHR API the a simple way to measure file upload time is by using xhr.upload object which takes an event listener for progress. As pointed out, this isn't necessary given the previous tools.
xhr.upload.addEventListener("progress", function(evt){
// Initialize and finalize a timer here
if (evt.lengthComputable) {
console.log(evt.loaded + "/" + evt.total);
}
}, false);
Server Processing Time
In order to achieve the goal of measuring performance of the server and reporting it back to the client, the server must be involved in order to share its internal processing timing that you seek in your question. There is no way to determine that from the browser alone.
I recommend the use of the Server-Timing feature with details about its use in the PerformanceServerTiming API
It is fairly simple to use this API. As the example shows (using a NodeJS server), all your server has to do is respond with a specific HTTP header that contains the performance data you would like to display in the browser:
const headers = {
'Server-Timing': `
cache;desc="Cache Read";dur=23.2,
db;dur=53,
app;dur=47.2
`.replace(/\n/g, '')
};
Using the information on the client is as simple as this (from the MDN link page):
let entries = performance.getEntriesByType('resource');
console.log(entries[0].serverTiming);
// 0: PerformanceServerTiming {name: "cache", duration: 23.2, description: "Cache Read"}
// 1: PerformanceServerTiming {name: "db", duration: 53, description: ""}
// 2: PerformanceServerTiming {name: "app", duration: 47.2, description: ""}
For monitoring the upload state, I think you need XMLHttpRequestUpload and request.upload.addEventListener("progress", updateProgress) or request.onprogress and onloadend to check the loadend event. See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/upload.
I don't see there is a partucular HTTP state to determine the start of a response from a server. Check https://developer.mozilla.org/en-US/docs/Web/HTTP/Status. So from the HTTP API level (XMLHttpRequest) I dont think you can find a clue of that. But the browser should be able to know from TCP level. If checking devtools is not your preference, you may need to specify the timestamp in the response. Once the client gets the response, the client knows the start time of the response.
The client can easily get the time that it receives the response from the server.
So
Dur_uploading = Time_loadend - Time_requeststarts
Dur_serverprocessing = Time_responsespecified - Time_loadend
Dur_download = Time_responsereceived - Time_resonsespecified

On one click open 2 pages but not simultaneously [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
ok I want a help with a code, when user click the "download", it should go to the first link but if link 1 is down, it should go to 2nd link ........link 1 should be a default, it should only send the visitor to 2nd link if 1st link dead or down
please tell me if this kind of thing is possible, or just my imagination
and it will be great if the 2nd link is hidden which can't found out by simple inspect tool,if not possible just forget the last line
You can make a call and check the return status with AJAX. Then based on the status code such as 200,404, you can decide what you want to do. This can be done easier with jQuery.ajax() method if you use jQuery.
One of the approach would be to check the URL and recieve the status with AJAX. Based on the returned status code (example 404), you decide what to do next:
with jQuery
$.ajax({
type: 'HEAD',
url: 'http://yoursite.com/pagename.php',
success: function() {
// NO 404 ERROR
},
error: function() {
// error in HEAD (404)
}
});
with Pure Javascript:
function checkUrl(url) {
var request = false;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest;
} else if (window.ActiveXObject) {
request = new ActiveXObject("Microsoft.XMLHttp");
}
if (request) {
request.open("GET", url);
if (request.status == 200) { return true; }
}
return false;

Async call not working in vanilla javascript [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
The following code is my frontend code for a http long poll. In this I am expecting the code setTimeout(getChat, 0) to call the method asynchronously. But when the getChat method's XHR is pending all following XHRs of different methods are also getting into pending state.
discussTask = function(taskId) {
taskIdChat = taskId
getChat() // initial call
}
var getChat = function() {
taskId = taskIdChat
payLoad = {
'task_id': taskIdChat,
'recent_message_id': recentMessageId
}
var xmlhttp = XHR('/chat/sync', 'POST', payLoad)
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === 4) {
buildChat(JSON.parse(xmlhttp.responseText))
setTimeout(getChat, 0) // Async recursive call
}
}
}
var XHR = function(action, method, payLoad) {
var xmlhttp = new XMLHttpRequest()
xmlhttp.open(method, action, true)
xmlhttp.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')
xmlhttp.send(JSON.stringify(payLoad))
return xmlhttp
}
Found the issue. The Problem was not client side. I am using flask framework which by default will run in single threaded mode. So it was not serving the async requests from client side.

Bitly API - how to shorten a link with pure javascript, no libraries available (not even jquery)

Below is working code to use jquery+javascript with Bitly's API to shorten a link (when you have a Bitly account with a login and API key).
My question is, how can I produce the exact same result using only pure javascript with no other libraries available?
Thank you very much to anybody who can help me out.
EDIT:
This question does not already have an answer (the recommended answer is not relevant at all) due to how specific this is. Also, no references to DOM are possible as this is for server-side code. Therefore every single answer in the suggested duplicate question will not work. Please do not mark this as duplicate.
I believe the way to do this is with an xmlhttprequest, but I have absolutely no idea how...
Thanks again.
var login = "LOGIN_HERE";
var api_key = "API_KEY_HERE";
var long_url = "http://www.kozlenko.info";
$.getJSON(
"http://api.bitly.com/v3/shorten?callback=?",
{
"format": "json",
"apiKey": api_key,
"login": login,
"longUrl": long_url
},
function(response)
{
alert('Shortened link is: ' + response.data.url);
}
);
Javascript libraries use the XMLHttpRequest object to make ajax calls. You could make the calls using this object. I quickly googled one up:
var xmlhttp = new XMLHttpRequest();
var url = "buildTheURLHere.com";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var jsonObj = JSON.parse(xmlhttp.responseText);
alert('Shortened link is: ' + jsonObj.url);
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
Sources:
http://www.w3schools.com/json/json_http.asp
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
But are you actually talking about node.js? You mention something about server-side code in your post. If so, http.request would be your best bet.
Nodejs:
http://nodejs.org/api/http.html#http_http_request_options_callback
How to make external HTTP requests with Node.js

Consecutive Ajax requests without jQuery/ JS library

I have an issue, mainly with IE.
I need to be able to handle n queries one after another. But If I simply call my function below in a for loop IE does some strange things (like loading only so many of the calls).
If I use an alert box it proves that the function gets all of the calls, and surprisingly IT WORKS!
My guess is that IE needs more time than other browsers, and the alert box does just that.
Here is my code:
var Ajax = function(all) {
this.xhr = new XMLHTTPREQUEST(); // Function returns xhr object/ activeX
this.uri = function(queries) { // Takes an object and formats query string
var qs = "", i = 0, len = size(queries);
for (value in queries) {
qs += value + "=" + queries[value];
if (++i <= len) { qs += "&"; }
}
return qs;
};
xhr.onreadystatechange = function() { // called when content is ready
if (this.readyState === 4) {
if (this.status === 200) {
all.success(this.responseText, all.params);
}
this.abort();
}
};
this.post = function() { // POST
xhr.open("POST", all.where, true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send(uri(all.queries));
};
this.get = function() { // GET
xhr.open("GET", all.where + "?" + uri(all.queries), true);
xhr.send();
};
if (this instanceof Ajax) {
return this.Ajax;
} else {
return new Ajax(all);
}
};
This function works perfectly for a single request, but how can I get it to work when called so many times within a loop?
I think the problem might be related to the 2 concurrent connections limit that most web browsers implement.
It looks like the latency of your web service to respond is making your AJAX requests overlap, which in turn is exceeding the 2 concurrent connections limit.
You may want to check out these articles regarding this limitation:
The Dreaded 2 Connection Limit
The Two HTTP Connection Limit Issue
Circumventing browser connection limits for fun and profit
This limit is also suggested in the HTTP spec: section 8.14 last paragraph, which is probably the main reason why most browsers impose it.
To work around this problem, you may want to consider the option of relaunching your AJAX request ONLY after a successful response from the previous AJAX call. This will prevent the overlap from happening. Consider the following example:
function autoUpdate () {
var ajaxConnection = new Ext.data.Connection();
ajaxConnection.request({
method: 'GET',
url: '/web-service/',
success: function (response) {
// Add your logic here for a successful AJAX response.
// ...
// ...
// Relaunch the autoUpdate() function in 100ms. (Could be less or more)
setTimeout(autoUpdate, 100);
}
}
}
This example uses ExtJS, but you could very easily use just XMLHttpRequest.
Given that the limit to a single domain is 2 concurrent connections in most browsers, it doesn't confer any speed advantage launching more than 2 concurrent requests. Launch 2 requests, and dequeue and launch another each time one completes.
I'd suggest throttling your requests so you only have a few (4?) outstanding at any given time. You're probably seeing the result of multiple requests being queued and timing out before your code can handle them all. Just a gess though. We have an ajax library that has built-in throttling and queues the requests so we only have 4 outstanding at any one time and don't see any problems. We routinely q lots per page.
Your code looks like it's put together using the constructor pattern. Are you invoking it with the new operator like var foo = new Ajax(...) in your calling code? Or are you just calling it directly like var foo = Ajax(...) ?
If the latter, you're likely overwriting state on your later calls. It looks like it's designed to be called to create an object, on which the get/post methods are called. This could be your problem if you're "calling it within a loop" as you say.

Categories

Resources