Skip to main content
Trigger QA.tech test runs from your GitLab CI/CD pipelines using the REST API.
AI-powered exploratory testing is currently GitHub-only via the GitHub App. For GitLab, use API-driven testing as described below.

Setup

Prerequisites

You need three values from your project settings:
  • API Token - Your QA.tech API token
  • Project UUID - 36-character project identifier
  • Test Plan Short ID - 6-character ID from your test plan URL

Configure CI/CD Variables

Store your API token securely:
  1. Go to Settings → CI/CD → Variables
  2. Add variable:
    • Key: QA_TECH_API_TOKEN
    • Value: Your API token
    • Protected: ✅
    • Masked: ✅

Implementation Patterns

Basic Setup

trigger_qatech:
  stage: test
  variables:
    API_TOKEN: $QA_TECH_API_TOKEN
    QATECH_REQUEST_BODY: '{"integrationName": "GitLab", "testPlanShortId": "abc123"}'
  script: >
    curl --request POST
    --url "https://app.qa.tech/api/projects/YOUR_PROJECT_UUID/runs"
    --header "Authorization: Bearer $API_TOKEN"
    --header "Content-Type: application/json"
    --data "${QATECH_REQUEST_BODY}"
Replace YOUR_PROJECT_UUID and abc123 with your values.

Run on Merge Requests

test_mr:
  stage: test
  only:
    - merge_requests
  variables:
    API_TOKEN: $QA_TECH_API_TOKEN
    QATECH_REQUEST_BODY: '{"integrationName": "GitLab MR", "testPlanShortId": "smoke-tests"}'
  script: >
    curl --request POST
    --url "https://app.qa.tech/api/projects/YOUR_PROJECT_UUID/runs"
    --header "Authorization: Bearer $API_TOKEN"
    --header "Content-Type: application/json"
    --data "${QATECH_REQUEST_BODY}"

Test Preview Deployments

Pass dynamic URLs between jobs using dotenv artifacts:
stages:
  - deploy
  - test

deploy_preview:
  stage: deploy
  script:
    - echo "PREVIEW_URL=https://preview-${CI_MERGE_REQUEST_IID}.yourdomain.com" >> deploy.env
  artifacts:
    reports:
      dotenv: deploy.env

test_preview:
  stage: test
  dependencies:
    - deploy_preview
  variables:
    API_TOKEN: $QA_TECH_API_TOKEN
  before_script:
    - |
      echo '{"integrationName":"GitLab Preview","testPlanShortId":"regression-suite","applications":{"frontend-app":{"environment":{"url":"'$PREVIEW_URL'","name":"MR-'$CI_MERGE_REQUEST_IID'"}}}}' > /tmp/request.json
  script: >
    curl --request POST
    --url "https://app.qa.tech/api/projects/YOUR_PROJECT_UUID/runs"
    --header "Authorization: Bearer $API_TOKEN"
    --header "Content-Type: application/json"
    --data @/tmp/request.json

Scheduled Testing

nightly_tests:
  stage: test
  only:
    - schedules
  variables:
    API_TOKEN: $QA_TECH_API_TOKEN
    QATECH_REQUEST_BODY: '{"integrationName": "GitLab Scheduled", "testPlanShortId": "full-regression"}'
  script: >
    curl --request POST
    --url "https://app.qa.tech/api/projects/YOUR_PROJECT_UUID/runs"
    --header "Authorization: Bearer $API_TOKEN"
    --header "Content-Type: application/json"
    --data "${QATECH_REQUEST_BODY}"
Set up schedules at CI/CD → Schedules → New schedule.
Use GitLab schedules when:
  • Tests should run as part of your CI/CD pipeline
  • You need GitLab context (branch, commit SHA)
  • You want to gate deployments on scheduled test results
Use QA.tech schedules when:
  • Tests should run independently of CI/CD infrastructure
  • You prefer managing schedules in QA.tech UI
  • You want to avoid consuming GitLab runner minutes
See Test Plans for QA.tech scheduling.

GitLab Tips

Finding Your Test Plan Short ID

  1. Go to Test Plans
  2. Click on a test plan
  3. Check the URL: https://app.qa.tech/.../test-plans/abc123
  4. The short ID is abc123

Building JSON Payloads

For complex payloads with dynamic values, write to a file first:
before_script:
  - |
    echo '{"key": "'$VARIABLE'"}' > /tmp/request.json
script:
  - curl ... --data @/tmp/request.json

Custom Slack Notifications

Override notification channels per-run. See Notifications for details.

Blocking Mode

Wait for test completion before proceeding with deployments:
trigger_qatech:
  stage: test
  variables:
    API_TOKEN: $QA_TECH_API_TOKEN
    PROJECT_UUID: "your-project-uuid"
  script:
    # Start run and capture shortId
    - |
      RESPONSE=$(curl -s -X POST \
        "https://app.qa.tech/api/projects/$PROJECT_UUID/runs" \
        -H "Authorization: Bearer $API_TOKEN" \
        -H "Content-Type: application/json" \
        -d "{\"integrationName\": \"GitLab CI\", \"testPlanShortId\": \"abc123\"}")
      SHORT_ID=$(echo "$RESPONSE" | jq -r '.run.shortId')
    
    # Poll until completion (see Run Status API for details)
    - |
      while true; do
        RESPONSE=$(curl -s \
          "https://app.qa.tech/api/projects/$PROJECT_UUID/runs/$SHORT_ID" \
          -H "Authorization: Bearer $API_TOKEN")
        STATUS=$(echo "$RESPONSE" | jq -r '.status')
        if [[ "$STATUS" == "COMPLETED" || "$STATUS" == "ERROR" || "$STATUS" == "CANCELLED" ]]; then
          RESULT=$(echo "$RESPONSE" | jq -r '.result')
          [[ "$RESULT" == "PASSED" ]] && exit 0 || exit 1
        fi
        sleep 30
      done
See Run Status API for polling logic details and error handling.