Skip to content

Zorin95670/e2e-test-runner

Repository files navigation

e2e-test-runner

e2e-test-runner is a ready-to-use E2E test runner that leverages Cypress and Cucumber.

It provides a collection of pre-implemented reusable steps to simplify writing and maintaining end-to-end tests for your applications.

Features

  • πŸ§ͺ Predefined Cucumber steps for HTTP requests and assertions
  • 🧰 Built-in context system with template rendering (via Nunjucks)
  • βš™οΈ Compatible with Cypress and Cucumber ecosystem
  • πŸš€ Run tests via Node or Docker

Technologies

Installation

Option 1: use image from docker hub

You can pull and run the prebuilt image directly from Docker Hub:

docker pull vincentmoittie/e2e-test-runner:latest

Option 2: Clone the project

git clone https://github.com/zorin95670/e2e-test-runner e2e

Make sure to include e2e in your .gitignore if it's only for local use.

Option 3: Use as a Git submodule

git submodule add https://github.com/zorin95670/e2e-test-runner e2e

Then install dependencies:

cd e2e
npm install

πŸš€ Running Tests

πŸ”§ Required Environment Variable

The test runner requires the environment variable CYPRESS_FEATURES_PATH.

  • It must point to the directory containing your .feature files.
  • The path should be relative to the current working directory (i.e., where npm run start is executed).
  • For example, in a Java project structure, if the test runner is executed from the e2e folder, the correct value would typically be:
CYPRESS_FEATURES_PATH=../src/test/resources/features

You must define this variable in a .env file or inject it at runtime.

πŸ“¦ Local Execution (with dotenv)

To run the test runner locally and load environment variables from a .env file:

  1. Install dotenv-cli globally:
npm install -g dotenv-cli
  1. Run the test runner:
dotenv -e ../.env -- npm run start
# With ui
dotenv -e ../.env -- npm run start:ui

🐳 Run via Docker

To run the test runner in a Docker container, make sure to:

  • Provide access to the .env file.
  • Set the timezone (e.g., Europe/Paris) using the TZ environment variable.
  • Connect the container to the appropriate Docker network (e.g., to communicate with your application under test).

Example:

docker run --rm \
  --env-file .env \
  --env TZ=Europe/Paris \
  --network my-app-network \
  -v "$(pwd)/src/test/resources/features":/app/src/test/resources/features \
  vincentmoittie:e2e-test-runner:latest

Or one-line version:

docker run --rm --env-file .env --env TZ=Europe/Paris --network my-app-network  -v "$(pwd)/src/test/resources/features":/app/src/test/resources/features vincentmoittie:e2e-test-runner:latest

Replace my-app-network with the name of the Docker network your application is running on.

🐳 Run via local Docker

To run the test runner in a Docker container, make sure to:

  • Mount the project directory.
  • Provide access to the .env file.
  • Set the timezone (e.g., Europe/Paris) using the TZ environment variable.
  • Connect the container to the appropriate Docker network (e.g., to communicate with your application under test).

Example:

docker build e2e -t e2e-test-runner
docker run --rm \
  --env-file .env \
  --env TZ=Europe/Paris \
  --network my-app-network \
  -v "$(pwd)/src/test/resources/features":/app/src/test/resources/features \
  e2e-test-runner

Or one-line version:

docker run --rm --env-file .env --env TZ=Europe/Paris --network my-app-network  -v "$(pwd)/src/test/resources/features":/app/src/test/resources/features e2e-test-runner

Replace my-app-network with the name of the Docker network your application is running on.

Usage

The test runner supports writing tests in Gherkin using .feature files.

Example Feature

Feature: Basic HTTP check

  Scenario: GET Google homepage
    When I request "https://www.google.com" with method "GET"
    Then I expect status code is 200

Using Nunjucks in Step Values

You can use Nunjucks templating syntax inside step values. This allows dynamic content, especially useful when injecting data from environment variables or shared context.

Example with environment variable

Given I set http header "Authorization" with "Bearer {{ ctx.AUTH_TOKEN }}"

JSON formatting support

A custom json filter has been added to Nunjucks to properly serialize objects into formatted JSON strings.

Then I log "{{ response.body | json }}"

This is useful for debugging or displaying formatted JSON output directly from the response.

Context System

This test runner provides a built-in context system to share data between steps. It is designed to simplify dynamic value handling, templating, and state tracking during test execution.

Key Description
env Contains all environment variables. Useful for configuration and templating.
ctx A customizable object used to store any custom data needed during the test flow. Reset before each scenario.
response Stores the last HTTP response. Reset before each scenario.
httpHeaders Stores all HTTP headers set via step definitions. Reset before each scenario.

Example Usage

You can also use the context in templated strings (via Nunjucks):

When I request "{{ env.API_URL }}/users/{{ ctx.userId }}" with method "GET"

πŸ”€ Supported <type> values

Certain steps allow you to specify a type to interpret or convert values properly. The following types are supported:

Type Description
string Default type. Values are kept as-is.
integer Converts the value to a JavaScript integer (e.g., "42" β†’ 42).
float Converts the value to a JavaScript float (e.g., "3.14" β†’ 3.14).
boolean Converts the value to a boolean ("true" β†’ true, "false" β†’ false).
json Parses the value as a JSON object (e.g., "{ \"foo\": 123 }" β†’ { foo: 123 }).

πŸ“Œ These types are used to ensure that context variables, assertions, and request parameters behave as expected during test execution.

πŸ“Š Using <dataTable>

In some steps like:

When I request "<url>" with method "<method>" with query parameters

You can define a DataTable in your Gherkin file to pass query parameters dynamically.

The table must include at least key and value, and may optionally include a type column:

When I request "/api/search" with method "GET" with query parameters
| key       | value      | type     |
| q         | banana     | string   |
| limit     | 10         | integer  |
| exact     | true       | boolean  |
Column Required Description
key βœ… The name of the query parameter.
value βœ… The value to assign to the key.
type ❌ Optional type conversion (see supported types above). Default: string

βœ… The table is evaluated with Nunjucks, so you can dynamically reference values like {{ ctx.foo }}.

🏷️ Tags

You can use tags to control which scenarios or features to run during test execution:

βœ… Skip a single scenario

Use @skip above a scenario to skip it.

Feature: User login

  @skip
  Scenario: Valid credentials
    Given I visit the login page
    When I enter valid credentials
    Then I should be redirected to the dashboard

βœ… Run only one scenario

Use @only above a scenario to run only that one. All others will be ignored.

Feature: User login

  @only
  Scenario: Invalid credentials
    Given I visit the login page
    When I enter invalid credentials
    Then I should see an error message

βœ… Skip an entire feature

Use @skip above the Feature: line to skip all scenarios in that file.

@skip
Feature: Password recovery

  Scenario: Request password reset
    Given I visit the forgot password page
    When I enter my email
    Then I should receive a reset email

πŸ“š Step Definitions Reference

πŸ”§ Context Utilities

  1. Log a value
Then I log "<value>"

# Example:
Then I log "{{ response.status }}"
  1. Wait a duration
Then I wait <seconds>s

#Example:
Then I wait 2s
  1. Store a value in context
Then I store "<key>" as "<value>" in context

# Example:
Then I store "userId" as "{{ response.body.id }}" in context

  1. Store a raw value in context
Then I store as "<value>":
"""
My data
"""

# Example:
Then I store as "data":
"""
My data
"""

🌐 HTTP Requests

  1. Basic request
When I request "<url>" with method "<method>"

# Example:
When I request "https://api.example.com/items" with method "GET"
  1. Request with query parameters
When I request "<url>" with method "<method>" with query parameters
| key     | value      | type    |
| userId  | 123        | integer |

# Example:
When I request "https://api.example.com/users" with method "GET" with query parameters
| key     | value      | type    |
| userId  | 123        | integer |
  1. Request with raw body
When I request "<url>" with method "<method>" with body:
"""
{ "name": "John" }
"""

# Example:
When I request "https://api.example.com/users" with method "POST" with body:
"""
{ "name": "John" }
"""
  1. Set HTTP header
Given I set http header "<key>" with "<value>"

# Example:
Given I set http header "Authorization" with "Bearer abc123"

πŸ“₯ Response Assertions

  1. Check status code
Then I expect status code is <code>

# Example:
Then I expect status code is 200
  1. Compare templated values
Then I expect "<value>" is empty
Then I expect "<value>" is not empty
Then I expect "<value>" is "<expected>"
Then I expect "<value>" is not "<expected>"
Then I expect "<value>" contains "<expected>"
Then I expect "<value>" not contains "<expected>"

# Example:
Then I expect "{{ response.body }}" is empty
Then I expect "{{ response.body }}" is not empty
Then I expect "{{ response.status }}" is "200"
Then I expect "{{ response.status }}" is not "200"
Then I expect "{{ response.body.name }}" contains "test"
Then I expect "{{ response.body.name }}" not contains "test"
  1. Compare templated values with type
Then I expect "<value>" is "<expected>" as "<type>"

# Example:
Then I expect "{{ response.status }}" is "200" as "integer"
  1. Check length of value
Then I expect "<value>" to have length <number>

# Example:
Then I expect "{{ response.body.users }}" to have length 5
  1. Check length with type
Then I expect "<value>" as "<type>" to have length <number>

# Example:
Then I expect "{{ response.body.users }}" as "json" to have length 5

πŸ” Resource Assertions

  1. One resource equals to a value
Then I expect one resource of "<value>" equals to "<expected>"

# Example:
Then I expect one resource of "{{ response.body.users }}" equals to "John"
  1. One resource equals with type
Then I expect one resource of "<value>" equals to "<expected>" as "<type>"

# Example:
Then I expect one resource of "{{ response.body.users }}" equals to "123" as "integer"
  1. Resource field match expected
Then I expect one resource of "<value>" contains "<field>" equals to "<expected>"

# Example:
Then I expect one resource of "{{ response.body.users }}" contains "name" equals to "Alice"
  1. Resource field match expected with type
Then I expect one resource of "<value>" contains "<field>" equals to "<expected>" as "<type>"

# Example:
Then I expect one resource of "{{ response.body.users }}" contains "age" equals to "30" as "integer"

πŸ” Manipulate localStorage

  1. Set a value in LocalStorage
Given I set in localstorage field "<key>" with "<value>"

# Example:
Given I set in localstorage field "token" with "abc123"
  1. Assert a value in LocalStorage
Then I expect localstorage field "<key>" is "<expected>"

# Example:
Then I expect localstorage field "token" is "abc123"
  1. Delete a value from LocalStorage
Then I delete "<key>" in localstorage

# Example:
Then I delete "token" in localstorage
  1. Copy LocalStorage field to context
Then I set localstorage field "<localStorageField>" to context field "<contextField>"

# Example:
Then I set localstorage field "token" to context field "userToken"
  1. Copy LocalStorage field to context with type conversion
Then I set localstorage field "<localStorageField>" to context field "<contextField>" as "<type>"

# Example:
Then I set localstorage field "isAdmin" to context field "adminFlag" as "boolean"

🌐 URL Navigation & Assertions

  1. Visit a URL
Given I visit "<url>"

# Example:
Given I visit "{{ env.baseUrl }}/login"
  1. Reload a specific URL
Given I reload to "<url>"

# Example:
Given I reload to "{{ env.baseUrl }}/dashboard"
  1. Expect current URL is exactly
Then I expect current url is "<url>"

# Example:
Then I expect current url is "{{ env.baseUrl }}/home"
  1. Expect current URL contains a string
Then I expect current url contains "<url>"

# Example:
Then I expect current url contains "/home"
  1. Expect current URL matches a pattern
Then I expect current url matches "<regex>"

# Example:
Then I expect current url matches ".*\\/profile\\/\\d+$"
  1. Expect current URL is no longer a specific URL
Then I expect the current URL no longer is "<url>"

# Example:
Then I expect the current URL no longer is "{{ env.baseUrl }}/splash"
  1. Expect current URL no longer contains a string
Then I expect the current URL no longer contains "<text>"

# Example:
Then I expect the current URL no longer contains "/splash"
  1. Expect current URL no longer matches a pattern
Then I expect the current URL no longer matches "<regex>"

# Example:
Then I expect the current URL no longer matches ".*\\/splash$"

πŸ–±οΈ HTML Element Interactions

  1. Click on an element
When I click on "<selector>"

# Example:
When I click on "#submit-button"
  1. Force click on an element (ignores visibility)
When I force click on "<selector>"

# Example:
When I force click on ".dropdown-toggle"
  1. Double-click on an element
When I double click on "<selector>"

# Example:
When I double click on "#editable-cell"
  1. Scroll to a position inside an element
When I scroll to "<position>" into "<selector>"

# Example:
When I scroll to "bottom" into ".scrollable-container"
  1. Hover an element to make it visible
When I hover "<selector>" to make it visible

# Example:
When I hover ".tooltip-trigger" to make it visible
  1. Drag an element onto another
When I drag "<originSelector>" onto "<destinationSelector>"

# Example:
When I drag "#item" onto "#dropzone"
  1. Drag an element by a specific offset
When I drag "<selector>" of <x>,<y>

# Example:
When I drag "#slider" of 50,0
  1. Move an element by offset
When I move "<selector>" of <x>,<y>

# Example:
When I move "#box" of 20,30
  1. Select an option inside a dropdown or menu
When I select "<option>" in "<selector>"

# Example:
When I select ".option-2" in ".dropdown-menu"

πŸ‘οΈ HTML Element Assertions

  1. Expect element to exist
Then I expect the HTML element "<selector>" exists
  1. Expect element to not exist
Then I expect the HTML element "<selector>" not exists
  1. Expect element to be visible
Then I expect the HTML element "<selector>" to be visible
  1. Expect element to be hidden
Then I expect the HTML element "<selector>" to be hidden
  1. Expect element to be disabled
Then I expect the HTML element "<selector>" to be disabled
  1. Expect element to be enabled
Then I expect the HTML element "<selector>" to be enabled
  1. Expect element to have exact width
Then I expect the HTML element "<selector>" width is <width>

# Example:
Then I expect the HTML element "#image" width is 200
  1. Expect element to have exact height
Then I expect the HTML element "<selector>" height is <height>

# Example:
Then I expect the HTML element "#container" height is 400
  1. Expect element to be at a specific position
Then I expect the HTML element "<selector>" to be at position <x>,<y>

# Example:
Then I expect the HTML element "#popup" to be at position 100,200
  1. Expect element to have a specific attribute and value
Then I expect the HTML element "<selector>" to have attribute "<attribute>" with value "<value>"

# Example:
Then I expect the HTML element "#logo" to have attribute "alt" with value "Company Logo"
  1. Expect element to contain specific text
Then I expect the HTML element "<selector>" contains "<text>"

# Example:
Then I expect the HTML element "#message" contains "Welcome!"
  1. Expect element to not contain specific text
Then I expect the HTML element "<selector>" not contains "<text>"

# Example:
Then I expect the HTML element "#message" not contains "Welcome!"
  1. Expect element to have a specific value
Then I expect the HTML element "<selector>" to have value "<value>"

# Example:
Then I expect the HTML element "#username" to have value "john.doe"
  1. Expect element to appear a certain number of times
Then I expect the HTML element "<selector>" appear <count> time(s) on screen

# Example:
Then I expect the HTML element ".card" appear 3 time(s) on screen
  1. Expect element is checked
Then I expect the HTML element "<selector>" is checked

# Example:
Then I expect the HTML element ".checkbox" is checked
  1. Expect element is not checked
Then I expect the HTML element "<selector>" is not checked

# Example:
Then I expect the HTML element ".checkbox" is not checked

✏️ HTML Element Text Manipulation

  1. Clear the text inside an element
Then I clear the text in the HTML element "<selector>"

# Example:
Then I clear the text in the HTML element "#search-box"
  1. Set a specific text inside an element
Then I set the text "<text>" in the HTML element "<selector>"

# Example:
Then I set the text "admin" in the HTML element "#username"

πŸ“ Viewport Configuration

  1. Set viewport size (useful for responsive tests)
Given I set the viewport size to <width> px by <height> px

# Example:
Given I set the viewport size to 1280 px by 720 px

β˜• Kafka Messaging Steps

  1. Setup Kafka client with clientId and broker
Given I setup kafka with clientId "<clientId>" and broker "<broker>"

# Example:
Given I setup kafka with clientId "my-client" and broker "localhost:9092"
  1. Setup Kafka producer
Given I setup kafka producer

# Example:
Given I setup kafka producer
  1. Setup Kafka consumer with groupId
Given I setup kafka consumer with groupId "<groupId>"

# Example:
Given I setup kafka consumer with groupId "test-group"
  1. Listen for Kafka messages on a topic
Given I listen for Kafka messages on the topic "<topic>"

# Example:
Given I listen for Kafka messages on the topic "orders"
  1. Send kafka message
When I send a Kafka message on the topic "<topic>" with body "<body>"

# Example:
When I send a Kafka message on the topic "orders" with body "my data"
  1. Send kafka message with raw value
When I send a Kafka message on the topic "<topic>" with body:
"""
{ "name": "John" }
"""

# Example:
When I send a Kafka message on the topic "orders" with body:
"""
{ "name": "John" }
"""
  1. Expect a number of messages received on a Kafka topic
Then I expect {int} message(s) received on Kafka topic "<topic>"

# Example:
Then I expect 3 message(s) received on Kafka topic "orders"
  1. Expect a message on a Kafka topic to be equal to a string
Then I expect a message on Kafka topic "<topic>" equals to "<value>"

# Example:
Then I expect a message on Kafka topic "orders" equals to "{\"orderId\":123}"
  1. Expect a message on a Kafka topic to be equal to a provided type
Then I expect a message on Kafka topic "<topic>" equals to "<value>" as "<type>"

# Example:
Then I expect a message on Kafka topic "orders" equals to "{\"orderId\":123}" as "json"
  1. Expect a message on a Kafka topic to be equal to a multi-line string
Then I expect a message on Kafka topic "<topic>" equals to:
"""
{
  "orderId": 123,
  "status": "shipped"
}
"""

# Example:
Then I expect a message on Kafka topic "orders" equals to:
"""
{
  "orderId": 123,
  "status": "shipped"
}
"""
  1. Expect a message on a Kafka topic contains a substring
Then I expect a message on Kafka topic "<topic>" contains "<value>"

# Example:
Then I expect a message on Kafka topic "orders" contains "shipped"
  1. Expect a message on a Kafka topic contains a multi-line string
Then I expect a message on Kafka topic "<topic>" contains:
"""
{
  "status": "shipped"
}
"""

# Example:
Then I expect a message on Kafka topic "orders" contains:
"""
{
  "status": "shipped"
}
"""
  1. Expect a message on a Kafka topic matches a regex
Then I expect a message on Kafka topic "<topic>" matches regex "<regex>"

# Example:
Then I expect a message on Kafka topic "orders" matches regex "^\\{.*\"status\":\\s*\"shipped\".*\\}$"
  1. Log kafka messages
Then I log kafka messages

πŸ”‘ Ldap directory

  1. Setup ldap client with url, bind dn and password
Given I setup Ldap with url "<url>" bind dn "<bindDn>" and password "<password>"

# Example:
Given I setup Ldap with url "ldap://localhost:389" bind dn "cn=admin,dc=company,dc=com" and password "my_password"
  1. Search ldap results with base Dn, filter and attributes
Given I search ldap results on base dn "<baseDn>" with filter "<filter>" and attributes "<attributes>"

# Example:
Given I search ldap results on base dn "ou=users,dc=company,dc=com" with filter "[email protected]" and attributes "cn sn mail"
  1. Expect search results to a given length
Given I expect "<expectedLength>" ldap results
# Example:
Given I expect 2 ldap results
  1. Delete all search results previously found
Given I delete all ldap results
# Example:
Given I delete all ldap results
  1. Add a new ldap entry with dn and with raw attributes
Given I add a ldap entry with dn "<dn>" and with attributes:
# Example:
Given I add a ldap entry with dn "uid=c1aa97e9-fdff-4b81-b468-0cb41be3e550,dc=company,dc=com" and with attributes:
"""
{
    "objectClass": "top",
    "objectClass": "person",
    "objectClass": "organizationalPerson",
    "objectClass": "inetOrgPerson",
    "uid": "c1aa97e9-fdff-4b81-b468-0cb41be3e550",
    "cn": "John Doe",
    "sn": "Doe",
    "mail": "[email protected]",
    "givenName": "John"
}
"""
  1. Add a new ldap entry with dn and with attributes
Given I add a ldap entry with dn "<dn>" and with attributes <attributes>
# Example:
Given I add a ldap entry with dn "uid=c1aa97e9-fdff-4b81-b468-0cb41be3e550,dc=company,dc=com" and with attributes "{ ... }"

βœ… Step Summary

# πŸ”§ Context Utilities
Then I log "<value>"
Then I wait <seconds>s
Then I store "<key>" as "<value>" in context
Then I store as "<value>":
"""
My data
"""

# 🌐 HTTP Requests
Given I set http header "<key>" with "<value>"
When I request "<url>" with method "<method>"
When I request "<url>" with method "<method>" with query parameters
| key     | value      | type    |
| userId  | 123        | integer |
When I request "<url>" with method "<method>" with body:
"""
{ "name": "John" }
"""

# πŸ“₯ Response Assertions
Then I expect status code is <code>
Then I expect "<value>" is empty
Then I expect "<value>" is not empty
Then I expect "<value>" is "<expected>"
Then I expect "<value>" is not "<expected>"
Then I expect "<value>" is "<expected>" as "<type>"
Then I expect "<value>" to have length <number>
Then I expect "<value>" as "<type>" to have length <number>
Then I expect "<value>" contains "<expected>"
Then I expect "<value>" not contains "<expected>"

# πŸ” Resource Assertions
Then I expect one resource of "<value>" equals to "<expected>"
Then I expect one resource of "<value>" equals to "<expected>" as "<type>"
Then I expect one resource of "<value>" contains "<field>" equals to "<expected>"
Then I expect one resource of "<value>" contains "<field>" equals to "<expected>" as "<type>"

# πŸ” Manipulate localStorage
Given I set in localstorage field "<key>" with "<value>"
Then I expect localstorage field "<key>" is "<expected>"
Then I delete "<key>" in localstorage
Then I set localstorage field "<localStorageField>" to context field "<contextField>"
Then I set localstorage field "<localStorageField>" to context field "<contextField>" as "<type>"

# 🌐 URL Navigation & Assertions
Given I visit "<url>"
Given I reload to "<url>"
Then I expect current url is "<url>"
Then I expect current url contains "<url>"
Then I expect current url matches "<regex>"
Then I expect the current URL no longer is "<url>"
Then I expect the current URL no longer contains "<text>"
Then I expect the current URL no longer matches "<regex>"

# πŸ–±οΈ HTML Element Interactions
When I click on "<selector>"
When I force click on "<selector>"
When I double click on "<selector>"
When I scroll to "<position>" into "<selector>"
When I hover "<selector>" to make it visible
When I drag "<originSelector>" onto "<destinationSelector>"
When I drag "<selector>" of <x>,<y>
When I move "<selector>" of <x>,<y>
When I select "<option>" in "<selector>"

# πŸ‘οΈ HTML Element Assertions
Then I expect the HTML element "<selector>" exists
Then I expect the HTML element "<selector>" not exists
Then I expect the HTML element "<selector>" to be visible
Then I expect the HTML element "<selector>" to be hidde
Then I expect the HTML element "<selector>" to be disabled
Then I expect the HTML element "<selector>" to be enabled
Then I expect the HTML element "<selector>" is checked
Then I expect the HTML element "<selector>" is not checked
Then I expect the HTML element "<selector>" width is <width>
Then I expect the HTML element "<selector>" height is <height>
Then I expect the HTML element "<selector>" to be at position <x>,<y>
Then I expect the HTML element "<selector>" to have attribute "<attribute>" with value "<value>"
Then I expect the HTML element "<selector>" contains "<text>"
Then I expect the HTML element "<selector>" not contains "<text>"
Then I expect the HTML element "<selector>" to have value "<value>"
Then I expect the HTML element "<selector>" appear <count> time(s) on screen

# ✏️ HTML Element Text Manipulation
Then I clear the text in the HTML element "<selector>"
Then I set the text "<text>" in the HTML element "<selector>"

# πŸ“ Viewport Configuration
Given I set the viewport size to <width> px by <height> px

# β˜• Kafka Messaging Steps
Given I setup kafka with clientId "<clientId>" and broker "<broker>"
Given I setup kafka producer
Given I setup kafka consumer with groupId "<groupId>"
Given I listen for Kafka messages on the topic "<topic>"
When I send a Kafka message on the topic "<topic>" with body "<body>"
When I send a Kafka message on the topic "<topic>" with body:
"""
{ "name": "John" }
"""
Then I expect <count> message(s) received on Kafka topic "<topic>"
Then I expect a message on Kafka topic "<topic>" equals to "<value>"
Then I expect a message on Kafka topic "<topic>" equals to "<value>" as "<type>"
Then I expect a message on Kafka topic "<topic>" equals to:
"""
{
  "orderId": 123,
  "status": "shipped"
}
"""
Then I expect a message on Kafka topic "<topic>" contains "<value>"
Then I expect a message on Kafka topic "<topic>" contains:
"""
{
  "status": "shipped"
}
"""
Then I expect a message on Kafka topic "<topic>" matches regex "<regex>"
Then I log kafka messages

🚧 Missing a Step?

If you need a step that doesn't exist yet, there are two options:

  • πŸ’¬ Open an issue: Create an issue describing the step you need, including:

    • The Gherkin syntax you’d like to use
    • A short example of the expected behavior
    • Any relevant context or use case
  • 🀝 Contribute directly: If you're comfortable with JavaScript and Cypress, feel free to open a Pull Request. Please:

    • Follow the existing step definitions style
    • Add Gherkin usage and examples to the README
    • Keep tests modular and consistent

πŸ™ Contributions and feedback are welcome! This runner is designed to be extensible and team-friendly.

About

e2e-test-runner is a ready-to-use E2E test runner that leverages Cypress and Cucumber.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •