Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

To add support for websocket #395

Closed
4M01 opened this issue May 16, 2018 · 6 comments
Closed

To add support for websocket #395

4M01 opened this issue May 16, 2018 · 6 comments
Assignees

Comments

@4M01
Copy link

4M01 commented May 16, 2018

Karate supports HTTP protocol, it would be great if it can support Websocket.

@ptrthomas
Copy link
Member

closing due to inactivity

@ptrthomas
Copy link
Member

@4M01 and others - reopening this, and we've made some progress adding websocket helpers to the code. can you provide some examples of test scenarios / requirements

@ptrthomas ptrthomas reopened this Sep 16, 2018
@4M01
Copy link
Author

4M01 commented Sep 18, 2018

@ptrthomas I will try to provide some example for this by Sunday. Hope that is fine

@ptrthomas
Copy link
Member

ptrthomas commented Oct 30, 2018

commit message was not descriptive enough, so a few notes:

  • doc pending
  • not sure if websocket should be first-class keyword and if clients should be auto-closed at end of scenario
  • two new methods on karate JS API, listen() and signal()
  • the combination of JS and karate works very nicely for callbacks !

EDIT: for those looking for the current example (syntax will change slightly): https://github.com/intuit/karate/blob/cukexit/karate-demo/src/test/java/demo/websocket/websocket.feature

@ptrthomas ptrthomas added this to the 0.9.0 milestone Oct 31, 2018
@ptrthomas
Copy link
Member

ptrthomas commented Oct 31, 2018

I think the new "native" support for an "await" has turned out really well.
the CDC example which includes a JMS message listener has been revamped in prev commit.

Feature: payment service

Background:
* def QueueConsumer = Java.type('mock.contract.QueueConsumer')
* def queue = new QueueConsumer(queueName)
* def handler = function(msg){ karate.signal(msg) }
* eval queue.listen(handler)
* url paymentServiceUrl + '/payments'

Scenario: create, get, update, list and delete payments
    Given request { amount: 5.67, description: 'test one' }
    When method post
    Then status 200
    And match response == { id: '#number', amount: 5.67, description: 'test one' }
    And def id = response.id
    * json shipment = karate.listen(5000)
    * print '### received:', shipment
    * match shipment == { paymentId: '#(id)', status: 'shipped' }

and something I just found out is that function(o){ } gets converted to java.util.function.Consumer<Object> via the magic of Nashorn / JVM JS interop !

which leads us to the code behind the queue.listen(handler) that you see in the Background above:

    public void listen(java.util.function.Consumer<String> handler) {
        setMessageListener(message -> {
            TextMessage tm = (TextMessage) message;
            try {
                handler.accept(tm.getText());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }

and yes, instead of String you should be able to use more complex types as the function argument, and the usual rules of JS conversion (e.g. Map --> JSON) apply

the improved API is designed so the karate.listen(timeout) call will return the value passed to karate.signal(value) which makes things pretty elegant if I may say so

which gives us this beauty that can send as well as receive from a websocket connection while ignoring messages we are not interested in:

    * def handler = function(msg){ if (msg.startsWith('hello')) karate.signal(msg) }
    * def socket = karate.webSocket(demoBaseUrl + '/websocket', handler)
    * eval socket.send('Billie')
    * def result = karate.listen(5000)
    * match result == 'hello Billie !'

ptrthomas added a commit that referenced this issue Nov 1, 2018
added echo example, support binary messages
introduced type conversion for bytes
ptrthomas added a commit that referenced this issue Nov 7, 2018
so if a signal arrives before we start listening it will still be handled
@ptrthomas
Copy link
Member

0.9.0 released

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants