This directory contains ready-to-use GitHub Actions workflow templates for integrating Qontinui tests into your CI/CD pipeline.
-
Copy the setup action to your repository:
mkdir -p .github/actions cp -r ci-templates/github-actions/setup-qontinui .github/actions/
-
Choose and copy a workflow template:
cp ci-templates/github-actions/qontinui-test.yml .github/workflows/
-
Create a Qontinui test configuration:
{ "workflows": [ { "name": "Login Test", "actions": [ { "type": "CLICK", "target": "login_button" } ] } ] }Save this as
tests/ci-test-config.jsonin your repository. -
Commit and push - the workflow will run automatically on your next PR!
Use when: You want simple, fast CI tests on every push/PR.
Features:
- Runs on push to main/develop and on pull requests
- Installs Qontinui with all dependencies
- Runs tests from configuration file
- Uploads test results as artifacts
- Posts test summary as PR comment
- Fails CI if tests fail
Configuration:
# No secrets required
# Adjust test config path in the workflow fileExample PR comment:
## ✅ Qontinui Test Results
All tests passed!
| Metric | Count |
|--------|-------|
| Total | 15 |
| Passed | ✅ 15 |
| Failed | ❌ 0 |
Use when: You want live test results streamed to the Qontinui dashboard for monitoring.
Features:
- Everything from basic test workflow, plus:
- Creates test run in Qontinui dashboard
- Streams results in real-time during execution
- Provides live monitoring link
- Better debugging with centralized results
Required Secrets:
QONTINUI_API_KEY: "your-api-key-here"Optional Variables:
QONTINUI_STREAM_URL: "https://api.qontinui.io/v1/test-runs"Setup:
- Get your API key from qontinui.io/settings/api-keys
- Add it to your repository secrets:
- Go to Settings → Secrets and variables → Actions
- Click "New repository secret"
- Name:
QONTINUI_API_KEY - Value: Your API key
Example PR comment:
## Qontinui Test Results
All tests passed!
| Metric | Count |
|--------|-------|
| Total | 15 |
| Passed | ✅ 15 |
| Failed | ❌ 0 |
### 🔗 Links
- View live results on Qontinui Dashboard
- GitHub Actions workflow
Use when: You want thorough daily testing with coverage reporting.
Features:
- Runs daily at 2 AM UTC (configurable)
- Extended timeout (2 hours)
- Full test suite with coverage reporting
- Performance metrics collection
- Slack notifications on failure
- Manual trigger support
Required Secrets (for notifications):
SLACK_WEBHOOK_URL: "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"Manual Trigger:
# From GitHub UI:
Actions → Qontinui Nightly Tests → Run workflow
Options:
- Test suite: full, smoke, or regression
- Send notification: yes/no
Schedule Configuration:
on:
schedule:
- cron: '0 2 * * *' # Daily at 2 AM UTC
# Or customize:
# - cron: '0 0 * * 1' # Weekly on Monday
# - cron: '0 0 1 * *' # Monthly on 1stUse when: You want to detect unintended UI changes automatically.
Features:
- Compares screenshots against approved baselines
- Highlights visual differences
- Blocks PR if changes detected (unless approved)
- Auto-updates baselines when approved
- Detailed diff images for review
Workflow:
- PR is opened with UI changes
- Workflow captures screenshots
- Compares with baseline screenshots from main branch
- If differences detected:
- Posts PR comment with details
- Uploads diff images
- Requests review
- Blocks merge
- Reviewer examines diffs
- If intentional: Re-run workflow with "Update baselines" option
- If unintentional: Fix the code
Example PR comment:
## ⚠️ Visual Regression Test Results
| Status | Count |
|--------|-------|
| Total Screenshots | 25 |
| ✅ Identical | 23 |
| 🔄 Changed | 2 |
| ➕ New | 0 |
| ❌ Missing | 0 |
### ⚠️ Visual Changes Detected
This PR introduces visual changes. Please review the screenshots carefully.
#### Changes:
- 🔄 login-page.png (92.3% similar)
- 🔄 dashboard.png (88.7% similar)
### 📸 Review Instructions
1. Download the visual-regression-results artifact
2. Review screenshots in the diff/ folder
3. If changes are intentional, approve and update baselines
4. If changes are unintentional, fix the code before merging
The setup-qontinui action handles all environment setup. It's used by all workflow templates.
Inputs:
| Input | Description | Default | Required |
|---|---|---|---|
python-version |
Python version to install | 3.12 |
No |
cache-key-suffix |
Additional cache key suffix | "" |
No |
install-dev-dependencies |
Install dev dependencies | true |
No |
install-system-dependencies |
Install system deps (Linux) | true |
No |
poetry-version |
Poetry version to install | 1.8.0 |
No |
Outputs:
| Output | Description |
|---|---|
python-version |
Installed Python version |
cache-hit |
Whether cache was hit |
Example usage:
- name: Setup Qontinui
uses: ./.github/actions/setup-qontinui
with:
python-version: '3.12'
install-dev-dependencies: 'true'Qontinui workflows require JSON configuration files defining which tests to run.
File: tests/ci-test-config.json
{
"name": "CI Test Suite",
"description": "Fast tests for CI pipeline",
"timeout": 600,
"workflows": [
{
"name": "Login Test",
"description": "Verify user can log in",
"actions": [
{
"type": "CLICK",
"target": "login_button",
"wait": 1000
},
{
"type": "TYPE",
"target": "username_field",
"text": "testuser"
},
{
"type": "TYPE",
"target": "password_field",
"text": "testpass123"
},
{
"type": "CLICK",
"target": "submit_button"
},
{
"type": "WAIT_FOR",
"target": "dashboard",
"timeout": 5000
}
],
"success_criteria": {
"required_states": ["logged_in", "dashboard_visible"]
}
}
]
}File: tests/nightly-full-config.json
{
"name": "Nightly Full Test Suite",
"description": "Comprehensive tests run nightly",
"timeout": 3600,
"workflows": [
{
"name": "User Registration Flow",
"actions": [...]
},
{
"name": "Complete Purchase Flow",
"actions": [...]
},
{
"name": "Admin Panel Access",
"actions": [...]
}
],
"coverage": {
"enabled": true,
"threshold": 80
},
"performance": {
"enabled": true,
"max_action_time": 1000,
"max_vision_time": 500
}
}File: tests/visual-regression-config.json
{
"name": "Visual Regression Tests",
"description": "Capture screenshots for visual comparison",
"workflows": [
{
"name": "Capture Login Page",
"actions": [
{
"type": "NAVIGATE",
"url": "https://myapp.com/login"
},
{
"type": "SCREENSHOT",
"name": "login-page",
"full_page": true
}
]
},
{
"name": "Capture Dashboard",
"actions": [
{
"type": "NAVIGATE",
"url": "https://myapp.com/dashboard"
},
{
"type": "SCREENSHOT",
"name": "dashboard",
"full_page": true
}
]
}
],
"screenshot_options": {
"format": "png",
"quality": 100,
"full_page": true
}
}Run on specific paths only:
on:
push:
paths:
- 'src/**'
- 'tests/**'
- 'qontinui-config.json'Run on specific branches:
on:
push:
branches: [ main, staging, develop ]Disable PR comments:
# Remove or comment out the "Comment PR" stepWorkflow timeout:
jobs:
qontinui-test:
timeout-minutes: 30 # Adjust as neededTest timeout:
poetry run python -m qontinui.cli run \
--timeout 1200 # Adjust as needed (seconds)jobs:
test:
strategy:
matrix:
python-version: ['3.12', '3.13']
steps:
- name: Setup Qontinui
with:
python-version: ${{ matrix.python-version }}jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}Note: Virtual display setup differs by OS:
Linux (Xvfb):
export DISPLAY=:99
Xvfb :99 -screen 0 1920x1080x24 &macOS: No virtual display needed for headless mode
Windows: Use --headless flag
Add these secrets to your repository settings (Settings → Secrets and variables → Actions):
| Secret | Description | How to Get |
|---|---|---|
QONTINUI_API_KEY |
Qontinui API key | qontinui.io/settings/api-keys |
| Secret | Description | How to Get |
|---|---|---|
SLACK_WEBHOOK_URL |
Slack incoming webhook URL | Slack App Settings → Incoming Webhooks |
| Secret | Description | How to Get |
|---|---|---|
CODECOV_TOKEN |
Codecov upload token | codecov.io |
Cause: Tests take longer in CI than locally due to slower machines.
Solution:
- Increase workflow timeout:
timeout-minutes: 60 - Increase test timeout:
--timeout 1800 - Reduce test suite size for CI
Cause: Virtual display not properly configured.
Solution:
# Ensure Xvfb is running before tests
export DISPLAY=:99
Xvfb :99 -screen 0 1920x1080x24 > /dev/null 2>&1 &
sleep 3 # Wait for Xvfb to startCause: Different screen resolution or DPI.
Solution:
- Use
--headlessmode with fixed resolution - Ensure Xvfb uses same resolution as test patterns:
1920x1080x24 - Adjust pattern matching thresholds for CI
Cause: Cache key mismatch or cache full.
Solution:
- Check
poetry.lockis committed - Bump cache version:
cache-key-suffix: 'v2' - Clear cache from Actions settings
Cause: Anti-aliasing or slight rendering differences.
Solution:
- Adjust similarity threshold in comparison script:
similarity < 0.95→similarity < 0.90 - Use higher quality screenshots:
quality: 100 - Ensure consistent fonts and rendering
- Run full suite nightly, subset in CI
- Use
--headlessmode - Cache dependencies aggressively
- Parallelize independent tests
- CI tests: 5-10 minutes per workflow
- Nightly tests: Up to 1 hour
- Individual actions: 5-30 seconds
- Add retries for unstable actions:
{ "type": "CLICK", "target": "submit_button", "retry": 3, "retry_delay": 1000 } - Use explicit waits instead of sleeps
- Increase timeouts for slow operations
tests/
├── ci-test-config.json # Fast CI tests
├── nightly-full-config.json # Comprehensive nightly
├── smoke-test-config.json # Critical path only
├── regression-test-config.json # Regression suite
└── visual-regression-config.json # Visual tests
- Track test duration trends
- Set performance budgets
- Alert on slow tests
- Update baselines when UI intentionally changes
- Store baselines in version control
- Review all visual changes before approving
Scenario: Test login and basic navigation on every PR.
Setup:
- Copy
qontinui-test.ymlto.github/workflows/ - Create
tests/ci-test-config.json:{ "workflows": [ {"name": "Login", "actions": [...]}, {"name": "Navigate Home", "actions": [...]} ] } - Push and create PR - tests run automatically
Scenario: Test complete purchase flow nightly with Slack alerts.
Setup:
- Copy
qontinui-nightly.ymlto.github/workflows/ - Add
SLACK_WEBHOOK_URLsecret - Create
tests/nightly-full-config.jsonwith checkout workflow - Tests run daily at 2 AM, Slack notification on failure
Scenario: Ensure component rendering doesn't break with visual regression.
Setup:
- Copy
qontinui-visual-regression.yml - Create
tests/visual-regression-config.json:{ "workflows": [ {"name": "Button Variants", "actions": [...]}, {"name": "Form Components", "actions": [...]}, {"name": "Modal Dialogs", "actions": [...]} ] } - Commit baseline screenshots
- PR automatically blocked if visual changes detected
Add a step to parse custom test results:
- name: Custom result parsing
run: |
poetry run python scripts/parse_qontinui_results.py \
--input .qontinui/test-results/results.json \
--output custom-report.htmlSend to custom dashboard:
- name: Send to dashboard
run: |
curl -X POST https://my-dashboard.com/api/results \
-H "Authorization: Bearer ${{ secrets.DASHBOARD_TOKEN }}" \
-d @.qontinui/test-results/results.jsonConvert to JUnit format:
- name: Convert to JUnit
run: |
poetry run python -m qontinui.cli convert \
--input .qontinui/test-results/results.json \
--output junit.xml \
--format junit- Documentation: qontinui.github.io
- Issues: github.com/qontinui/qontinui/issues
- Discussions: github.com/qontinui/qontinui/discussions
- Discord: discord.gg/qontinui
These templates are provided under the MIT License, same as Qontinui itself.