citrus icon indicating copy to clipboard operation
citrus copied to clipboard

Selectors for web-socket messages.

Open natasha4 opened this issue 6 years ago • 6 comments

Citrus version: 2.7.4

Hello! I am trying to understand is it possible to use selectors for web-sockets or not. And if it is not is it any way to filter received messages.

I have the following test case. In the same socket the client can send messages and get responses on them and the same time it can get broadcasting messages. Test case contains the following steps:

  1. Open socket
  2. send message
  3. get response for message 2
  4. get broadcast message

But I can not predict the behaviour and I can get broadcast message before I get response in step 3. So on step 3 I have error that I expect one message and get the another. I thought that maybe selector functionality can help me here, but seems it does not work with websockets. I would appreciate any help.

Thank you!

natasha4 avatar Mar 03 '19 23:03 natasha4

Hi!

The WebSocketConsumer does not support message selectors currently. This would be something to add to the framework.

I assume you want to filter based on the payload?

BR, Sven

svettwer avatar Mar 07 '19 11:03 svettwer

Hi @natasha4!

Is this feature still required for you? If yes: Could you please specify your feature request concerning web socket selectors? Do you want to select based on the payload?

Thx and BR, Sven

svettwer avatar Mar 19 '19 11:03 svettwer

Hi @svettwer !

I apologise for long response. Yeah, I was thinking about filtering based on payload. For example, if my response payload is json

{
"type":"okResponse",
....
}

I could use selector like:

runner.receive(action -> action.selector("$.type", "okResponse"))

But honestly I am not sure that selectors really help in situation which I have. In my situation I send request and then I can get two responses. And I don't know an order of this responses. For example, one response is {"type":"okResponse"} and another one is {"type":"broadcast"} Then my code will be:

runner.send(action -> action.payload("{my request}"));
runner.receive(action -> action.selector("$.type", "okResponse").validate(...));
runner.receive(action -> action.selector("$.type", "broadcast").validate(...));

So if I understand selectors correctly. even if they will work for websockets, in case if broadcast come first the first receive command will ignore it and wait for okResponse and then second receive will never get its response. Am I correct?

natasha4 avatar Mar 21 '19 05:03 natasha4

Hi @natasha4!

Thx for the specification! :+1: I'll convert this to a enhancement request. I can't give you a date when the implementation will be done, but I think this is a useful extension which is easy to achieve.

In my situation I send request and then I can get two responses. And I don't know an order of this responses.

This is the ideal use case for message selectors. If a message is received using a selector, all other messages stored in the channel stay untouched. Only the matching message is removed from the message channel.

E.g.

Message Channel
   |1: header->foo
   |2. header->bar
   |3. header->foobar

action.selector("header", "bar"));

Message Channel
   |1: header->foo
   |2. header->bar (match!)
   |3. header->foobar

get message from channel

Message Channel
   |1: header->foo
   |2. header->foobar

So if the broadcast message arrives first, it will be ignored in the first place. As soon the okResponse arrives, the first receive action using the selector will find it. After that, the broadcast message will be evaluated directly, because it is already waiting in the channel.

BR, Sven

svettwer avatar Mar 21 '19 07:03 svettwer

Hi,

I'm currently evaluating Citrus for our automated testing and I believe we would also need selectors with the WebSocket client. In our case, we are subscribing to multiple RabbitMQ topics with STOMP and we can't predict in which order we will receive messages from those topics over the same WebSocket.

Other than selectors, is there another way we could validate messages arriving in unpredictable order?

Best regards, Erik

erikfournier avatar Aug 03 '21 03:08 erikfournier

Hi, any update on this ? I've just found this issue, after spending quite some time wondering why my tests are not working as expected :) I have JSON (and non-json) messages circulating over a web-socket chanel and in my test I just need to validate the ones which are JSON (ignoring the others). I wanted to use selectors (either with jsonPath or ... simply assuring that my payload @startsWith({)@ or something like that. But it didn't work. We're using citrus v. 2.8 . Thanks

wbuczak avatar Sep 02 '21 09:09 wbuczak