Configuration
TestFlowKit uses YAML configuration files to define test environments, element selectors, and execution settings. This page covers all configuration options available.
Configuration File
By default, TestFlowKit looks for config.yml in the current directory. You can specify a different file:
tkit run --config my-config.yml
Basic Structure
# Global settings
settings:
think_time: 1000
concurrency: 1
report_format: "html"
gherkin_location: "features"
env_file: ".env.yml" # Optional: external env file
# Environment Variables
# Access these using {{ env.variable_name }} in Gherkin and config
env:
base_url: "http://localhost:3000"
jsonplaceholder_base_url: "http://localhost:3001"
my_graphql_endpoint: "http://localhost:3001/graphql"
# Frontend testing configuration
frontend:
base_url: "{{ env.base_url }}"
default_timeout: 1000
headless: false
screenshot_on_failure: true
user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
locale: "en-US"
timezone_id: "America/New_York"
pages:
home: "/"
elements:
common:
submit_button:
- "#submit-btn"
# API testing configuration
apis:
default_timeout: 30000
definitions:
jsonplaceholder:
type: rest
base_url: "{{ env.jsonplaceholder_base_url }}"
default_headers:
Content-Type: "application/json"
endpoints:
get_users:
method: "GET"
path: "/users"
description: "Get all users"
Environment Variables
Environment variables allow you to define configuration values that can be accessed throughout your tests and configuration files using {{ env.variable_name }} syntax.
Inline Environment Variables
Define variables directly in your config file:
settings:
concurrency: 1
gherkin_location: "features"
# Inline environment variables
env:
base_url: "http://localhost:3000"
jsonplaceholder_base_url: "http://localhost:3001"
my_graphql_endpoint: "http://localhost:3001/graphql"
api_key: "your-api-key"
# Nested variables (accessed with dot notation)
database:
host: "localhost"
port: "5432"
name: "testdb"
frontend:
base_url: "{{ env.base_url }}"
External Environment Files
For better organization and environment-specific configurations, use external YAML files:
config.yml:
settings:
env_file: ".env.local.yml" # Default env file
concurrency: 1
.env.local.yml:
base_url: "http://localhost:3000"
jsonplaceholder_base_url: "http://localhost:3001"
my_graphql_endpoint: "http://localhost:3001/graphql"
api_key: "local-dev-key"
database:
host: "localhost"
port: "5432"
.env.staging.yml:
base_url: "https://staging.example.com"
jsonplaceholder_base_url: "https://api-staging.example.com"
my_graphql_endpoint: "https://api-staging.example.com/graphql"
api_key: "staging-api-key"
database:
host: "staging-db.example.com"
port: "5432"
CLI Override
Override the env file at runtime:
# Use staging environment
tkit run --env-file .env.staging.yml
# Use production environment
tkit run --env-file .env.production.yml
Variable Priority
When the same variable is defined in multiple places, TestFlowKit uses this priority order:
- CLI
--env-file(highest priority) - Config
settings.env_file - Inline
envblock (lowest priority)
Using Environment Variables
Access environment variables using {{ env.variable_name }} syntax:
In Gherkin:
Given the user goes to "{{ env.base_url }}"
When I prepare a request to "jsonplaceholder.get_user"
And I set the header "Authorization" to "Bearer {{ env.api_key }}"
In Config:
apis:
definitions:
jsonplaceholder:
type: rest
base_url: "{{ env.jsonplaceholder_base_url }}"
default_headers:
Authorization: "Bearer {{ env.api_key }}"
endpoints:
get_users:
method: "GET"
path: "/users"
description: "Get all users"
Nested Variables:
# Access nested variables with dot notation
Given I connect to database at "{{ env.database.host }}:{{ env.database.port }}"
Settings Configuration
Global test execution settings:
settings:
# Delay between actions (ms) - useful for debugging
think_time: 1000
# Number of parallel test executions (1-20)
concurrency: 1
# Report output format: html, json, junit
report_format: "html"
# Location of Gherkin feature files
gherkin_location: "./features"
# Optional: Path to environment variables file
env_file: ".env.yml"
# Optional: Filter tests by tags
tags: "@smoke"
Frontend Configuration
Configure browser-based testing:
frontend:
# Base URL for the frontend application (required for page navigation)
# Supports variable interpolation: "{{ env.base_url }}"
base_url: "http://localhost:3000"
# Default timeout for element interactions (ms)
default_timeout: 1000
# Run without visible browser window
headless: false
# Capture screenshots when tests fail
screenshot_on_failure: true
# Delay between browser actions in milliseconds (simulate human behavior)
think_time: 1000
# Browser user agent string
user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
# Browser locale (e.g., "en-US", "fr-FR", "de-DE")
locale: "en-US"
# IANA timezone ID (e.g., "America/New_York", "Europe/Paris", "Asia/Tokyo")
timezone_id: "America/New_York"
# Page definitions
pages:
home: "/"
login: "/login"
dashboard: "/dashboard"
settings: "/settings/profile"
# Element selectors grouped by page or feature
elements:
common:
login_button:
- "#login-btn"
- "[data-testid='login']"
- "button.login"
login_page:
email_input:
- "#email"
- "[name='email']"
password_input:
- "#password"
- "[name='password']"
Browser Configuration
Configure browser behavior for frontend testing:
frontend:
# Base URL (required) - defines the application URL
base_url: "http://localhost:3000"
# Timeouts and delays
default_timeout: 10000 # Element search timeout in milliseconds
think_time: 1000 # Delay between actions (ms) - simulates human behavior
# Browser mode
headless: false # Set to true to run without visible window
screenshot_on_failure: true # Capture screenshots on test failures
# User agent emulation - customize how the browser identifies itself
user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
# Locale settings - affects language and formatting
locale: "en-US" # Browser locale (e.g., "en-US", "fr-FR", "de-DE")
# Timezone - sets the browser timezone
timezone_id: "America/New_York" # IANA timezone (e.g., "Europe/Paris", "Asia/Tokyo")
Page Definitions
Define named pages to use in your tests:
frontend:
pages:
home: "/"
login: "/auth/login"
register: "/auth/register"
dashboard: "/app/dashboard"
profile: "/app/settings/profile"
Use in tests:
Given the user goes to the "login" page
# Navigates to https://example.com/auth/login
Element Selectors
Define elements with fallback selectors for robustness. Elements should be grouped by page or feature:
frontend:
elements:
# Common elements used across multiple pages
common:
header:
- "#main-header"
submit_button:
- "#submit-btn"
- "[data-testid='submit']"
- "button[type='submit']"
- "xpath://button[contains(text(), 'Submit')]"
user_menu:
- "[data-testid='user-menu']"
- ".user-dropdown"
# Login page specific elements
login_page:
email_input:
- "#email"
- "[name='email']"
- "input[type='email']"
password_input:
- "#password"
- "[name='password']"
login_button:
- "#login-btn"
- "button[type='submit']"
# Form page elements
form_page:
text_field:
- "xpath://*[@id='text']"
- "#text-input"
checkbox:
- "#checkbox"
- "input[type='checkbox']"
💡 Selector Priority: TestFlowKit tries selectors in parallel and uses the first one that matches.
💡 Element Grouping: Group elements by their context for better maintainability. Use
commonfor elements shared across pages, or create page-specific groups matching the page names defined in yourpagesconfiguration (e.g., if you have a page namedlogin, create alogin_pagegroup for its elements).
APIs Configuration
TestFlowKit supports multiple REST and GraphQL APIs with a unified configuration structure. Each API can have its own base URL, headers, timeout, and endpoints/operations.
Structure
apis:
# Default timeout for all APIs (optional, defaults to 30000ms)
default_timeout: 30000
# Named API definitions
definitions:
# REST API example
jsonplaceholder:
type: rest
base_url: "{{ env.jsonplaceholder_base_url }}"
timeout: 5000 # Optional: override default timeout
default_headers:
Content-Type: "application/json"
Accept: "application/json"
User-Agent: "TestFlowKit/1.0"
endpoints:
get_users:
method: "GET"
path: "/users"
description: "Retrieve all users"
get_user:
method: "GET"
path: "/users/{id}"
description: "Retrieve a specific user by ID"
create_user:
method: "POST"
path: "/users"
description: "Create a new user"
# GraphQL API example
my_graphql:
type: graphql
endpoint: "{{ env.my_graphql_endpoint }}"
default_headers:
Content-Type: "application/json"
Authorization: "Bearer {{ env.api_token }}"
operations:
getUser:
type: "query"
operation: |
query GetUser($id: ID!) {
user(id: $id) {
id
username
email
}
}
description: "Fetch user by ID"
createPost:
type: "mutation"
operation: |
mutation CreatePost($input: PostInput!) {
createPost(input: $input) {
id
title
content
}
}
description: "Create a new post"
Using APIs in Tests
Reference APIs using the api_name.endpoint_name syntax:
# REST API
Given I prepare a request to "jsonplaceholder.get_user"
And I set the following path parameters:
| id | 123 |
When I send the request
Then the response status code should be 200
# GraphQL API
Given I prepare a request to "my_graphql.getUser"
And I set the following GraphQL variables:
| id | 123 |
When I send the request
Then the GraphQL response should not have errors
REST API Configuration
REST APIs require:
type: restbase_url: Base URL for the API (supports environment variables)endpoints: Map of named endpoints with method, path, and description
Optional:
default_headers: Headers applied to all requeststimeout: Override default timeout for this API
GraphQL API Configuration
GraphQL APIs require:
type: graphqlendpoint: Full GraphQL endpoint URL (supports environment variables)operations: Map of named operations with type (query/mutation), operation definition, and description
Optional:
default_headers: Headers applied to all requeststimeout: Override default timeout for this API
Path Parameters
Use {param} syntax for path parameters in REST endpoints:
endpoints:
get_comment:
method: GET
path: "/posts/{postId}/comments/{commentId}"
description: "Get a specific comment"
Set parameters in tests:
Given I prepare a request to "jsonplaceholder.get_comment"
And I set the following path parameters:
| postId | 123 |
| commentId | 456 |
When I send the request
Header Merging
Headers are merged with this priority (highest to lowest):
- Request-specific headers (set in test steps)
- API default headers
- Global headers
# API default headers are automatically applied
Given I prepare a request to "jsonplaceholder.get_user"
# Additional headers override defaults
And I set the request header "Authorization" to "Bearer custom-token"
When I send the request
Backend Configuration (Deprecated)
⚠️ Deprecated: The old
backendconfiguration is deprecated in favor of the newapisstructure. Please migrate to the new format.
The old backend configuration:
backend:
# Default headers for all API requests
default_headers:
Content-Type: "application/json"
# API endpoint definitions
endpoints:
get_users:
method: "GET"
path: "/users"
description: "Retrieve all users"
get_user:
method: "GET"
path: "/users/{id}"
description: "Retrieve a specific user by ID"
create_user:
method: "POST"
path: "/users"
description: "Create a new user"
update_user:
method: "PUT"
path: "/users/{id}"
description: "Update an existing user"
delete_user:
method: "DELETE"
path: "/users/{id}"
description: "Delete a user"
💡 Base URL: The API base URL is defined in the
environmentssection asrest_api_base_url.
Endpoint Path Parameters
Use {param} syntax for path parameters:
endpoints:
get_post:
method: GET
path: "/posts/{postId}/comments/{commentId}"
Set parameters in tests:
Given I prepare a request for the "get_post" endpoint
And I set the following path parameters:
| postId | 123 |
| commentId | 456 |
When I send the request
GraphQL Configuration
Configure GraphQL API testing within the backend section. The endpoint URL is defined in the environment variables:
# Environment variables
env:
graphql_endpoint: "https://graphqlzero.almansi.me/api"
# Backend section
backend:
graphql:
# Default headers for GraphQL requests
default_headers:
Content-Type: "application/json"
Authorization: "Bearer ${TOKEN}"
# GraphQL operations
operations:
getUser:
type: "query"
operation: |
query GetUser($id: ID!) {
user(id: $id) {
id
username
email
}
}
description: "Fetch user by ID"
createPost:
type: "mutation"
operation: "graphql_queries/create_post.graphql"
description: "Create a new post"
deletePost:
type: "mutation"
operation: |
mutation DeletePost($id: ID!) {
deletePost(id: $id)
}
description: "Delete a post"
💡 Endpoint Location: The GraphQL endpoint URL must be defined in your environment variables as
graphql_endpoint, not in the backend section.
💡 Operation Types: Specify whether each operation is a
queryormutation.
💡 Inline vs File: Operations can be defined inline using the
|multiline syntax, or reference external.graphqlfiles.
Files Configuration
Configure file paths for file upload testing:
files:
# Base directory for test files
base_directory: "./test-files"
# Named file definitions
definitions:
avatar_image: "images/avatar.png"
gallery_image1: "images/gallery/image1.jpg"
gallery_image2: "images/gallery/image2.jpg"
test_document: "documents/test.pdf"
sample_csv: "data/sample.csv"
Use in tests:
When I upload the "avatar_image" file to the "avatar_field" field
And I upload the following files to the "gallery_field" field:
| gallery_image1 |
| gallery_image2 |
Switching Environments
Switch between environments using different environment files:
Using default env file in config:
settings:
env_file: ".env.local.yml" # Default environment
Override with CLI:
# Use staging environment
tkit run --env-file .env.staging.yml
# Use production environment
tkit run --env-file .env.production.yml
Or use inline env variables:
env:
base_url: "http://localhost:3000"
rest_api_base_url: "http://localhost:3001"
graphql_endpoint: "http://localhost:3001/graphql"
frontend:
base_url: "{{ env.base_url }}"
Complete Example
settings:
think_time: 1000
concurrency: 1
report_format: "html"
gherkin_location: "./features"
tags: "@smoke"
env_file: ".env.local.yml" # Optional: default env file
# Inline environment variables (or use external files)
env:
base_url: "http://localhost:3000"
rest_api_base_url: "http://localhost:3001"
graphql_endpoint: "http://localhost:3001/graphql"
frontend:
base_url: "{{ env.base_url }}"
default_timeout: 1000
headless: false
screenshot_on_failure: true
user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
locale: "en-US"
timezone_id: "America/New_York"
pages:
home: "/"
login: "/login"
register: "/register"
dashboard: "/dashboard"
profile: "/settings/profile"
elements:
common:
nav_home:
- "[data-testid='nav-home']"
nav_dashboard:
- "[data-testid='nav-dashboard']"
user_menu:
- "[data-testid='user-menu']"
- "#user-dropdown"
login_page:
email_input:
- "#email"
- "[name='email']"
- "input[type='email']"
password_input:
- "#password"
- "[name='password']"
login_button:
- "#login-btn"
- "button[type='submit']"
messages:
error_message:
- ".alert-error"
success_message:
- ".alert-success"
backend:
default_headers:
Content-Type: "application/json"
Accept: "application/json"
endpoints:
login:
method: "POST"
path: "/auth/login"
description: "Authenticate user"
get_profile:
method: "GET"
path: "/users/me"
description: "Get current user profile"
update_profile:
method: "PUT"
path: "/users/{id}"
description: "Update user profile"
graphql:
default_headers:
Content-Type: "application/json"
Authorization: "Bearer ${TOKEN}"
operations:
getUser:
type: "query"
operation: |
query GetUser($id: ID!) {
user(id: $id) {
id
username
email
}
}
description: "Fetch user by ID"
files:
base_directory: "./test-files"
definitions:
avatar_image: "images/avatar.png"
test_document: "documents/test.pdf"
sample_data: "data/sample.csv"
Next Steps
- Selectors — Deep dive into element selectors
- Variables — Use dynamic data in tests
- CLI Reference — Command line options