This question already has answers here:
Dynamic scenario freezes when called using afterFeature hook
(2 answers)
Closed 1 year ago.
I want a common implementation to write the: request-body, request-method & response-body to an output file for all the HTTP requests that I make in any of the karate feature files.
I have read through the documentation, and the closest option that I found was the afterScenario hook. However this doesn't help me in cases where I want to make multiple API calls in the same scenario.
I also tried using karate.prevRequest object by passing it to java function that I wrote. While this helps me capture the information that I want, I have to keep calling my java function after every API call, which I don't want to do.
I want to be able to write a hook that gets called after every API call and gives me access to request-body, request-headers, response-headers, response-body, request-method and request URL.
This should be fairly straight forward, clearly I seem to be missing something here.
First, I personally think that this is a mis-use of Karate, and you seem to be more interested in reports than actually doing testing. Take some time to think about it. Karate has excellent report integration and you are just wasting your time doing this in my very honest, sincere opinion. No one has asked for this.
Anyway. There is a new ExecutionHook in 0.9.5.RC4, details here: https://github.com/intuit/karate/issues/970#issuecomment-557443551
You can implement afterStep, see if it is a method step and then do this. If you need changes, open an issue. Also see: https://stackoverflow.com/a/60944060/143475
EDIT: just remembered - in the develop branch we added a way to intercept all requests and responses: https://twitter.com/karatedsl/status/1195240779213496320 - will be happy to get your feedback and see if we can merge this concept with the above hook - or improve the interfaces if needed
EDIT: in many cases, the afterScenario may be sufficient, note that you can call any Karate feature, which means you can do HTTP requests: https://stackoverflow.com/a/51467470/143475
EDIT - the hooks API has changed for 1.0: https://github.com/intuit/karate/wiki/1.0-upgrade-guide
The ExecutionHook supports quite a lot different use cases.
Steps can be aborted or changed
Request and Response can be sniffed
See ExecutionHookExampleTest on how to use an ExecutionHook.
The API has changed. With karate version 1.1.0 (correct me, if I'm wrong)
It's now com.intuit.karate.RuntimeHook and you can use
com.intuit.karate.Runner.Builder#hook or
com.intuit.karate.Runner.Builder#hooks
method to add a hook to your karate test case execution.
Related
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 3 years ago.
Improve this question
I'm working on a big project with complex code that is not well written, it looks like spaghetti, with a lot of imbrications, functions calling each other with a lot of stack depth.
Please note that as of now, the project code is 100% synchronous (no promises, no API calls, no database, no IO - it's a very complex test project that relies on hardcoded scenarios).
The evolution I need to code:
In a very deep sub-function, I need to do a very simple API call (using fetch) to return a simple integer value to the parent function, instead of an hardcoded value.
The problem I get:
Obviously, I need to change this function to async and I need to await for the result.
But now, in the functions calling it, I need to await for the result, which means I need to set those parent functions to async as well, but then their parents need to await and to become async... All the way to the top, which, in this project, I estimate to around 100 functions to update.
Is there a way to do this that wouldn't require refactoring so much occurences?
Is there a way to do this that wouldn't require refactoring so much occurences?
Not a good one, no.¹ Once you've introduced asynchronousness, you have to allow for it right the way up the call chain. You can't convert an asynchronous process into a synchronous one.
If your app works in a loop as many apps do (well, at a low level all Node.js apps do in some sense, but you know what I mean), you might have one loop start the async process and store the result somewhere, then subsequent loops can check to see if it's there and, if it is, use it. But that depends on whether that will actually suit your situation.
Otherwise, you've tagged node.js, so the bad browser hack for this² doesn't apply. There appears to be an equivalent bad Node.js hack, though: Doing the request synchronously. I strongly recommend not doing that (at least not without really carefully thinking it through) since it will suspend the thread you do it on, bringing all other processing on that thread (I/O completions, etc.) to a halt until the request completes. It's a very bad idea. But it's there as a last resort or part of a migration strategy.
¹ Or at least, not a good one that avoids having to make a different change to all of those places (adding a callback they all pass around — even worse than making everything async).
² XMLHttpRequest's async: false option, which makes it synchronous, locking up the UI of the browser until the request completes. Not a good idea. :-)
I'm trying to find a way to cancel BreezeJS queries for the purpose of implementing a live search that queries BreezeJS on keypress (see my other question).
I know that in Angular, $http requests can be cancelled by passing a promise to the timeout parameter in the config object, and then calling resolve() on that promise.
I also know that I can get BreezeJS to use my module's $http insance with:
var ajax = breeze.config.initializeAdapterInstance('ajax', 'angular');
ajax.setHttp($http);
So I was thinking about possibly creating a request interceptor on $http that would set config.timeout to a promise. But that still leaves me quite a few steps away from solving the problem, because I would somehow need to be able to give the promise to my interceptor from the code running the query (so that the querying code could resolve() the promise if needed).
Is there a better way? Is it even possible?
Update 16 May 2014
You can set HTTP-level timeout and cancellation with the AJAX Adapter's requestInterceptor as of v.1.4.12. See the documentation, "Controlling AJAX calls".
Original answer
The EntityManager HTTP service operations don't offer cancel or timeout options. Maybe they will someday.
The v.1.4.11 Breeze AJAX adapters don't offer cancel or timeout options either. But they will in v.1.4.12 and you can see the preview on github right now.
The samples on github illustrate both cancel and timeout with the new adapters. For users of the jQuery AJAX component there is DocCode:jQueryAjaxAdapterTests.js. For users of Angular's $http there is the Zza-Node-Mongo:ajax-adapter.async.spec.js.
It's best if you can run the samples but if you can't (perhaps because you don't use one of the technologies involved), the test files (see links above) are easy to read and you should glean the ideas that will help. At least I hope so.
Usage
Cancel and timeout are useful features. Do you need them for your use case? Maybe. But you'd want to take a first step of de-bouncing the text that users enter into your "live search" so that you aren't firing off 100s of pointless queries.
That observation is discussed in your related StackOverflow question.
I'm a java developer. I really like to learn javascript. I'm finding it very difficult to pick-up a library and just learn/use it for two reasons:
1) There is no decent auto-complete. I've tried, eclipse, vjet, nodeclipse and webstorm...each has its own frustrating set of issues. Maybe the language is such that, autocomplete is super-difficult.
2) The API documentation is extremely confusing. I guess it is because I'm new to JavaScript.
For example, I wanted to figure what the callback function in mongoose.connect method does and how to declare it. So I checked the api doc. All it says is that the callback is a function...it doesn't say how many params it takes, what the values of the params are under various invocation scenarios...etc.
I feel like I'm missing something...
How does one go about reading these docs?
It's not you. I often find myself scratching my head about what the callback arguments should be. It's a problem with many JavaScript libraries.
However, in Node at least there is a convention that most libraries follow:
In node.js, it is considered standard practice to handle errors in asynchronous functions by returning them as the first argument to the current function's callback. If there is an error, the first parameter is passed an Error object with all the details. Otherwise, the first parameter is null.
For what it's worth, I haven't yet found an IDE that offers JavaScript autocomplete at anything nearly approaching the level of what's available for Java.
For the connect function, the callback passes an error argument given failure:
mongoose.connect('mongodb://localhost/dbname', function(err) {
if (err) {
// handle error
}
});
Generally, JavaScript tools are behind those for Java.
I feel like I'm missing something...
Me too. But, I think situation will change in 1-2 ears.
You can just wait for things to change or improve that you need by small step in a time.
Welcome to Nodeclipse.
It is time inefficient to solve problem only for one library (e.g. Mongoose),
but if there is web service like one for Node.js there is big chance for things change. Especially if you care enough to contribute, e.g. with ideas and materials or just raising an issue.
I feel like it should be obvious doing this from reading the documentation, but maybe somebody can save me some time. We are using Ruby's CookieStore, and we want to share the cookie with another server that is part of our website which is using WCF. We're already b64-decoding the cookie and we are able to validate the signature (by means of sharing the secret token), all of that is great... but of course the session object is marshalled as a Ruby object, and it's not clear what is the best way to proceed. We could probably have the WCF application make a call to Ruby and have it unmarshal the object and write it out as JSON, but that seems like it will add an unnecessary layer of complexity to the WCF server.
What I'd really like to do is maybe subclass CookieStore, so that instead of just b64 encoding the session object, it writes the object to JSON and then b64's it. (And does the reverse on the way back in, of course) That way, the session token is completely portable, I don't have to worry about Ruby version mismatches, etc. But I'm having trouble figuring out where to do that. I thought it would be obvious if I pulled up the source for cookie_store.rb, but it's not (at least not to me). Anybody want to point me in the right direction?
(Anticipating a related objection: Why the hell do we have two separate servers that need to be so intimately coordinated that they share the session cookie? The short answer: Deadlines.)
Update: So from reading the code, I found that when the MessageVerifier class gets initialized, it looks to see if there is an option for :serializer, and if not it uses Marshal by default. There is already a class called JSON that fulfills the same contract, so if I could just pass that in, I'd be golden.
Unfortunately, the initialize function for CookieStore very specifically only grabs the :digest option to pass along as the options to MessageVerifier. I don't see an easy way around this... If I could get it to just pass along that :serializer option to the verifier_for call, then achieving what I want would literally be as simple as adding :serializer => JSON to my session_store.rb.
Update 2: A co-worker found this, which appears to be exactly what I want. I haven't gotten it to work yet, though... getting a (bah-dump) stack overflow. Will update once again if I find anything worthy of note, but I think that link solves my problem.
I'm building a complex application in JavaScript which needs to make several requests to the server. Sometimes that request cannot be completed as sent, and addition information is needed. I would like the ability to have the server inform the application in the request's response that more information is needed and to describe how to retrieve that information.
For example, say a user tries to perform an operation that his current permissions level does not allow. The server needs to ask the application for an override authorization code, basically meaning the application needs to pop up with a dialog asking for an admin passcode.
I'd like to have some kind of framework that abstracts all this. Possible a main "Request" or "Operation" class, which I can define sub-Request classes that define possible interpretations of requests. I'm not sure if something like this exists already or not.
So I guess my questions are: 1) Does a framework like this exists? and 2) Are there any articles on this topic (platform and language agnostic, I can learn how they work from any source). I know frameworks like Dojo and ExtJS use something like it for their data stores, but I'm not sure if it's exactly what i'm needing, or how it even works for that matter.
Any help leading me in the right direction is appreciated, Thank You.
EDIT:
A point should be made I am looking for something that is abstract from the technology used to actually send that data to the server. That way I could utilize the same framework on different ajax technologies.
Basically I'm looking for a framework or article that can help me figure out how to create a custom "Application Protocol". An example of this would be:
{
type: 512,
success: true,
data: { some: "data" }
}
I know I have to design the protocol itself, but what I need help with is creating a "class" or something that interprets this protocol automatically instead of just making redundant onSuccess callbacks
I have worked on an open source project named Pomegranate Framework which does what you want (to some extent). Perhaps you can extend it in order to meet your needs. It comes with an application layer close to want you asked for but you need to implement your protocol as it fits. Here's its address:
Pomegranate Framework
I haven't found the time to document it yet but it comes with a bunch of examples that may be useful to you. You may also want to take a look at its example page:
Pomegranate Framework Examples
I think you would like to see the 021 example titled "Handling server errors in client". I hope it's what you are looking for.
Use Dojo and jQuery's Deferred object for callbacks. It is an implementation of the Promise design pattern. Every action has a success callback chain and a failure callback chain and both chains can diverge or merge at various points along the chains and chains can branch off to create sub-deferreds.
If you know the state of your application on the client (and there are only a few error causes and you do not need detailed information from the server), you can and should use HTTP status codes. As far as I know 200 is the only one with a body, so you can't (or shouldn't, there's always adding headers, but I'd stay clear of that path) transmit anything else - but every framework should provide you with the means to pass an error handler on sending a request. In the callback function you pass as an error handler, you just have to do whatever the respective status calls for.
It's supported by the protocol, independent of whether you pass HTML, JSON or anything else and error callbacks based on the status code are supported by every library worth using.
Since you're basically talking about "server-sided push events", you need some technique that allows your server script to send data to your clients.
There are some well knowns methods like COMET, Flash Sockets and the latest guy in town WebSockets around.
Since WebSockets is probably the most sophisticated stuff from all of these, you should aim for that. Unfortunately, its browser support is limited to the "latest version" for most browsers, if you're good with that, just use them right away. If you want some fallbacks for older browsers, the most used framework for that should be socket.IO.
But even socketIO only abstracts all the different communication techniques away for you. Anyway, it should be fairly easy to build a solid management framework around that by yourself. So my answer on that part is, I'm not aware of any library or framework which deals with that kind of stuff.
There are various ways to achieve this using ExtJs.
The most bare-bone one is to use Ext.Ajax.request() providing url, params, method. Then in your success handler, check for the server response and if it requires an additional data from the user - display an extra credentials dialog, and send another request with the extra credentials details that will unlock the server side script.
Notice that the success hander of the request method gives you back the config object of the request in its options parameter, so you can quite easily call the same request again, only adding the extra credentials this time around.
Here's a jsfiddle code demonstrating this concept (I've shown both using success and a global handler for all calls - I hope you'll be able to work out how to take it from here). And a similar one, which I believe is more what you're after exactly.
I'll be happy to help further, just ask the questions.
If abstraction and testability is what you want, I highly recommend AngularJS. angular $q which is an implementation of Kris Kowal's Q. You can create services that will hide away how you call the server and will allow you to change server implentations in future will little grief.
It will look like problem of server push i.e. wherever change occured data will be pushed to client There are following options
reverse AJAX by DWR Framework.
Ajax Push Engine http://www.ape-project.org/
Commercial
WebSync
You can use long polling mechanism like this
(
function poll(){
$.ajax({ url: "server", success: function(data){
myobject.setValue(data.value);
}, dataType: "json", complete: poll, timeout: 30000 });
})();
You will get more info at ajax push server