2026-08-27 14:59:34 -06:00
2026-08-27 14:59:34 -06:00
2026-08-27 14:59:25 -06:00
2026-08-27 14:59:34 -06:00
2026-08-27 14:59:25 -06:00
2026-08-27 14:59:25 -06:00
2026-08-27 14:59:25 -06:00
2026-08-27 14:59:25 -06:00

QKForce Framework CWQ

The QKForce browser-automation template is the fixed TypeScript + Cucumber + WebdriverIO + QKTestAnalytics profile.

Contract status

CWQ consumes the central v1.1 run config and optional package-local version-locked CSV inputs before WDIO starts. It does not create packages or receive results; those are API/Client responsibilities. The remaining documentation/operational concern is a verifiable required CI check, tracked in CWQ #6.

Run

npm ci
npm run qkforce:test
npm run qkforce:report

qkforce:test is the only execution entry point used by QKForce Client. Results belong under qreport-results/; raw test-data CSV files must not be copied into results archives.

Immutable run configuration

Every v1.1 workspace contains qkforce.config.json with numeric schemaVersion: 1, fixed profile id qkforce-wdio-cucumber-qkta, and run.targetUrl. The loader rejects unknown fields, non-fixed profiles, credentials/query/fragment URLs, non-HTTPS non-loopback targets, and target URLs over 2048 UTF-8 bytes.

{
  "schemaVersion": 1,
  "profile": {
    "id": "qkforce-wdio-cucumber-qkta",
    "language": "typescript",
    "bdd": "cucumber",
    "runner": "webdriverio",
    "adapter": "webdriverio-cucumber-node",
    "reporter": "qk-test-analytics"
  },
  "run": { "targetUrl": "https://example.test" }
}

Version-locked CSV test data

When test data is bound, QKForce materializes only immutable selected CSV versions below test-data/ and writes qkforce.test-data.lock.json. No lock is required for executions without bound test data. The framework preflights every present lock before WDIO starts and never fetches live data.

Validation covers schema version, unknown/duplicate metadata, safe package-local test-data/*.csv paths, regular-file/symlink checks, SHA-256, UTF-8, RFC-4180 quoting, unique headers and declared row count.

Use the typed step-definition helper:

import { Given } from '@wdio/cucumber-framework';
import { loadTestData } from '../support/test-data.js';

const testData = loadTestData();

Given('I use customer {string}', async (id: string) => {
  const customer = testData.dataset('customers').first({ id });
  await $('#username').setValue(customer.name);
});

Rows are immutable and scenario selection is never stored in global mutable state. Use row(index), where({...}) or first({...}) for deterministic addressing. typedRow(index, schema) supports string, integer, number, boolean (true/false) and ISO date (YYYY-MM-DD); { type, nullable: true } maps an empty cell to null.

Diagnostics identify dataset/version, row and column without printing cell contents. provenance() returns only testDataLockSha256 and {datasetId, versionId, sha256} entries, matching the QKForce results-manifest contract without raw CSV values.

Starter positive/negative fixtures live under test/fixtures/test-data/. Execution-specific CSV files are generated by QKForce and should not be hand-edited in the template.

Run non-browser validation with:

npm run check

Active development is performed on develop.

Description
No description provided
Readme 194 KiB
Languages
JavaScript 86%
TypeScript 12.3%
Gherkin 1.7%