How is XHR a viable alternative to asynchronous module definition? - xmlhttprequest

I'm learning about the case for asynchronous module definition (AMD) from here but am not quite clear about the below:
It is tempting to use XMLHttpRequest (XHR) to load the scripts. If XHR
is used, then we can massage the text above -- we can do a regexp to
find require() calls, make sure we load those scripts, then use eval()
or script elements that have their body text set to the text of the
script loaded via XHR.
XHR is using ajax or something to make a call to grab a resource from the database, correct? What does the eval() or script elements have to do with this? An example would be very helpful

That part of RequireJS' documentation is explaining why using XHR rather than doing what RequireJS does is problematic.
XHR is using ajax or something to make a call to grab a resource from the database, correct?
XHR is what allows you to make an Ajax call. jQuery's $.ajax for instance creates an XHR instance for you and uses it to perform the query. How the server responds depends on how the server is designed. Most of the servers I've developed won't use a database to answer a request made to a URL that corresponds to a JavaScript file. The file is just read from the file system and sent back to the client.
What does the eval() or script elements have to do with this?
Once the request is over, what you have is a string that contains JavaScript. You've fetched the code of your module but presumably you also want to execute it. eval is one way to do it but it has the disadvantages mentioned in the documentation. Another way to do it would be to create a script element whose body is the code you've fetched, and then insert this script in the DOM but this also has issues, as explained in the documentation you refer to.

Related

API call inside a JavaScript function present in a feature file

I tried my best but could not find information on calling an API inside the Javascript function when dealing with automation in Karate. Now, I might get suggestions to call the API outside the function and then do operations inside the function. However, my use case is such that I have to call the API inside the function only. Is there a way to do this?
One approach is to create a Java file and then write the code in java. However, I specifically want to know if there is any way to call an API inside a JS function in a FEATURE FILE itself.
First, these kinds of "clever" tests are not recommended, please read this to understand why: https://stackoverflow.com/a/54126724/143475
If you still want to do this, read on.
First - most of the time, this kind of need can be achieved by doing a call to a second feature file:
* if (condition) karate.call('first.feature')
Finally, this is an experimental and un-documented feature in Karate, but there is a JS API to perform HTTP requests:
* eval
"""
var http = karate.http('https://httpbin.org');
http.path('anything');
var response = http.get().body;
karate.log('response:', response);
"""
It is a "fluent API" so you can do everything in one-line:
var body = karate.http('https://httpbin.org/get').get().body;
If you need details, read the source-code of the HttpRequestBuilder and Response classes in the Karate project.

In TestCafe Is possibile to register xhr and use as mocking (automocking)

I'm using testCafe for my functional test.
My project used a lot of XHR request and I don't want to waste my time to generate each single mock.
Exists an automocker like this: https://github.com/scottschafer/cypressautomocker for testcafe?
TestCafe does not provide the described functionality out of the box. However, you can use the combination of RequestLogger and RequestMock
The idea is in that you can create a JSON file with request results at the first run using the RequestLogger.
Then, based on results of the first run, you can configure your RequestMock object to respond with the results from the file for all consequent requests.

Accessing the built request details in Karate

Just like how the response information can be accessed through response, responseHeaders etc, is there any way to access the request information? I noticed that request information is not available through variables. Are there are any workarounds to access this information?
I understand that we build the request ourselves in the test scenario using the Given, When steps, so it may sound redundant. The reason I'm looking for this is I would like to access the complete request details Karate would've built using our test definition. The idea is to make this information available to a java class which can be called through the Java Interop. More specifically, I'm trying to build a swagger request and response validator to be used from karate.
The workaround I am using is to explicitly create variables like apipath and apimethod and use them with path and method. This does the job, but still one has to ensure that these variables are explicitly set. It will be cleaner if whatever request Karate built is just accessible through a variable.
Please raise a feature request. We can look at making this available as karate.request or similar.

Is it possible to determine the http request method (POST/GET) using a variable?

I am using a csv file as the basis for my requests. The thing is, I have some GET requests and some POST requests. Is there a way to use the same http request element for both request types where the method will be determined by the variable from the csv file?
This is really simple using Beanshell Preprocessor.
Add a Beanshell preprocessor for your existing HTTP request. Lets assume the default HTTP method is GET.
Now lets change it to POST whenever the csv variable 'method' is 'POST'
if(vars.get("method").equalsIgnoreCase("POST")){
sampler.setMethod("POST"); //this will change current sampler's http method from GET to POST.
}
The most direct solution for this would be to have two requests in the test plan, one a GET and one a POST. This does not quite satisfy your requirement to have it use the SAME request element, but it is probably the best solution.
Nest each of those inside their own IF controllers that reads a value from the CSV.
For example lets say the csv is the following:
http_method,host,path,params...
The first IF could be:
"${http_method}" == "GET"
Then the next:
"${http_method}" == "POST"
Each line from the CSV would only evaluate true to one of the statements, and then make the correct POST or GET call.
There are 2 options:
Use HTTP Raw Request available via JMeter Plugins
Write your custom logic in Java. See "How to Write a Custom AJAX Request Sampler" chapter of How to Load Test AJAX/XHR Enabled Sites With JMeter for idea on how this could be done.

dojo load js script and then execute it

I am trying to load a template with xhr and then append it to the page in some div.
the problem is that the page loads the script but doesn't execute it.
the only solution I got is to add some flags in the page (say: "Splitter"), before the splitter, I put the js code, and after the splitter I add the html code, and when getting the template by ajax, I split it. here is an example:
the data I request by ajax is:
//js code:
work_types = <?php echo $work_types; ?>; //json data
<!-- Splitter -->
html code:
<div id="work_types_container"></div>
so the callback returns 'data' which I simply split and exeute like this:
data = data.split("<!-- Splitter -->");
dojo.query("#some_div").append(data[1]); //html part
eval(data[0]); //js part
Although this works for me, but it doesn't seem so professional!
is there another way in dojo to make it work?
If you're using Dojo, it might be worth to look at the dojox/layout/ContentPane module (reference guide). It's quite similar to the dijit/layout/ContentPane variant but with one special extension, that it allows executing the JavaScript on that page (using eval()).
So if you don't want to do all that work by yourself, you could do something like:
<div data-dojo-type="dojox/layout/ContentPane" data-dojo-props="href: myXhrUrl, executeScripts: true"></div>
If you're concerned about it being a DojoX module (DojoX will disappear in Dojo 2.0), the module is labeled as maintained, so it has a higher chance of being integrated in dijit in later versions.
As an anwer to your eval() safety question (in comments). Well, it's allowed of course, else they wouldn't have such a function called eval(). But indeed, it's less secure, the reason for this is that the client in fact trusts the server and executes everything the server sends to the client.
Normally, there are no problems unless the server sends malicious content (this could be due to an issue on your server or man in the middle attacks) which will be executed and thus, causing an XSS vulnerability.
In the ideal world the server only sends data and the client interpretes this data and renders it by himself. In this design, the client only trusts data from the server, so no malicious logic can be executed (so there will be no XSS vulnerability).
It's unlikely that it will happen and the ideal world solution is not even possible in many cases since the initial page request (loading your webpage) is in fact a similar scenario where the client executes whatever the server sends.
Web application security is not about being 100% safe (it's impossible), but it's to try to create as less as possible open doors that can be used by hackers. It's up to you what you consider safe and to verify if the "ideal world" solution is possible in this specific scenario (it might not be, or it might take too much time compared to the other solution).