API Reference (curated)

The most-used exports from @meintest/cc-testframework, plus the Self-Healing Writeback and Custom-Step additions. For the full export list, see the package’s TypeScript declarations under pm/node_modules/@meintest/cc-testframework/dist/*.d.ts.

← Back to overview · 🇩🇪 Deutsch · ← Concepts · Self-Healing →


Conventions

  • All async functions return Promise<void> unless noted.
  • All UI-locating functions take a view-name + view-type prefix to scope the lookup (e.g., 'Login', 'dialog' finds elements inside a dialog titled “Login”).
  • All TestStep-level helpers log their action to the test-step report — you don’t need to add manual logging.

1. Action

Low-level action primitives: clicks, fills, hovers, scrolls, navigation.

import { Action } from '@meintest/cc-testframework';

await Action.click(locator, 'Submit button');
await Action.fill(locator, 'jane@example.com', 'Email field');
await Action.hover(locator, 'Menu item');
await Action.scroll(page, 500);

When to use directly: inside your Step_*.ts files, after a Control has resolved a locator. Don’t call from TestCases — use TestSteps instead.


2. Check

Assertion primitives for labels, URLs, element existence, dialog states.

import { Check } from '@meintest/cc-testframework';

await Check.label_ByXpath_IsEqual(page, './/h1', 'Welcome');
await Check.label_ByXpath_Contains(page, './/p', 'Successfully created');
await Check.urlContains(page, '/dashboard');
await Check.elementExists(page, '#user-menu');

Each Check throws an informative error on mismatch (Playwright’s standard expect() semantics, with framework-friendly error messages).


3. Step

Block structures and step-level orchestration.

import { Step } from '@meintest/cc-testframework';

Step.setCurrentTestCaseName('TC_UserCreation');

await Step.numberedStepBlock('Login', async () => {
    // contents become numbered child steps in the test report
});

await Step.logParam('username', 'jane@example.com');

numberedStepBlock is the mandatory grouping mechanism — every TestCase wraps its work in numberedStepBlocks so the test report shows readable structure.


4. baseConfig

A PlaywrightTestConfig object you spread into your project’s playwright.config.ts. Contains framework defaults that don’t change between projects.

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
import { baseConfig } from '@meintest/cc-testframework';

export default defineConfig({
    ...baseConfig,
    timeout: 300000,
    testDir: './3_Cases',
    use: {
        ...baseConfig.use,
        baseURL: 'https://<your-app>',
        headless: false,
    },
    projects: [
        { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    ],
});

What’s in baseConfig: fullyParallel, forbidOnly, retries, workers, reportSlowTests, reporter, and use.{ignoreHTTPSErrors, acceptDownloads, screenshot, trace, video}. Not in it: anything project-specific (testDir, baseURL, projects, headless, slowMo, globalSetup).

reporter always includes ['html']. It also conditionally includes SelfHealingWritebackReporter, appended automatically whenever SELF_HEALING_WRITEBACK or SELF_HEALING_WRITEBACK_DISCOVERY is set to true in the environment at the moment this file loads — see Self-Healing Locators — Setup. A project that overrides reporter in its own config (rather than spreading baseConfig.reporter) needs to add the reporter itself if it wants it.


5. SearchEngine

Locator strategies with hierarchical fallback.

import { SearchEngine } from '@meintest/cc-testframework';

const locator = await SearchEngine.findLocators(page, {
    view: { name: 'Login', type: 'dialog' },
    element: { tag: 'button', text: 'Sign in' },
});

The SearchEngine handles edge cases: elements inside iframes, shadow DOM, multiple match-disambiguation, retry-on-not-yet-rendered. Use this from inside your Control files rather than page.locator() directly — you get the framework’s robustness for free.


6. AppReady

Page/browser lifecycle helpers.

import { AppReady } from '@meintest/cc-testframework';

await AppReady.waitForPageLoad(page, { timeout: 30000 });
await AppReady.waitForNetworkIdle(page);

Useful inside TestSteps that need to ensure the application is fully loaded before interacting. Reduces flakiness from “click happened too early” scenarios.


7. Filesystem / I_Filesystem

File I/O utilities. The Filesystem export is internal; the I_Filesystem export is the public interface for use in TestSteps.

import { I_Filesystem } from '@meintest/cc-testframework';

const content = await I_Filesystem.readFile('./data/users.csv');
await I_Filesystem.writeFile('./output/result.json', JSON.stringify(data));

8. Logger

Structured logging that’s integrated with the test report.

import { Logger } from '@meintest/cc-testframework';

Logger.info('Starting test setup');
Logger.warn('Falling back to second selector strategy');
Logger.error('Element not found after retries');

Output appears in both the console and in the per-test artifacts. Use this instead of console.log for any test-relevant messages.


9. I_PasswordManager

Password retrieval — useful for tests that need credentials without hard-coding them.

import { I_PasswordManager } from '@meintest/cc-testframework';

const password = await I_PasswordManager.TS_GetPassword('TestUser');

The implementation reads from a configured secret store (env vars, keystore, or encrypted file — depending on your setup). Never log the result.


10. I_Utils

Misc utilities — date formatting, random IDs, etc.

import { I_Utils } from '@meintest/cc-testframework';

const timestamp = I_Utils.GetDate('ssms');     // → "20260603143015123"
const dateStr = I_Utils.GetDate('iso');         // → "2026-06-03"
const randomId = I_Utils.GenerateRandomId(8);   // → "kP9xQ2bA"

Date-formatting is especially useful for generating unique email addresses in registration tests: ${user}${I_Utils.GetDate('ssms')}@mailinator.com.


11. Self-Healing exports (Core.xpath, SelfHealingWritebackReporter, withCoordinatedWrite)

Locator-repair infrastructure — see Self-Healing Locators for the full setup guide, this section only lists the exports themselves.

import { xpath, SelfHealingWritebackReporter, withCoordinatedWrite, getProjectConfig, resolveSelfHealingConfig, PROJECT_CONFIG_FILE_NAME, setTestCaseId, getTestCaseId } from '@meintest/cc-testframework';
import type { WritebackResult, WriteResult, ProjectConfig, SelfHealingResolution } from '@meintest/cc-testframework';

// Inside a Control — tag a locator so it becomes writeback-eligible
Core.xpath`(//*[@ControlType='ControlType.DataItem'])[${rowIndex}]`;

// Top of a TC_*.spec.ts file — give the TestCase a stable, rename-safe id
Core.setTestCaseId('tc_<your-scenario>');
  • Core.setTestCaseId(uid: string): void — sets a stable, filesystem-safe id for the current TestCase, used to key its reference-asset folder (7_Assets/<uid>/) independently of the Playwright test title. Recommended slug format: tc_[a-z0-9-]{4,}. See Self-Healing Locators — Giving a TestCase a stable id for where and when to call it, and the full path-resolution and migration story.
  • Core.getTestCaseId(): string | null — reads back the id set for the current TestCase via setTestCaseId; null if none has been set.
  • Core.xpath — a tagged template literal. Produces the exact same string as an equivalent raw template literal; the tag additionally lets the framework trace the locator back to its file:line for self-healing. Purely additive — untagged locators keep working unchanged.
  • SelfHealingWritebackReporter — a Playwright Reporter class you register in playwright.config.ts’s reporter array — or that baseConfig registers for you automatically once SELF_HEALING_WRITEBACK/_DISCOVERY is set (see Section 4). Runs once at the end of the test run and persists any successful heals into their owning Control files (opt-in via SELF_HEALING_WRITEBACK=true, an environment variable or the persisted config file). Routes its writes through withCoordinatedWrite (see below) so it never conflicts with a colleague editing the same file — see Self-Healing Locators — Multi-user coordination. Also reachable via the dedicated sub-path export @meintest/cc-testframework/reporter/self-healing-writeback (both a named and a default export, resolving to the same class) for a project with its own reporter[] array that doesn’t import the package’s full barrel — see Self-Healing Locators — Registering the reporter manually. The older, wildcard-derived path @meintest/cc-testframework/Reporter/SelfHealingWritebackReporter (uppercase) still resolves for existing configs; the lowercase sub-path above is the canonical form going forward.
  • WritebackResult (type-only) — the shape of a single writeback outcome (per healed locator: applied vs. skipped, and why); exported for advanced tooling that wraps or inspects the writeback step programmatically. Most Customers only need the JSON report file (.self-healing-report.json), not this type directly.
  • withCoordinatedWrite(files, writeFn) — a reusable coordination wrapper: runs writeFn under a git-based lock so concurrent writes to the same tracked files (from a colleague, another CI job, or any other code built on this same function) never produce a merge conflict. In projects without an origin remote it degrades to a zero-overhead no-op. Most Customers never call this directly — SelfHealingWritebackReporter already uses it internally — but it’s exported for teams building their own agent-driven write tooling on top of the framework.
  • WriteResult (type-only) — the return shape of withCoordinatedWrite: status ('applied' | 'skipped' | 'partial' | 'error'), mode ('local-only' | 'coordinated'), the list of filesWritten, and — on a skip — lockedFiles naming each blocking lock’s owner and acquisition time.
  • getProjectConfig(startDir?) — reads and validates the project-level .cc-testframework.local.json config file (upward-searched from startDir, default process.cwd()). Returns null for a missing file, invalid JSON, an unsupported schemaVersion, or when no repo root could be found — never throws. Most Customers use the npx cc-testframework config self-healing <action> CLI (see Self-Healing Locators — Persisting the setup across sessions) instead of calling this directly.
  • resolveSelfHealingConfig() — merges the SELF_HEALING_WRITEBACK / SELF_HEALING_WRITEBACK_DISCOVERY / SELF_HEALING_AGENT_IDENTITY environment variables with the config file’s selfHealing block into one SelfHealingResolution, following the same env-var-wins-over-config-file-wins-over-default priority chain the Credential Management chain also follows.
  • PROJECT_CONFIG_FILE_NAME — the literal filename .cc-testframework.local.json, exported so tooling doesn’t need to hardcode it.
  • ProjectConfig (type-only) — the on-disk shape: schemaVersion: 1, optional selfHealing: { enabled?, discoveryMode?, agentIdentity? }.
  • SelfHealingResolution (type-only) — the merged result: enabled, discoveryMode, agentIdentity: string | null, plus a source object naming which tier ('env' | 'config' | 'default') produced each of the three values.

12. Custom-Step exports (discoverCustomSteps, validateCustomStep, runAuthoringAgent, runAuthorCli, runAuthorTestRunner)

Convention, discovery, validation, automated implementation, and the Test-Case-driven Runtime-Authoring-Loop for steps without an automated implementation yet — see Custom Steps for the full authoring guide, this section only lists the exports themselves.

import {
    discoverCustomSteps, validateCustomStep, runAuthoringAgent, AnthropicElementFinderClient,
    runAuthorCli, runAuthorTestRunner, classifyFailure, synthesizeCustomStepFromFailure,
} from '@meintest/cc-testframework';
import type {
    CustomSpec, CustomStepDiscovery, ValidationResult,
    AuthoringAgentOptions, AuthoringProgressEvent, AuthoringResult,
    AppliedStep, SkippedStep, ErrorStep,
    IElementFinderClient, ElementFinderResult, GeneratedImplementation,
    AuthorCliOptions, AuthorCliResult,
    AuthorTestRunnerOptions, AuthorTestResult, AuthorTestProgressEvent, TestRunResult,
    FixContext, FixResult, IterationRecord, FixRecord,
    FailureClassification, FailureKind,
} from '@meintest/cc-testframework';

const discoveries = await discoverCustomSteps(path.join(process.cwd(), 'tests'));
const result = validateCustomStep(discoveries[0]);

const authoringResult = await runAuthoringAgent({
    rootDir: path.join(process.cwd(), 'tests'),
    treeDigest: myLiveTreeDigest,
});

const cliResult = await runAuthorCli({ app: 'DemoApp', batchMode: true }); // boots the App itself, no treeDigest needed

const testResult = await runAuthorTestRunner({ testPath: 'pm/3_Cases/TC_<YourFlow>.spec.ts' });
  • discoverCustomSteps(rootDir) — scans <rootDir>/2_Apps/*/2_Steps/*.ts for TS_* exports marked with a @custom JSDoc block and returns one CustomStepDiscovery per step, in file order. Returns an empty array if 2_Apps doesn’t exist. Duplicate @step IDs across files are logged as a warning but both are still returned.
  • validateCustomStep(discovery) — checks a single CustomStepDiscovery for common authoring mistakes and returns a ValidationResult with separate errors (blocking) and warnings (informational) arrays.
  • CustomSpec (type-only) — the parsed @custom JSDoc block: description, intent ('check' | 'action'), optional target ({ view, section, control, label }), optional property / operator / expected, and the required stepId.
  • CustomStepDiscovery (type-only) — one discovered step: file, stepName, line, the parsed spec, and isNotImplemented (true while the body still throws the “not yet automated” placeholder).
  • ValidationResult (type-only) — isValid, warnings: string[], errors: string[].
  • runAuthoringAgent(options) — discovers, validates, and (per step, where confidence allows) implements Custom Steps against a supplied UI-tree digest. See Custom Steps — Automated implementation for the full setup, configuration env-vars, and skip-reason table.
  • AnthropicElementFinderClient — the default IElementFinderClient implementation, calling the Anthropic API (BYOK via ANTHROPIC_API_KEY, model override via AI_VISION_MODEL or npx cc-testframework set-ai-vision-model <model>). Most Customers never construct this directly — runAuthoringAgent does so internally unless you pass your own client via advanced options.
  • AuthoringAgentOptions (type-only) — rootDir, treeDigest, optional dryRun / maxSteps / onProgress / anthropicApiKey.
  • AuthoringProgressEvent (type-only) — one streamed progress notification: phase ('discover' | 'validate' | 'infer' | 'generate' | 'write' | 'done'), optional step, message, optional detail.
  • AuthoringResult (type-only) — the return value of runAuthoringAgent: schemaVersion: 1, runTimestamp, mode ('applied' | 'dry-run'), totalDiscovered, applied: AppliedStep[], skipped: SkippedStep[], errors: ErrorStep[], optional commitSha, optional lockedByHumans.
  • AppliedStep / SkippedStep / ErrorStep (type-only) — one entry each in AuthoringResult.applied / .skipped / .errors; see Custom Steps — Why a step gets skipped for the full SkippedStep.reason enumeration.
  • IElementFinderClient / ElementFinderResult (type-only) — the pluggable Vision-client contract behind AnthropicElementFinderClient, for teams supplying their own element-finding backend.
  • GeneratedImplementation (type-only) — the shape runAuthoringAgent’s internal code generator produces before writing it into a Custom-Step’s body; exported for advanced tooling that wants to inspect a generated implementation before it’s applied.
  • runAuthorCli(options) — the logic behind npx cc-testframework author, exported for teams that want to invoke it programmatically instead of shelling out. Runs in one of two mutually exclusive modes depending on which option is set — Runtime (options.testPath, delegates to runAuthorTestRunner) or Batch (options.batchMode: true + options.app, resolves the App’s runtime strategy, boots a session, captures the UI-tree digest, calls runAuthoringAgent, persists the result as JSON, and closes the session). See Custom Steps — Running the agent from the command line for the full CLI-facing contract (options, environment variables, exit codes) of both modes.
  • AuthorCliOptions (type-only) — app (required only when batchMode: true), testPath (required for Runtime mode) / batchMode, optional maxIterations / maxAttemptsPerStep (Runtime mode), optional testsRoot / appsConfig / maxSteps (Batch mode), plus dryRun / reportPath / anthropicApiKey shared by both.
  • AuthorCliResult (type-only) — exitCode (0 | 1 | 2 | 3 | 4; 3 is Batch-mode-only, 4 is the credential-related error described in Section 13), optional result: AuthoringResult (Batch mode) or testResult: AuthorTestResult (Runtime mode) — never both, optional error (set only for exitCode: 2).
  • runAuthorTestRunner(options) — the Runtime-Authoring-Loop: runs options.testPath iteratively as a fresh Playwright subprocess per attempt, classifying every failure (classifyFailure) and, for the three fixable kinds, dispatching the Authoring Agent, until the Test-Case passes or a non-fixable/circuit-breaker condition is hit. Persists an AuthorTestResult JSON report and always returns it (it does not throw for a fixable-but-failing run). See Custom Steps — Runtime mode.
  • AuthorTestRunnerOptions (type-only) — testPath (required), optional projectRoot / maxIterations / maxAttemptsPerStep / dryRun / reportPath / anthropicApiKey / onProgress.
  • AuthorTestResult (type-only) — schemaVersion: 1, runTimestamp, mode ('runtime' | 'runtime-dry-run'), testPath, finalStatus ('passed' | 'failed-non-fixable' | 'stuck-in-loop' | 'max-iterations-reached' | 'credential-error'), totalIterations, iterations: IterationRecord[], fixes: FixRecord[], commitShas: string[], optional credentialIssues: CredentialIssueRecord[] — populated when finalStatus === 'credential-error' (credential-related entries), and/or whenever the zero-matched-tests guard fired during an otherwise-normal run (kind: 'playwright-0-tests') — check this array even after an apparent finalStatus: 'passed'. See Section 13.
  • AuthorTestProgressEvent (type-only) — one streamed loop event: phase ('test-run' | 'test-pass' | 'test-fail' | 'classify' | 'fix-attempt' | 'fix-applied' | 'fix-failed' | 'stuck' | 'real-fail' | 'done' | 'credential-expired' | 'credential-expiring-soon' | 'credential-missing' | 'credential-invalid' | 'interactive-prompt-required' | 'interactive-prompt-shown' | 'playwright-0-tests'), iteration, message, optional detail.
  • TestRunResult (type-only) — one Playwright subprocess run’s outcome: passed, exitCode, stdout / stderr, optional parsed jsonReport, optional screenshotPath / htmlSnapshotPath extracted from its attachments.
  • FixContext / FixResult (type-only) — the contract between the loop and its Agent-dispatch step: a FailureClassification plus artifact paths in, an 'applied' | 'skipped' | 'error' status (plus optional commitSha) out. Mainly relevant to teams supplying their own _agentDispatcher test-double or dispatch strategy.
  • IterationRecord / FixRecord (type-only) — one loop iteration’s outcome, and one fix-location’s cumulative outcome across the whole run, respectively — both persisted inside AuthorTestResult.
  • classifyFailure(errorText, stackTrace?, testFileContent?) — pure, dependency-free classification of a Playwright failure’s error text into one of nine FailureKinds (only three of which are fixable: true). Used internally by runAuthorTestRunner’s default wiring; exported standalone for teams building their own failure-triage tooling on top of it. See Custom Steps — Runtime mode for what each fixable kind means.
  • FailureClassification (type-only) — kind: FailureKind, fixable, optional file / line / stepName, originalError.
  • FailureKind (type-only) — the nine-value string union: 'custom-not-implemented' | 'element-not-found-no-refid' | 'element-not-found-refid-exhausted' | 'timeout-no-refid' | 'assertion-fail' | 'runtime-error' | 'network-fail' | 'app-crash' | 'unknown'.
  • synthesizeCustomStepFromFailure(file, line, failedXPath, failedActionText?) — builds a synthetic CustomStepDiscovery for an already-implemented step with no @custom tag, so the same Authoring-Agent machinery that implements Custom Steps can also attempt to identify a fix for it. Used internally for the element-not-found-no-refid / timeout-no-refid classifications; exported standalone for advanced tooling.

13. Credential-Management exports (getCredential, setCredential, resolveCredentialWithPrompt)

A cross-platform OS-credential-store abstraction (Windows Credential Manager / macOS Keychain / Linux Secret Service) plus the shared resolution logic consumed by the Authoring Agent CLI — see Credential Management for the full setup guide (the config CLI subcommand, project scoping, expiry handling), this section only lists the exports themselves.

import {
    getCredential, setCredential, deleteCredential, listCredentials,
    getCredentialEnvelope, checkCredentialStatus, detectProjectId,
    normalizeGitRemoteUrl, KNOWN_CREDENTIAL_TYPES, resolveCredentialWithPrompt,
} from '@meintest/cc-testframework';
import type {
    CredentialScope, CredentialTypeSpec, CredentialStore, CredentialEnvelope, CredentialStatus,
    CredentialSource, ResolvedCredential, CredentialProgressPhase,
    CredentialResolverProgressEvent, CredentialResolverOptions, CredentialIssueRecord,
} from '@meintest/cc-testframework';

const key = await getCredential('anthropic-api-key');

await setCredential('github-token', myFreshToken, { source: 'oauth-device', expiresAt: '2026-07-15T18:00:00Z' });

const status = await checkCredentialStatus('anthropic-api-key');
if (status.expired) { /* re-authenticate and set a fresh value */ }
  • getCredential(name, options?) — reads a credential’s plain value from the OS store (project-scoped entry first, then global-scoped, per the type’s default scope). Returns null when nothing is stored, or when the OS store is unavailable on this machine — never throws for “not there”.
  • setCredential(name, value, options?) — validates the value against the credential type’s format rule and stores it as a JSON envelope. options accepts project / scope / expiresAt / source. Throws when a project-scoped type has no resolvable project context (not inside a git repository with an origin remote) and none was passed explicitly.
  • deleteCredential(name, options?) — removes a stored credential. Returns true if an entry was actually deleted, false for a no-op (nothing was there).
  • listCredentials() — lists every stored credential as { name, scope, projectId? } tuples, independent of whether name is a currently-known credential type.
  • getCredentialEnvelope(name, options?) — like getCredential, but returns the full CredentialEnvelope (value plus expiry/source metadata) instead of just the value.
  • checkCredentialStatus(name, options?) — checks existence and expiry without exposing the value — safe to log or include in a report. Returns a CredentialStatus.
  • detectProjectId(cwd?) — resolves the current project’s id from git config --get remote.origin.url, normalized via normalizeGitRemoteUrl. Returns null outside a git repository or without an origin remote — never throws.
  • normalizeGitRemoteUrl(url) — normalizes an SSH/HTTPS/git:// remote URL into the stable <host>/<owner>/<repo> form used as the project-scoping key.
  • KNOWN_CREDENTIAL_TYPES — the static registry of the two credential types the framework knows about today (anthropic-api-key, github-token), each a CredentialTypeSpec. See Credential Management — Known credential types.
  • CredentialScope (type-only) — 'global' | 'project'.
  • CredentialTypeSpec (type-only) — name, defaultScope, description, optional envVar, optional validate(value).
  • CredentialStore (type-only) — the { get, set, delete, list } contract a custom backing store would need to implement; most Customers never need this, it exists for advanced/test tooling.
  • CredentialEnvelope (type-only) — the on-disk shape: required v (the value), optional exp (ISO-8601 expiry), src (informational source tag), meta (reserved for future use).
  • CredentialStatus (type-only) — exists, optional expired / expiresAt / secondsUntilExpiry / withinGracePeriod, optional source / scope / projectId.
  • resolveCredentialWithPrompt(name, options?) — the 5-tier priority chain described in Credential Management: CLI-arg value, env-var, OS store (project-scoped), OS store (global-scoped), then an interactive first-run prompt (TTY only). Returns null when nothing could be resolved anywhere, including a Non-TTY context where the prompt cannot run.
  • CredentialSource (type-only) — 'cli-arg' | 'env' | 'store' | 'prompt', identifying which tier a ResolvedCredential came from.
  • ResolvedCredential (type-only) — { value, source: CredentialSource }.
  • CredentialProgressPhase (type-only) — the six credential-related progress phases: 'credential-expired' | 'credential-expiring-soon' | 'credential-missing' | 'credential-invalid' | 'interactive-prompt-required' | 'interactive-prompt-shown'.
  • CredentialResolverProgressEvent (type-only) — one streamed event: phase: CredentialProgressPhase, credential, message, optional expiredAt / secondsUntilExpiry / secondsExpired / source.
  • CredentialResolverOptions (type-only) — options accepted by resolveCredentialWithPrompt: optional cliArgValue / project / onProgress.
  • CredentialIssueRecord (type-only) — one notable issue recorded in AuthorTestResult.credentialIssues (see Section 12): kind ('credential-expired' | 'credential-expiring-soon' | 'credential-missing' | 'credential-invalid' | 'interactive-prompt-required' | 'playwright-0-tests'), message, and optional fields depending on kindcredential / expiredAt / source for the credential-related kinds, or pattern (the --test path/pattern that matched zero files) for 'playwright-0-tests'. The array doubles as this runner’s general “notable diagnostic” bucket rather than growing a second, parallel one.

14. Appium URL resolution (resolveAppiumUrl)

For a Desktop AUT (Windows, via Appium), the framework resolves the Appium server URL internally before opening a session — this export surfaces that same logic for advanced setups, e.g. a custom pre-flight check.

import { resolveAppiumUrl } from '@meintest/cc-testframework';
import type { AppiumUrlResolutionResult } from '@meintest/cc-testframework';

const resolution = resolveAppiumUrl(myAppConfig.appiumUrl);
console.log(resolution.url, resolution.source, resolution.platform);
  • resolveAppiumUrl(explicitAppiumUrl?) — resolves the effective Appium server URL via a three-tier priority chain: the explicit value passed in (your AUT’s appiumUrl in GlobalConfig.apps, if set), then the APPIUM_URL environment variable, then a platform-based default (http://localhost:4723 when the test process itself runs natively on Windows, http://host.docker.internal:4723 otherwise). See FAQ — How does the framework know where to find the Appium server for Desktop tests?.
  • AppiumUrlResolutionResult (type-only) — { url, source, platform }; source is 'explicit-config' | 'env-var' | 'platform-default'.

15. Step-description i18n catalogs (.i18n.json convention + validator)

Not a TypeScript export — a file convention plus a standalone validator script, both shipped by the @meintest/cc-testframework-templates package. Any step file <StepFile>.ts may have a same-named sibling <StepFile>.i18n.json, keyed by exported step-function name, mapping locale codes to translated copies of that step’s numberedStep/description/logTitle text:

{
  "TS_Main_Button_Click": {
    "en": "On Main, click button '${label}'",
    "de": "Auf 'Main', Schaltfläche '${label}' klicken"
  }
}

Every locale entry must use the exact same ${paramName} placeholders as the en entry — the catalog’s source-of-truth. A missing catalog, or a missing locale within one, falls back to English — this is the normal, non-error case.

From inside pm/ (once @meintest/cc-testframework-templates is installed there as a dev dependency):

node ./node_modules/@meintest/cc-testframework-templates/bin/validate-i18n.js <path>

Validates the KEYs referenced in every step file against their sibling .i18n.json catalog: every referenced KEY needs an en entry (missing entirely is a failure; an unreferenced catalog key is a warning), and every other locale’s placeholder set must match en’s exactly. Exit code 0 on success (including “no catalogs found” and warning-only findings), 1 on any failure-level finding, with a file/key/locale-scoped error list. See Step-Description Localization for the full convention, a worked example, and how a programmatic consumer renders the localized text.

Core.i18n — runtime localization API

Unlike the file convention above, Core.i18n is a real TypeScript export — the framework’s own execution reads it to localize what it renders itself (Playwright’s reports, console output, the Self-Healing writeback report). See Runtime localization for the full priority chain and behavior.

import { i18n } from '@meintest/cc-testframework';
import type { SupportedLocale, TranslateOptions } from '@meintest/cc-testframework';

i18n.setLocale('de');
i18n.getLocale(); // 'de'

const text = i18n.t('TS_Main_Button_Click', { label: 'Save' });
  • Core.i18n.getLocale(): SupportedLocale — resolves the effective locale via the priority chain: Core.i18n.setLocale(...) override, then the CC_TESTFRAMEWORK_LOCALE environment variable, then GlobalConfig.language, then the 'en' default.
  • Core.i18n.setLocale(locale: SupportedLocale): void — sets an explicit in-process override, primarily for tests or a one-off runtime switch; outranks the environment variable and GlobalConfig.language.
  • Core.i18n.t(key: string, values?: Record<string, unknown>, options?: TranslateOptions): string — resolves key against the sibling .i18n.json catalog for the calling step file (auto-detected from the call stack, or options.callerFile when passed explicitly) and substitutes every ${paramName} placeholder found in values. options.fallback is optional and used ONLY when no catalog is expected for the caller — e.g. runtime-generated Custom-Steps (see TS_Custom.ts for the canonical pattern). Under the standard convention, the sibling catalog’s en entry is the source-of-truth and fallback should be omitted; when both a catalog and fallback are absent for a given key, t() logs a warning once per missing key and returns the raw key literal. Never throws.
  • SupportedLocale (type-only) — 'de' | 'en'.
  • TranslateOptions (type-only) — { callerFile?: string; fallback?: string }. fallback is a Custom-Step-only escape hatch — see When to use fallback.

Core.defineTestStep and Core.defineExecutionStep accept an optional descriptionI18n field as an alternative to logTitle/description{ key, values(...args), fallback?(...args) } (typed as TestStepDescriptionI18nSpec / ExecutionStepDescriptionI18nSpec). fallback is optional and, like TranslateOptions.fallback above, a Custom-Step-only escape hatch — a factory-based step with a catalog omits it and relies on the catalog’s en entry instead. See Writing new steps with i18n support for worked examples of both the factory-based and direct-t()-call forms.


16. Core.defineExecutionStep

App-lifecycle steps. Scaffolds a tester-facing TS_Execution_<Action> step (browser start/close/restart/navigate for a Web AUT, process start/close for a Desktop AUT) from a declarative factory, without hand-wiring a Playwright page or a hardcoded URL. See Writing your first TestCase — Step-naming convention for where this fits into the overall naming scheme.

import * as Core from '@meintest/cc-testframework';

export const TS_Execution_Start = Core.defineExecutionStep(
    'MyApp',
    'Start',
    (env) => ({
        descriptionI18n: {
            key: 'TS_Execution_Start',
            values: () => ({ url: env.url }),
        },
        run: () => Core.I_BrowserHandler.start(env.page, env.url, { waitForReady: true }),
    }),
);
  • defineExecutionStep(appName, action, factory)appName is the App’s key in GlobalConfig.apps, not part of the generated function’s exported name (it stays TS_Execution_Start, not TS_MyApp_Execution_Start — see Writing your first TestCase for why); it tells the framework which App entry to resolve env from. action is a freeform label ('Start', 'Close', 'Restart', 'NavigateTo', …) folded into the generated function’s identity for readability — the framework doesn’t interpret its value. factory(env) receives an env object the framework assembles for you from GlobalConfig.apps[appName] — no manual page/url/Playwright-fixture wiring in your step file.

Family-aware env shape, resolved from the matching GlobalConfig.apps[appName] entry:

App family env fields
Web (Playwright) page: Core.Page, url: string, appConfig: WebPlaywrightAppConfig
Desktop (Appium-Windows) executable: string, appiumUrl: string, appConfig: DesktopAppiumWindowsAppConfig

env.appConfig is the full, family-typed app entry from GlobalConfig.apps[appName] — reach for it when a step needs a field the two shapes above don’t surface directly.

Why the env-based shape: it lets a test-management tool’s UI — or a tester without TypeScript experience — scaffold an App-lifecycle step for a given App without ever typing page, a Playwright fixture, or a hardcoded URL; the framework resolves all of that from the App’s own GlobalConfig entry. See Custom Steps — What is a Custom Step? for how this differs from a hand-written or agent-generated Custom Step.

Backward compatibility: the older 2-argument form still works unchanged:

export const TS_Execution_Start = Core.defineExecutionStep(
    'MyApp',
    (page, url) => ({
        description: `Start browser and navigate to '${url}'`,
        run: () => Core.I_BrowserHandler.start(page, url, { waitForReady: true }),
    }),
);

Calling it this way still works exactly as before, and emits a one-time deprecation warning per call site (console.warn, deduplicated by caller file:line) recommending the migration to the env-based form — no functional change, no forced rewrite.


17. Debug-Session exports (resolveDebugSession, runSessionCli)

Persistent-debug-session infrastructure — see Persistent Debug Session for the full setup guide, this section only lists the exports themselves.

import { resolveDebugSession, runSessionCli } from '@meintest/cc-testframework';
import type { DebugSessionResolution, SessionCliDeps, SessionCliResult } from '@meintest/cc-testframework';
  • resolveDebugSession() — merges the CC_DEBUG_SESSION environment variable with the config file’s debugSession key into one DebugSessionResolution, following the same env-var-wins-over-config-file-wins-over-default priority chain as resolveSelfHealingConfig above. Most Customers never call this directly — it drives the framework’s own attach-or-launch decision at test-runner startup.
  • DebugSessionResolution (type-only) — the merged result: enabled: boolean plus source: 'env' | 'config' | 'default'.
  • runSessionCli(argv, deps) — the implementation behind npx cc-testframework session status/close (see Persistent Debug Session — Manage the session from the command line). Exported for advanced tooling that wants to drive the same status/close logic programmatically; most Customers use the CLI directly instead.
  • SessionCliDeps (type-only) — the injectable dependency surface runSessionCli accepts (state read/clear, endpoint reachability check, process termination, output sinks); relevant only when calling runSessionCli directly.
  • SessionCliResult (type-only) — { exitCode: number }, the outcome of a runSessionCli call.

Re-exports for convenience

The framework also re-exports common Playwright + Node bits, so you don’t need separate imports in your test files:

import { test, expect, fs, path, moment, pdfParse, csvParser, authenticator, crypto }
    from '@meintest/cc-testframework';

This means a typical TestCase has one import line@GlobalRef (your barrel) — and everything is available via Project.Core.* and Project.<YourApp>.*.


Discovering the full surface

If you need an export that’s not listed above, the TypeScript declarations in pm/node_modules/@meintest/cc-testframework/dist/References.d.ts are the authoritative list. Your IDE (VS Code, WebStorm, etc.) will auto-complete from there.


📧 Need a function that isn’t there? Suggest it via jens.szelag@itsbusiness.ch.

itsbusiness AG · Bern · Switzerland