├── kafka-mtls ├── ssl │ ├── creds_sslkey │ ├── ca.srl │ ├── creds_keystore │ ├── server.p12 │ ├── server.keystore.pkcs12 │ ├── client.truststore.pkcs12 │ ├── server.csr │ ├── ca.crt │ ├── server.crt │ ├── ca.key │ ├── server.key │ └── ca.pem ├── src │ └── test │ │ └── java │ │ ├── karate-config.js │ │ ├── karate │ │ ├── mock.feature │ │ ├── AllRunner.java │ │ ├── KafkaJsonTest.java │ │ ├── KafkaHybridTest.java │ │ ├── kafka-json.feature │ │ ├── KafkaUtils.java │ │ └── kafka-hybrid.feature │ │ └── logback-test.xml ├── conf │ ├── ca.cnf │ ├── server.cnf │ └── commands.txt ├── docker-compose.yml ├── README.md └── pom.xml ├── kafka ├── src │ └── test │ │ └── java │ │ ├── karate-config.js │ │ ├── karate │ │ ├── hello-common.proto │ │ ├── hello.proto │ │ ├── complex.json │ │ ├── AllRunner.java │ │ ├── KafkaTest.java │ │ ├── KafkaJsonTest.java │ │ ├── KafkaMultiTest.java │ │ ├── KafkaProtoTest.java │ │ ├── hello.avsc │ │ ├── kafka-json.feature │ │ ├── kafka-proto.feature │ │ ├── kafka.feature │ │ ├── complex.avsc │ │ └── kafka-multi.feature │ │ └── logback-test.xml ├── docker-compose.yml ├── README.md └── pom.xml ├── quarkus ├── src │ ├── test │ │ └── java │ │ │ ├── application.properties │ │ │ ├── karate-config.js │ │ │ ├── karate │ │ │ ├── greeting.feature │ │ │ └── GreetingTest.java │ │ │ └── logback-test.xml │ └── main │ │ └── java │ │ └── io │ │ └── karatelabs │ │ └── examples │ │ └── quarkus │ │ ├── GreetingService.java │ │ └── GreetingResource.java ├── README.md └── pom.xml ├── websocket ├── src │ └── test │ │ └── java │ │ ├── karate-config.js │ │ ├── karate │ │ ├── echo.feature │ │ ├── json.feature │ │ ├── EchoTest.java │ │ ├── JsonRunner.java │ │ ├── StompRunner.java │ │ ├── stomp.feature │ │ └── StompAdapter.java │ │ └── logback-test.xml ├── pom.xml └── README.md ├── database ├── src │ ├── test │ │ └── java │ │ │ ├── schema.sql │ │ │ ├── application.properties │ │ │ ├── karate-config.js │ │ │ ├── logback-test.xml │ │ │ └── karate │ │ │ ├── dogs.feature │ │ │ ├── DogsTest.java │ │ │ └── DbUtils.java │ └── main │ │ └── java │ │ └── io │ │ └── karatelabs │ │ └── examples │ │ └── database │ │ ├── Application.java │ │ ├── Dog.java │ │ └── DogsController.java ├── README.md └── pom.xml ├── ssh ├── src │ └── test │ │ └── java │ │ ├── karate-config.js │ │ ├── karate │ │ ├── ssh.feature │ │ ├── SshTest.java │ │ └── SshSession.java │ │ └── logback-test.xml ├── README.md └── pom.xml ├── grpc ├── src │ ├── test │ │ └── java │ │ │ ├── karate-config.js │ │ │ ├── karate │ │ │ ├── hello.proto │ │ │ ├── hello-tls.feature │ │ │ ├── hello-tls-mutual.feature │ │ │ ├── HelloTest.java │ │ │ ├── HelloTlsTest.java │ │ │ ├── HelloTlsMutualTest.java │ │ │ └── hello.feature │ │ │ ├── logback-test.xml │ │ │ ├── io │ │ │ └── karatelabs │ │ │ │ └── examples │ │ │ │ └── grpc │ │ │ │ └── HelloJavaRunner.java │ │ │ ├── client.crt │ │ │ ├── server.crt │ │ │ ├── ca.crt │ │ │ ├── crypto.txt │ │ │ ├── client.pem │ │ │ └── server.pem │ └── main │ │ └── proto │ │ └── hello.proto └── README.md ├── micronaut ├── src │ ├── test │ │ └── java │ │ │ ├── application-test.yml │ │ │ ├── karate-config.js │ │ │ ├── karate │ │ │ ├── hello.feature │ │ │ └── HelloTest.java │ │ │ └── logback-test.xml │ └── main │ │ ├── resources │ │ ├── application.yml │ │ └── logback.xml │ │ └── java │ │ └── io │ │ └── karatelabs │ │ └── examples │ │ ├── Application.java │ │ └── HelloController.java ├── README.md └── pom.xml ├── .gitignore ├── grpc-custom ├── src │ ├── test │ │ └── java │ │ │ ├── karate-config.js │ │ │ ├── karate │ │ │ ├── grpc.feature │ │ │ ├── GrpcTest.java │ │ │ ├── GrpcJavaTest.java │ │ │ ├── grpc-java.feature │ │ │ └── GrpcUtils.java │ │ │ ├── io │ │ │ └── karatelabs │ │ │ │ └── examples │ │ │ │ └── grpc │ │ │ │ └── HelloTest.java │ │ │ └── logback-test.xml │ └── main │ │ ├── proto │ │ └── hello.proto │ │ └── java │ │ └── io │ │ └── karatelabs │ │ └── examples │ │ └── grpc │ │ ├── HelloServer.java │ │ └── HelloClient.java └── README.md ├── jbang-npm ├── test.js ├── package.json ├── Hello.java └── javaTest.feature ├── ssl ├── src │ ├── main │ │ ├── resources │ │ │ └── server-keystore.p12 │ │ └── java │ │ │ └── io │ │ │ └── karatelabs │ │ │ └── examples │ │ │ └── ssl │ │ │ └── TestService.java │ └── test │ │ └── java │ │ ├── ssl │ │ ├── SslRunner.java │ │ ├── ssl-truststore.feature │ │ ├── SslTest.java │ │ └── ssl-keystore.feature │ │ └── logback-test.xml ├── README.md └── pom.xml ├── rabbitmq ├── src │ └── test │ │ └── java │ │ ├── karate-config.js │ │ ├── karate │ │ ├── rabbitmq.feature │ │ ├── RmqTest.java │ │ └── RMQUtils.java │ │ ├── logback-test.xml │ │ └── io │ │ └── karatelabs │ │ └── examples │ │ └── rabbitMQ │ │ ├── KarateRMQRunner.java │ │ ├── KarateRMQProducer.java │ │ └── KarateRMQConsumer.java ├── docker-compose.yml ├── README.md └── pom.xml ├── docker ├── Dockerfile ├── src │ └── test.feature └── README.md ├── kafka-custom ├── src │ └── test │ │ └── java │ │ ├── karate-config.js │ │ ├── karate │ │ ├── kafka.feature │ │ ├── KafkaTest.java │ │ ├── hello.avsc │ │ └── KafkaUtils.java │ │ ├── io │ │ └── karatelabs │ │ │ └── examples │ │ │ └── kafka │ │ │ ├── AvroUtilsRunner.java │ │ │ ├── KarateKafkaRunner.java │ │ │ ├── AvroUtils.java │ │ │ ├── KarateKafkaProducer.java │ │ │ └── KarateKafkaConsumer.java │ │ └── logback-test.xml ├── docker-compose.yml ├── README.md └── pom.xml ├── aws-dynamodb ├── src │ └── test │ │ └── java │ │ ├── karate │ │ ├── dynamo-db.feature │ │ └── DynamoDbTest.java │ │ ├── logback-test.xml │ │ └── examples │ │ └── DynamoDbUtils.java ├── README.md └── pom.xml ├── aws └── README.md ├── jbang ├── karate.java ├── test.feature └── README.md ├── slack └── README.md ├── axe └── README.md ├── cli └── README.md ├── browserstack ├── browserstack.feature └── README.md ├── lambdatest ├── lambdatest.feature └── README.md ├── saucelabs ├── saucelabs.feature └── README.md ├── LICENSE └── spring-boot └── README.md /kafka-mtls/ssl/creds_sslkey: -------------------------------------------------------------------------------- 1 | karate 2 | -------------------------------------------------------------------------------- /kafka-mtls/ssl/ca.srl: -------------------------------------------------------------------------------- 1 | C711566EEFF43565 2 | -------------------------------------------------------------------------------- /kafka-mtls/ssl/creds_keystore: -------------------------------------------------------------------------------- 1 | karate 2 | -------------------------------------------------------------------------------- /kafka/src/test/java/karate-config.js: -------------------------------------------------------------------------------- 1 | function fn() { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /kafka-mtls/src/test/java/karate-config.js: -------------------------------------------------------------------------------- 1 | function fn() { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /quarkus/src/test/java/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.http.test-port=0 2 | -------------------------------------------------------------------------------- /websocket/src/test/java/karate-config.js: -------------------------------------------------------------------------------- 1 | function fn() { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /database/src/test/java/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE DOGS (ID INT, NAME VARCHAR(50)); -------------------------------------------------------------------------------- /ssh/src/test/java/karate-config.js: -------------------------------------------------------------------------------- 1 | function fn() { 2 | return {}; 3 | } 4 | -------------------------------------------------------------------------------- /grpc/src/test/java/karate-config.js: -------------------------------------------------------------------------------- 1 | function fn() { 2 | return {}; 3 | } 4 | -------------------------------------------------------------------------------- /micronaut/src/test/java/application-test.yml: -------------------------------------------------------------------------------- 1 | server: 2 | host: localhost 3 | port: -1 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | target/ 3 | .idea/ 4 | .vscode/ 5 | .karate/ 6 | node_modules/ 7 | package-lock.json 8 | -------------------------------------------------------------------------------- /database/src/test/java/application.properties: -------------------------------------------------------------------------------- 1 | server.port=0 2 | spring.datasource.generate-unique-name=false 3 | -------------------------------------------------------------------------------- /kafka-mtls/ssl/server.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karatelabs/karate-examples/HEAD/kafka-mtls/ssl/server.p12 -------------------------------------------------------------------------------- /kafka/src/test/java/karate/hello-common.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message Sender { 4 | string name = 1; 5 | } -------------------------------------------------------------------------------- /grpc-custom/src/test/java/karate-config.js: -------------------------------------------------------------------------------- 1 | function fn() { 2 | return { Grpc: Java.type('karate.GrpcUtils') }; 3 | } 4 | -------------------------------------------------------------------------------- /kafka-mtls/ssl/server.keystore.pkcs12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karatelabs/karate-examples/HEAD/kafka-mtls/ssl/server.keystore.pkcs12 -------------------------------------------------------------------------------- /micronaut/src/test/java/karate-config.js: -------------------------------------------------------------------------------- 1 | function fn() { 2 | return { 3 | urlBase: karate.properties['url.base'] 4 | }; 5 | } 6 | -------------------------------------------------------------------------------- /quarkus/src/test/java/karate-config.js: -------------------------------------------------------------------------------- 1 | function fn() { 2 | return { 3 | urlBase: karate.properties['url.base'] 4 | }; 5 | } 6 | -------------------------------------------------------------------------------- /kafka-mtls/ssl/client.truststore.pkcs12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karatelabs/karate-examples/HEAD/kafka-mtls/ssl/client.truststore.pkcs12 -------------------------------------------------------------------------------- /jbang-npm/test.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | const karate = require('@karatelabs/karate'); 3 | karate.jvm.args = `Hello.java` 4 | karate.exec(); 5 | -------------------------------------------------------------------------------- /ssl/src/main/resources/server-keystore.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karatelabs/karate-examples/HEAD/ssl/src/main/resources/server-keystore.p12 -------------------------------------------------------------------------------- /rabbitmq/src/test/java/karate-config.js: -------------------------------------------------------------------------------- 1 | function fn() { 2 | var Rmq = Java.type('karate.RmqUtils'); 3 | return { rmq: new Rmq('my-queue') }; 4 | } 5 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM eclipse-temurin:17-jre 2 | 3 | RUN curl -L -o karate.jar https://github.com/karatelabs/karate/releases/download/v1.5.0/karate-1.5.0.jar 4 | -------------------------------------------------------------------------------- /micronaut/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | micronaut: 2 | application: 3 | name: default 4 | netty: 5 | default: 6 | allocator: 7 | max-order: 3 8 | -------------------------------------------------------------------------------- /kafka-custom/src/test/java/karate-config.js: -------------------------------------------------------------------------------- 1 | function fn() { 2 | var KafkaUtils = Java.type('karate.KafkaUtils'); 3 | return { kafka: new KafkaUtils('test-topic') }; 4 | } 5 | -------------------------------------------------------------------------------- /kafka-mtls/src/test/java/karate/mock.feature: -------------------------------------------------------------------------------- 1 | @ignore 2 | Feature: 3 | 4 | Background: 5 | * def KafkaUtils = Java.type('karate.KafkaUtils') 6 | 7 | Scenario: 8 | * KafkaUtils.send() 9 | * def response = { success: true } 10 | -------------------------------------------------------------------------------- /jbang-npm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "test": "node test.js" 4 | }, 5 | "devDependencies": { 6 | "@karatelabs/karate": "^0.2.2" 7 | }, 8 | "dependencies": { 9 | "karate": "^1.0.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /kafka/src/test/java/karate/hello.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "hello-common.proto"; 4 | 5 | message Hello { 6 | string message = 1; 7 | Sender sender = 2; 8 | } 9 | 10 | message Another { 11 | string foo = 1; 12 | } -------------------------------------------------------------------------------- /micronaut/src/test/java/karate/hello.feature: -------------------------------------------------------------------------------- 1 | Feature: micronaut integration test 2 | 3 | Background: 4 | * url urlBase 5 | 6 | Scenario: hello endpoint 7 | * path 'hello' 8 | * method get 9 | * status 200 10 | * match response == 'hello world' 11 | -------------------------------------------------------------------------------- /aws-dynamodb/src/test/java/karate/dynamo-db.feature: -------------------------------------------------------------------------------- 1 | Feature: 2 | 3 | Scenario: 4 | * def Utils = Java.type('examples.DynamoDbUtils') 5 | * def db = new Utils() 6 | * def result = db.getItem('myKeyValue') 7 | * match result == { myFieldName: '#string' } -------------------------------------------------------------------------------- /grpc-custom/src/test/java/karate/grpc.feature: -------------------------------------------------------------------------------- 1 | Feature: example of using helper classes so that your karate tests 2 | can focus only on the calls, requests and responses 3 | look at karate-config.js for how "Grpc" was initialized 4 | 5 | Scenario: 6 | * match Grpc.hello('world') == 'hello world' 7 | -------------------------------------------------------------------------------- /ssh/src/test/java/karate/ssh.feature: -------------------------------------------------------------------------------- 1 | Feature: 2 | 3 | Scenario: 4 | * def config = { user: 'ec2-user', host: '', privateKey: '' } 5 | * def SshSession = Java.type('karate.SshSession') 6 | * def ssh = new SshSession(config) 7 | * ssh.input('pwd') 8 | * ssh.input('whoami') 9 | * ssh.input('exit') 10 | -------------------------------------------------------------------------------- /aws/README.md: -------------------------------------------------------------------------------- 1 | # Karate and AWS 2 | 3 | Any AWS service can be integrated into a Karate test using the [AWS Java SDK](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html) and [Java Interop](https://github.com/karatelabs/karate#calling-java). 4 | 5 | * [AWS DynamoDB](../aws-dynamodb/README.md) -------------------------------------------------------------------------------- /jbang/karate.java: -------------------------------------------------------------------------------- 1 | ///usr/bin/env jbang "$0" "$@" ; exit $? 2 | //DEPS com.intuit.karate:karate-core:1.4.1:all 3 | //DEPS com.github.javafaker:javafaker:1.0.2 4 | 5 | public class karate { 6 | 7 | public static void main(String[] args) { 8 | com.intuit.karate.Main.main(args); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /slack/README.md: -------------------------------------------------------------------------------- 1 | # Karate and Slack 2 | 3 | Refer to this [blog-post](https://medium.com/@markhughes321/integrate-karate-dsl-cucumber-reports-into-your-slack-channel-f6b4f7d71d08) and [sample code](https://github.com/markhughes321/karate-slack-integration) by [Mark Hughes](https://www.linkedin.com/in/markhughes321/). -------------------------------------------------------------------------------- /micronaut/src/main/java/io/karatelabs/examples/Application.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples; 2 | 3 | import io.micronaut.runtime.Micronaut; 4 | 5 | public class Application { 6 | 7 | public static void main(String[] args) { 8 | Micronaut.run(Application.class, args); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /jbang/test.feature: -------------------------------------------------------------------------------- 1 | Feature: 2 | 3 | Background: 4 | * def faker = new com.github.javafaker.Faker() 5 | 6 | Scenario: 7 | * def name = faker.name().fullName() 8 | 9 | * url 'https://httpbin.org/post' 10 | * request { name: '#(name)' } 11 | * method post 12 | * status 200 13 | * match response.json.name == name 14 | -------------------------------------------------------------------------------- /jbang-npm/Hello.java: -------------------------------------------------------------------------------- 1 | ///usr/bin/env jbang "$0" "$@" ; exit $? 2 | //DEPS com.intuit.karate:karate-core:1.4.1:all 3 | //DEPS com.github.javafaker:javafaker:1.0.2 4 | 5 | class Hello { 6 | 7 | public static void main(String[] args) throws Exception { 8 | com.intuit.karate.Main.main(args); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /quarkus/src/main/java/io/karatelabs/examples/quarkus/GreetingService.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.quarkus; 2 | 3 | import jakarta.enterprise.context.ApplicationScoped; 4 | 5 | @ApplicationScoped 6 | public class GreetingService { 7 | 8 | public String greeting(String name) { 9 | return "hello " + name; 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /rabbitmq/src/test/java/karate/rabbitmq.feature: -------------------------------------------------------------------------------- 1 | Feature: example of using helper classes so that your karate tests 2 | can focus only on the calls, requests and responses 3 | look at karate-config.js for how "rmq" was initialized 4 | 5 | Scenario: 6 | * rmq.send('hello world') 7 | * def result = rmq.listen() 8 | * match result == ['hello world'] 9 | -------------------------------------------------------------------------------- /websocket/src/test/java/karate/echo.feature: -------------------------------------------------------------------------------- 1 | Feature: demo plain-text 2 | 3 | Scenario: 4 | * def session = karate.channel('websocket') 5 | * session.url = 'wss://ws.postman-echo.com/raw' 6 | * session.start() 7 | 8 | * session.send('hello') 9 | 10 | * def response = session.collect() 11 | * match response == ['hello'] 12 | -------------------------------------------------------------------------------- /grpc-custom/src/main/proto/hello.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option java_multiple_files = true; 4 | option java_package = "io.karatelabs.examples.grpc"; 5 | 6 | service HelloService { 7 | rpc Hello (HelloRequest) returns (HelloReply) {} 8 | } 9 | 10 | message HelloRequest { 11 | string name = 1; 12 | } 13 | 14 | message HelloReply { 15 | string message = 1; 16 | } -------------------------------------------------------------------------------- /quarkus/src/test/java/karate/greeting.feature: -------------------------------------------------------------------------------- 1 | Feature: quarkus integration test 2 | 3 | Background: 4 | * url urlBase 5 | 6 | Scenario: hello endpoint 7 | * path 'hello' 8 | * method get 9 | * status 200 10 | * match response == 'hello' 11 | 12 | Scenario: greeting endpoint 13 | * path 'hello', 'greeting', 'world' 14 | * method get 15 | * status 200 16 | * match response == 'hello world' -------------------------------------------------------------------------------- /kafka/src/test/java/karate/complex.json: -------------------------------------------------------------------------------- 1 | { 2 | "meta": { 3 | "metaId": "123", 4 | "metaType": "AAA", 5 | "metaChildren": [{ "name": "foo", "status": "ONE" }] 6 | }, 7 | "payload": { 8 | "payloadId": "456", 9 | "payloadType": null, 10 | "payloadEnum": "FIRST", 11 | "payloadChild": {"field1": "foo", "field2": "bar"} 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /ssl/src/test/java/ssl/SslRunner.java: -------------------------------------------------------------------------------- 1 | package ssl; 2 | 3 | import com.intuit.karate.junit5.Karate; 4 | 5 | class SslRunner { 6 | 7 | @Karate.Test 8 | Karate testKeystore() { 9 | return Karate.run("classpath:ssl/ssl-keystore.feature"); 10 | } 11 | 12 | @Karate.Test 13 | Karate testTruststore() { 14 | return Karate.run("classpath:ssl/ssl-truststore.feature"); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /kafka-custom/src/test/java/karate/kafka.feature: -------------------------------------------------------------------------------- 1 | Feature: example of using helper classes so that your karate tests 2 | can focus only on the calls, requests and responses 3 | look at karate-config.js for how "kafka" was initialized 4 | 5 | Scenario: 6 | * kafka.send({ message: 'hello', info: { first: 5, second: true } }) 7 | * def result = kafka.listen() 8 | * match result == [{ message: 'hello', info: { first: 5, second: true } }] 9 | -------------------------------------------------------------------------------- /database/src/test/java/karate-config.js: -------------------------------------------------------------------------------- 1 | function fn() { 2 | var DbUtils = Java.type('karate.DbUtils'); 3 | var dbConfig = { 4 | url: 'jdbc:h2:mem:testdb', 5 | username: 'sa', 6 | password: '', 7 | driverClassName: 'org.h2.Driver' 8 | }; 9 | var serverPort = karate.properties['server.port']; 10 | return { 11 | urlBase: 'http://localhost:' + serverPort, 12 | db: new DbUtils(dbConfig) 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /jbang-npm/javaTest.feature: -------------------------------------------------------------------------------- 1 | Feature: Example of NPM usage of Java library in Karate feature file. 2 | 3 | Background: 4 | * def faker = new com.github.javafaker.Faker() 5 | 6 | Scenario: 7 | * def name = faker.name().fullName() 8 | 9 | Given url 'https://httpbin.org/post' 10 | And request { name: '#(name)' } 11 | When method post 12 | Then status 200 13 | And match response.json.name == name 14 | -------------------------------------------------------------------------------- /database/src/main/java/io/karatelabs/examples/database/Application.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.database; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(Application.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /rabbitmq/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.2" 2 | services: 3 | rabbitmq: 4 | image: rabbitmq:3-management-alpine 5 | container_name: 'rabbitmq' 6 | ports: 7 | - 5672:5672 8 | - 15672:15672 9 | volumes: 10 | - ~/.docker-conf/rabbitmq/data/:/var/lib/rabbitmq/ 11 | - ~/.docker-conf/rabbitmq/log/:/var/log/rabbitmq 12 | networks: 13 | - rabbitmq_go_net 14 | 15 | networks: 16 | rabbitmq_go_net: 17 | driver: bridge 18 | -------------------------------------------------------------------------------- /grpc/src/test/java/karate/hello.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | service HelloService { 4 | rpc Hello (HelloRequest) returns (HelloReply) {} 5 | rpc LotsOfReplies (HelloRequest) returns (stream HelloReply) {} 6 | rpc LotsOfGreetings (stream HelloRequest) returns (HelloReply) {} 7 | rpc BidiHello (stream HelloRequest) returns (stream HelloReply) {} 8 | } 9 | 10 | message HelloRequest { 11 | string name = 1; 12 | } 13 | 14 | message HelloReply { 15 | string message = 1; 16 | } -------------------------------------------------------------------------------- /ssl/src/test/java/ssl/ssl-truststore.feature: -------------------------------------------------------------------------------- 1 | Feature: ssl with trust store / cert 2 | 3 | Background: 4 | * configure ssl = 5 | """ 6 | { 7 | trustStore: 'classpath:server-keystore.p12', 8 | trustStorePassword: 'karate-mock', 9 | trustStoreType: 'pkcs12' 10 | } 11 | """ 12 | * url 'https://localhost:8080' 13 | 14 | Scenario: 15 | * path 'test' 16 | * method get 17 | * status 200 18 | * match response == { success: true } 19 | -------------------------------------------------------------------------------- /websocket/src/test/java/karate/json.feature: -------------------------------------------------------------------------------- 1 | Feature: demo auto-conversion to json 2 | 3 | Scenario: 4 | * def session = karate.channel('websocket') 5 | * session.url = 'wss://ws.postman-echo.com/raw' 6 | * def Adapter = Java.type('io.karatelabs.websocket.JsonAdapter') 7 | * session.adapter = new Adapter() 8 | * session.start() 9 | 10 | * session.send({ message: 'hello' }) 11 | 12 | * def response = session.collect() 13 | * match response == [{ message: 'hello' }] 14 | -------------------------------------------------------------------------------- /kafka/src/test/java/karate/AllRunner.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class AllRunner { 9 | 10 | @Test 11 | void testFeature() { 12 | Results results = Runner.path("classpath:karate").parallel(1); 13 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /micronaut/src/main/java/io/karatelabs/examples/HelloController.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples; 2 | 3 | import io.micronaut.http.MediaType; 4 | import io.micronaut.http.annotation.Controller; 5 | import io.micronaut.http.annotation.Get; 6 | import io.micronaut.http.annotation.Produces; 7 | 8 | @Controller("/hello") 9 | public class HelloController { 10 | 11 | @Get 12 | @Produces(MediaType.TEXT_PLAIN) 13 | public String index() { 14 | return "hello world"; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /ssh/src/test/java/karate/SshTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import static org.junit.jupiter.api.Assertions.*; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class SshTest { 9 | 10 | @Test 11 | void testFeature() { 12 | Results results = Runner.path("classpath:karate/ssh.feature").parallel(1); 13 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /kafka-mtls/src/test/java/karate/AllRunner.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class AllRunner { 9 | 10 | @Test 11 | void testFeature() { 12 | Results results = Runner.path("classpath:karate").parallel(1); 13 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /rabbitmq/src/test/java/karate/RmqTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import static org.junit.jupiter.api.Assertions.*; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class RmqTest { 9 | 10 | @Test 11 | void testFeature() { 12 | Results results = Runner.path("classpath:karate/rabbitmq.feature").parallel(1); 13 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /aws-dynamodb/src/test/java/karate/DynamoDbTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import static org.junit.jupiter.api.Assertions.*; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class DynamoDbTest { 9 | 10 | @Test 11 | void testFeature() { 12 | Results results = Runner.path("classpath:karate/dynamo-db.feature").parallel(1); 13 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /grpc-custom/src/test/java/karate/GrpcTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import static org.junit.jupiter.api.Assertions.*; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class GrpcTest { 9 | 10 | @Test 11 | void testFeature() { 12 | Results results = Runner.path("classpath:karate/grpc.feature").parallel(1); 13 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /kafka/src/test/java/karate/KafkaTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import static org.junit.jupiter.api.Assertions.*; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class KafkaTest { 9 | 10 | @Test 11 | void testFeature() { 12 | Results results = Runner.path("classpath:karate/kafka.feature").parallel(1); 13 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /docker/src/test.feature: -------------------------------------------------------------------------------- 1 | Feature: sample karate api test script 2 | 3 | Background: 4 | * url 'https://jsonplaceholder.typicode.com' 5 | 6 | Scenario: get all users and then get the first user by id 7 | * path 'users' 8 | * method get 9 | * status 200 10 | * match response[0] contains { id: 1, name: 'Leanne Graham', website: 'hildegard.org' } 11 | 12 | * def first = response[0] 13 | 14 | * path 'users', first.id 15 | * method get 16 | * status 200 17 | * match response == first -------------------------------------------------------------------------------- /kafka-custom/src/test/java/karate/KafkaTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import static org.junit.jupiter.api.Assertions.*; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class KafkaTest { 9 | 10 | @Test 11 | void testFeature() { 12 | Results results = Runner.path("classpath:karate/kafka.feature").parallel(1); 13 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /kafka/src/test/java/karate/KafkaJsonTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import static org.junit.jupiter.api.Assertions.*; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class KafkaJsonTest { 9 | 10 | @Test 11 | void testFeature() { 12 | Results results = Runner.path("classpath:karate/kafka-json.feature").parallel(1); 13 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /grpc-custom/src/test/java/karate/GrpcJavaTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import static org.junit.jupiter.api.Assertions.*; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class GrpcJavaTest { 9 | 10 | @Test 11 | void testFeature() { 12 | Results results = Runner.path("classpath:karate/grpc-java.feature").parallel(1); 13 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /kafka-mtls/src/test/java/karate/KafkaJsonTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import static org.junit.jupiter.api.Assertions.*; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class KafkaJsonTest { 9 | 10 | @Test 11 | void testFeature() { 12 | Results results = Runner.path("classpath:karate/kafka-json.feature").parallel(1); 13 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /kafka/src/test/java/karate/KafkaMultiTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import static org.junit.jupiter.api.Assertions.*; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class KafkaMultiTest { 9 | 10 | @Test 11 | void testFeature() { 12 | Results results = Runner.path("classpath:karate/kafka-multi.feature").parallel(1); 13 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /websocket/src/test/java/karate/EchoTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | class EchoTest { 10 | 11 | @Test 12 | void testFeature() { 13 | Results results = Runner.path("classpath:karate/echo.feature").parallel(1); 14 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /websocket/src/test/java/karate/JsonRunner.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | class JsonRunner { 10 | 11 | @Test 12 | void testFeature() { 13 | Results results = Runner.path("classpath:karate/json.feature").parallel(1); 14 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /websocket/src/test/java/karate/StompRunner.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | class StompRunner { 10 | 11 | @Test 12 | void testFeature() { 13 | Results results = Runner.path("classpath:karate/stomp.feature").parallel(1); 14 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /kafka/src/test/java/karate/KafkaProtoTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | class KafkaProtoTest { 10 | 11 | @Test 12 | void testFeature() { 13 | Results results = Runner.path("classpath:karate/kafka-proto.feature").parallel(1); 14 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /grpc/src/main/proto/hello.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option java_multiple_files = true; 4 | option java_package = "io.karatelabs.examples.grpc"; 5 | 6 | service HelloService { 7 | rpc Hello (HelloRequest) returns (HelloReply) {} 8 | rpc LotsOfReplies (HelloRequest) returns (stream HelloReply) {} 9 | rpc LotsOfGreetings (stream HelloRequest) returns (HelloReply) {} 10 | rpc BidiHello (stream HelloRequest) returns (stream HelloReply) {} 11 | } 12 | 13 | message HelloRequest { 14 | string name = 1; 15 | } 16 | 17 | message HelloReply { 18 | string message = 1; 19 | } -------------------------------------------------------------------------------- /ssl/src/test/java/ssl/SslTest.java: -------------------------------------------------------------------------------- 1 | package ssl; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import io.karatelabs.examples.ssl.TestService; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertEquals; 9 | 10 | class SslTest { 11 | 12 | @Test 13 | void testAll() { 14 | TestService.main(new String[]{}); 15 | Results results = Runner.path("classpath:ssl").parallel(1); 16 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /micronaut/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 7 | 8 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /kafka/src/test/java/karate/hello.avsc: -------------------------------------------------------------------------------- 1 | { 2 | "type": "record", 3 | "name": "Hello", 4 | "namespace": "io.karatelabs.examples", 5 | "fields": [ 6 | { 7 | "name": "message", 8 | "type": "string" 9 | }, 10 | { 11 | "name": "info", 12 | "type": { 13 | "name": "Info", 14 | "type": "record", 15 | "fields": [ 16 | { 17 | "name": "first", 18 | "type": "long" 19 | }, 20 | { 21 | "name": "second", 22 | "type": "boolean" 23 | } 24 | ] 25 | } 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /kafka-custom/src/test/java/karate/hello.avsc: -------------------------------------------------------------------------------- 1 | { 2 | "type": "record", 3 | "name": "Hello", 4 | "namespace": "io.karatelabs.examples", 5 | "fields": [ 6 | { 7 | "name": "message", 8 | "type": "string" 9 | }, 10 | { 11 | "name": "info", 12 | "type": { 13 | "name": "Info", 14 | "type": "record", 15 | "fields": [ 16 | { 17 | "name": "first", 18 | "type": "long" 19 | }, 20 | { 21 | "name": "second", 22 | "type": "boolean" 23 | } 24 | ] 25 | } 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /ssl/src/test/java/ssl/ssl-keystore.feature: -------------------------------------------------------------------------------- 1 | Feature: ssl with trust store / cert 2 | 3 | Background: 4 | * configure ssl = 5 | """ 6 | { 7 | keyStore: 'classpath:server-keystore.p12', 8 | keyStorePassword: 'karate-mock', 9 | keyStoreType: 'pkcs12', 10 | trustStore: 'classpath:server-keystore.p12', 11 | trustStorePassword: 'karate-mock', 12 | trustStoreType: 'pkcs12' 13 | } 14 | """ 15 | * url 'https://localhost:8080' 16 | 17 | Scenario: 18 | * path 'test' 19 | * method get 20 | * status 200 21 | * match response == { success: true } 22 | -------------------------------------------------------------------------------- /kafka-mtls/conf/ca.cnf: -------------------------------------------------------------------------------- 1 | [ policy_match ] 2 | countryName = match 3 | stateOrProvinceName = match 4 | organizationName = match 5 | organizationalUnitName = optional 6 | commonName = supplied 7 | emailAddress = optional 8 | 9 | [ req ] 10 | prompt = no 11 | distinguished_name = dn 12 | default_md = sha256 13 | default_bits = 4096 14 | x509_extensions = v3_ca 15 | 16 | [ dn ] 17 | countryName = US 18 | organizationName = Karate Labs 19 | commonName = ca 20 | 21 | [ v3_ca ] 22 | subjectKeyIdentifier=hash 23 | basicConstraints = critical,CA:true 24 | authorityKeyIdentifier=keyid:always,issuer:always 25 | keyUsage = critical,keyCertSign,cRLSign 26 | -------------------------------------------------------------------------------- /grpc/src/test/java/karate/hello-tls.feature: -------------------------------------------------------------------------------- 1 | Feature: grpc with tls / ssl 2 | 3 | Background: 4 | * def session = karate.channel('grpc') 5 | * session.host = 'localhost' 6 | * session.port = karate.properties['grpc.port'] 7 | 8 | # note this short-cut to set multiple session properties on one line 9 | * session.config = { proto: 'classpath:karate/hello.proto', service: 'HelloService', method: 'Hello' } 10 | 11 | * session.trustCert = 'classpath:ca.crt' 12 | 13 | Scenario: unary 14 | * session.send({ name: 'John' }) 15 | * match session.pop() == { message: 'hello John' } 16 | * session.send({ name: 'Smith' }) 17 | * match session.pop() == { message: 'hello Smith' } -------------------------------------------------------------------------------- /grpc-custom/src/test/java/io/karatelabs/examples/grpc/HelloTest.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.grpc; 2 | 3 | import io.grpc.Server; 4 | import org.junit.jupiter.api.Test; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | 9 | class HelloTest { 10 | 11 | static final Logger logger = LoggerFactory.getLogger(HelloTest.class); 12 | 13 | @Test 14 | void testHello() throws Exception { 15 | Server server = HelloServer.start(0); 16 | HelloClient client = new HelloClient("localhost", server.getPort()); 17 | String result = client.hello("world"); 18 | logger.debug("response is: {}", result); 19 | client.shutdown(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /database/src/main/java/io/karatelabs/examples/database/Dog.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.database; 2 | 3 | public class Dog { 4 | 5 | private int id; 6 | private String name; 7 | 8 | public Dog() { 9 | // zero arg constructor 10 | } 11 | 12 | public Dog(int id, String name) { 13 | this.id = id; 14 | this.name = name; 15 | } 16 | 17 | public int getId() { 18 | return id; 19 | } 20 | 21 | public void setId(int id) { 22 | this.id = id; 23 | } 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | public void setName(String name) { 30 | this.name = name; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /quarkus/src/main/java/io/karatelabs/examples/quarkus/GreetingResource.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.quarkus; 2 | 3 | import jakarta.inject.Inject; 4 | import jakarta.ws.rs.GET; 5 | import jakarta.ws.rs.Path; 6 | import jakarta.ws.rs.Produces; 7 | import jakarta.ws.rs.core.MediaType; 8 | 9 | @Path("/hello") 10 | public class GreetingResource { 11 | 12 | @Inject 13 | GreetingService service; 14 | 15 | @GET 16 | @Produces(MediaType.TEXT_PLAIN) 17 | @Path("/greeting/{name}") 18 | public String greeting(String name) { 19 | return service.greeting(name); 20 | } 21 | 22 | @GET 23 | @Produces(MediaType.TEXT_PLAIN) 24 | public String hello() { 25 | return "hello"; 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /axe/README.md: -------------------------------------------------------------------------------- 1 | # Karate and Axe for Accessibility Testing 2 | 3 | It is possible to load any arbitrary JS library and execute it within a Karate UI test. One of the things that this opens up is the possibility to connect [Axe](https://www.deque.com/axe/) and even run a custom report. 4 | 5 | ## Example 6 | Here is a simple example: [axe.feature](https://github.com/karatelabs/karate/blob/master/karate-e2e-tests/src/test/java/axe/axe.feature) 7 | 8 | How it works is very straightforward: 9 | * get the axe library JS / module from a CDN (this can also be from the file-system) 10 | * wait for the page to load and then execute the library 11 | * use a [cusom HTML template](https://github.com/karatelabs/karate#doc) to generate a report 12 | 13 | 14 | -------------------------------------------------------------------------------- /kafka-mtls/conf/server.cnf: -------------------------------------------------------------------------------- 1 | [req] 2 | prompt = no 3 | distinguished_name = dn 4 | default_md = sha256 5 | default_bits = 4096 6 | req_extensions = v3_req 7 | 8 | [ dn ] 9 | countryName = US 10 | organizationName = Karate Labs 11 | commonName=kafka 12 | 13 | [ v3_ca ] 14 | subjectKeyIdentifier=hash 15 | basicConstraints = critical,CA:true 16 | authorityKeyIdentifier=keyid:always,issuer:always 17 | keyUsage = critical,keyCertSign,cRLSign 18 | 19 | [ v3_req ] 20 | subjectKeyIdentifier = hash 21 | basicConstraints = CA:FALSE 22 | nsComment = "OpenSSL Generated Certificate" 23 | keyUsage = critical, digitalSignature, keyEncipherment 24 | extendedKeyUsage = serverAuth, clientAuth 25 | subjectAltName = @alt_names 26 | 27 | [ alt_names ] 28 | DNS.1=kafka 29 | DNS.2=localhost 30 | -------------------------------------------------------------------------------- /grpc-custom/src/test/java/karate/grpc-java.feature: -------------------------------------------------------------------------------- 1 | Feature: example of how to use java interop in a karate test 2 | you can compare this code with HelloTest.java and see how 3 | karate compares one-to-one with the equivalent in java 4 | you can avoid the boilerplate in the background by using a well-designed 5 | utility / helper java class (recommended) refer: grpc.feature 6 | 7 | Background: 8 | * def HelloServer = Java.type('io.karatelabs.examples.grpc.HelloServer') 9 | * def HelloClient = Java.type('io.karatelabs.examples.grpc.HelloClient') 10 | * def server = HelloServer.start(0) 11 | * def client = new HelloClient('localhost', server.getPort()) 12 | 13 | Scenario: 14 | * def result = client.hello('world') 15 | * match result == 'hello world' 16 | * client.shutdown() 17 | -------------------------------------------------------------------------------- /kafka/src/test/java/karate/kafka-json.feature: -------------------------------------------------------------------------------- 1 | Feature: karate-kafka demo 2 | 3 | Background: 4 | * configure kafka = 5 | """ 6 | { 7 | 'bootstrap.servers': '127.0.0.1:29092' 8 | } 9 | """ 10 | 11 | Scenario: 12 | * def channel = karate.channel('kafka') 13 | * def consumer = channel.consumer() 14 | 15 | * consumer.count = 1 16 | * consumer.topic = 'test-topic' 17 | * consumer.timeout = 5000 18 | * consumer.start() 19 | 20 | * def producer = channel.producer() 21 | 22 | * producer.topic = 'test-topic' 23 | * producer.key = 'first' 24 | * producer.value = { message: 'hello', info: { first: 1, second: true } } 25 | * producer.send() 26 | 27 | * def response = consumer.pop() 28 | * match response.key == 'first' 29 | * match response.value == { message: 'hello', info: { first: 1, second: true } } -------------------------------------------------------------------------------- /quarkus/src/test/java/karate/GreetingTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import io.quarkus.test.common.http.TestHTTPResource; 6 | import io.quarkus.test.junit.QuarkusTest; 7 | import java.net.URL; 8 | import static org.junit.jupiter.api.Assertions.*; 9 | import org.junit.jupiter.api.Test; 10 | 11 | @QuarkusTest 12 | class GreetingTest { 13 | 14 | @TestHTTPResource("/") 15 | URL urlBase; 16 | 17 | @Test 18 | void testGreeting() { 19 | Results results = Runner.path("classpath:karate/greeting.feature") 20 | .systemProperty("url.base", urlBase.toString()) 21 | .parallel(1); 22 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /cli/README.md: -------------------------------------------------------------------------------- 1 | # Karate and CLI / Bash 2 | 3 | Karate has excellent support for calling external processes via the command-line. You can block and wait for output or you can even fork a process on a separate thread and listen to the output from the test. 4 | 5 | The best documentation is present in [this answer on Stack Overflow](https://stackoverflow.com/a/62911366/143475) 6 | 7 | ## Examples 8 | * [fork.feature](https://github.com/karatelabs/karate/blob/master/karate-core/src/test/java/com/intuit/karate/core/fork.feature) 9 | * [fork-listener.feature](https://github.com/karatelabs/karate/blob/master/karate-core/src/test/java/com/intuit/karate/core/fork-listener.feature) 10 | 11 | ## Further Reading 12 | 13 | [Using cURL to simulate non-standard HTTP request](https://stackoverflow.com/a/64352676/143475) 14 | [Karate and SSH](../ssh/README.md) -------------------------------------------------------------------------------- /micronaut/src/test/java/karate/HelloTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import io.micronaut.runtime.server.EmbeddedServer; 6 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest; 7 | import jakarta.inject.Inject; 8 | 9 | import static org.junit.jupiter.api.Assertions.*; 10 | import org.junit.jupiter.api.Test; 11 | 12 | @MicronautTest 13 | class HelloTest { 14 | 15 | @Inject 16 | EmbeddedServer server; 17 | 18 | @Test 19 | void testGreeting() { 20 | Results results = Runner.path("classpath:karate/hello.feature") 21 | .systemProperty("url.base", server.getURL().toString()) 22 | .parallel(1); 23 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /aws-dynamodb/src/test/java/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | target/karate.log 12 | 13 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ssl/src/test/java/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | target/karate.log 12 | 13 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /kafka/src/test/java/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | target/karate.log 12 | 13 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /websocket/src/test/java/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | target/karate.log 12 | 13 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /kafka-mtls/src/test/java/karate/KafkaHybridTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import com.intuit.karate.core.MockServer; 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import org.junit.jupiter.api.BeforeAll; 8 | import org.junit.jupiter.api.Test; 9 | 10 | class KafkaHybridTest { 11 | 12 | static MockServer server; 13 | 14 | @BeforeAll 15 | static void beforeAll() { 16 | server = MockServer.feature("classpath:karate/mock.feature").build(); 17 | } 18 | 19 | @Test 20 | void testHybrid() { 21 | Results results = Runner.path("classpath:karate/kafka-hybrid.feature") 22 | .systemProperty("server.port", server.getPort() + "") 23 | .parallel(1); 24 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /kafka-mtls/src/test/java/karate/kafka-json.feature: -------------------------------------------------------------------------------- 1 | Feature: karate-kafka demo 2 | 3 | Background: 4 | * configure kafka = 5 | """ 6 | { 7 | 'bootstrap.servers': 'localhost:29093', 8 | 'security.protocol': 'SSL', 9 | 'ssl.truststore.location': 'ssl/client.truststore.pkcs12', 10 | 'ssl.truststore.password': 'karate' 11 | } 12 | """ 13 | 14 | Scenario: 15 | * def channel = karate.channel('kafka') 16 | 17 | * def consumer = channel.consumer() 18 | * consumer.topic = 'test-topic' 19 | * consumer.count = 1 20 | * consumer.start() 21 | 22 | * def producer = channel.producer() 23 | 24 | * producer.topic = 'test-topic' 25 | * producer.key = 'first' 26 | * producer.value = { message: 'hello', info: { first: 1, second: true } } 27 | * producer.send() 28 | 29 | * def response = consumer.pop() 30 | * match response.key == 'first' 31 | * match response.value == { message: 'hello', info: { first: 1, second: true } } -------------------------------------------------------------------------------- /grpc/src/test/java/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | target/karate.log 12 | 13 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ssh/src/test/java/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | target/karate.log 12 | 13 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /kafka-custom/src/test/java/io/karatelabs/examples/kafka/AvroUtilsRunner.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.kafka; 2 | 3 | import com.intuit.karate.Json; 4 | import org.apache.avro.Schema; 5 | import org.apache.avro.generic.GenericRecord; 6 | import org.junit.jupiter.api.Test; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | class AvroUtilsRunner { 11 | 12 | static final Logger logger = LoggerFactory.getLogger(AvroUtilsRunner.class); 13 | 14 | @Test 15 | void testAvro() { 16 | Schema schema = AvroUtils.toSchema("src/test/java/karate/hello.avsc"); 17 | String json = Json.of("{ message: 'hello', info: { first: 5, second: true } }").toString(); 18 | GenericRecord record = AvroUtils.fromJson(schema, json); 19 | logger.debug("record: {}", record); 20 | String result = AvroUtils.toJson(record); 21 | logger.debug("result: {}", result); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /rabbitmq/src/test/java/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | target/karate.log 12 | 13 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /grpc-custom/src/test/java/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | target/karate.log 12 | 13 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /kafka-custom/src/test/java/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | target/karate.log 12 | 13 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /kafka-mtls/src/test/java/karate/KafkaUtils.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Json; 4 | import io.karatelabs.kafka.KarateKafkaProducer; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import org.apache.kafka.clients.producer.ProducerRecord; 8 | 9 | public class KafkaUtils { 10 | 11 | public static void send() { 12 | Map map = new HashMap(); 13 | map.put("bootstrap.servers", "localhost:29093"); 14 | map.put("security.protocol", "SSL"); 15 | map.put("ssl.truststore.location", "ssl/client.truststore.pkcs12"); 16 | map.put("ssl.truststore.password", "karate"); 17 | KarateKafkaProducer producer = new KarateKafkaProducer(map); 18 | String json = Json.of("{ hello: 'world' }").toString(); 19 | ProducerRecord pr = new ProducerRecord("test-topic", null, "first", json.getBytes(), null); 20 | producer.send(pr); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /grpc/src/test/java/karate/hello-tls-mutual.feature: -------------------------------------------------------------------------------- 1 | Feature: grpc with tls / ssl and using client-side certificate (mutual) auth 2 | 3 | Background: 4 | * def session = karate.channel('grpc') 5 | * session.host = 'localhost' 6 | * session.port = karate.properties['grpc.port'] 7 | 8 | * session.config = { trustCert: 'classpath:ca.crt', clientCert: 'classpath:client.crt', clientKey: 'classpath:client.pem' } 9 | 10 | # note that session.config can be updated multiple times 11 | * def method = 'Hello' 12 | # and that everything is pure-JS which means Karate variable references work directly 13 | * session.config = { proto: 'classpath:karate/hello.proto', service: 'HelloService', method: method } 14 | 15 | Scenario: unary 16 | * session.send({ name: 'John' }) 17 | * match session.pop() == { message: 'hello John' } 18 | * session.send({ name: 'Smith' }) 19 | * match session.pop() == { message: 'hello Smith' } -------------------------------------------------------------------------------- /kafka-mtls/src/test/java/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | target/karate.log 12 | 13 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /grpc-custom/src/main/java/io/karatelabs/examples/grpc/HelloServer.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.grpc; 2 | 3 | import io.grpc.Server; 4 | import io.grpc.ServerBuilder; 5 | import io.grpc.stub.StreamObserver; 6 | 7 | public class HelloServer extends HelloServiceGrpc.HelloServiceImplBase { 8 | 9 | @Override 10 | public void hello(HelloRequest request, StreamObserver response) { 11 | HelloReply reply = HelloReply.newBuilder().setMessage("hello " + request.getName()).build(); 12 | response.onNext(reply); 13 | response.onCompleted(); 14 | } 15 | 16 | public static Server start(int port) throws Exception { 17 | Server server = ServerBuilder.forPort(port) 18 | .addService(new HelloServer()) 19 | .build() 20 | .start(); 21 | System.out.println("grpc server started on port: " + server.getPort()); 22 | return server; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /grpc/README.md: -------------------------------------------------------------------------------- 1 | # Karate and gRPC 2 | 3 | Karate has native support for gRPC as an optional dependency (non-open source and commercial). Enterprise users can find more information here: [Karate-gRPC](https://github.com/karatelabs/karate-addons/tree/main/karate-grpc). 4 | 5 | A license is required for running (for e.g. in CI/CD) and a Karate Labs IDE subscription is required per developer seat. Make sure you have a `.karate/karate.lic` file in place before running the example. 6 | 7 | ## Running 8 | This is a normal Java / Maven project so running `mvn clean compile test` will be sufficient to run all the tests. 9 | 10 | Take a look at [`hello.feature`](src/test/java/karate/hello.feature) to see how simple yet expressive gRPC tests can be. 11 | 12 | ## Further Reading 13 | * [grpc-custom](../grpc-custom/README.md) - it is possible to test gRPC by writing the Java integration code yourself and generating Java code, but the approach above is recommended 14 | 15 | -------------------------------------------------------------------------------- /browserstack/browserstack.feature: -------------------------------------------------------------------------------- 1 | Feature: browserstack automation demo 2 | 3 | Background: 4 | # enter the value for the next line from your browserstack account 5 | * def browserStackUrl = '' 6 | * def browserStackOptions = { projectName: 'Karate and Browser Stack', buildName: 'myBuild', sessionName: '#(karate.feature.prefixedPath)' } 7 | * def session = { capabilities: { alwaysMatch: { browserName: 'chrome', browserVersion: 'latest', platformName: 'Windows 11', 'bstack:options': '#(browserStackOptions)' } } } 8 | * configure driver = { type: 'chromedriver', start: false, webDriverSession: '#(session)', webDriverUrl: '#(browserStackUrl)' } 9 | 10 | Scenario: try to login to github and check for expected error message 11 | * driver 'https://github.com/login' 12 | * input('#login_field', 'XXXX') 13 | * input('#password', 'world') 14 | * submit().click("input[name=commit]") 15 | * match html('.flash-error') contains 'Incorrect username or password.' -------------------------------------------------------------------------------- /kafka/src/test/java/karate/kafka-proto.feature: -------------------------------------------------------------------------------- 1 | Feature: karate-kafka demo 2 | 3 | Background: 4 | * configure kafka = 5 | """ 6 | { 7 | 'bootstrap.servers': '127.0.0.1:29092' 8 | } 9 | """ 10 | * def channel = karate.channel('kafka') 11 | * channel.register({ name: 'hello-proto', path: 'classpath:karate/hello.proto', message: 'Hello', roots: ['classpath:karate'] }) 12 | 13 | Scenario: 14 | * def consumer = channel.consumer() 15 | * consumer.count = 1 16 | * consumer.topic = 'test-topic' 17 | * consumer.schema = 'hello-proto' 18 | * consumer.start() 19 | 20 | * def producer = channel.producer() 21 | 22 | * producer.topic = 'test-topic' 23 | * producer.schema = 'hello-proto' 24 | * producer.key = 'first' 25 | * producer.value = { message: 'hello', sender: { name: 'John Smith' } } 26 | * producer.send() 27 | 28 | * def response = consumer.collect() 29 | * match response[0].key == 'first' 30 | * match response[0].value == { message: 'hello', sender: { name: 'John Smith' } } -------------------------------------------------------------------------------- /kafka-custom/src/test/java/io/karatelabs/examples/kafka/KarateKafkaRunner.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.kafka; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import static org.junit.jupiter.api.Assertions.*; 6 | import org.junit.jupiter.api.Test; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | public class KarateKafkaRunner { 11 | 12 | static final Logger logger = LoggerFactory.getLogger(KarateKafkaRunner.class); 13 | 14 | @Test 15 | void testKafka() throws Exception { 16 | String topic = "test-topic"; 17 | KarateKafkaConsumer consumer = new KarateKafkaConsumer(topic); 18 | KarateKafkaProducer producer = new KarateKafkaProducer(topic); 19 | producer.send("hello world"); 20 | List messages = consumer.getMessages(); 21 | logger.debug("got messages: {}", messages); 22 | assertEquals(Arrays.asList("hello world"), messages); 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /kafka-mtls/src/test/java/karate/kafka-hybrid.feature: -------------------------------------------------------------------------------- 1 | Feature: 2 | 3 | Background: 4 | * configure kafka = 5 | """ 6 | { 7 | 'bootstrap.servers': 'localhost:29093', 8 | 'security.protocol': 'SSL', 9 | 'ssl.truststore.location': 'ssl/client.truststore.pkcs12', 10 | 'ssl.truststore.password': 'karate' 11 | } 12 | """ 13 | 14 | Scenario: 15 | # set up the listener before triggering any kafka events 16 | * def channel = karate.channel('kafka') 17 | 18 | * def consumer = channel.consumer() 19 | 20 | * consumer.topic = 'test-topic' 21 | * consumer.count = 1 22 | * consumer.start() 23 | 24 | # this api call will trigger a kafka message (from mock.feature) 25 | * url 'http://localhost:' + karate.properties['server.port'] 26 | * method get 27 | * match response == { success: true } 28 | 29 | # here we wait until the session gets the expected message 30 | * def response = consumer.pop() 31 | * match response.key == 'first' 32 | * match response.value == { hello: 'world' } 33 | -------------------------------------------------------------------------------- /rabbitmq/src/test/java/io/karatelabs/examples/rabbitMQ/KarateRMQRunner.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.rabbitMQ; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import static org.junit.jupiter.api.Assertions.*; 6 | import org.junit.jupiter.api.Test; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | public class KarateRmqRunner { 11 | 12 | static final Logger logger = LoggerFactory.getLogger(KarateRmqRunner.class); 13 | 14 | @Test 15 | void testRMQ() throws Exception { 16 | String queueName = "my-queue"; 17 | KarateRmqConsumer consumer = new KarateRmqConsumer(queueName); 18 | KarateRmqProducer producer = new KarateRmqProducer(queueName); 19 | producer.putMessage("hello world"); 20 | List messages = consumer.getMessageList(); 21 | logger.debug("messages: {}", messages); 22 | assertEquals(Arrays.asList("hello world"), messages); 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /micronaut/src/test/java/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | target/karate.log 12 | 13 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /quarkus/src/test/java/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | target/karate.log 12 | 13 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /database/src/test/java/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | target/karate.log 12 | 13 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /lambdatest/lambdatest.feature: -------------------------------------------------------------------------------- 1 | Feature: lambdatest automation demo 2 | 3 | Background: 4 | # enter the values for the next few lines from your lambatest account 5 | * def lambdaTestUser = '' 6 | * def lambdaTestKey = '' 7 | * def lambdaTestUrl = 'https://hub.lambdatest.com/wd/hub' 8 | * def lambdaTestOptions = { project: '#(karate.feature.prefixedPath)', username: '#(lambdaTestUser)', accessKey: '#(lambdaTestKey)' } 9 | * def session = { capabilities: { alwaysMatch: { browserName: 'chrome', browserVersion: 'latest', platformName: 'Windows 11', 'LT:Options': '#(lambdaTestOptions)' } } } 10 | * configure driver = { type: 'chromedriver', start: false, webDriverSession: '#(session)', webDriverUrl: '#(lambdaTestUrl)' } 11 | 12 | Scenario: try to login to github and check for expected error message 13 | * driver 'https://github.com/login' 14 | * input('#login_field', 'XXXX') 15 | * input('#password', 'world') 16 | * submit().click("input[name=commit]") 17 | * match html('.flash-error') contains 'Incorrect username or password.' -------------------------------------------------------------------------------- /grpc/src/test/java/karate/HelloTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import io.grpc.Server; 6 | import io.karatelabs.examples.grpc.HelloServer; 7 | import org.junit.jupiter.api.AfterAll; 8 | import org.junit.jupiter.api.BeforeAll; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertEquals; 12 | 13 | class HelloTest { 14 | 15 | static Server server; 16 | 17 | @BeforeAll 18 | static void beforeAll() throws Exception { 19 | server = HelloServer.start(0, false); 20 | } 21 | 22 | @Test 23 | void testFeature() { 24 | Results results = Runner.path("classpath:karate/hello.feature") 25 | .systemProperty("grpc.port", server.getPort() + "") 26 | .parallel(1); 27 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 28 | } 29 | 30 | @AfterAll 31 | static void afterAll() { 32 | server.shutdownNow(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /jbang/README.md: -------------------------------------------------------------------------------- 1 | # Karate and JBang 2 | 3 | [JBang](https://www.jbang.dev) is a good option for teams that don't want to install Java or an IDE or worry about compiling code. This simple example uses the [Java Faker](https://github.com/DiUS/java-faker) library to generate a user name and then make an API call. 4 | 5 | * [karate.java](karate.java) - this sets up Karate and adds the Java Faker dependency to the classpath 6 | * [test.feature](test.feature) - a simple test that uses the Java Faker Java API to generate a person name 7 | 8 | ## Running 9 | With JBang installed, this command will run the tests. You can replace `.` with any valid path that contains `*.feature` files. 10 | 11 | ``` 12 | jbang karate.java . 13 | ``` 14 | 15 | ## Further Reading 16 | 17 | * [Other Runtime Options](https://github.com/karatelabs/karate/wiki/Get-Started:-Other-Runtime-Options) 18 | * [Karate, JBang and NPM](../jbang-npm/README.md) - for those who want to use 3rd party Java libraries or custom code and avoid Java compilation and Maven 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /grpc/src/test/java/karate/HelloTlsTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import io.grpc.Server; 6 | import io.karatelabs.examples.grpc.HelloServer; 7 | import org.junit.jupiter.api.AfterAll; 8 | import org.junit.jupiter.api.BeforeAll; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertEquals; 12 | 13 | class HelloTlsTest { 14 | 15 | static Server server; 16 | 17 | @BeforeAll 18 | static void beforeAll() throws Exception { 19 | server = HelloServer.start(0, true); 20 | } 21 | 22 | // @Test 23 | void testFeature() { 24 | Results results = Runner.path("classpath:karate/hello-tls.feature") 25 | .systemProperty("grpc.port", server.getPort() + "") 26 | .parallel(1); 27 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 28 | } 29 | 30 | @AfterAll 31 | static void afterAll() { 32 | server.shutdownNow(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /grpc/src/test/java/karate/HelloTlsMutualTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import io.grpc.Server; 6 | import io.karatelabs.examples.grpc.HelloServer; 7 | import org.junit.jupiter.api.AfterAll; 8 | import org.junit.jupiter.api.BeforeAll; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertEquals; 12 | 13 | class HelloTlsMutualTest { 14 | 15 | static Server server; 16 | 17 | @BeforeAll 18 | static void beforeAll() throws Exception { 19 | server = HelloServer.start(0, true); 20 | } 21 | 22 | // @Test 23 | void testFeature() { 24 | Results results = Runner.path("classpath:karate/hello-tls-mutual.feature") 25 | .systemProperty("grpc.port", server.getPort() + "") 26 | .parallel(1); 27 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 28 | } 29 | 30 | @AfterAll 31 | static void afterAll() { 32 | server.shutdownNow(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /kafka-custom/src/test/java/karate/KafkaUtils.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Logger; 4 | import com.intuit.karate.core.ScenarioEngine; 5 | import io.karatelabs.examples.kafka.KarateKafkaConsumer; 6 | import io.karatelabs.examples.kafka.KarateKafkaProducer; 7 | import java.util.List; 8 | 9 | public class KafkaUtils { 10 | 11 | private final String topic; 12 | private final KarateKafkaConsumer consumer; 13 | private final KarateKafkaProducer producer; 14 | 15 | public KafkaUtils(String topic) { 16 | this.topic = topic; 17 | consumer = new KarateKafkaConsumer(topic); 18 | producer = new KarateKafkaProducer(topic); 19 | } 20 | 21 | private static Logger logger() { 22 | ScenarioEngine engine = ScenarioEngine.get(); 23 | return engine.logger; 24 | } 25 | 26 | public void send(Object data) { 27 | logger().debug(">> kafka send [{}]", topic); 28 | producer.send(data); 29 | } 30 | 31 | public List listen() { 32 | return consumer.getMessages(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /ssl/README.md: -------------------------------------------------------------------------------- 1 | # Karate and SSL 2 | 3 | This is a "standard" [Spring Boot](https://spring.io/projects/spring-boot) project. 4 | 5 | It shows how to test a server that uses a trust-store and / or keystore for security. 6 | 7 | The relevant Karate documentation can be found here: [X509 Certificate Authentication](https://github.com/karatelabs/karate#x509-certificate-authentication). 8 | 9 | Run the server from the IDE or via Maven using this command: 10 | 11 | ``` 12 | mvn -Dexec.mainClass=io.karatelabs.examples.ssl.TestService compile exec:java 13 | ``` 14 | 15 | This will start an HTTPS server on port 8080. 16 | 17 | Now you can run the two Karate tests individually from the IDE. 18 | 19 | Or by using the [SslRunner](src/test/java/ssl/SslRunner.java) JUnit helper. 20 | 21 | ``` 22 | mvn test -Dtest=SslRunner 23 | ``` 24 | 25 | You can also run the test suite that will start the server automatically. 26 | 27 | ``` 28 | mvn test 29 | ``` 30 | 31 | ## Further Reading 32 | * [Karate and Spring Boot](../spring-boot/README.md) 33 | * [Karate and Databases](../database/README.md) 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /saucelabs/saucelabs.feature: -------------------------------------------------------------------------------- 1 | Feature: sauce labs automation demo 2 | 3 | Background: 4 | # enter the values for the next few lines from your sauce labs account 5 | * def sauceLabsBuild = '' 6 | * def sauceLabsUser = '' 7 | * def sauceLabsKey = '' 8 | * def sauceLabsUrl = 'https://ondemand.eu-central-1.saucelabs.com:443/wd/hub' 9 | * def sauceOptions = { build: '#(sauceLabsBuild)', name: '#(karate.feature.prefixedPath)', username: '#(sauceLabsUser)', accessKey: '#(sauceLabsKey)' } 10 | * def session = { capabilities: { alwaysMatch: { browserName: 'chrome', browserVersion: 'latest', platformName: 'Windows 11', 'sauce:options': '#(sauceOptions)' } } } 11 | * configure driver = { type: 'chromedriver', start: false, webDriverSession: '#(session)', webDriverUrl: '#(sauceLabsUrl)' } 12 | 13 | Scenario: try to login to github and check for expected error message 14 | * driver 'https://github.com/login' 15 | * input('#login_field', 'XXXX') 16 | * input('#password', 'world') 17 | * submit().click("input[name=commit]") 18 | * match html('.flash-error') contains 'Incorrect username or password.' -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Karate Labs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /rabbitmq/src/test/java/karate/RMQUtils.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Logger; 4 | import com.intuit.karate.core.ScenarioEngine; 5 | import io.karatelabs.examples.rabbitMQ.KarateRmqConsumer; 6 | import io.karatelabs.examples.rabbitMQ.KarateRmqProducer; 7 | 8 | import java.io.IOException; 9 | import java.util.List; 10 | import java.util.concurrent.TimeoutException; 11 | 12 | public class RmqUtils { 13 | 14 | private final KarateRmqConsumer consumer; 15 | private final KarateRmqProducer producer; 16 | 17 | public RmqUtils(String queueName) throws IOException, TimeoutException { 18 | consumer = new KarateRmqConsumer(queueName); 19 | producer = new KarateRmqProducer(queueName); 20 | } 21 | 22 | private static Logger logger() { 23 | ScenarioEngine engine = ScenarioEngine.get(); 24 | return engine.logger; 25 | } 26 | 27 | public void send(String message) throws IOException { 28 | logger().debug(">> RMQ send - {}", message); 29 | producer.putMessage(message); 30 | } 31 | 32 | public List listen() throws IOException { 33 | return consumer.getMessageList(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /grpc-custom/src/main/java/io/karatelabs/examples/grpc/HelloClient.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.grpc; 2 | 3 | import io.grpc.ManagedChannel; 4 | import io.grpc.ManagedChannelBuilder; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | public class HelloClient { 8 | 9 | private final ManagedChannel channel; 10 | private final HelloServiceGrpc.HelloServiceBlockingStub stub; 11 | 12 | HelloClient(ManagedChannel channel) { 13 | this.channel = channel; 14 | stub = HelloServiceGrpc.newBlockingStub(channel); 15 | } 16 | 17 | public HelloClient(String host, int port) { 18 | this(ManagedChannelBuilder.forAddress(host, port) 19 | // channels are secure by default (SSL / TLS) 20 | // we use plaintext to avoid needing certificates 21 | .usePlaintext() 22 | .build()); 23 | } 24 | 25 | public String hello(String message) { 26 | HelloReply resp = stub.hello(HelloRequest.newBuilder().setName(message).build()); 27 | return resp.getMessage(); 28 | } 29 | 30 | public void shutdown() throws InterruptedException { 31 | channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /database/src/test/java/karate/dogs.feature: -------------------------------------------------------------------------------- 1 | Feature: dogs end-point that uses jdbc as part of the test 2 | 3 | Background: 4 | * url urlBase 5 | 6 | Scenario: create and retrieve a dog 7 | 8 | # create a dog 9 | * path 'dogs' 10 | * request { name: 'Scooby' } 11 | * method post 12 | * status 200 13 | * match response == { id: '#number', name: 'Scooby' } 14 | 15 | * def id = response.id 16 | 17 | # get by id 18 | * path 'dogs', id 19 | * method get 20 | * status 200 21 | * match response == { id: '#(id)', name: 'Scooby' } 22 | 23 | # get all dogs 24 | * path 'dogs' 25 | * method get 26 | * status 200 27 | * match response contains { id: '#(id)', name: 'Scooby' } 28 | 29 | # use jdbc to validate 30 | # look at karate-config.js to see how "db" was initialized 31 | 32 | # since the DbUtils returns a Java List (of Map-s), it becomes normal JSON here ! 33 | # which means that you can use the full power of Karate's 'match' syntax 34 | * def dogs = db.readRows('SELECT * FROM DOGS') 35 | * match dogs contains { ID: '#(id)', NAME: 'Scooby' } 36 | 37 | * def dog = db.readRow('SELECT * FROM DOGS D WHERE D.ID = ' + id) 38 | * match dog.NAME == 'Scooby' 39 | 40 | * def test = db.readValue('SELECT ID FROM DOGS D WHERE D.ID = ' + id) 41 | * match test == id 42 | -------------------------------------------------------------------------------- /kafka/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | 3 | zookeeper: 4 | image: confluentinc/cp-zookeeper:latest 5 | ports: 6 | - 22181:2181 7 | environment: 8 | ZOOKEEPER_CLIENT_PORT: 2181 9 | ZOOKEEPER_TICK_TIME: 2000 10 | 11 | kafka: 12 | image: confluentinc/cp-kafka:latest 13 | depends_on: 14 | - zookeeper 15 | ports: 16 | - 29092:29092 17 | environment: 18 | KAFKA_BROKER_ID: 1 19 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 20 | KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092 21 | KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT 22 | KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT 23 | KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 24 | KAFKA_OFFSETS_TOPIC_NUM_PARTITIONS: 1 25 | KAFKA_MIN_INSYNC_REPLICAS: 1 26 | KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true" 27 | 28 | schema-registry: 29 | image: confluentinc/cp-schema-registry:latest 30 | depends_on: 31 | - zookeeper 32 | - kafka 33 | ports: 34 | - 8081:8081 35 | environment: 36 | SCHEMA_REGISTRY_HOST_NAME: localhost 37 | SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: PLAINTEXT://kafka:9092 38 | -------------------------------------------------------------------------------- /rabbitmq/README.md: -------------------------------------------------------------------------------- 1 | # Karate and RabbitMQ 2 | 3 | This sample project demonstrates how you can test RabbitMQ messaging with a Java client. 4 | 5 | When you use well designed utility classes, your Karate tests will be clean and only focus on making a call and what data is sent and received. 6 | 7 | For example if you look at [`rabbitmq.feature`](src/test/java/karate/rabbitmq.feature) the test is just a few lines. Behind the scenes a Rabbit consumer and producer is initialized and a message is passed. The HTML report even includes details of the "put" operation, which you can easily customize, or extend to other operations. 8 | 9 | ## Running 10 | 11 | * Docker is required to start the RabbitMQ server. There is a `docker-compose.yml` file in this project. 12 | * `docker-compose up -d` 13 | * `mvn test` 14 | * To stop the Docker container run `docker-compose down` 15 | 16 | ### References 17 | * https://x-team.com/blog/set-up-rabbitmq-with-docker-compose/ 18 | * https://www.rabbitmq.com/download.html 19 | * [Kafka example](../kafka/README.md) 20 | * [ActiveMQ example](https://github.com/karatelabs/karate/tree/master/karate-netty#consumer-provider-example) 21 | * [Async and Mocks example](https://twitter.com/getkarate/status/1417023536082812935) 22 | 23 | -------------------------------------------------------------------------------- /kafka-mtls/ssl/server.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIDMTCCAhkCAQAwMzELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0thcmF0ZSBMYWJz 3 | MQ4wDAYDVQQDDAVrYWZrYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 4 | AMP+MMq9DZO2Ynenhf2BLi1eaMNi4jrWgW9Mq4EU6IjrjG4YiJnPIy8d5QUANcub 5 | Y5YpZ2lUtbVjN6eIRBf2g6r/73u5sXbJx1A/SRZMEEhojDC+SmL1Bg4AAuvI+vaN 6 | NW0Gar9gWRWRGuk3qQ4+X8M/qfRRg9TdheIyDiSNaf6S/OakpR32bqfamxNNk568 7 | EDDio+TSM7t3MP61JaPMZ+Pk7dKI3KoUz/h2kBLtsWmZYxTG8fOxghnk6Ql15yMh 8 | eFRa8f2ZDoGgLKZuZ1yyrzQsU8cCRwSsTQlZuWh4GmHdDuYOqWUQ5GlyfHjyrtnf 9 | aUCFVLz9wuCnUVBL6QLuAKsCAwEAAaCBuDCBtQYJKoZIhvcNAQkOMYGnMIGkMB0G 10 | A1UdDgQWBBTuUuupXC/x8W0D/TB9Nx4BTvN42zAJBgNVHRMEAjAAMCwGCWCGSAGG 11 | +EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAOBgNVHQ8BAf8E 12 | BAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBsGA1UdEQQUMBKC 13 | BWthZmthgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAGOldAq/pzegqHXr 14 | AZPvwGI18fkl49vqL5FaRr/DR919FYEcHoHztRH/Ce7xT8bOy12X+lJARSL4gn+x 15 | KtC/TBGVen9AQhvnoNwFqOiLtb2tBNPCdmOS8mvHJtuYZjcDzlCvyFQzUib4T7Qo 16 | 46opuS81kFwANh17760orbj2FMDOu/FU0XVMzP3ayFgyth3bFX68U4Ml7F+Xb3LH 17 | t+qY/CtMqavJj6+g8LwwX5qIeDmAE+dxtouRcsd2bWIx0A6Qe4NG1MF4cynKoVpf 18 | DPeQa4jT5xI68l1auZppMzdT4iCECv5Uh39QIFutog0aTIR42XTokv7Hs+en1lwI 19 | cXWFees= 20 | -----END CERTIFICATE REQUEST----- 21 | -------------------------------------------------------------------------------- /kafka-custom/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | 4 | zookeeper: 5 | image: confluentinc/cp-zookeeper:latest 6 | ports: 7 | - 22181:2181 8 | environment: 9 | ZOOKEEPER_CLIENT_PORT: 2181 10 | ZOOKEEPER_TICK_TIME: 2000 11 | 12 | kafka: 13 | image: confluentinc/cp-kafka:latest 14 | depends_on: 15 | - zookeeper 16 | ports: 17 | - 29092:29092 18 | environment: 19 | KAFKA_BROKER_ID: 1 20 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 21 | KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092 22 | KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT 23 | KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT 24 | KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 25 | KAFKA_OFFSETS_TOPIC_NUM_PARTITIONS: 1 26 | KAFKA_MIN_INSYNC_REPLICAS: 1 27 | KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true" 28 | 29 | schema-registry: 30 | image: confluentinc/cp-schema-registry:latest 31 | depends_on: 32 | - zookeeper 33 | - kafka 34 | ports: 35 | - 8081:8081 36 | environment: 37 | SCHEMA_REGISTRY_HOST_NAME: localhost 38 | SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: PLAINTEXT://kafka:9092 39 | -------------------------------------------------------------------------------- /kafka-mtls/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | 3 | zookeeper: 4 | image: confluentinc/cp-zookeeper:latest 5 | ports: 6 | - 22181:2181 7 | environment: 8 | ZOOKEEPER_CLIENT_PORT: 2181 9 | ZOOKEEPER_TICK_TIME: 2000 10 | 11 | kafka: 12 | image: confluentinc/cp-kafka:latest 13 | hostname: kafka 14 | depends_on: 15 | - zookeeper 16 | ports: 17 | - 29092:29092 18 | - 29093:29093 19 | environment: 20 | KAFKA_BROKER_ID: 1 21 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 22 | KAFKA_LISTENERS: PLAINTEXT://kafka:29092,SSL://kafka:29093,BROKER://kafka:9092 23 | KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:29092,SSL://localhost:29093,BROKER://kafka:9092 24 | KAFKA_INTER_BROKER_LISTENER_NAME: BROKER 25 | KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,SSL:SSL,BROKER:PLAINTEXT 26 | KAFKA_SSL_KEYSTORE_FILENAME: server.keystore.pkcs12 27 | KAFKA_SSL_KEYSTORE_CREDENTIALS: creds_keystore 28 | KAFKA_SSL_KEY_CREDENTIALS: creds_sslkey 29 | KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 30 | KAFKA_OFFSETS_TOPIC_NUM_PARTITIONS: 1 31 | KAFKA_MIN_INSYNC_REPLICAS: 1 32 | KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true' 33 | volumes: 34 | - ./ssl:/etc/kafka/secrets 35 | -------------------------------------------------------------------------------- /database/src/test/java/karate/DogsTest.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Results; 4 | import com.intuit.karate.Runner; 5 | import io.karatelabs.examples.database.Application; 6 | import static org.junit.jupiter.api.Assertions.*; 7 | import org.junit.jupiter.api.Test; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.test.context.SpringBootTest; 12 | import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; 13 | 14 | @SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) 15 | class DogsTest { 16 | 17 | static final Logger logger = LoggerFactory.getLogger(DogsTest.class); 18 | 19 | @Autowired 20 | private ServletWebServerApplicationContext webContext; 21 | 22 | @Test 23 | void testFeature() { 24 | int port = webContext.getWebServer().getPort(); 25 | logger.debug("server port detected as: {}", port); 26 | Results results = Runner.path("classpath:karate/dogs.feature") 27 | .systemProperty("server.port", port + "") 28 | .parallel(1); 29 | assertEquals(0, results.getFailCount(), results.getErrorMessages()); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /kafka-mtls/ssl/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDiTCCAnGgAwIBAgIJAN7uVLWpEtQTMA0GCSqGSIb3DQEBCwUAMDAxCzAJBgNV 3 | BAYTAlVTMRQwEgYDVQQKDAtLYXJhdGUgTGFiczELMAkGA1UEAwwCY2EwHhcNMjMx 4 | MjA2MDgyNTI4WhcNMjQxMjA1MDgyNTI4WjAwMQswCQYDVQQGEwJVUzEUMBIGA1UE 5 | CgwLS2FyYXRlIExhYnMxCzAJBgNVBAMMAmNhMIIBIjANBgkqhkiG9w0BAQEFAAOC 6 | AQ8AMIIBCgKCAQEAviBwCANI/NLnUtkTbmerkO+8ySMNciLO+eNe+E5thH3Vg1GQ 7 | Yyj5vFL3tOCw6l4UTRAV4rXLSnMMEA2R1kAmKwlk+w45yg3b2kNdTq8mtgrqOv6/ 8 | NtkKjqLl3QKl8JfeIcmB9Rh8VstYZXdkQ48XKLd0gAaGDfh2pWzjiGGDP8tdEVYa 9 | n5a18rlZ8UFaWNtTbFm4mya4EQQEeSspYn00wcdqmklQUQ7OrBBFpHjlbUDurj4Q 10 | Ci9MZvC5WFwh8VFDCD/zaTlQ8quuw/peITlkJT2cUW6Gd9pBIjxCmuNx1THsns2Y 11 | nLjrBUQ8rvc0Kz4fV93DZsjmRdzE0MtSRQ/fPwIDAQABo4GlMIGiMB0GA1UdDgQW 12 | BBR2IEmMF5SOg5uCMaJ41aPfb3OcsDAPBgNVHRMBAf8EBTADAQH/MGAGA1UdIwRZ 13 | MFeAFHYgSYwXlI6Dm4IxonjVo99vc5ywoTSkMjAwMQswCQYDVQQGEwJVUzEUMBIG 14 | A1UECgwLS2FyYXRlIExhYnMxCzAJBgNVBAMMAmNhggkA3u5UtakS1BMwDgYDVR0P 15 | AQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBercJWzrHx05fjj8+r8q3vUWuz 16 | iqhCBs3H8k+48PcHjEqAKKdIttdysJE1g95LNEeQD23NSM1d5mJU9fmQcN2UUv7D 17 | 2dbMB3/nV27YoS93srOPyGPpf2qmE0LQtDTt1M+H+hhWJIlFvMkdvxS86XK9tpiz 18 | c1ZkgHgP9PgITYKaCUl7B30lFXWk3QJQ4ns8TZDIoaPAv52/UrDvWz1drk9rQneN 19 | u7yX3WpqdCJq1SxBq9TarPZZvAgnUkMS3i143F4Zt51pFnzr3S3PEfb71AloAOpw 20 | AoMrapFGkTrURJL+kcgDeQMY72vsy6cdGRQ/NJxMzaSFRqQlsqEoWvzhjg5W 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /spring-boot/README.md: -------------------------------------------------------------------------------- 1 | # Karate and Spring Boot 2 | 3 | Since Karate fits well into Maven and Gradle projects, it is easy to run Karate tests as part of a Spring Boot project. You can start and stop the main application from a JUnit class and then run your Karate test-suite. 4 | 5 | * [examples/database](../database/README.md) - this is a "standard" Spring Boot project that shows how to combine Karate with the `@SpringBootTest` annotation to test a REST service as well as a database via JDBC 6 | * [examples/ssl](../ssl/README.md) - another minimal Spring Boot project that shows how to test SSL / MTLS using client-side certificates configured. 7 | * [karate-demo](https://github.com/karatelabs/karate/tree/master/karate-demo) - this is part of the main Karate open-source project, and has examples of how to use Karate to test a Spring Boot application 8 | * [consumer-driven-contracts](https://github.com/karatelabs/karate/tree/master/examples/consumer-driven-contracts) - this is a multi-module Maven project that is focused on testing a Spring Boot application 9 | * [hello-karate](https://github.com/Sdaas/hello-karate) - an example created by the community, which tests a Spring Boot REST service using Karate from within IntelliJ, Maven, and Gradle. 10 | 11 | ## Further Reading 12 | 13 | [Karate and Spring Boot on Stack Overflow](https://stackoverflow.com/search?q=%5Bkarate%5D+spring+boot) 14 | 15 | -------------------------------------------------------------------------------- /grpc-custom/src/test/java/karate/GrpcUtils.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Logger; 4 | import com.intuit.karate.core.ScenarioEngine; 5 | import io.grpc.Server; 6 | import io.karatelabs.examples.grpc.HelloClient; 7 | import io.karatelabs.examples.grpc.HelloServer; 8 | 9 | public class GrpcUtils { 10 | 11 | private static final GrpcUtils INSTANCE = new GrpcUtils(); 12 | 13 | private final HelloClient client; 14 | 15 | private GrpcUtils() { 16 | try { 17 | Server server = HelloServer.start(0); 18 | client = new HelloClient("localhost", server.getPort()); 19 | } catch (Exception e) { 20 | throw new RuntimeException(e); 21 | } 22 | } 23 | 24 | private static Logger logger() { 25 | ScenarioEngine engine = ScenarioEngine.get(); 26 | return engine.logger; 27 | } 28 | 29 | // the logging will appear in the html report for grpc.feature 30 | public static String hello(String message) { 31 | Logger logger = logger(); 32 | logger.debug("grpc call to hello()"); 33 | logger.debug("===================="); 34 | logger.debug(">> hello: {}", message); 35 | String result = INSTANCE.client.hello(message); 36 | logger.debug("<< hello: {}", result); 37 | return result; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /kafka-mtls/ssl/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDjjCCAnagAwIBAgIJAMcRVm7v9DVlMA0GCSqGSIb3DQEBCwUAMDAxCzAJBgNV 3 | BAYTAlVTMRQwEgYDVQQKDAtLYXJhdGUgTGFiczELMAkGA1UEAwwCY2EwHhcNMjMx 4 | MjA2MDgyNTU5WhcNMzMxMjAzMDgyNTU5WjAzMQswCQYDVQQGEwJVUzEUMBIGA1UE 5 | CgwLS2FyYXRlIExhYnMxDjAMBgNVBAMMBWthZmthMIIBIjANBgkqhkiG9w0BAQEF 6 | AAOCAQ8AMIIBCgKCAQEAw/4wyr0Nk7Zid6eF/YEuLV5ow2LiOtaBb0yrgRToiOuM 7 | bhiImc8jLx3lBQA1y5tjlilnaVS1tWM3p4hEF/aDqv/ve7mxdsnHUD9JFkwQSGiM 8 | ML5KYvUGDgAC68j69o01bQZqv2BZFZEa6TepDj5fwz+p9FGD1N2F4jIOJI1p/pL8 9 | 5qSlHfZup9qbE02TnrwQMOKj5NIzu3cw/rUlo8xn4+Tt0ojcqhTP+HaQEu2xaZlj 10 | FMbx87GCGeTpCXXnIyF4VFrx/ZkOgaAspm5nXLKvNCxTxwJHBKxNCVm5aHgaYd0O 11 | 5g6pZRDkaXJ8ePKu2d9pQIVUvP3C4KdRUEvpAu4AqwIDAQABo4GnMIGkMB0GA1Ud 12 | DgQWBBTuUuupXC/x8W0D/TB9Nx4BTvN42zAJBgNVHRMEAjAAMCwGCWCGSAGG+EIB 13 | DQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAOBgNVHQ8BAf8EBAMC 14 | BaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBsGA1UdEQQUMBKCBWth 15 | Zmthgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAL2WHxZQQdMwlWp2fs9f 16 | D5WShSG8dvELB7foC2vKn57/DmLWsnaiLZs8PH6MMXC8FyLHlS/qlgp2CWHG/P7d 17 | nBuElGn8o4pL2znA4+xBG7f1sCuNT+PG/zG5x+sxqCor8iObw2IWVUTbKt6oQNsg 18 | 8J/fVb11TUt0AvPwk/HqRlQyJFPv1GprOsaK4JE1BlLewbkDVG9Bx+0UAYBqcdnB 19 | wP8bv3h51CogesYgULZeq49SHVQ+uxc5rxysSenz2TmJUUnRuXCeczPB93jJrU/4 20 | 5yExhJsS6v6Zr3uHTW59oxQz+QVk8v6ax+liZsu6omk7Krcz9eD7PqkoGH1UOJYn 21 | uXU= 22 | -----END CERTIFICATE----- 23 | -------------------------------------------------------------------------------- /ssh/README.md: -------------------------------------------------------------------------------- 1 | # Karate and SSH 2 | 3 | Using the [Jsch](https://github.com/mwiede/jsch) Java library it is possible to open an SSH connection from Karate and send commands. This project provides a starting point and can be easily extended to return output to Karate for assertions or performing conditional logic. 4 | 5 | > Note that we use a fork of the popular [Jsch](http://www.jcraft.com/jsch) library which supports stricter security, needed by AWS EC2 instances for example. 6 | 7 | A test can be very simple as seen in [ssh.feature](src/test/java/karate/ssh.feature). 8 | 9 | Most of the work is handled by [`SshSession.java`](src/test/java/karate/SshSession.java). It takes care of opening a connection and returning an object (itself) that can be used to send command to the remote server. 10 | 11 | If you need more functionality, you can use the Karate core [Command](https://github.com/karatelabs/karate/blob/master/karate-core/src/main/java/com/intuit/karate/shell/Command.java) and [Console](https://github.com/karatelabs/karate/blob/master/karate-core/src/main/java/com/intuit/karate/shell/Console.java) classes as a reference to run a background thread, collect server output and make it available to the Karate / calling script. 12 | 13 | Please do consider improving this example and contributing code back to this project ! 14 | 15 | ## Further Reading 16 | [Karate and CLI / Bash](../cli/README.md) -------------------------------------------------------------------------------- /websocket/src/test/java/karate/stomp.feature: -------------------------------------------------------------------------------- 1 | Feature: tests the following spring-websocket example 2 | https://github.com/spring-guides/gs-messaging-stomp-websocket 3 | 4 | Background: 5 | * def result = 6 | """ 7 | function(name) { 8 | var session = karate.get('session'); 9 | var message = { command: 'SEND', headers: { destination: '/app/hello' }, body: { name: name } }; 10 | session.send(message); 11 | var response = session.pop(); 12 | return response.body.content; 13 | } 14 | """ 15 | 16 | Scenario: 17 | * def session = karate.channel('websocket') 18 | * session.url = 'ws://localhost:8080/gs-guide-websocket' 19 | * def Adapter = Java.type('karate.StompAdapter') 20 | * session.adapter = new Adapter() 21 | * session.start() 22 | * session.send({ command: 'CONNECT', headers: { 'accept-version': '1.2', 'heart-beat': '0,0' } }) 23 | * match session.pop() contains { command: 'CONNECTED' } 24 | * session.send({ command: 'SUBSCRIBE', headers: { id: 'sub-0', destination: '/topic/greetings' } }) 25 | 26 | * match result('foo') == 'Hello, foo!' 27 | * match result('bar') == 'Hello, bar!' 28 | 29 | * session.send({ command: 'DISCONNECT', headers: { receipt: 'disc-0' } }) 30 | * match session.pop() contains { command: 'RECEIPT', headers: { 'receipt-id': 'disc-0' } } 31 | * session.stop() 32 | -------------------------------------------------------------------------------- /kafka/README.md: -------------------------------------------------------------------------------- 1 | # Karate Kafka 2 | 3 | Karate has native support for [Apache Kafka](https://kafka.apache.org) as an optional dependency (non-open source and commercial). Enterprise users can find more information here: [Karate-Kafka](https://github.com/karatelabs/karate-addons/tree/main/karate-kafka). 4 | 5 | A license is required for running (for e.g. in CI/CD) and a Karate Labs IDE subscription is required per developer seat. 6 | 7 | This sample project shows how to use the Avro and plain-JSON support. Make sure you have a `.karate/karate.lic` file in place before running the example. 8 | 9 | ## Running 10 | * Docker is required to start the Kafka broker and Zookeeper. There is a `docker-compose.yml` file in this project. 11 | * Run the following commands 12 | * `docker compose up -d` 13 | * `mvn test` 14 | * To stop the Docker containers run `docker compose down` 15 | 16 | ## Further Reading 17 | * [kafka-custom](../kafka-custom/README.md) - it is possible to test Kafka by writing the Java integration code yourself and generating Java code, but the approach above is recommended 18 | * [kafla-mtls](../kafka-mtls/README.md) - using MTLS (SSL / Auth) with Kafka and also includes an example of hybrid API + Kafka testing 19 | * [community-example](https://github.com/Sdaas/karate-kafka) - a community project that provides a generic approach to testing Kafka with Karate, but requires you to to write / generate Java code. -------------------------------------------------------------------------------- /kafka/src/test/java/karate/kafka.feature: -------------------------------------------------------------------------------- 1 | Feature: karate-kafka demo 2 | 3 | Background: 4 | * configure kafka = 5 | """ 6 | { 7 | 'bootstrap.servers': '127.0.0.1:29092', 8 | 'schema.registry.url': 'http://localhost:8081' 9 | } 10 | """ 11 | 12 | Scenario: 13 | * def channel = karate.channel('kafka') 14 | * channel.register({ name: 'hello', path: 'classpath:karate/hello.avsc' }) 15 | 16 | * def consumer = channel.consumer() 17 | 18 | * consumer.topic = 'test-topic' 19 | * consumer.count = 2 20 | * consumer.filter = x => x.key != 'zero' 21 | * consumer.timeout = 5000 22 | * consumer.start() 23 | 24 | * def producer = channel.producer() 25 | 26 | * producer.topic = 'test-topic' 27 | * producer.schema = 'hello' 28 | * producer.key = 'zero' 29 | * producer.value = { message: 'hello0', info: { first: 0, second: false } } 30 | * producer.send() 31 | 32 | * producer.headers = { foo: 'bar1', baz: 'ban1' } 33 | * producer.key = 'first' 34 | * producer.value = { message: 'hello1', info: { first: 1, second: true } } 35 | * producer.send() 36 | 37 | * producer.key = 'second' 38 | * producer.headers = null 39 | * producer.value = { message: 'hello2', info: { first: 2, second: false } } 40 | * producer.send() 41 | 42 | * def response = consumer.collect() 43 | * match response[0].key == 'first' 44 | * match response[0].headers == { foo: 'bar1', baz: 'ban1' } 45 | * match response[1].value == { message: 'hello2', info: { first: 2, second: false } } -------------------------------------------------------------------------------- /kafka-mtls/README.md: -------------------------------------------------------------------------------- 1 | # Karate Kafka MTLS 2 | 3 | This is an additional example for [Karate Kafka](../kafka/README.md) that shows how to use MTLS and client-side authentication. 4 | 5 | This section of the test in [kafka-json.feature](src/test/java/karate/kafka-json.feature) sets up client-side SSL: 6 | 7 | ```cucumber 8 | * configure kafka = 9 | """ 10 | { 11 | 'bootstrap.servers': 'localhost:29093', 12 | 'security.protocol': 'SSL', 13 | 'ssl.truststore.location': 'ssl/client.truststore.pkcs12', 14 | 'ssl.truststore.password': 'karate' 15 | } 16 | """ 17 | ``` 18 | 19 | Here the [docker-compose.yml](docker-compose.yml) configures Kafka to use SSL. This example does not use the schema registry. 20 | 21 | The certificates and related files in the [/ssl](ssl) folder were created using [conf/commands.txt](conf/commands.txt). 22 | 23 | ## Hybrid Test 24 | This example also contains an example of how to mix API and Kafka tests, which is a common scenario. 25 | 26 | Refer to [kafka-hybrid.feature](src/test/java/karate/kafka-hybrid.feature). Note how `karate.consume()` is called at the start of the test before any other actions. 27 | 28 | Commands were adapted from these references: 29 | * [Setting up Encryption](https://developer.confluent.io/courses/security/hands-on-setting-up-encryption) 30 | * [Encrypting Traffic](https://developer.confluent.io/courses/security/hands-on-requiring-encryption-for-broker-traffic/) 31 | * [GitHub Repo](https://github.com/confluentinc/learn-kafka-courses/tree/main/fund-kafka-security) -------------------------------------------------------------------------------- /ssl/src/main/java/io/karatelabs/examples/ssl/TestService.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.ssl; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 5 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 6 | import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | @Configuration 13 | @EnableAutoConfiguration(exclude = {SecurityAutoConfiguration.class, DataSourceAutoConfiguration.class}) 14 | public class TestService { 15 | 16 | @RestController 17 | @RequestMapping("/test") 18 | class TestController { 19 | 20 | @GetMapping 21 | public String test() { 22 | return "{ \"success\": true }"; 23 | } 24 | 25 | } 26 | 27 | public static void main(String[] args) { 28 | String[] customArgs = { 29 | "--server.port=8080", 30 | "--server.ssl.key-store=src/main/resources/server-keystore.p12", 31 | "--server.ssl.key-store-password=karate-mock", 32 | "--server.ssl.keyStoreType=PKCS12", 33 | "--server.ssl.keyAlias=karate-mock"}; 34 | SpringApplication.run(TestService.class, customArgs); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /database/src/test/java/karate/DbUtils.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.jdbc.core.JdbcTemplate; 8 | import org.springframework.jdbc.datasource.DriverManagerDataSource; 9 | 10 | public class DbUtils { 11 | 12 | private static final Logger logger = LoggerFactory.getLogger(DbUtils.class); 13 | 14 | private final JdbcTemplate jdbc; 15 | 16 | public DbUtils(Map config) { 17 | String url = (String) config.get("url"); 18 | String username = (String) config.get("username"); 19 | String password = (String) config.get("password"); 20 | String driver = (String) config.get("driverClassName"); 21 | DriverManagerDataSource dataSource = new DriverManagerDataSource(); 22 | dataSource.setDriverClassName(driver); 23 | dataSource.setUrl(url); 24 | dataSource.setUsername(username); 25 | dataSource.setPassword(password); 26 | jdbc = new JdbcTemplate(dataSource); 27 | logger.info("init jdbc template: {}", url); 28 | } 29 | 30 | public Object readValue(String query) { 31 | return jdbc.queryForObject(query, Object.class); 32 | } 33 | 34 | public Map readRow(String query) { 35 | return jdbc.queryForMap(query); 36 | } 37 | 38 | public List> readRows(String query) { 39 | return jdbc.queryForList(query); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /rabbitmq/src/test/java/io/karatelabs/examples/rabbitMQ/KarateRMQProducer.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.rabbitMQ; 2 | 3 | import com.rabbitmq.client.Channel; 4 | import com.rabbitmq.client.Connection; 5 | import com.rabbitmq.client.ConnectionFactory; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.io.IOException; 10 | import java.util.concurrent.TimeoutException; 11 | 12 | public class KarateRmqProducer { 13 | 14 | private static final Logger logger = LoggerFactory.getLogger(KarateRmqProducer.class); 15 | 16 | private final Channel channel; 17 | private final String queueName; 18 | 19 | public KarateRmqProducer(String queueName) { 20 | this.queueName = queueName; 21 | try { 22 | ConnectionFactory factory = new ConnectionFactory(); 23 | factory.setUsername("guest"); 24 | factory.setPassword("guest"); 25 | factory.setHost("localhost"); 26 | factory.setPort(5672); 27 | Connection connection = factory.newConnection(); 28 | channel = connection.createChannel(); 29 | channel.queueDeclare(queueName, false, false, false, null); 30 | logger.debug("init producer"); 31 | } catch (IOException | TimeoutException e) { 32 | throw new RuntimeException(e); 33 | } 34 | } 35 | 36 | public void putMessage(String msg) throws IOException { 37 | channel.basicPublish("", queueName, null, msg.getBytes()); 38 | logger.debug("put message: '{}'", msg); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /grpc-custom/README.md: -------------------------------------------------------------------------------- 1 | # Karate and gRPC (custom) 2 | 3 | > [!NOTE] 4 | > The [built-in support for gRPC](https://github.com/karatelabs/karate-addons/blob/main/karate-grpc/README.md) is recommended instead of this approach below. The advantage is that you don't need to generate and compile Java code. 5 | 6 | This sample project demonstrates how you can test gRPC if your implementation is in Java. It also demonstrates concepts you can use for any case where you use Java interop to connect Karate to any custom code, library or communication protocol. 7 | 8 | When you use well designed utility classes, your Karate tests will be clean and only focus on making a call and what data is sent and received. 9 | 10 | For example if you look at [`grpc.feature`](src/test/java/karate/grpc.feature) the test is just one line. Behind the scenes a gRPC server and client is initialized and the call is made. The HTML report even includes details of the call and the messages on the wire, which you can easily customize. 11 | 12 | Rather than attempt a generic and dynamic approach, this approach shown here can re-use your existing gRPC implementation code-base and domain classes. If your gRPC implementation is in another language, you can still use this approach, but use Maven (or Gradle) to generate the Java code from the `.proto` files. 13 | 14 | ## Further Reading 15 | 16 | * [Karate Official Support for gRPC](https://github.com/karatelabs/karate-addons/blob/main/karate-grpc/README.md) - recommended 17 | * [karate-grpc](https://github.com/pecker-io/karate-grpc) - This is significantly out of date and not recommended any more, but remains here as a reference. This is a community project that provides a generic approach to testing gRPC with Karate 18 | -------------------------------------------------------------------------------- /grpc/src/test/java/io/karatelabs/examples/grpc/HelloJavaRunner.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.grpc; 2 | 3 | import io.grpc.Server; 4 | import org.junit.jupiter.api.*; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.util.List; 9 | 10 | 11 | class HelloJavaRunner { 12 | 13 | static final Logger logger = LoggerFactory.getLogger(HelloJavaRunner.class); 14 | 15 | static Server server; 16 | HelloClient client; 17 | 18 | @BeforeAll 19 | static void beforeAll() throws Exception { 20 | server = HelloServer.start(0, true); 21 | } 22 | 23 | @AfterAll 24 | static void afterAll() { 25 | server.shutdownNow(); 26 | } 27 | 28 | @BeforeEach 29 | void beforeEach() { 30 | client = new HelloClient(server.getPort(), true); 31 | } 32 | 33 | @AfterEach 34 | void afterEach() throws Exception { 35 | client.shutdown(); 36 | } 37 | 38 | @Test 39 | void testHello() throws Exception { 40 | String result = client.hello("world"); 41 | logger.debug("response is: {}", result); 42 | } 43 | 44 | @Test 45 | void testLotsOfReplies() throws Exception { 46 | List result = client.lotsOfReplies("world"); 47 | logger.debug("response is: {}", result); 48 | } 49 | 50 | @Test 51 | void testLotsOfGreetings() throws Exception { 52 | String result = client.lotsOfGreetings("foo", "bar", "baz"); 53 | logger.debug("response is: {}", result); 54 | } 55 | 56 | @Test 57 | void testBidiHello() throws Exception { 58 | List result = client.bidiHello("foo", "bar", "baz"); 59 | logger.debug("response is: {}", result); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /database/src/main/java/io/karatelabs/examples/database/DogsController.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.database; 2 | 3 | import java.util.Collection; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.jdbc.core.JdbcTemplate; 7 | import org.springframework.jdbc.core.RowMapper; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | @RestController 16 | @RequestMapping("/dogs") 17 | public class DogsController { 18 | 19 | @Autowired(required = true) 20 | private JdbcTemplate jdbc; 21 | 22 | private final AtomicInteger counter = new AtomicInteger(); 23 | 24 | private static final RowMapper ROW_MAPPER = (rs, rowNum) -> new Dog(rs.getInt("ID"), rs.getString("NAME")); 25 | 26 | @PostMapping 27 | public Dog create(@RequestBody Dog dog) { 28 | int id = counter.incrementAndGet(); 29 | dog.setId(id); 30 | jdbc.update("INSERT INTO DOGS(ID, NAME) values(?, ?)", dog.getId(), dog.getName()); 31 | return dog; 32 | } 33 | 34 | @GetMapping 35 | public Collection list() { 36 | return jdbc.query("SELECT * FROM DOGS", ROW_MAPPER); 37 | } 38 | 39 | @GetMapping("/{id:.+}") 40 | public Dog get(@PathVariable int id) { 41 | return jdbc.queryForObject("SELECT * FROM DOGS D WHERE D.ID = ?", ROW_MAPPER, id); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /aws-dynamodb/src/test/java/examples/DynamoDbUtils.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; 4 | import software.amazon.awssdk.regions.Region; 5 | import software.amazon.awssdk.services.dynamodb.DynamoDbClient; 6 | import software.amazon.awssdk.services.dynamodb.model.AttributeValue; 7 | import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; 8 | import software.amazon.awssdk.services.dynamodb.model.GetItemResponse; 9 | 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | 13 | public class DynamoDbUtils { 14 | 15 | final DynamoDbClient db; 16 | 17 | public DynamoDbUtils() { 18 | db = DynamoDbClient.builder() 19 | .credentialsProvider(ProfileCredentialsProvider.create("myAwsProfile")) 20 | .region(Region.US_EAST_2) 21 | .build(); 22 | } 23 | 24 | public Map getItem(String keyValue) { 25 | Map keyToGet = new HashMap<>(); 26 | keyToGet.put("myPrimaryKeyName", AttributeValue.builder().s(keyValue).build()); 27 | // keyToGet.put("mySecondaryKeyName", AttributeValue.builder().s(keyValue).build()); 28 | GetItemRequest get = GetItemRequest.builder().key(keyToGet).tableName("myTableName").build(); 29 | GetItemResponse response = db.getItem(get); 30 | if (!response.hasItem()) { 31 | System.out.println("item not found by key: " + keyValue); 32 | return null; 33 | } 34 | Map row = response.item(); 35 | Map result = new HashMap<>(); 36 | result.put("myFieldName", row.get("myFieldName").s()); 37 | return result; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /grpc/src/test/java/client.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEnDCCAoQCAQEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJbG9jYWxob3N0 3 | MB4XDTI0MDYwNDA1MTIwOVoXDTI1MDYwNDA1MTIwOVowFDESMBAGA1UEAwwJbG9j 4 | YWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoIUrc4hp60cx 5 | eVI+o5fucyFX4chWqXY33Ie4wP/oMHijVx61QXR6XgyTiWRb1widoYVg1gikt/2m 6 | C98FcPY5FH8T0rtiePaTXVy+1ibAt4Po31M/7fZ21U+UFglQ0ezU1FombLgj0cdt 7 | AoJeJelQUB3SLfQ8LNgopN8vwtGYWSb3oTCVBurB3EkYiwtGtkxeeADVPYm6msXi 8 | 6AO2GFtX4PbLJZYhv37oIDuOiZMG9HTy/CE7e1eunfSAw8W/cVw3wJQtKQ8tx++k 9 | cUnMkNyr4s1NePSJg1Mbx9tm/0dzyqWe4UZQYVZQrSm8ZS2aKuIdP/Qc+vxmVQEm 10 | QqEwjwrsZ4E5ZKK/XDmcL9RI86Y0tRzIv/KGDRV+jqFe7gdgRF7MC9H4X82eZL1v 11 | gthp7xa/nT8GzvlCYa/ocvA7XOYob/0hrotdDTkXoHqTkp6+YHzckeUPF1Lq+DxM 12 | y4AOiDaAQQFwK+e+ubMUZTvgc+3W8nA+E7X0o4X7hgiUElO78rHDxWqdVeuRBvFf 13 | GtFqVQ+kH+hiB8Fvxgaf02HFjSxDKsTdPTCtIey1O8CfmCE3/Jp6c7CSmbN+YPuP 14 | +QXFl3mkpf+JAQ0+XOmbsTo8xNcDlXLO6EUm+I3g59YhXvdLUD6uZ6A3ZrplV1mV 15 | TGVpUbEUV9YuDXXHniQtRLOeDbM5gjMCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA 16 | xjsB5txNy1xb7hnSFMs534boOtb7erVXAZMV2lqYSMex+ZajRfnHXHoy0j8R1tC2 17 | IFID0CIURuXriCR42GzyGVrU5CPVkoMiSFCHvhyKOkBM7BmOdM4zmD+v5z/LKl/f 18 | gq4EbCs8cYAgG9Ms0odiXIGxdiLQ5lrEmNf9/EsBS7IjFESMb0dH6JQsSV4evqwt 19 | xw07SFh+dCtcrkvtdhXpdSEzCPAeKmqAqC+7zmOdT2KZ7QfxOcuh7Y4bNT6T34dH 20 | iI5HnKhxJn0sWAon+FME0UKYNkKyq5FC6nhGCsD58gwwtSNgkQlWGDQqStsssohe 21 | vj/tvzZBtJH/Q3Cqkv8MytTfIyFtX/ygB4Y8spSUqcpzSJXjRIKl/nONmMX2hqXC 22 | 4UJfIzv47Z/6n+8G49iL76M2tMzsFrmUYzdl4i6isMV9iNsUEy+O3fazbCkcOlsd 23 | kJ6YAzk3iBJ1zX8bipBnRCejwbRzWVyvO4flFp611Zehruwn3CXMJEO0ZuW0BzTJ 24 | de9ihWzsJgW5IYXukR8lhyEPBVtJom/rN87KM/TBRt48wxXKM5tRxBlHMzwnmlje 25 | kz67pH03PjRj/KsUaBK5hUhZ5nmk9idN0HRIhwqyr3Ky05Ix7M9aPEesUWUK94mh 26 | ACSx2Gi4Ox+ZMHTgK80JfkfncJ98AI5kvhVqoZr6pY4= 27 | -----END CERTIFICATE----- 28 | -------------------------------------------------------------------------------- /grpc/src/test/java/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEnDCCAoQCAQEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJbG9jYWxob3N0 3 | MB4XDTI0MDYwMzEyMjAzNloXDTI1MDYwMzEyMjAzNlowFDESMBAGA1UEAwwJbG9j 4 | YWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyXEvssp1PHs5 5 | XXCJDI7WEpqt4rZlBDWZrKNP1/mIAJOPXluZMhWwtGxqnWiJqSVwfCdoYIB8Ycmv 6 | y9LQ2hfTKQKjTVGIKgMvnQJst1koDjhlPnJYKdezYyX4N+RhYRT0hxmJkrAubCxt 7 | /e7kOP9/hWqfgDmpDjTnXJxl/uAa8WciWSXA2IVTXKY7NtevZLZc0DZx5aXqIGqm 8 | p0xKT1VykKNpOQijvSxBh2aIdi6ftjUbTWL08R5g2No7FVN+VfUN1fziobkrX23t 9 | bQqXoIib8txdqgySt2hTze/FKH63uVTS5zEMqAUCDd85/GPO1LtzjgqIZR1j5lHO 10 | ONxdyVR7YM6JumWv42zvNwrNc/l3vs5xJwHTvdXo5KaQFlR1d34rBYbIxeeYYK+n 11 | AZSHFZ698fvsGr2V4XFfsrrpl7bdjH9i3G3kPgbPPxG78VV0+/fnR7B7MLuRoxAx 12 | tdGFeu/PsSJ/R6SR8Fx2WB7RQ6VUQ//XUwgcX240omSCQMt2naOcIpVxSt7ay908 13 | KPaaN1Vbqvoxh5g1knneZ7p5C8AE0vC8P+qS2UEoa6Yzb/WRK3sSQKuIJX9pV1d+ 14 | lQwvcZfsS+IxH7I/QnOE3qxxmvnI8oY6qxT/khBr9azKT+nifFMbho023w80thaH 15 | HXkuZZIHyfnSfNRsKoxK8C0i0JmRRE8CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA 16 | YeTwTwkoVoazXS/Vzh8DfxxHZVv2EUZkfW1GmUwUsNgsdwB+rLUt/YKAz3IXo6GR 17 | znWOcoV/zXkjrMJu6Mwtyy4JoRsq6yk/1sR9LUarn0AlVbMPdNAXlIxkQKC/EunS 18 | l/+jzzNAsDX2uTfImAE6OaU4J0F/3DF04HwIQ8cxUBRKDCn4X3RPotmPS1bOquG+ 19 | 5nlH8GZmPh1qQLIwgJQHk4sqtbHcSju6t9ljuIIrxYmxjPIOB31vMAuzNXU6UKiM 20 | 8YtdrwHxGVpRr9X5rzkslg134Qa5RZrxt3HIIeg9xErFSRQZaPxGzdj1pUmmnsHZ 21 | UaVkjr7LBuBGuDNurjrCI0Po4cWogdJMNFAG3dPRor99gnuZvreHVWC4WLGIe8op 22 | a0dWpdv+RQLsDWgU7as+qFDm7E6iaf1PPvzMNm43WaOyIolXXOeWRSWsBLamlKIS 23 | Tr9jPIj3/9W8SW6+M5CDeym4Wu+t5fHHujJCpKLqwzExtOU8jjvanKAeGhFeofNZ 24 | QtzxRreTcfd1D6fivjABKgd91jS40tviz5SingYduI3YpSlgRQSYAt4pQx/67bOq 25 | 0E1jcwFdj8tRH0LOJbs0aEVm01IikEoUfDMAJvGAvxVkQrYcEh4jucTRu9U60vmR 26 | bVXXL+gMQd2YXeLJyFK6IP8nh/3Etc0eW5DNkDMJXa4= 27 | -----END CERTIFICATE----- 28 | -------------------------------------------------------------------------------- /grpc/src/test/java/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEpDCCAowCCQCK6TA8xYooLTANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls 3 | b2NhbGhvc3QwHhcNMjQwNjAzMTIyMDE5WhcNMjUwNjAzMTIyMDE5WjAUMRIwEAYD 4 | VQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDe 5 | Xoaqu1WzdzNEi8LDjvQ7PPpCa7HTP7ymH6SriKbGrXBa3u8VY4OJgrcCrk85lf0j 6 | 67mTGLn8Z07404kYx8ZCHKqf3Y5Dqq32u58+LVN08Zj2zBy9XcGI5SDWhKzDB8q4 7 | xTfw3eco9lSJBzMPscjqQYIOlLDKKzzAT5vktMnCEVuUBQRHRVxF8oF4l/Pi7riw 8 | LENuUvJvulw2P46V1qgIsVwkMPW5HRXAziwwQcAVVrFH69mDxiDiazohow+LjvC9 9 | nxQH5A6wntY1O/leUneFE2IPbWmU9hkj1x2kz3aN5cwnhll+3oscxsg0P/+sdbEf 10 | vR3udZaUGyXET40spIGevoXQU/wZf5P1ZeZjtCxCpCwMQ5DuQXPa5QbcLAQ1Roa8 11 | 4u3ey1nxO6Zf7AcFojO/DyyEGKeyGA63f4XIdNYBK2eUhu55maF91KOqOglI7Ys2 12 | JK5y1akWfGRQQVvOLH2jUB9TCjXxXmGHNa99cfuQl745qoDwMku3cAWoF2V5hPFq 13 | X00xUTeSQk9WEDVtkZ5cjB/zldTTzkiu4tz3qEALz5zMCFgPs8f2pke7k2GMq3N9 14 | armwmbNxFipHJMUQmyb2GRvYMo/oJUxpddp+0f6r9e8BP731aSHqgkr6gRsl9Cc1 15 | vFd1tLnfWlCcosJO5rU/46wKLI8QNRGp6wSQl4KkXQIDAQABMA0GCSqGSIb3DQEB 16 | CwUAA4ICAQANT87MPXF/Znl5ITVnvEDdigQZ9YG2XyJJnK6jng32tyzzz7UkPOmf 17 | 0ck3vwrvtqqKeHBi7NUe8Seqt3eOSNszB+t7l1njLfzOJgLLljTNI92wcbkrXaKh 18 | 1gYg8E37U5Tym3ylUzDQi/CHKZKuf+hc8pE3x/PtnxKtwHLlZK8WWErHWPjO6bkY 19 | /LvhbEoTUnkabd4sAi8zuziaGgMScUo8Ql1G8l+QEZLoDVJeFRJNkCFIN/N7S8Tg 20 | ZK6jRWfXOFoLxr9NRSGLs19Cp9NOxN6CxUbNIJfkV6HOAmyoFdQoxZ8e2jyh6q2F 21 | B+C0V81GAMQezhvSEsg3GSYeX8TXKiJSqmrpK8QmEnG9EZQzCLXtqJCejoJvSjy+ 22 | 5Fat48OhhLY0NK/4t7OM6lnI/+widCakFZ5kTfzqT6nNpX1k1Q+OjUhtj9Rz32d5 23 | Dk2SDTKZUVGomd+e0vrprgVytaRASHkZo1nojmHXOD1bm7538DNj3LrGdaflcFJD 24 | MeMcQEqzS/V/oUdhCl4VIz/QiDjjRpzLsxy3fQRIi08xtex1TuYIjYJQaubVM4wR 25 | qRL8Ma3Ztp2ymb3VGvVjnrT6YAUSjcxB2xTQ7xQRYpz5NSRbAndxRcB8sENRewv+ 26 | PYf1lmRhogJQJOT+os6mTujESUcNdWyC7Rsk0LaI+o1q5DktFxlNFA== 27 | -----END CERTIFICATE----- 28 | -------------------------------------------------------------------------------- /kafka-mtls/ssl/ca.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC+IHAIA0j80udS 3 | 2RNuZ6uQ77zJIw1yIs754174Tm2EfdWDUZBjKPm8Uve04LDqXhRNEBXitctKcwwQ 4 | DZHWQCYrCWT7DjnKDdvaQ11Orya2Cuo6/r822QqOouXdAqXwl94hyYH1GHxWy1hl 5 | d2RDjxcot3SABoYN+HalbOOIYYM/y10RVhqflrXyuVnxQVpY21NsWbibJrgRBAR5 6 | KylifTTBx2qaSVBRDs6sEEWkeOVtQO6uPhAKL0xm8LlYXCHxUUMIP/NpOVDyq67D 7 | +l4hOWQlPZxRboZ32kEiPEKa43HVMeyezZicuOsFRDyu9zQrPh9X3cNmyOZF3MTQ 8 | y1JFD98/AgMBAAECggEAMsY65QjrjwlL2aY7ODrbaKN9iUGhL5/4ImgETs+zE7T/ 9 | NkisBK9GsnJ90IJI/O4PAd2P2rGuDr3WtNrK3arYBppFq35LFJjK4+klnAPOlMMp 10 | doPd0On5lcoPFQzGABCus9s6p5fYbN11R/OwhRJLnwYPSLl1R3nZRahkw2E3Seux 11 | ddHEq4Sav3WNrX9tDTywJK/SexdFu6NDVyoimo8TwdxdJENyHjESIeYkq4wkswk7 12 | anHnPpApWkIoySO3HO28uS2Tb4S5n1MafpdMF6YaerKYrJGm6kLJ1/oJJxfDZ3b4 13 | z10q+DOF5LXB+LiF/Ng7AUOIO1XKiNREzYBlhiC3gQKBgQDpBlxqXEcuhwoV5C3l 14 | mROo4x2ke0pmCFztzZKXGJPHiZCdMMVcV3C8EaPBjIRgKfIi6Cy6FWX9/vgpWWxx 15 | PfFaqXbI+KlkVRd3CeiqiYaRqhxovqz2mu9BYUv8d+Y11IsO4OEQDKWVgtnHl18Z 16 | FspqOob1+HuQyWOiWAgXNPS5HwKBgQDQ30+KkLKUFive0UtaHlUAFVTl491cjUZc 17 | dq77tZIKeWtE4CGJpI8tgKWy53g/Ls1IZkz9IoTLjDk6NGeoCDo74GAxtTfxAL0d 18 | /OrIszG5KisvqlvxGpbdE6QNIj6Uga9RBrUuLYMkAjOYt18FcPqC3S15ZrmaqZIf 19 | bsUADOJ14QKBgAZ6dMtIMXprqq4dH+GINfG2Drbp7pGTnfHGi1LEDie3/VtBZdtB 20 | WxL/cowI+g0qXV73EXdC7Qj4s7GCmO81B6a7m1/O+faeHv7iOaO0GxeloRCQbIKW 21 | oBwzNkeYlb/dXthVDCzEDT5w2tkfrjcmWQ5G/kWMWPMXhjuXMvJiOIOFAoGAdzGo 22 | O4O9VMKeQGYhYQkEKqsBqrrw/LrmFyfnTV7dOzr02vYoTVrqFeZfKIvs0+mKXjF6 23 | 582GCH45vhxftsUTLk4pttQaW163jWBiPyv7SRZmVKocE6e/xeNKb/BF1At5l3yD 24 | chmox6i19wVVpU5Gtt0u8SOM8VSpPWTB6PhxVyECgYBq2XoLLm3DAduOuwKuTqOn 25 | 0DyaW0HNUJWcXjHvqOhAUAvOCcO4zIuAbfMPpaE0VNVWoCQIZTnkI6VdZViAaUjy 26 | iZGGBQCsqh1e50xll0H+/7mR5q6gyxuiPXNAX5jdtiJL9A/M9TwaCGrZ/G4JW5be 27 | GTIggRjjzkLjWr19Kc/LYw== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /kafka-mtls/ssl/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDD/jDKvQ2TtmJ3 3 | p4X9gS4tXmjDYuI61oFvTKuBFOiI64xuGIiZzyMvHeUFADXLm2OWKWdpVLW1Yzen 4 | iEQX9oOq/+97ubF2ycdQP0kWTBBIaIwwvkpi9QYOAALryPr2jTVtBmq/YFkVkRrp 5 | N6kOPl/DP6n0UYPU3YXiMg4kjWn+kvzmpKUd9m6n2psTTZOevBAw4qPk0jO7dzD+ 6 | tSWjzGfj5O3SiNyqFM/4dpAS7bFpmWMUxvHzsYIZ5OkJdecjIXhUWvH9mQ6BoCym 7 | bmdcsq80LFPHAkcErE0JWbloeBph3Q7mDqllEORpcnx48q7Z32lAhVS8/cLgp1FQ 8 | S+kC7gCrAgMBAAECggEAP7O9vheGcy1DgeqUNVooXRyjZmYca81OkpNT5weZsO8G 9 | XL5in8Nghy7rQh3YXk4qJyNb9jNPQB54d15l63f3Qbwf5ZHsaVSaEK4RHksou7An 10 | aKxg1xsWlbRRPru7PimVZNNCHOO+8LCSE51AuF1zmK13mu5nr+c0XdmxGRZRjik8 11 | p62vqN0tthMecnHhEDBZMZao/mZVtXX8/ILzAYEHVYSMk4W5wL0sjR/ZsNMXH1Mk 12 | zIB3kt+8IKY8i4Rf9TGm3upTnlYVGe+i6Gn60RuzNqE9k/CWDBg/jbNDkYZUaoUR 13 | BngGQyCZIpWeg2vC2dFa0FzXT3be6tj0x1igJV0oeQKBgQDgno7mm6cmVdKNHaKY 14 | 5VCuZbir0TmiXnYE/+H51cAIQG2Rl1WpnRNn/Juj3SA2ncVGsRZmB1V3EWqTZHfc 15 | lFgLnEsxXZWPlYoF4UYsIxQ09iGk6aa7rhhBDyXAR46XSJYHQNu3RAoehZXAUX/G 16 | aWgmoeRF1T4c1Rp3PnpIhG57dQKBgQDfX9EapWSPUi1/PI82EcW+C9LdtTaFnKgc 17 | i8Z5Qb9Nfxm8vJWgExBE7E+Py0OJBVIMXIL16GbfGheaQmt/WAxs6p6qqOklh89I 18 | KwyGznuDPXKHq831NeKdNMIJiTUbfdP8JkMT1pltmiIpvFbXmEecyJ/7Au6Ax69T 19 | FuK8Je6nnwKBgG/As1wsiObbwBuRaPok7RU3ar+hIsmTsagfHvDL1fTFCT5sSqRO 20 | j/8mgNDwDTzfFe1r4bb1YyIQOjQGwlOuQnfUVNzEsMp1Hex6/gyrjzwiUO7ZiKjL 21 | nymPPbsCXwEJjgshy67MXTR+RdkfMzEl9Dl0RjwwMezqYXZ+URyPNuCZAoGAFGDu 22 | d8rdCMJLik8hFaK7cqIrg7STm871+1y5J7ja1hwhYfmmgOscUd1pSMoXiDmnCZ+r 23 | BvpD4FjGDHnAyuZig9FH1nQAiT8BpyjeRLIzzH5fo4cGDDf1S7hTd4FAChkJrPhk 24 | qDus1bX5Jeub1KF87w3Sopja337YPPFakCW5xysCgYBZ2bUDxKTN0qHF6ourNS42 25 | 3vrLCWKr9LZPcfk83th0MMhnaKTs1Ijm4kOOanfYind/yvRcvwsVM96m46nCmR+L 26 | TBRjGkl2hdUpckKpQ3L7oMNAMthudQL2gvfsmL6mdAgONgmEh9gCIyljAdfQHgyF 27 | /x9eq5Fs8rZg8C5y0cmM7A== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /micronaut/README.md: -------------------------------------------------------------------------------- 1 | # Karate and Micronaut 2 | 3 | This is a "standard" [Micronaut](https://micronaut.io) project adapted from the Micronaut [getting started guide](https://guides.micronaut.io/latest/creating-your-first-micronaut-app-maven-java.html). 4 | 5 | A few highlights: 6 | 7 | * shows how to run Karate via JUnit using the [`@MicronautTest`](https://micronaut-projects.github.io/micronaut-test/latest/guide) annotation 8 | * uses an `@Inject`-ed `EmbeddedServer` to get the URL after resolving the (dynamic) port that the Micronaut application is running on 9 | * in test mode, `(server:) port: -1` in [src/test/java/application-test.yml](src/test/java/application-test.yml) configures the server to start on a random and unused port 10 | * the Karate script [`hello.feature`](src/test/java/karate/hello.feature) has a test for the `/hello` end point 11 | * shows how the URL (including dynamic port number) is passed to Karate from the Micronaut environment in [`HelloTest.java`](src/test/java/karate/HelloTest.java) 12 | * Uses [`all`](https://github.com/karatelabs/karate#karate-core-fat-jar) in the Maven [`pom.xml`](pom.xml) to avoid conflicts with Micronaut dependencies 13 | 14 | 15 | ## Graal 16 | Micronaut heavily depends on Graal and so does Karate which requires us to align the versions pulled in by the [`pom.xml`](pom.xml). This is why we have the additional entries for `org.graalvm.js:js-scriptengine` and `org.graalvm.js:js` and we force them to be the version that Micronaut needs. 17 | 18 | If you see the application hanging or things like a [`NoClassDefFoundError` and `polyglot` or "graal"](https://stackoverflow.com/q/72952986/143475) mentioned in the stack traces, you need to adjust this. 19 | 20 | 21 | ## Running 22 | Run `mvn test` to execute the JUnit test: [`HelloTest.java`](src/test/java/karate/HelloTest.java) 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /kafka-custom/src/test/java/io/karatelabs/examples/kafka/AvroUtils.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.kafka; 2 | 3 | import com.intuit.karate.FileUtils; 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.File; 6 | import java.nio.charset.StandardCharsets; 7 | import org.apache.avro.Schema; 8 | import org.apache.avro.generic.GenericDatumReader; 9 | import org.apache.avro.generic.GenericDatumWriter; 10 | import org.apache.avro.generic.GenericRecord; 11 | import org.apache.avro.io.DatumReader; 12 | import org.apache.avro.io.DatumWriter; 13 | import org.apache.avro.io.DecoderFactory; 14 | import org.apache.avro.io.EncoderFactory; 15 | import org.apache.avro.io.JsonEncoder; 16 | 17 | public class AvroUtils { 18 | 19 | public static Schema toSchema(String fileName) { 20 | Schema.Parser parser = new Schema.Parser(); 21 | String schemaText = FileUtils.toString(new File(fileName)); 22 | return parser.parse(schemaText); 23 | } 24 | 25 | public static String toJson(GenericRecord gr) { 26 | try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { 27 | DatumWriter writer = new GenericDatumWriter(gr.getSchema()); 28 | JsonEncoder encoder = EncoderFactory.get().jsonEncoder(gr.getSchema(), outputStream); 29 | writer.write(gr, encoder); 30 | encoder.flush(); 31 | return new String(outputStream.toByteArray(), StandardCharsets.UTF_8); 32 | } catch (Exception e) { 33 | throw new RuntimeException(e); 34 | } 35 | } 36 | 37 | public static GenericRecord fromJson(Schema schema, String json) { 38 | try { 39 | DatumReader reader = new GenericDatumReader(schema); 40 | return (GenericRecord) reader.read(null, DecoderFactory.get().jsonDecoder(schema, json)); 41 | } catch (Exception e) { 42 | throw new RuntimeException(e); 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /aws-dynamodb/README.md: -------------------------------------------------------------------------------- 1 | # Karate and AWS DynamoDB 2 | 3 | Many enterprise users of Karate have successfully included calls to databases or message-queues within their test-automation. This is a great way to test some architectural flows, for example - whether a message resulted in the expected database update. 4 | 5 | This is made possible by Karate's unique approach to Java inter-op. It takes only one line of code to load a Java class - and then you can invoke methods or even the constructor. Creating a Java "adapter" is a one-time activity, and after it is in place, the entire team can write functional tests and assertions using the simple and readable syntax that Karate is known for. 6 | 7 | This sample project demonstrates how you can test AWS DynamoDB using [Java interop](https://github.com/karatelabs/karate#calling-java). You just need to use the [AWS Java SDK](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html). 8 | 9 | The [`DynamoDbUtils.java`](src/test/java/examples/DynamoDbUtils.java) class does the work of connecting to DynamoDB. You need to modify this class to fit your AWS [profile](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials-profiles.html), region, table, and schema. 10 | 11 | This project is just a simple reference and starting point for what you need to add to the Maven [`pom.xml`](pom.xml) as a dependency. 12 | 13 | Now [`dynamo-db.feature`](src/test/java/karate/dynamo-db.feature) is just a few lines and as long as you return a `Map` from your "query", it gets converted to JSON, and you can perform a `match` in Karate. 14 | 15 | ## Running 16 | This is a normal Java / Maven project so running `mvn clean test` will be sufficient to run tests. 17 | 18 | ### References 19 | * [RDBMS example](../database/README.md) - how to test Spring Boot and an RDBMS in a single example 20 | * [SSH example](../ssh/README.md) - shows how you can pass data to your Java helper class from your test 21 | 22 | 23 | -------------------------------------------------------------------------------- /rabbitmq/src/test/java/io/karatelabs/examples/rabbitMQ/KarateRMQConsumer.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.rabbitMQ; 2 | 3 | import com.rabbitmq.client.Channel; 4 | import com.rabbitmq.client.Connection; 5 | import com.rabbitmq.client.ConnectionFactory; 6 | import com.rabbitmq.client.DeliverCallback; 7 | import java.io.IOException; 8 | import java.nio.charset.StandardCharsets; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.concurrent.TimeoutException; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | public class KarateRmqConsumer { 16 | 17 | static final Logger logger = LoggerFactory.getLogger(KarateRmqConsumer.class); 18 | 19 | private final ConnectionFactory factory = new ConnectionFactory(); 20 | private final Connection connection; 21 | private final Channel channel; 22 | public static List messages = new ArrayList<>(); 23 | 24 | private final String queueName; 25 | 26 | public KarateRmqConsumer(String queueName) throws IOException, TimeoutException { 27 | this.queueName = queueName; 28 | factory.setHost("localhost"); 29 | connection = factory.newConnection(); 30 | channel = connection.createChannel(); 31 | channel.queueDeclare(queueName, false, false, false, null); 32 | logger.debug("init consumer, waiting for messages ..."); 33 | listen(); 34 | } 35 | 36 | public void listen() throws IOException { 37 | DeliverCallback deliverCallback = (consumerTag, delivery) -> { 38 | String msg = new String(delivery.getBody(), StandardCharsets.UTF_8); 39 | logger.debug("received message: '{}'", msg); 40 | messages.add(msg); 41 | }; 42 | channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { 43 | }); 44 | } 45 | 46 | public List getMessageList() { 47 | return messages; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /grpc/src/test/java/karate/hello.feature: -------------------------------------------------------------------------------- 1 | Feature: grpc 2 | 3 | Background: 4 | * def session = karate.channel('grpc') 5 | * session.host = 'localhost' 6 | * session.port = karate.properties['grpc.port'] 7 | * session.proto = 'classpath:karate/hello.proto' 8 | * session.service = 'HelloService' 9 | 10 | Scenario: unary 11 | * session.method = 'Hello' 12 | * session.send({ name: 'John' }) 13 | * match session.pop() == { message: 'hello John' } 14 | # metadata handling 15 | * session.metadata = { authorization: 'secret' } 16 | * session.send({ name: 'Smith' }) 17 | * match session.pop() == { message: 'hello Smith with authorization: secret' } 18 | * match session.metadataResponse contains { 'authorization-response': 'secret-response' } 19 | 20 | Scenario: server stream 21 | * session.method = 'LotsOfReplies' 22 | * session.count = 3 23 | * session.send({ name: 'John' }) 24 | * def result = session.collect() 25 | * match result == 26 | """ 27 | [ 28 | { message: 'hello John 1' }, 29 | { message: 'hello John 2' }, 30 | { message: 'hello John 3' } 31 | ] 32 | """ 33 | 34 | Scenario: client stream 35 | * session.method = 'LotsOfGreetings' 36 | * session.stream = true 37 | * session.send({ name: 'John' }) 38 | * session.send({ name: 'Smith' }) 39 | * session.send({ name: 'Jane' }) 40 | * session.flush() 41 | * match session.pop() == { message: 'hello [John, Smith, Jane]' } 42 | 43 | Scenario: bidi 44 | * session.method = 'BidiHello' 45 | * session.stream = true 46 | * session.count = 3 47 | * session.send({ name: 'John' }) 48 | * session.send({ name: 'Smith' }) 49 | * session.send({ name: 'Jane' }) 50 | * match session.collect() == 51 | """ 52 | [ 53 | { message: 'hello [John]' }, 54 | { message: 'hello [John, Smith]' }, 55 | { message: 'hello [John, Smith, Jane]' } 56 | ] 57 | """ 58 | -------------------------------------------------------------------------------- /kafka-mtls/conf/commands.txt: -------------------------------------------------------------------------------- 1 | # adapted from https://developer.confluent.io/courses/security/hands-on-setting-up-encryption 2 | # and https://developer.confluent.io/courses/security/hands-on-requiring-encryption-for-broker-traffic 3 | # cut and paste and run one at a time 4 | 5 | openssl req -new -nodes \ 6 | -x509 \ 7 | -days 365 \ 8 | -newkey rsa:2048 \ 9 | -keyout ssl/ca.key \ 10 | -out ssl/ca.crt \ 11 | -config conf/ca.cnf 12 | 13 | cat ssl/ca.crt ssl/ca.key > ssl/ca.pem 14 | 15 | openssl req -new \ 16 | -newkey rsa:2048 \ 17 | -keyout ssl/server.key \ 18 | -out ssl/server.csr \ 19 | -config conf/server.cnf \ 20 | -nodes 21 | 22 | openssl x509 -req \ 23 | -days 3650 \ 24 | -in ssl/server.csr \ 25 | -CA ssl/ca.crt \ 26 | -CAkey ssl/ca.key \ 27 | -CAcreateserial \ 28 | -out ssl/server.crt \ 29 | -extfile conf/server.cnf \ 30 | -extensions v3_req 31 | 32 | openssl pkcs12 -export \ 33 | -in ssl/server.crt \ 34 | -inkey ssl/server.key \ 35 | -chain \ 36 | -CAfile ssl/ca.pem \ 37 | -name kafka \ 38 | -out ssl/server.p12 \ 39 | -password pass:karate 40 | 41 | keytool -importkeystore \ 42 | -deststorepass karate \ 43 | -destkeystore ssl/server.keystore.pkcs12 \ 44 | -srckeystore ssl/server.p12 \ 45 | -deststoretype PKCS12 \ 46 | -srcstoretype PKCS12 \ 47 | -noprompt \ 48 | -srcstorepass karate 49 | 50 | keytool -list -v \ 51 | -keystore ssl/server.keystore.pkcs12 \ 52 | -storepass karate 53 | 54 | # type in "karate" ENTER "EOF" ENTER for the next two 55 | 56 | tee ssl/creds_sslkey << EOF >/dev/null 57 | 58 | tee ssl/creds_keystore << EOF >/dev/null 59 | 60 | openssl s_client -connect localhost:29093 -tls1_3 -showcerts 61 | 62 | keytool -keystore ssl/client.truststore.pkcs12 \ 63 | -alias CARoot \ 64 | -import \ 65 | -file ssl/ca.crt \ 66 | -storepass karate \ 67 | -noprompt \ 68 | -storetype PKCS12 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /ssl/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | io.karatelabs.examples 6 | examples-ssl 7 | 1.0-SNAPSHOT 8 | jar 9 | 10 | 11 | 1.5.1 12 | 3.4.2 13 | 14 | 15 | 16 | 17 | org.springframework.boot 18 | spring-boot-dependencies 19 | ${spring.boot.version} 20 | pom 21 | import 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-web 26 | ${spring.boot.version} 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-logging 31 | ${spring.boot.version} 32 | 33 | 34 | io.karatelabs 35 | karate-junit5 36 | ${karate.version} 37 | test 38 | 39 | 40 | 41 | 42 | 43 | 44 | src/test/java 45 | 46 | **/*.java 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /quarkus/README.md: -------------------------------------------------------------------------------- 1 | # Karate and Quarkus 2 | 3 | This is a "standard" [Quarkus](https://quarkus.io/) project adapted from the Quarkus [getting started guide](https://quarkus.io/guides/getting-started). 4 | 5 | A few highlights: 6 | 7 | * shows how to run Karate via JUnit using the [`@QuarkusTest`](https://quarkus.io/guides/getting-started-testing#recap-of-http-based-testing-in-jvm-mode) annotation 8 | * uses an injected `@TestHTTPResource` to get the URL after resolving the (dynamic) port that the Quarkus application is running on 9 | * in test mode, `quarkus.http.test-port=0` in [src/test/java/application.properties](src/test/java/application.properties) configures the server to start on a random and unused port 10 | * the Karate script [`greeting.feature`](src/test/java/karate/greeting.feature) has two tests for each REST end-point 11 | * shows how the URL (including dynamic port number) is passed to Karate from the Quarkus environment in [`GreetingTest.java`](src/test/java/karate/GreetingTest.java) 12 | * Uses [`all`](https://github.com/karatelabs/karate#karate-core-fat-jar) in the Maven [`pom.xml`](pom.xml) to avoid conflicts with Quarkus dependencies 13 | * we also use `karate-core` instead of `karate-junit5` as JUnit is brought in by `quarkus-junit5` 14 | * Uses the [`quarkus-logging-logback`](https://quarkiverse.github.io/quarkiverse-docs/quarkus-logging-logback/dev/index.html) extension to bridge Karate with Quarkus' logging system 15 | * note the over-ride of the `ch.qos.logback:logback-classic` dependency since Quarkus requires a higher version 16 | 17 | ## Graal 18 | 19 | Quarkus heaviliy depends on Graal and so does Karate, so watch out for `NoClassDefFoundError` or `polyglot` in stack traces. You may need to adjust dependencies so that Karate works without issues. Refer to [this thread](https://github.com/karatelabs/karate/issues/2009) for more details. 20 | 21 | ## Running 22 | Run `mvn test` to execute the JUnit test: [`GreetingTest.java`](src/test/java/karate/GreetingTest.java) 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /grpc/src/test/java/crypto.txt: -------------------------------------------------------------------------------- 1 | # adapted with thanks from: 2 | # https://medium.com/@ankitgrg.26/generate-a-self-signed-certificate-for-grpc-java-56323df05be4 3 | 4 | # output files 5 | # ============ 6 | # ca.crt: Certificate Authority (CA) or "trust manager" certificate 7 | # server.crt: Server certificate signed by CA 8 | # server.pem: Server key in format gRPC likes 9 | # client.crt: Client certificate signed by CA 10 | # client.pem: Client key in format gRPC likes 11 | 12 | # Change this CN to match host(s) in your environment if needed 13 | SERVER_CN=localhost 14 | 15 | # Step 1: generate (ca.crt) 16 | openssl genrsa -passout pass:1111 -des3 -out ca.key 4096 17 | openssl req -passin pass:1111 -new -x509 -days 365 -key ca.key -out ca.crt -subj "/CN=${SERVER_CN}" 18 | 19 | # Step 2: generate server private key (server.key) 20 | openssl genrsa -passout pass:1111 -des3 -out server.key 4096 21 | 22 | # Step 3: get server certificate signing request from CA (server.csr) 23 | openssl req -passin pass:1111 -new -key server.key -out server.csr -subj "/CN=${SERVER_CN}" 24 | 25 | # Step 4: self-sign server certificate using CA (server.crt) 26 | openssl x509 -req -passin pass:1111 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt 27 | 28 | # Step 5: convert server private key to .pem format (server.pem) 29 | openssl pkcs8 -topk8 -nocrypt -passin pass:1111 -in server.key -out server.pem 30 | 31 | # Step 6: generate client private key (client.key) 32 | openssl genrsa -passout pass:1111 -des3 -out client.key 4096 33 | 34 | # Step 7: get client certificate signing request from CA (client.csr) 35 | openssl req -passin pass:1111 -new -key client.key -out client.csr -subj "/CN=${SERVER_CN}" 36 | 37 | # Step 8: self-sign client certificate using CA (client.crt) 38 | openssl x509 -req -passin pass:1111 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt 39 | 40 | # Step 9: convert client private key to .pem format (client.pem) 41 | openssl pkcs8 -topk8 -nocrypt -passin pass:1111 -in client.key -out client.pem 42 | -------------------------------------------------------------------------------- /kafka-custom/README.md: -------------------------------------------------------------------------------- 1 | # Karate and Kafka (Custom Integration) 2 | 3 | > [!Note] 4 | > The [built-in support for Kafka](https://github.com/karatelabs/karate-addons/blob/main/karate-kafka/README.md) is recommended instead of this approach below. The advantage is that you don't need to generate or compile extra Java code. 5 | 6 | This sample project demonstrates how you can test Kafka messaging if your implementation is in Java. It also demonstrates concepts you can use for any case where you use Java interop to connect Karate to any custom code, library or communication protocol. 7 | 8 | When you use well designed utility classes, your Karate tests will be clean and only focus on making a call and what data is sent and received. 9 | 10 | For example if you look at [`kafka.feature`](src/test/java/karate/kafka.feature) the test is just a few lines. Behind the scenes a Kafka consumer and producer is initialized and the call is made. The HTML report even includes details of the call and the messages on the wire, which you can easily customize. 11 | 12 | Rather than attempt a generic and dynamic approach, this approach shown here can re-use your existing Kafka implementation code-base and domain classes. 13 | 14 | This example also shows how to handle Avro for both serializing and deserializing of messages. You should be able to easily write a conversion from your Avro or Java payloads to JSON and vice-versa. 15 | 16 | ## Running 17 | * Docker is required to start the Kafka broker and Zookeeper. There is a `docker-compose.yml` file in this project. 18 | * Run the following commands 19 | * `docker-compose up -d` 20 | * `mvn test` 21 | * To stop the Docker containers run `docker-compose down` 22 | 23 | ## Further Reading 24 | * [Karate Official Support for Kafka](https://github.com/karatelabs/karate-addons/blob/main/karate-kafka/README.md) - recommended 25 | * [community-example](https://github.com/Sdaas/karate-kafka) - a community project that provides a generic approach to testing Kafka with Karate 26 | -------------------------------------------------------------------------------- /ssh/src/test/java/karate/SshSession.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.jcraft.jsch.Channel; 4 | import com.jcraft.jsch.ChannelShell; 5 | import com.jcraft.jsch.JSch; 6 | import com.jcraft.jsch.Session; 7 | import java.io.OutputStream; 8 | import java.io.PrintStream; 9 | import java.util.Map; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | public class SshSession { 13 | 14 | private final Channel channel; 15 | private final Session session; 16 | private final PrintStream terminal; 17 | 18 | public SshSession(Map map) { 19 | try { 20 | String user = (String) map.get("user"); 21 | String host = (String) map.get("host"); 22 | String privateKey = (String) map.get("privateKey"); 23 | Integer port = (Integer) map.get("port"); 24 | if (port == null) { 25 | port = 22; 26 | } 27 | JSch jsch = new JSch(); 28 | jsch.addIdentity(privateKey); 29 | session = jsch.getSession(user, host, port); 30 | java.util.Properties config = new java.util.Properties(); 31 | config.put("StrictHostKeyChecking", "no"); 32 | session.setConfig(config); 33 | session.connect(); 34 | channel = session.openChannel("shell"); 35 | OutputStream channelInput = channel.getOutputStream(); 36 | terminal = new PrintStream(channelInput, true); 37 | channel.setOutputStream(System.out, true); 38 | ((ChannelShell) channel).setPty(true); 39 | channel.connect(); 40 | } catch (Exception e) { 41 | throw new RuntimeException(e); 42 | } 43 | } 44 | 45 | public void input(String line) { 46 | terminal.println(line); 47 | } 48 | 49 | public void close() { 50 | try { 51 | do { 52 | TimeUnit.SECONDS.sleep(1); 53 | } while (!channel.isEOF()); 54 | session.disconnect(); 55 | } catch (Exception e) { 56 | throw new RuntimeException(e); 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /lambdatest/README.md: -------------------------------------------------------------------------------- 1 | # Karate and Lambdatest 2 | 3 | Karate supports the [W3C WebDriver protocol](https://www.w3.org/TR/webdriver) and can be used to run tests on [Lambdatest](https://www.lambdatest.com). 4 | 5 | The [example in this folder](lambdatest.feature) demonstrates how to run a test on Lambdatest using Karate. All you need is a Lambdatest account and values such as the URL, user, key etc. 6 | 7 | From your Lambdatest profile, you can get the values you need. The main ones you need are the `username` and `accessKey`. 8 | 9 | All you need to do in Karate is perform the [`configure driver` step](https://github.com/karatelabs/karate/tree/master/karate-core/#configure-driver) as per the documentation. Note how `LT:Options` are added to the WebDriver "capabilities": 10 | 11 | ```cucumber 12 | * def session = { capabilities: { alwaysMatch: { browserName: 'chrome', browserVersion: 'latest', platformName: 'Windows 11', 'LT:Options': '#(lambdaTestOptions)' } } } 13 | * configure driver = { type: 'chromedriver', start: false, webDriverSession: '#(session)', webDriverUrl: '#(lambdaTestUrl)' } 14 | ``` 15 | 16 | Of course you can change the `browserVersion` and `platformName` to suit your needs. You will have to ensure that the Karate driver type matches the `browserName`, for example `chromedriver` for `chrome`. Refer to the [Karate documentation](https://github.com/karatelabs/karate/tree/master/karate-core/#driver-types) for all possible types. 17 | 18 | Also refer to the documentation of [`webDriverSession`](https://github.com/karatelabs/karate/tree/master/karate-core/#webdriversession) and [`webDriverUrl`](https://github.com/karatelabs/karate/tree/master/karate-core/#webdriverurl) for more details. 19 | 20 | Note that for a typical test-suite, you will set variables via the [`karate-config.js`](https://github.com/karatelabs/karate/#karate-configjs) so you can switch browsers or between local and remote execution. 21 | 22 | ## Further Reading 23 | 24 | * [Karate and Lambdatest on Stack Overflow](https://stackoverflow.com/search?q=%5Bkarate%5D+lambdatest) 25 | * [Running UI Tests in parallel](https://stackoverflow.com/a/60387907/143475) 26 | * [LambdaTest support for Karate](https://github.com/LambdaTest/hyperexecute-karate-sample) 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /saucelabs/README.md: -------------------------------------------------------------------------------- 1 | # Karate and Sauce Labs 2 | 3 | Karate supports the [W3C WebDriver protocol](https://www.w3.org/TR/webdriver) and can be used to run tests on [Sauce Labs](https://saucelabs.com). 4 | 5 | The [example in this folder](saucelabs.feature) demonstrates how to run a test on Sauce Labs using Karate. All you need is a Sauce Labs account and values such as the URL, user, key etc. 6 | 7 | From your Sauce Labs dashboard, you can get the values you need from the quickstart guide for Selenium / Java. The main ones you need are the `username` and `accessKey`. Change the Sauce Labs URL if needed, based on which region you want to use. 8 | 9 | All you need to do in Karate is perform the [`configure driver` step](https://github.com/karatelabs/karate/tree/master/karate-core/#configure-driver) as per the documentation. Note how `sauce:options` are added to the WebDriver "capabilities": 10 | 11 | ```cucumber 12 | * def session = { capabilities: { alwaysMatch: { browserName: 'chrome', browserVersion: 'latest', platformName: 'Windows 11', 'sauce:options': '#(sauceOptions)' } } } 13 | * configure driver = { type: 'chromedriver', start: false, webDriverSession: '#(session)', webDriverUrl: '#(sauceLabsUrl)' } 14 | ``` 15 | 16 | Of course you can change the `browserVersion` and `platformName` to suit your needs. You will have to ensure that the Karate driver type matches the `browserName`, for example `chromedriver` for `chrome`. Refer to the [Karate documentation](https://github.com/karatelabs/karate/tree/master/karate-core/#driver-types) for all possible types. 17 | 18 | Also refer to the documentation of [`webDriverSession`](https://github.com/karatelabs/karate/tree/master/karate-core/#webdriversession) and [`webDriverUrl`](https://github.com/karatelabs/karate/tree/master/karate-core/#webdriverurl) for more details. 19 | 20 | Note that for a typical test-suite, you will set variables via the [`karate-config.js`](https://github.com/karatelabs/karate/#karate-configjs) so you can switch browsers or between local and remote execution. 21 | 22 | ## Further Reading 23 | 24 | * [Karate and Sauce Labs on Stack Overflow](https://stackoverflow.com/search?q=%5Bkarate%5D+sauce+labs) 25 | * [Running UI Tests in parallel](https://stackoverflow.com/a/60387907/143475) 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /browserstack/README.md: -------------------------------------------------------------------------------- 1 | # Karate and BrowserStack 2 | 3 | Karate supports the [W3C WebDriver protocol](https://www.w3.org/TR/webdriver) and can be used to run tests on [BrowserStack](https://www.browserstack.com). 4 | 5 | The [example in this folder](browserstack.feature) demonstrates how to run a test on BrowserStack using Karate. All you need is a BrowserStack account and the URL (which encodes your credentials). 6 | 7 | All you need to do in Karate is perform the [`configure driver` step](https://github.com/karatelabs/karate/tree/master/karate-core/#configure-driver) as per the documentation. You can also pass the name of your project, build and test-case which will be used by BrowserStack to organize results in your dashboard view. 8 | 9 | Note how `bstack:options` are added to the WebDriver "capabilities": 10 | 11 | ```cucumber 12 | * def browserStackOptions = { projectName: 'Karate and Browser Stack', buildName: 'myBuild', sessionName: '#(karate.feature.prefixedPath)' } 13 | * def session = { capabilities: { alwaysMatch: { browserName: 'chrome', browserVersion: 'latest', platformName: 'Windows 11', 'bstack:options': '#(browserStackOptions)' } } } 14 | * configure driver = { type: 'chromedriver', start: false, webDriverSession: '#(session)', webDriverUrl: '#(browserStackUrl)' } 15 | ``` 16 | 17 | Of course you can change the `browserVersion` and `platformName` to suit your needs. You will have to ensure that the Karate driver type matches the `browserName`, for example `chromedriver` for `chrome`. Refer to the [Karate documentation](https://github.com/karatelabs/karate/tree/master/karate-core/#driver-types) for all possible types. 18 | 19 | Also refer to the documentation of [`webDriverSession`](https://github.com/karatelabs/karate/tree/master/karate-core/#webdriversession) and [`webDriverUrl`](https://github.com/karatelabs/karate/tree/master/karate-core/#webdriverurl) for more details. 20 | 21 | Note that for a typical test-suite, you will set variables via the [`karate-config.js`](https://github.com/karatelabs/karate/#karate-configjs) so you can switch browsers or between local and remote execution. 22 | 23 | ## Further Reading 24 | 25 | * [Karate and BrowserStack on Stack Overflow](https://stackoverflow.com/search?q=%5Bkarate%5D+browserstack) 26 | * [Running UI Tests in parallel](https://stackoverflow.com/a/60387907/143475) 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /aws-dynamodb/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | io.karatelabs.examples 6 | karate-examples-aws-dynamodb 7 | 1.0-SNAPSHOT 8 | jar 9 | 10 | 11 | UTF-8 12 | 17 13 | 3.11.0 14 | 3.0.0 15 | 16 | 17 | 18 | 19 | io.karatelabs 20 | karate-junit5 21 | 1.5.0 22 | test 23 | 24 | 25 | software.amazon.awssdk 26 | dynamodb 27 | 2.27.5 28 | test 29 | 30 | 31 | 32 | 33 | 34 | 35 | src/test/java 36 | 37 | **/*.java 38 | 39 | 40 | 41 | 42 | 43 | org.apache.maven.plugins 44 | maven-compiler-plugin 45 | ${maven.compiler.version} 46 | 47 | UTF-8 48 | ${java.version} 49 | ${java.version} 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-surefire-plugin 55 | ${maven.surefire.version} 56 | 57 | -Dfile.encoding=UTF-8 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /kafka/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | io.karatelabs.examples 6 | karate-examples-kafka 7 | 1.0-SNAPSHOT 8 | jar 9 | 10 | 11 | UTF-8 12 | 17 13 | 3.11.0 14 | 3.0.0 15 | 16 | 17 | 18 | 19 | io.karatelabs 20 | karate-kafka 21 | 0.3.0 22 | test 23 | 24 | 25 | org.junit.jupiter 26 | junit-jupiter 27 | 5.6.2 28 | test 29 | 30 | 31 | 32 | 33 | 34 | 35 | src/test/java 36 | 37 | **/*.java 38 | 39 | 40 | 41 | 42 | 43 | org.apache.maven.plugins 44 | maven-compiler-plugin 45 | ${maven.compiler.version} 46 | 47 | UTF-8 48 | ${java.version} 49 | ${java.version} 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-surefire-plugin 55 | ${maven.surefire.version} 56 | 57 | -Dfile.encoding=UTF-8 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /kafka/src/test/java/karate/complex.avsc: -------------------------------------------------------------------------------- 1 | { 2 | "namespace": "io.karatelabs.examples", 3 | "type": "record", 4 | "name": "Complex", 5 | "version": "0.2", 6 | "fields": [ 7 | { 8 | "name": "meta", 9 | "type": { 10 | "type": "record", 11 | "name": "Meta", 12 | "fields": [ 13 | { 14 | "name": "metaId", 15 | "type": "string" 16 | }, 17 | { 18 | "name": "metaType", 19 | "type": { 20 | "type": "enum", 21 | "name": "MetaType", 22 | "symbols": ["AAA", "BBB", "CCC"] 23 | } 24 | }, 25 | { 26 | "name": "metaChildren", 27 | "type": { 28 | "type": "array", 29 | "items": { 30 | "type": "record", 31 | "name": "MetaChild", 32 | "fields": [ 33 | { 34 | "name": "name", 35 | "type": "string" 36 | }, 37 | { 38 | "name": "status", 39 | "type": { 40 | "name": "Status", 41 | "type": "enum", 42 | "symbols": ["ONE", "TWO", "THREE"] 43 | } 44 | } 45 | ] 46 | } 47 | } 48 | } 49 | ] 50 | } 51 | }, 52 | { 53 | "name": "payload", 54 | "type": { 55 | "type": "record", 56 | "name": "Payload", 57 | "fields": [ 58 | { 59 | "name": "payloadId", 60 | "type": "string" 61 | }, 62 | { 63 | "name": "payloadType", 64 | "type": ["null", "string"] 65 | }, 66 | { 67 | "name": "payloadEnum", 68 | "type": { 69 | "name": "PayloadEnum", 70 | "type": "enum", 71 | "symbols": ["FIRST", "SECOND", "THIRD"] 72 | } 73 | }, 74 | { 75 | "name": "payloadChild", 76 | "type": { 77 | "type": "record", 78 | "name": "PayloadChild", 79 | "fields": [ 80 | { 81 | "name": "field1", 82 | "type": "string" 83 | }, 84 | { 85 | "name": "field2", 86 | "type": "string" 87 | } 88 | ] 89 | } 90 | } 91 | ] 92 | } 93 | } 94 | ] 95 | } 96 | -------------------------------------------------------------------------------- /kafka-mtls/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | io.karatelabs.examples 6 | karate-kafka-mtls-example 7 | 1.0-SNAPSHOT 8 | jar 9 | 10 | 11 | UTF-8 12 | 11 13 | 3.11.0 14 | 3.0.0 15 | 16 | 17 | 18 | 19 | io.karatelabs 20 | karate-kafka 21 | 0.3.0 22 | test 23 | 24 | 25 | org.junit.jupiter 26 | junit-jupiter 27 | 5.6.2 28 | test 29 | 30 | 31 | 32 | 33 | 34 | 35 | src/test/java 36 | 37 | **/*.java 38 | 39 | 40 | 41 | 42 | 43 | org.apache.maven.plugins 44 | maven-compiler-plugin 45 | ${maven.compiler.version} 46 | 47 | UTF-8 48 | ${java.version} 49 | ${java.version} 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-surefire-plugin 55 | ${maven.surefire.version} 56 | 57 | -Dfile.encoding=UTF-8 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /rabbitmq/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | io.karatelabs.examples 6 | karate-rabbitmq 7 | 1.0-SNAPSHOT 8 | jar 9 | 10 | 11 | UTF-8 12 | 17 13 | 3.11.0 14 | 3.0.0 15 | 1.4.0 16 | 17 | 18 | 19 | 20 | com.rabbitmq 21 | amqp-client 22 | 5.17.0 23 | 24 | 25 | com.intuit.karate 26 | karate-junit5 27 | ${karate.version} 28 | test 29 | 30 | 31 | 32 | 33 | 34 | 35 | src/test/java 36 | 37 | **/*.java 38 | 39 | 40 | 41 | 42 | 43 | org.apache.maven.plugins 44 | maven-compiler-plugin 45 | ${maven.compiler.version} 46 | 47 | UTF-8 48 | ${java.version} 49 | ${java.version} 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-surefire-plugin 55 | ${maven.surefire.version} 56 | 57 | -Dfile.encoding=UTF-8 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /ssh/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | io.karatelabs.examples 6 | karate-ssh 7 | 1.0-SNAPSHOT 8 | jar 9 | 10 | 11 | UTF-8 12 | 11 13 | 3.11.0 14 | 3.0.0 15 | 1.4.0 16 | 17 | 18 | 19 | 20 | com.github.mwiede 21 | jsch 22 | 0.2.9 23 | test 24 | 25 | 26 | com.intuit.karate 27 | karate-junit5 28 | ${karate.version} 29 | test 30 | 31 | 32 | 33 | 34 | 35 | 36 | src/test/java 37 | 38 | **/*.java 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-compiler-plugin 46 | ${maven.compiler.version} 47 | 48 | UTF-8 49 | ${java.version} 50 | ${java.version} 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-surefire-plugin 56 | ${maven.surefire.version} 57 | 58 | -Dfile.encoding=UTF-8 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /websocket/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | io.karatelabs.examples 6 | karate-websocket-example 7 | 1.0-SNAPSHOT 8 | jar 9 | 10 | 11 | UTF-8 12 | 17 13 | 3.11.0 14 | 3.0.0 15 | 5.6.2 16 | 17 | 18 | 19 | 20 | io.karatelabs 21 | karate-websocket 22 | 0.1.1 23 | test 24 | 25 | 26 | org.junit.jupiter 27 | junit-jupiter 28 | ${junit5.version} 29 | test 30 | 31 | 32 | 33 | 34 | 35 | 36 | src/test/java 37 | 38 | **/*.java 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-compiler-plugin 46 | ${maven.compiler.version} 47 | 48 | UTF-8 49 | ${java.version} 50 | ${java.version} 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-surefire-plugin 56 | ${maven.surefire.version} 57 | 58 | -Dfile.encoding=UTF-8 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /kafka-custom/src/test/java/io/karatelabs/examples/kafka/KarateKafkaProducer.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.kafka; 2 | 3 | import com.intuit.karate.Json; 4 | import io.confluent.kafka.serializers.KafkaAvroSerializer; 5 | import io.confluent.kafka.serializers.KafkaAvroSerializerConfig; 6 | import java.util.Properties; 7 | import org.apache.avro.Schema; 8 | import org.apache.avro.generic.GenericRecord; 9 | import org.apache.kafka.clients.producer.KafkaProducer; 10 | import org.apache.kafka.clients.producer.ProducerConfig; 11 | import org.apache.kafka.clients.producer.ProducerRecord; 12 | import org.apache.kafka.common.serialization.StringSerializer; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | public class KarateKafkaProducer { 17 | 18 | static final Logger logger = LoggerFactory.getLogger(KarateKafkaProducer.class); 19 | 20 | private final String topic; 21 | private final KafkaProducer kafka; 22 | private final Schema helloSchema; 23 | 24 | public KarateKafkaProducer(String topic) { 25 | this.topic = topic; 26 | kafka = new KafkaProducer(config()); 27 | helloSchema = AvroUtils.toSchema("src/test/java/karate/hello.avsc"); 28 | } 29 | 30 | public void send(Object object) { 31 | String json = Json.of(object).toString(); 32 | GenericRecord record = AvroUtils.fromJson(helloSchema, json); 33 | ProducerRecord pr = new ProducerRecord(topic, null, record); 34 | kafka.send(pr); 35 | } 36 | 37 | public void close() { 38 | kafka.close(); 39 | } 40 | 41 | public static Properties config() { 42 | // refer https://kafka.apache.org/documentation/#producerconfigs 43 | Properties props = new Properties(); 44 | props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "127.0.0.1:29092"); 45 | props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); 46 | props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, KafkaAvroSerializer.class); 47 | props.put(KafkaAvroSerializerConfig.SCHEMA_REGISTRY_URL_CONFIG, "http://localhost:8081"); 48 | 49 | // create a safe producer 50 | props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true"); 51 | props.put(ProducerConfig.ACKS_CONFIG, "all"); 52 | props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "5"); 53 | // high throughput producer 54 | props.put(ProducerConfig.COMPRESSION_TYPE_CONFIG, "snappy"); 55 | props.put(ProducerConfig.LINGER_MS_CONFIG, "20"); // linger for 20ms 56 | props.put(ProducerConfig.BATCH_SIZE_CONFIG, Integer.toString(32 * 1024)); // 32 kb 57 | return props; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /websocket/src/test/java/karate/StompAdapter.java: -------------------------------------------------------------------------------- 1 | package karate; 2 | 3 | import com.intuit.karate.Json; 4 | import io.karatelabs.websocket.WebsocketAdapter; 5 | import io.karatelabs.websocket.WebsocketConsumer; 6 | 7 | import java.util.LinkedHashMap; 8 | import java.util.Map; 9 | 10 | public class StompAdapter implements WebsocketAdapter, String> { 11 | 12 | @Override 13 | public void onMessage(WebsocketConsumer client, Map msg) { 14 | client.receive(msg); 15 | } 16 | 17 | @SuppressWarnings("unchecked") 18 | @Override 19 | public String toWire(Map map) { 20 | String command = (String) map.get("command"); 21 | Map headers = (Map) map.get("headers"); 22 | Object body = map.get("body"); 23 | if (body instanceof Map) { 24 | body = Json.of(body).toString(); 25 | } 26 | StringBuilder sb = new StringBuilder(); 27 | sb.append(command).append('\n'); 28 | if (headers != null) { 29 | headers.forEach((k, v) -> { 30 | sb.append(k).append(':').append(v).append('\n'); 31 | }); 32 | } 33 | sb.append('\n'); 34 | if (body != null) { 35 | sb.append(body); 36 | } 37 | sb.append('\0'); 38 | return sb.toString(); 39 | } 40 | 41 | @Override 42 | public Map fromWire(String text) { 43 | Map map = new LinkedHashMap<>(); 44 | String[] lines = text.split("\\R"); 45 | Map headers = new LinkedHashMap<>(); 46 | boolean headersDone = false; 47 | for (String line : lines) { 48 | if (map.isEmpty()) { 49 | map.put("command", line); 50 | } else if (line.isEmpty()) { 51 | map.put("headers", headers); 52 | headersDone = true; 53 | } else if ("\0".equals(line)) { 54 | continue; 55 | } else { 56 | if (headersDone) { 57 | line = line.trim(); 58 | if (line.charAt(0) == '{') { 59 | map.put("body", Json.of(line).asMap()); 60 | } else { 61 | map.put("body", line); 62 | } 63 | } else { 64 | int pos = line.indexOf(':'); 65 | if (pos == -1) { 66 | throw new RuntimeException("unexpected header: " + line); 67 | } 68 | String key = line.substring(0, pos); 69 | String value = line.substring(pos + 1); 70 | headers.put(key, value); 71 | } 72 | } 73 | } 74 | return map; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /kafka-custom/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | io.karatelabs.examples 6 | karate-kafka 7 | 1.0-SNAPSHOT 8 | jar 9 | 10 | 11 | UTF-8 12 | 11 13 | 3.11.0 14 | 3.0.0 15 | 1.4.0 16 | 17 | 18 | 19 | 20 | org.apache.kafka 21 | kafka-clients 22 | 3.3.1 23 | test 24 | 25 | 26 | io.confluent 27 | kafka-streams-avro-serde 28 | 7.4.1 29 | test 30 | 31 | 32 | com.intuit.karate 33 | karate-junit5 34 | ${karate.version} 35 | test 36 | 37 | 38 | 39 | 40 | 41 | 42 | src/test/java 43 | 44 | **/*.java 45 | 46 | 47 | 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-compiler-plugin 52 | ${maven.compiler.version} 53 | 54 | UTF-8 55 | ${java.version} 56 | ${java.version} 57 | 58 | 59 | 60 | org.apache.maven.plugins 61 | maven-surefire-plugin 62 | ${maven.surefire.version} 63 | 64 | -Dfile.encoding=UTF-8 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | confluent 73 | https://packages.confluent.io/maven 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /kafka-mtls/ssl/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDiTCCAnGgAwIBAgIJAN7uVLWpEtQTMA0GCSqGSIb3DQEBCwUAMDAxCzAJBgNV 3 | BAYTAlVTMRQwEgYDVQQKDAtLYXJhdGUgTGFiczELMAkGA1UEAwwCY2EwHhcNMjMx 4 | MjA2MDgyNTI4WhcNMjQxMjA1MDgyNTI4WjAwMQswCQYDVQQGEwJVUzEUMBIGA1UE 5 | CgwLS2FyYXRlIExhYnMxCzAJBgNVBAMMAmNhMIIBIjANBgkqhkiG9w0BAQEFAAOC 6 | AQ8AMIIBCgKCAQEAviBwCANI/NLnUtkTbmerkO+8ySMNciLO+eNe+E5thH3Vg1GQ 7 | Yyj5vFL3tOCw6l4UTRAV4rXLSnMMEA2R1kAmKwlk+w45yg3b2kNdTq8mtgrqOv6/ 8 | NtkKjqLl3QKl8JfeIcmB9Rh8VstYZXdkQ48XKLd0gAaGDfh2pWzjiGGDP8tdEVYa 9 | n5a18rlZ8UFaWNtTbFm4mya4EQQEeSspYn00wcdqmklQUQ7OrBBFpHjlbUDurj4Q 10 | Ci9MZvC5WFwh8VFDCD/zaTlQ8quuw/peITlkJT2cUW6Gd9pBIjxCmuNx1THsns2Y 11 | nLjrBUQ8rvc0Kz4fV93DZsjmRdzE0MtSRQ/fPwIDAQABo4GlMIGiMB0GA1UdDgQW 12 | BBR2IEmMF5SOg5uCMaJ41aPfb3OcsDAPBgNVHRMBAf8EBTADAQH/MGAGA1UdIwRZ 13 | MFeAFHYgSYwXlI6Dm4IxonjVo99vc5ywoTSkMjAwMQswCQYDVQQGEwJVUzEUMBIG 14 | A1UECgwLS2FyYXRlIExhYnMxCzAJBgNVBAMMAmNhggkA3u5UtakS1BMwDgYDVR0P 15 | AQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBercJWzrHx05fjj8+r8q3vUWuz 16 | iqhCBs3H8k+48PcHjEqAKKdIttdysJE1g95LNEeQD23NSM1d5mJU9fmQcN2UUv7D 17 | 2dbMB3/nV27YoS93srOPyGPpf2qmE0LQtDTt1M+H+hhWJIlFvMkdvxS86XK9tpiz 18 | c1ZkgHgP9PgITYKaCUl7B30lFXWk3QJQ4ns8TZDIoaPAv52/UrDvWz1drk9rQneN 19 | u7yX3WpqdCJq1SxBq9TarPZZvAgnUkMS3i143F4Zt51pFnzr3S3PEfb71AloAOpw 20 | AoMrapFGkTrURJL+kcgDeQMY72vsy6cdGRQ/NJxMzaSFRqQlsqEoWvzhjg5W 21 | -----END CERTIFICATE----- 22 | -----BEGIN PRIVATE KEY----- 23 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC+IHAIA0j80udS 24 | 2RNuZ6uQ77zJIw1yIs754174Tm2EfdWDUZBjKPm8Uve04LDqXhRNEBXitctKcwwQ 25 | DZHWQCYrCWT7DjnKDdvaQ11Orya2Cuo6/r822QqOouXdAqXwl94hyYH1GHxWy1hl 26 | d2RDjxcot3SABoYN+HalbOOIYYM/y10RVhqflrXyuVnxQVpY21NsWbibJrgRBAR5 27 | KylifTTBx2qaSVBRDs6sEEWkeOVtQO6uPhAKL0xm8LlYXCHxUUMIP/NpOVDyq67D 28 | +l4hOWQlPZxRboZ32kEiPEKa43HVMeyezZicuOsFRDyu9zQrPh9X3cNmyOZF3MTQ 29 | y1JFD98/AgMBAAECggEAMsY65QjrjwlL2aY7ODrbaKN9iUGhL5/4ImgETs+zE7T/ 30 | NkisBK9GsnJ90IJI/O4PAd2P2rGuDr3WtNrK3arYBppFq35LFJjK4+klnAPOlMMp 31 | doPd0On5lcoPFQzGABCus9s6p5fYbN11R/OwhRJLnwYPSLl1R3nZRahkw2E3Seux 32 | ddHEq4Sav3WNrX9tDTywJK/SexdFu6NDVyoimo8TwdxdJENyHjESIeYkq4wkswk7 33 | anHnPpApWkIoySO3HO28uS2Tb4S5n1MafpdMF6YaerKYrJGm6kLJ1/oJJxfDZ3b4 34 | z10q+DOF5LXB+LiF/Ng7AUOIO1XKiNREzYBlhiC3gQKBgQDpBlxqXEcuhwoV5C3l 35 | mROo4x2ke0pmCFztzZKXGJPHiZCdMMVcV3C8EaPBjIRgKfIi6Cy6FWX9/vgpWWxx 36 | PfFaqXbI+KlkVRd3CeiqiYaRqhxovqz2mu9BYUv8d+Y11IsO4OEQDKWVgtnHl18Z 37 | FspqOob1+HuQyWOiWAgXNPS5HwKBgQDQ30+KkLKUFive0UtaHlUAFVTl491cjUZc 38 | dq77tZIKeWtE4CGJpI8tgKWy53g/Ls1IZkz9IoTLjDk6NGeoCDo74GAxtTfxAL0d 39 | /OrIszG5KisvqlvxGpbdE6QNIj6Uga9RBrUuLYMkAjOYt18FcPqC3S15ZrmaqZIf 40 | bsUADOJ14QKBgAZ6dMtIMXprqq4dH+GINfG2Drbp7pGTnfHGi1LEDie3/VtBZdtB 41 | WxL/cowI+g0qXV73EXdC7Qj4s7GCmO81B6a7m1/O+faeHv7iOaO0GxeloRCQbIKW 42 | oBwzNkeYlb/dXthVDCzEDT5w2tkfrjcmWQ5G/kWMWPMXhjuXMvJiOIOFAoGAdzGo 43 | O4O9VMKeQGYhYQkEKqsBqrrw/LrmFyfnTV7dOzr02vYoTVrqFeZfKIvs0+mKXjF6 44 | 582GCH45vhxftsUTLk4pttQaW163jWBiPyv7SRZmVKocE6e/xeNKb/BF1At5l3yD 45 | chmox6i19wVVpU5Gtt0u8SOM8VSpPWTB6PhxVyECgYBq2XoLLm3DAduOuwKuTqOn 46 | 0DyaW0HNUJWcXjHvqOhAUAvOCcO4zIuAbfMPpaE0VNVWoCQIZTnkI6VdZViAaUjy 47 | iZGGBQCsqh1e50xll0H+/7mR5q6gyxuiPXNAX5jdtiJL9A/M9TwaCGrZ/G4JW5be 48 | GTIggRjjzkLjWr19Kc/LYw== 49 | -----END PRIVATE KEY----- 50 | -------------------------------------------------------------------------------- /database/README.md: -------------------------------------------------------------------------------- 1 | # Karate and Databases 2 | 3 | This is a "standard" [Spring Boot](https://spring.io/projects/spring-boot) project. A few highlights: 4 | 5 | * shows how to run Karate via JUnit using the [`@SpringBootTest`](https://spring.io/guides/gs/testing-web) annotation 6 | * uses an `@Autowired` `ServletWebServerApplicationContext` to get the (dynamic) port that the Spring Boot application is running on 7 | * in test mode, `server.port=0` in [src/test/java/application.properties](src/test/java/application.properties) configures the server to start on a random and unused port 8 | * for more options, refer to [this article at Baeldung](https://www.baeldung.com/spring-boot-running-port). 9 | * the Karate test [`dogs.feature`](src/test/java/karate/dogs.feature) is a "hybrid" test that calls the REST API as well as the database directly via JDBC 10 | * shows how [Java interop](https://github.com/karatelabs/karate#calling-java) can be used in [karate-config.js](src/test/java/karate-config.js) to configure as well as initialize the database connection 11 | * note how the port number is dynamically passed to Karate from the Spring context in [`DogsTest.java`](src/test/java/karate/DogsTest.java) 12 | 13 | The Java "glue" code that connects to the database and is able to make SQL queries is in [`DbUtils.java`](src/test/java/karate/DbUtils.java). Note that this is just a starting point. You can use this code as a reference and implement what is appropriate for your project. This example uses the [Spring JDBC template](https://spring.io/guides/gs/relational-data-access) that makes working with databases a lot easier in Java. You are free to use any Java code that gets the job done. Calling Java code from Karate is easy using [Java interop](https://github.com/karatelabs/karate#calling-java). 14 | 15 | Note that this code just needs to be created "one time". Once it is in place, no more Java code needs to be written (or compiled). Karate tests can be written by anyone in the team including non-programmers. And the tests will remain clean and focused on the business-scenario. 16 | 17 | ## Running 18 | 19 | Run `mvn test` to execute the JUnit test: [`DogsTest.java`](src/test/java/karate/DogsTest.java) 20 | 21 | ## Using the Shaded JAR 22 | 23 | In some projects, when Spring or Spring dependencies use the same libraries that Karate uses, you may run into classloading or issues such as a "class not found exception". You can switch to using the shaded "fat jar" of `karate-core` as [explained here](https://github.com/karatelabs/karate#karate-core-fat-jar). 24 | 25 | If you use the shaded JAR, you may see extra logging from libraries such as Thymeleaf. Instead of the `org.thymeleaf` entry in [`logback-test.xml`](src/test/java/logback-test.xml) you may need to change it to `karate.org.thymeleaf`. 26 | 27 | ## Further Reading 28 | * [Karate and Databases on Stack Overflow](https://stackoverflow.com/search?q=%5Bkarate%5D+database) 29 | * [Karate and CLI](../cli/README.md) - teams have reported success with using Karate to call CLI commands that in turn call the 30 | database 31 | * [Karate and Spring Boot](../spring-boot/README.md) 32 | * [Karate and SSL](../ssl/README.md) - another minimal Spring Boot Maven project. 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /websocket/README.md: -------------------------------------------------------------------------------- 1 | # Karate Websocket 2 | 3 | Karate has native support for [the Websocket API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) as an optional dependency (non-open source and commercial). Enterprise users can find more information here: [Karate-Websocket](https://github.com/karatelabs/karate-addons/tree/main/karate-websocket). 4 | 5 | A license is required for running (for e.g. in CI/CD) and a Karate Labs IDE subscription is required per developer seat. 6 | 7 | This sample project shows how to handle the async nature of Websocket communication and handle a custom protocol such as [STOMP](https://stomp.github.io/). Make sure you have a `.karate/karate.lic` file in place before running the example. 8 | 9 | ## Running 10 | 11 | This is a normal Java / Maven project. To run the simple [`echo.feature`](src/test/java/karate/echo.feature) you can do: `mvn clean test`. 12 | 13 | There is also [`json.feature`](src/test/java/karate/json.feature) that can be run as follows: `mvn test -Dtest=JsonRunner`. This shows how the built-in `io.karatelabs.websocket.JsonAdapter` can be used if all messages are known to be JSON. 14 | 15 | There is an advanced example: [`stomp.feature`](src/test/java/karate/stomp.feature) that shows how to fully control the flow of messages and the conversion of text (or bytes) to and from JSON in the test. Concepts such as how to implement a message adapter i.e. [`StompAdapter.java`](src/test/java/karate/StompAdapter.java) are explained in the [documentation](https://github.com/karatelabs/karate-addons/tree/main/karate-websocket). 16 | 17 | To run the STOMP example, you need to download and start this Spring-Boot based project: [gs-messaging-stomp-websocket 18 | ](https://github.com/spring-guides/gs-messaging-stomp-websocket). The [`/complete`](https://github.com/spring-guides/gs-messaging-stomp-websocket/tree/main/complete) directory has a ready to run Maven project which you can start from the command-line like this: 19 | 20 | ``` 21 | mvn exec:java -Dexec.mainClass="com.example.messagingstompwebsocket.MessagingStompWebsocketApplication" 22 | ``` 23 | 24 | You can also open the `complete` project within a Java IDE and run the main class referred in the command above as an alternative. 25 | 26 | This will start a local web-app on port 8080 and you can also view a demo web-page at `http://localhost:8080`. Now you can run the Karate test that communicates to the just-started server via STOMP over Websocket like this: 27 | 28 | ``` 29 | mvn test -Dtest=StompRunner 30 | ``` 31 | 32 | ## Further Reading 33 | 34 | Karate has had very basic support for websockets in the open-source version which may suffice for some teams. The following information is available: 35 | 36 | * [Documentation](https://github.com/karatelabs/karate#websocket) 37 | * Examples: 38 | * [echo.feature](https://github.com/karatelabs/karate/blob/master/karate-demo/src/test/java/demo/websocket/echo.feature) 39 | * [websocket.feature](https://github.com/karatelabs/karate/blob/master/karate-demo/src/test/java/demo/websocket/websocket.feature) 40 | * [Karate and WebSockets on Stack Overflow](https://stackoverflow.com/search?q=%5Bkarate%5D+websocket) 41 | * [Using a custom Java implementation if required](https://stackoverflow.com/a/69299321/143475) 42 | -------------------------------------------------------------------------------- /database/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.1.0 9 | 10 | 11 | io.karatelabs.examples 12 | karate-database 13 | 1.0-SNAPSHOT 14 | jar 15 | 16 | 17 | UTF-8 18 | 11 19 | 3.11.0 20 | 3.0.0 21 | 1.4.0 22 | 2.6.6 23 | 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-web 29 | 30 | 31 | org.springframework 32 | spring-jdbc 33 | 34 | 35 | com.h2database 36 | h2 37 | runtime 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-test 42 | test 43 | 44 | 45 | com.intuit.karate 46 | karate-junit5 47 | ${karate.version} 48 | test 49 | 50 | 51 | 52 | 53 | 54 | 55 | src/test/java 56 | 57 | **/*.java 58 | 59 | 60 | 61 | 62 | 63 | org.apache.maven.plugins 64 | maven-compiler-plugin 65 | ${maven.compiler.version} 66 | 67 | UTF-8 68 | ${java.version} 69 | ${java.version} 70 | 71 | 72 | 73 | org.apache.maven.plugins 74 | maven-surefire-plugin 75 | ${maven.surefire.version} 76 | 77 | -Dfile.encoding=UTF-8 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /grpc/src/test/java/client.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCghStziGnrRzF5 3 | Uj6jl+5zIVfhyFapdjfch7jA/+gweKNXHrVBdHpeDJOJZFvXCJ2hhWDWCKS3/aYL 4 | 3wVw9jkUfxPSu2J49pNdXL7WJsC3g+jfUz/t9nbVT5QWCVDR7NTUWiZsuCPRx20C 5 | gl4l6VBQHdIt9Dws2Cik3y/C0ZhZJvehMJUG6sHcSRiLC0a2TF54ANU9ibqaxeLo 6 | A7YYW1fg9sslliG/fuggO46Jkwb0dPL8ITt7V66d9IDDxb9xXDfAlC0pDy3H76Rx 7 | ScyQ3KvizU149ImDUxvH22b/R3PKpZ7hRlBhVlCtKbxlLZoq4h0/9Bz6/GZVASZC 8 | oTCPCuxngTlkor9cOZwv1EjzpjS1HMi/8oYNFX6OoV7uB2BEXswL0fhfzZ5kvW+C 9 | 2GnvFr+dPwbO+UJhr+hy8Dtc5ihv/SGui10NORegepOSnr5gfNyR5Q8XUur4PEzL 10 | gA6INoBBAXAr5765sxRlO+Bz7dbycD4TtfSjhfuGCJQSU7vyscPFap1V65EG8V8a 11 | 0WpVD6Qf6GIHwW/GBp/TYcWNLEMqxN09MK0h7LU7wJ+YITf8mnpzsJKZs35g+4/5 12 | BcWXeaSl/4kBDT5c6ZuxOjzE1wOVcs7oRSb4jeDn1iFe90tQPq5noDdmumVXWZVM 13 | ZWlRsRRX1i4NdceeJC1Es54NszmCMwIDAQABAoICAEKW2+6ikWXz87cjgi61UUrb 14 | cyyLwj+sdgH7H46Y2oZ5FTGH4KNVoYmwZ+fgBSVQQqwFu6Uukr5s79wO2aAB1K4H 15 | BX8vEuuhRoK9fcEy9FFs3EcArw2VZ7iXuZPmq2tadvPcrgH95YYZ18Pptwq9Hf8O 16 | T+mWXvwvc7TpjVOhRTT+sE1i7P+glWk/vXm45M2tIqdfmRZdM1cPblDXcUvrYKpH 17 | VwCxpjBdgggVDM1Pe9wfQ8mKM7W4Kw0FqAEO4JszKUGvdoiI7nH5nNsORVl24atF 18 | hbT+pKkg6e5fuvt9dbCEQkOrup6WgwNCxA+o+kJ96KpmJzuLRxxOTMPpQE6mtmiV 19 | XdU6Tutvf9HyYd7VttJUKuHIan4ExylDk84NyV1Da2KrwjN0iF2t609imWRB5au9 20 | 7N206QSaRib/zKRqhUBXF1RUb6klumCMxiZAI3f01PnwzwJm5hBdkXq9icvER05C 21 | bDpWaZNDXo6sRVJ1nJh91ISbRTnx/ERpxKnT91s7FxupwXnmn4bGrjeXLSTCK5wY 22 | jtAMS5+jV5wEodKpR76rTS/m9HSM97xajKywMASJvISDjkKcEExz86V375rdfQbX 23 | C+sdjH+TW2kERrn3BUkH4bi8pBVvtDUpXmwfmRUJtdt3SKqOhc0PVA5WV2BSDQzN 24 | 1/XJo2ky4UWjWuodWn5xAoIBAQDT2e1arV0MrNi1ybx2UZSIPWPn6VSiiP4uSjzh 25 | PUTKIcsMZieOHev7JKYNjSTcDK9jJdrnaOM+cFUz6kM78jNOl1uogd9PvazupApw 26 | aHwMnme4gEinZKeFZoh1LbmOxlAkj8oF4riQ7Y3UnM7a+GECe++4aQGSXXCeelpL 27 | HgIuXmLCi/Iw9s93k7uiPZqYOJRRVaxzMyRhpZ6EqRimbFuF0mqQYhPSbEEmwNfh 28 | ydYdB9mQEYutTpZPBbcLAvOhIefQZYwPuTIMDTWIF+QaaXhe64uC/WvpAy3AKjwp 29 | hInjhyKnhLjtL9arfUmNrOIcdZcWq49AKEjJ82JX4tS/oK6JAoIBAQDB+MamX3BF 30 | NShf+E6D2vQbejtYaovqwFMFMT7eG5ZYuXM0ND5OIutLtD8W9Rg9hkVsr4y6c03E 31 | j4W9HHOuz2TWxQyO62+MdHlvYQQ80gRDOWvMS7u3R/yOKolMDW/+Jevpkw7o1nFF 32 | sL4CY0k3+neuQBHRqs7PCIfg1FWP1TE6H/iS+80iNwgLSQKvQdvtzq1dVjshFFvS 33 | uoosPM6DWXEe7yV86bR5hLtDutgx05gn9PVesPaTGhnma8EmbqiBg83JRCYT3l3W 34 | SY/gvPeVPVp9LuJma9umAkNl1CGNH1j/XVhqLBDDx6p1dDColQXGfp3XzlD1a6FW 35 | xnumMwo+jdvbAoIBAGoWwQDevjEhwahPbRxHQD11mLlDJIn8VmVx8cjNuMwMXjVI 36 | VtiZbVooASvaGbJEe/QHufaWlO3orRJBZwf3AvCBZXoeB2lUT+x1o3ClMjHThZdk 37 | Tn3dLvLj5MPhcQHpl6qngwCth8Wz4ImvOPt41IO88tADbbERL9t85Ain72mvBH/u 38 | OwuAHWcBST424VsHQmb0o1ZRLw/jM121nE2DB9YdCBZjtw9x/LJecf106M9C5hV6 39 | Y9sW9rh94SsXgE+Zvg+jOp+JG2Hjn4IWjLkZRhkqlYO0Sry2RcvsmpIj+DVDr/v5 40 | v+2vPi5EoHfdMqIT1OSaZzM2uTTAt+fRBL8txRkCggEBALqd6iDu+UjcV7fdYUyi 41 | PvCgrK/n8i0sU7NPKbjuubsq0JeNG9R46/+trnUb4PJwWCK00qQfgtZ1bqn+0Z2B 42 | kva+JdLq2Cs9dAegQz9wnwE+IWQwCK3Q6D6u1eEBnJnbShkyjsmcZuYxoN0TQMJG 43 | ixZuNbaOquGsx22bW6ZB6laNo81lzHn6kBara5XJuxoUGd8Os1ykBaO8LGtbJSRh 44 | zN+CHYMMJcIz3SbQgGePt3fZyKgNgW0NU5XIXc/n7t6MPFRC6I99BLLBm1cQ9vHy 45 | UTjW/qKjanNRAh7Z9F2dpzYoTIP5WTfCxVCzNI08so3CC4Iw0NsNbe/ajePcfyKn 46 | wLkCggEACN3JZO71OoN78bTRe2e3LFdfcORhAKbX7TZHfUJ3ZYgbFxv5hgb0cllC 47 | DUvGFr14kpPHmlZkunRkjL5+KGrtXOtTWa0fUfQtGXH8T5hYV17LIx6zyMOQRFn2 48 | ggVF0JBe9L83bPbaheD5l+qHsmUMos70V5xQCEx15Hki06Gn4ib2b0rchZ1234rp 49 | UXld0EEcHtTKwzhZV1lCkVhoGK4Mm+SKUzUraUsxZ3S1KJu6RUcass2jdRN2EGSO 50 | pzWypYo043NDdP577gTqgFpEl+OYNQa0BVIfhNADBRcVeTb95vc+fXTws1PjgRiT 51 | bTcfBx3XkwhMjn1B/8Am3FPIfKphtA== 52 | -----END PRIVATE KEY----- 53 | -------------------------------------------------------------------------------- /grpc/src/test/java/server.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDJcS+yynU8ezld 3 | cIkMjtYSmq3itmUENZmso0/X+YgAk49eW5kyFbC0bGqdaImpJXB8J2hggHxhya/L 4 | 0tDaF9MpAqNNUYgqAy+dAmy3WSgOOGU+clgp17NjJfg35GFhFPSHGYmSsC5sLG39 5 | 7uQ4/3+Fap+AOakONOdcnGX+4BrxZyJZJcDYhVNcpjs2169ktlzQNnHlpeogaqan 6 | TEpPVXKQo2k5CKO9LEGHZoh2Lp+2NRtNYvTxHmDY2jsVU35V9Q3V/OKhuStfbe1t 7 | CpegiJvy3F2qDJK3aFPN78Uofre5VNLnMQyoBQIN3zn8Y87Uu3OOCohlHWPmUc44 8 | 3F3JVHtgzom6Za/jbO83Cs1z+Xe+znEnAdO91ejkppAWVHV3fisFhsjF55hgr6cB 9 | lIcVnr3x++wavZXhcV+yuumXtt2Mf2LcbeQ+Bs8/EbvxVXT79+dHsHswu5GjEDG1 10 | 0YV678+xIn9HpJHwXHZYHtFDpVRD/9dTCBxfbjSiZIJAy3ado5wilXFK3trL3Two 11 | 9po3VVuq+jGHmDWSed5nunkLwATS8Lw/6pLZQShrpjNv9ZErexJAq4glf2lXV36V 12 | DC9xl+xL4jEfsj9Cc4TerHGa+cjyhjqrFP+SEGv1rMpP6eJ8UxuGjTbfDzS2Focd 13 | eS5lkgfJ+dJ81GwqjErwLSLQmZFETwIDAQABAoICAEIN3WgxPzQv6+WZ6za097lu 14 | AyreSE2TDeswOhRF/LTDrjVwr9Fej2z6SBOJnepbHoF3oqBSQXcHXZ/mZxm8yj8e 15 | YFIQNCgil1BS5TdSAvJ2x6wsboB5/Ja8cqJRPyVIa86JLzVslCxgfUjRNwEBtt0W 16 | 02qGfcrsyhjyJ/floLAb84Vr/cqCHY257JzVKOxLaC/WSo7VUuqCTld5irxs9n47 17 | N1u+W4LCqlIt6v1l2HU1ANjlZBBUt8kj9k/N6xVgn8LVg7MoNvK55yrkWEgJw6ll 18 | XUlPiiSeDyzuPKZEtxYMnIO278GAsuW9lxQN3lqfhQrEpWkStBloJck7aX2FOFc3 19 | NDfZByNGjaUfzFGntL2azjBXt6Q/6hh9nZnz9YFuOXRlCPWKa+2XoXP2gz5Xu/+f 20 | UYQSO28WIekabXl/Rphxo2YOGdPQM3J6mdbz2UieJhPaVWld+We3bOubkN58zlvF 21 | HwHSxrzkull11LTkmyNc4LSugtZouyws4IP8nRDPA0cjAhfqM3JNiBzSk3HhO0Nj 22 | vHgG6LSj8/hIC+/A1PRDESPediNaP3SCSl3si2cxKA+t2gelfkc6/izWZ2f4qZuB 23 | ZL8FDoKRakxX1Hvr+ad2qV7w/vOxmsR7NyX/niEfssl7d+6EIJ4k+qHJUpVNkqv2 24 | jH/ip3kQ9bKnXkq4un2xAoIBAQDkLHF0+TOLBZmhjTiEMTZgt5f4yDIk/IBLoWEz 25 | E99a3i73wvRaUHBWm1zhdIyhKSdPQFaZ9XtFx/iFwO5RPnZSNFQuK/636EXdJUht 26 | DkuO67E8YIHfjxDqsBdnYXoorN9Ezuz8Gp/G+10Fr6yR8Tk2cCF/VQwj09iSJTyZ 27 | H5NkO0t7iIJxueu8kx3VbkqQLaHmnHJekyLZL124ASpXVnS0cP+ZbL1sR7N031xz 28 | daMQoNkdJscm+AwzqqtGWrl2XPlzj+ZDqlBLA7dng+33EkW6yA9ESS+P/Oj5Qs1V 29 | W17uwmGYqFjh7Cm8I/W/4dydp7K8QqFtp7LzOnL3CdjmB1/7AoIBAQDiAjB1BrAZ 30 | v1pl39e56SWhsJAh5RGRu3lxnN+pz1DbSlRA9K53COXMcQYSpOHSjJRowYytb7uQ 31 | etYysq5X9/UUqu0nZVA5QQw9ta9wiNlAwgCpH6qBulAwXOp7bpMjkSulGFzsjSR3 32 | X+O5Qd1L2hKHmPggEsSt1CmGvAU1KaLq3q6qreyQuwqSd7KWaVEKsAqQyNuHP2yw 33 | ePQXJVRCn8YvFAN/FVynpfU8RwqWOVE69/VXCcsvFUvjIEZBMa4ZlV8edJ5z1DSz 34 | 0q9/0GXW+dITvynIx6xslQB6r+08WY1xc/spw9hA4L1FSvzKqbsm7rBrwM/zoPKH 35 | qbyAcbb6+bi9AoIBAQCAybEUZCA6pOONMwemXZyixJ3LtzvOcpL7nVAeo2XbhTMf 36 | d3OyklqGF9U6EC3cPT1J1zfKWKvGvFNDM52QT+A7D/w/v2dbaIgehY+2tm3hcpks 37 | ShCkHb1fqhrbqEJqOQEgdmd++IwcpP5hWkHecjhnyKyvkVJz2nwQKWJlz1PDLFCz 38 | nl56UIWFf8hEEqeVb5xFbSKEzSnLSpfsZwP+HfdrbahnceANAP+CxRwKs2hh11gU 39 | wzF/hlxkwT1BTa4G5/2Iw70ljjkZzjQ0AlxLq42eGpO7aE+nRwo8vv7k4djYjPDH 40 | WKYqhsEbx3RLZPHALsqMxlMVcKVp8iC33WAGnj0HAoIBAFiQ5xBVCJluZSxa5ZzT 41 | Ao40NKczrwje4J5nDTbsKRFmNVInEF9RO0w8VlbkCiKKOHY8srYcfPIHUP0ZDD0o 42 | y//HY5v2ldN57CQamJ+O4SQBYmTkJdskedwZ7UFleX+Mmf/eZjvEq6+kAgdNCj15 43 | PZ2pkkJvWGeOJp/H+np00IUdsnDsKzIkOeZfxbovlzSK+/j03SJI9nzJSU3wsO5S 44 | 0kUMoLoiUubXoBx48msgFvb2yEvNaLQQsmZU9XMC1ujrohS7OoTFecmmHGQH9ICj 45 | 8XEPjn5B0Q3T7hYl7t+hcE4vVxNszcfOyhznX9zDWrXM/5GaQ2ODhMco+teSuFPt 46 | nDkCggEBALn8uEKXNrKNNpi2rFnQ7Cr2GdlKGJM1O0evZji9Oq81yh5T2tTtf6mh 47 | Zx+E3/j/K/fjX0Oyd5f4Ta3q7s61rWkC6Z8zZ9y/S+kvu987iFH5TlmEI3EJAD/Y 48 | pArgKggxNi4aBub8EYOj9pOjEjuo3OmaD48In5uq5MGwVGSN20E1J7/9RqfFxqng 49 | 0C9pDBXTMi/10T7azT8gqBkWHmITv2Ny8Wcad/9aK1mI9QSCMranCUAGgpX3lM6Y 50 | 2pw2H/nJFZcSdFCElUWxu2Y9B0d5o+nceIaDQ8i1cZn+8TcSPNSYE0G87H0oUWpP 51 | paKxl7LkLUSPPOOvDxmLojgcjYaXPAQ= 52 | -----END PRIVATE KEY----- 53 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | # Karate and Docker 2 | 3 | ## Standalone JAR 4 | This simple minimalistic [`Dockerfile`](Dockerfile) is sufficient to package a Java Runtime Environment and the Karate [Standalone JAR](https://github.com/karatelabs/karate/wiki/Get-Started:-Other-Runtime-Options#standalone-jar). 5 | 6 | Here we are using an [`eclipse-temurin`](https://hub.docker.com/_/eclipse-temurin/) Docker image as a base. 7 | 8 | ```docker 9 | FROM eclipse-temurin:17-jre 10 | 11 | RUN curl -L -o karate.jar https://github.com/karatelabs/karate/releases/download/v1.5.0/karate-1.5.0.jar 12 | ``` 13 | 14 | The Docker recipe is very simple, just download `karate.jar` into the root of the docker image. To build a docker image called `karate-jre` locally, you can do this: 15 | 16 | ```bash 17 | docker build -t karate-jre . 18 | ``` 19 | 20 | Now to run a set of Karate tests in a `src` folder within the current directory (outside the docker image) you can do this: 21 | 22 | ```bash 23 | docker run -it --rm -v "$(pwd)/src":/src -w /src karate-jre java -jar /karate.jar . 24 | ``` 25 | 26 | If you are on Windows, [refer to this](https://stackoverflow.com/a/41489151/143475) for equivalents of the `$(pwd)` etc. 27 | 28 | The explanation of the above command is as follows: 29 | 30 | * `-it` runs in interactive mode, and `--rm` removes the temporary image after use 31 | * use `-v` to mount the `./src` folder as `/src`. 32 | * use `-w` to make `/src` the working directory 33 | * now the command `java -jar /karate.jar .` will run all feature files in the current folder (which is `.`) 34 | * note that test reports will appear in `./src/target` 35 | 36 | All the possible Karate command-line options are explained here: [Usage](https://karatelabs.github.io/karate/karate-netty/#usage). 37 | 38 | You can easily customize the above recipe, for example you could bundle your tests within the docker image. One nice thing about the above example is that the test reports are created outside the image, so you can view them even after the docker process stops. 39 | 40 | ## Adding JARs to the classpath 41 | 42 | This [Dockerfile](https://github.com/karatelabs/karate-todo/blob/main/cfg/Dockerfile-app) which is part of the [karate-todo](https://github.com/karatelabs/karate-todo) example shows how you can add JAR files to the classpath (from a Maven build), and run a java command when the container starts. This pattern is useful if you want to "ship" a Docker image that embeds a [Karate mock](https://karatelabs.github.io/karate/karate-netty). 43 | 44 | You can also `ADD` feature files to the Docker image and run tests when the container starts. In this case, mounting a `/target` directory may be needed to see reports. 45 | 46 | ## Using Maven 47 | 48 | Using the [maven:3-amazoncorretto-17](https://hub.docker.com/layers/library/maven/3-amazoncorretto-17/images/sha256-9c29d34f56dcb979fb5819193abff63246115b21cdfc58287f73708af7a66117?context=explore) image may be sufficient for most use-cases. For example: 49 | 50 | ```bash 51 | docker run -it --rm -v "$(pwd)":/src -w /src -v "$HOME/.m2":/root/.m2 maven:3-amazoncorretto-17 mvn test 52 | ``` 53 | 54 | Here we use `-v "$HOME/.m2":/root/.m2` to mount and re-use your local Maven JAR download "cache" (which saves time), but you can omit it if needed for a true "from scratch" experience. 55 | 56 | ## Further Reading 57 | 58 | * [Get Started - Other Runtime Options](https://github.com/karatelabs/karate/wiki/Get-Started:-Other-Runtime-Options#docker) 59 | * There are some tips, tricks and recipes in this thread: [https://github.com/karatelabs/karate/issues/396](https://github.com/karatelabs/karate/issues/396) -------------------------------------------------------------------------------- /kafka/src/test/java/karate/kafka-multi.feature: -------------------------------------------------------------------------------- 1 | Feature: 2 | 3 | Background: 4 | * configure kafka = 5 | """ 6 | { 7 | 'bootstrap.servers': '127.0.0.1:29092', 8 | 'schema.registry.url': 'http://localhost:8081' 9 | } 10 | """ 11 | * def channel = karate.channel('kafka') 12 | * channel.register({ name: 'complex', path: 'classpath:karate/complex.avsc' }) 13 | 14 | Scenario: Complex Avro - test-topic1 15 | * def consumer = channel.consumer() 16 | 17 | * consumer.topic = 'test-topic1' 18 | * consumer.count = 1 19 | * consumer.start() 20 | 21 | * def producer = channel.producer() 22 | 23 | * producer.topic = 'test-topic1' 24 | * producer.schema = 'complex' 25 | * producer.key = 'zero' 26 | * producer.headers = { foo: 'bar1', baz: 'ban1' } 27 | * def value = 28 | """ 29 | { 30 | "meta": { 31 | "metaId": "123", 32 | "metaType": "AAA", 33 | "metaChildren": [{ "name": "foo", "status": "ONE" }] 34 | }, 35 | "payload": { 36 | "payloadId": "456", 37 | "payloadType": null, 38 | "payloadEnum": "FIRST", 39 | "payloadChild": {"field1": "foo", "field2": "bar"} 40 | } 41 | } 42 | """ 43 | * producer.value = value 44 | * producer.send() 45 | 46 | * def response = consumer.collect() 47 | * match response[0].key == 'zero' 48 | * match response[0].headers == { foo: 'bar1', baz: 'ban1' } 49 | * match response[0].value == 50 | """ 51 | { 52 | "meta": { 53 | "metaId": "123", 54 | "metaType": "AAA", 55 | "metaChildren": [ 56 | { 57 | "name": "foo", 58 | "status":"ONE" 59 | } 60 | ] 61 | }, 62 | "payload": { 63 | "payloadId": "456", 64 | "payloadType": null, 65 | "payloadEnum": "FIRST", 66 | "payloadChild": { 67 | "field1": "foo", 68 | "field2": "bar" 69 | } 70 | } 71 | } 72 | """ 73 | 74 | Scenario: Complex Avro - test-topic2 75 | * def consumer = channel.consumer() 76 | * consumer.topic = 'test-topic2' 77 | * consumer.count = 1 78 | * consumer.start() 79 | 80 | * def producer = channel.producer() 81 | 82 | * producer.topic = 'test-topic2' 83 | * producer.schema = 'complex' 84 | * producer.key = 'zero' 85 | * producer.headers = { foo: 'bar1', baz: 'ban1' } 86 | * def value = 87 | """ 88 | { 89 | "meta": { 90 | "metaId": "123", 91 | "metaType": "AAA", 92 | "metaChildren": [{ "name": "foo", "status": "ONE" }] 93 | }, 94 | "payload": { 95 | "payloadId": "456", 96 | "payloadType": null, 97 | "payloadEnum": "FIRST", 98 | "payloadChild": {"field1": "foo", "field2": "bar"} 99 | } 100 | } 101 | """ 102 | * producer.value = value 103 | * producer.send() 104 | 105 | * def response = consumer.collect() 106 | * match response[0].key == 'zero' 107 | * match response[0].headers == { foo: 'bar1', baz: 'ban1' } 108 | * match response[0].value == 109 | """ 110 | { 111 | "meta": { 112 | "metaId": "123", 113 | "metaType": "AAA", 114 | "metaChildren": [ 115 | { 116 | "name": "foo", 117 | "status":"ONE" 118 | } 119 | ] 120 | }, 121 | "payload": { 122 | "payloadId": "456", 123 | "payloadType": null, 124 | "payloadEnum": "FIRST", 125 | "payloadChild": { 126 | "field1": "foo", 127 | "field2": "bar" 128 | } 129 | } 130 | } 131 | """ 132 | -------------------------------------------------------------------------------- /micronaut/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | io.karatelabs.examples 7 | karate-micronaut 8 | 1.0.0-SNAPSHOT 9 | jar 10 | 11 | 12 | io.micronaut 13 | micronaut-parent 14 | 3.9.4 15 | 16 | 17 | 18 | 11 19 | 11 20 | 3.9.4 21 | netty 22 | 1.4.0 23 | 22.0.0.2 24 | 25 | 26 | 27 | 28 | io.micronaut 29 | micronaut-http-server-netty 30 | compile 31 | 32 | 33 | io.micronaut 34 | micronaut-jackson-databind 35 | compile 36 | 37 | 38 | jakarta.annotation 39 | jakarta.annotation-api 40 | compile 41 | 42 | 43 | ch.qos.logback 44 | logback-classic 45 | runtime 46 | 47 | 48 | io.micronaut.test 49 | micronaut-test-junit5 50 | test 51 | 52 | 53 | org.junit.jupiter 54 | junit-jupiter-api 55 | test 56 | 57 | 58 | org.junit.jupiter 59 | junit-jupiter-engine 60 | test 61 | 62 | 63 | com.intuit.karate 64 | karate-core 65 | ${karate.version} 66 | all 67 | test 68 | 69 | 70 | org.graalvm.js 71 | js-scriptengine 72 | ${karate.graal.version} 73 | test 74 | 75 | 76 | org.graalvm.js 77 | js 78 | ${karate.graal.version} 79 | test 80 | 81 | 82 | 83 | 84 | 85 | 86 | src/test/java 87 | 88 | **/*.java 89 | 90 | 91 | 92 | 93 | 94 | io.micronaut.build 95 | micronaut-maven-plugin 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /quarkus/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | io.karatelabs.examples 6 | karate-quarkus 7 | 1.0.0-SNAPSHOT 8 | 9 | 10 | quarkus-bom 11 | io.quarkus 12 | 3.1.0.Final 13 | 3.8.1 14 | 3.0.0-M7 15 | UTF-8 16 | 11 17 | 11 18 | true 19 | 1.4.0 20 | 21 | 22 | 23 | 24 | 25 | src/test/java 26 | 27 | **/*.java 28 | 29 | 30 | 31 | 32 | 33 | maven-compiler-plugin 34 | ${compiler-plugin.version} 35 | 36 | 37 | maven-surefire-plugin 38 | ${surefire-plugin.version} 39 | 40 | 41 | org.jboss.logmanager.LogManager 42 | ${maven.home} 43 | 44 | 45 | 46 | 47 | ${quarkus.platform.group-id} 48 | quarkus-maven-plugin 49 | ${quarkus.platform.version} 50 | 51 | 52 | 53 | build 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | ${quarkus.platform.group-id} 65 | ${quarkus.platform.artifact-id} 66 | ${quarkus.platform.version} 67 | pom 68 | import 69 | 70 | 71 | 72 | 73 | 74 | 75 | io.quarkus 76 | quarkus-resteasy-reactive 77 | 78 | 79 | io.quarkus 80 | quarkus-junit5 81 | test 82 | 83 | 84 | com.intuit.karate 85 | karate-core 86 | ${karate.version} 87 | all 88 | test 89 | 90 | 91 | ch.qos.logback 92 | logback-classic 93 | 1.4.7 94 | 95 | 96 | io.quarkiverse.logging.logback 97 | quarkus-logging-logback 98 | 1.1.0 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /kafka-custom/src/test/java/io/karatelabs/examples/kafka/KarateKafkaConsumer.java: -------------------------------------------------------------------------------- 1 | package io.karatelabs.examples.kafka; 2 | 3 | import com.intuit.karate.Json; 4 | import io.confluent.kafka.serializers.KafkaAvroDeserializer; 5 | import io.confluent.kafka.serializers.KafkaAvroSerializerConfig; 6 | import java.time.Duration; 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | import java.util.Properties; 11 | import java.util.Set; 12 | import java.util.UUID; 13 | import java.util.concurrent.CompletableFuture; 14 | import java.util.concurrent.ExecutorService; 15 | import java.util.concurrent.Executors; 16 | import org.apache.avro.generic.GenericRecord; 17 | import org.apache.kafka.clients.consumer.ConsumerConfig; 18 | import org.apache.kafka.clients.consumer.ConsumerRecord; 19 | import org.apache.kafka.clients.consumer.ConsumerRecords; 20 | import org.apache.kafka.clients.consumer.KafkaConsumer; 21 | import org.apache.kafka.common.TopicPartition; 22 | import org.apache.kafka.common.serialization.StringDeserializer; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | public class KarateKafkaConsumer { 27 | 28 | static final Logger logger = LoggerFactory.getLogger(KarateKafkaConsumer.class); 29 | 30 | private final KafkaConsumer kafka; 31 | private final CompletableFuture partitionFuture = new CompletableFuture(); 32 | private final CompletableFuture listenFuture = new CompletableFuture(); 33 | private final ExecutorService executor = Executors.newSingleThreadExecutor(); 34 | 35 | private final List messages = new ArrayList(); 36 | 37 | public KarateKafkaConsumer(String topic) { 38 | kafka = new KafkaConsumer(config()); 39 | listen(topic); // will block until partition is ready 40 | } 41 | 42 | private void listen(String topic) { 43 | kafka.subscribe(Collections.singletonList(topic)); 44 | logger.debug("kafka consumer subscibed to topic: {}", topic); 45 | executor.submit(() -> { 46 | while (true) { 47 | ConsumerRecords records = kafka.poll(Duration.ofMillis(1000)); 48 | if (records != null && !records.isEmpty()) { 49 | for (ConsumerRecord record : records) { 50 | logger.debug("<< kafka offet: {}, key: {}, value: {}", record.offset(), record.key(), record.value()); 51 | String json = AvroUtils.toJson(record.value()); 52 | messages.add(Json.of(json).value()); 53 | } 54 | listenFuture.complete(true); 55 | break; 56 | } 57 | // assignment() can only be called after poll() has been called at least once 58 | Set partitions = kafka.assignment(); 59 | if (partitions.isEmpty()) { 60 | try { 61 | logger.debug("waiting for partition ..."); 62 | Thread.sleep(1000); 63 | } catch (Exception e) { 64 | throw new RuntimeException(e); 65 | } 66 | } else { 67 | logger.debug("partitions: {}", partitions); 68 | partitionFuture.complete(true); 69 | } 70 | } 71 | }); 72 | try { 73 | partitionFuture.get(); 74 | logger.debug("kafka consumer partition ready"); 75 | } catch (Exception e) { 76 | throw new RuntimeException(e); 77 | } 78 | } 79 | 80 | public List getMessages() { 81 | try { 82 | logger.debug("kafka consumer waiting for messages ..."); 83 | listenFuture.get(); 84 | } catch (Exception e) { 85 | throw new RuntimeException(e); 86 | } 87 | return messages; 88 | } 89 | 90 | public void close() { 91 | kafka.close(); 92 | executor.shutdown(); 93 | } 94 | 95 | public static Properties config() { 96 | // refer https://kafka.apache.org/documentation/#consumerconfigs 97 | Properties props = new Properties(); 98 | props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "127.0.0.1:29092"); 99 | props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); 100 | props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, KafkaAvroDeserializer.class); 101 | props.put(KafkaAvroSerializerConfig.SCHEMA_REGISTRY_URL_CONFIG, "http://localhost:8081"); 102 | // we use a random id to avoid keeoing track and having to seek to the beginning 103 | props.put(ConsumerConfig.GROUP_ID_CONFIG, UUID.randomUUID().toString()); 104 | return props; 105 | } 106 | 107 | } 108 | --------------------------------------------------------------------------------