Skeleton Conventions
The naming, signature, and XPath-style rules the framework enforces on every scaffolded App — so a Custom Step, a Self-Healing writeback, or a hand-edit all produce byte-consistent code.
← Back to overview · 🇩🇪 Deutsch · ← Writing Your First TestCase
What these conventions cover
Structure — naming, function signature, import order, i18n wrapping — follows 6 fixed rules, checked automatically on every new file. Semantics — which Control, which label, which XPath fragment — stays your decision; the rules below only constrain the shape the code takes, never what it does.
The 6 rules
| Rule | Kind | What it checks | Severity |
|---|---|---|---|
| R1 — i18n | i18n | Every Core.i18n.t('KEY', ...) and every descriptionI18n.key: 'KEY' has an en entry in its sibling .i18n.json catalog; every locale variant has identical placeholders | Fatal |
| R2 — Naming | Steps | Every exported TS_* in a step file matches TS_<Type>_<Element>_<Action> (e.g. TS_Main_Button_Click) | Fatal |
| R3 — Signature | Steps | Every Core.defineTestStep’s run callback has pageLogName: string, _?sectionName: string as its first two parameters (TS_Main/TS_Dialog/TS_Message only) | Fatal |
| R4 — XPath Style | Controls | Skeleton Controls forbid @id, [@data-testid], [@data-cy] — the framework style is structural (text/role/label) | Fatal |
| R5 — Sibling Catalog | i18n | Every TS_*.ts with at least one defineTestStep has a sibling TS_*.i18n.json | Fatal |
| R6 — Import Order | Steps | Imports appear in canonical order: Core → Controls* (alphabetical) → other | Warning |
Check your files automatically
- Pre-commit hook. After
npm installinsidepm/,simple-git-hooksinstalls a.git/hooks/pre-commithook that validates the Skeleton files touched by the current commit. - CI. A
Validate Skeleton Conventionsstep runs on every pull request and push. - CLI, on demand. From inside
pm/:node node_modules/@meintest/cc-testframework-templates/bin/validate-conventions.js <root>runs the full rule set against a directory tree — manually, or wired into your own CI. Exit codes:0everything clean,1at least one fatal violation,2warnings only. - Machine-readable output. The
--jsonflag emits structured findings for a test-management tool or other external consumer instead of the human-readable text report.
Generated code — a Self-Healing writeback, or a step the Custom-Steps Authoring Agent produces — is checked against these same rules before it’s ever written to your source file, so it conforms from the moment it lands. See Self-Healing Locators and Custom Steps for what each of those write paths does.
What to do when validation fails
R1 — i18n
// Wrong — key 'TS_Main_Login_Click' has no en entry in the sibling catalog
Core.i18n.t('TS_Main_Login_Click', { user: 'alice' });
Fix: add the entry to the sibling .i18n.json catalog:
{
"TS_Main_Login_Click": { "en": "click Login for ${user}", "de": "..." }
}
R2 — Naming
// Wrong
export const clickLoginButton = ...
// Correct
export const TS_Main_Button_Click = Core.defineTestStep('MyApp', { ... });
R3 — Signature
// Wrong — run callback is missing pageLogName
Core.defineTestStep('MyApp', {
descriptionI18n: { ... },
run: (label: string) => Controls.click(label),
});
// Correct
Core.defineTestStep('MyApp', {
descriptionI18n: { ... },
run: (_pageLogName: string, _sectionName: string, label: string) => Controls.click(label),
});
R4 — XPath Style
// Wrong — Skeleton style is structural, not id-based
Core.xpath`.//*[@id='login-btn']`
// Correct
Core.xpath`.//button[.='${label}']`
R5 — Sibling Catalog
TS_Main.ts with at least one defineTestStep but no TS_Main.i18n.json next to it fails as Fatal. Create the sibling catalog file, even if it starts out empty ({}).
R6 — Import Order
// Wrong — Controls import appears before Core
import * as ControlsButton from '../1_Controls/Button';
import * as Core from '@Core';
// Correct
import * as Core from '@Core';
import * as ControlsButton from '../1_Controls/Button';
Know which of your files are checked
R2, R3, and R4 only apply when the validator’s root points at the Skeleton itself (packages/templates/templates). For your own Apps under pm/2_Apps/, only R1 and R5 are active — R2, R3, and R4 are skipped with an info-level log line, since those Apps grew before these conventions existed. Turn full enforcement on for your own Apps with strictConventions — see the next section.
Enforce all 6 rules on your own Apps (strictConventions)
By default, R2 (Naming), R3 (Signature), and R4 (XPath Style) apply only to the Skeleton itself, so Apps that grew before these conventions existed, or that already established their own naming or XPath style, keep working unchanged.
Opt in to the same guarantees on your own Apps under 2_Apps/ when you want a Self-Healing writeback, a hand-edit, or any external tool to stop drifting away from your naming, signature, and XPath style over time. Three ways to activate it, checked in this order — the first one found wins:
- CLI flag. Pass
--strictwhen invokingvalidate-conventions.jsdirectly, e.g. from your own pre-commit configuration. - Environment variable. Set
STRICT_CONVENTIONS=true— typically in your CI configuration, so every pipeline run enforces it without touching a project file. GlobalConfig.ts. Add to2_Apps/1_Global/GlobalConfig.ts:
// In 2_Apps/1_Global/GlobalConfig.ts
export const strictConventions = true;
This is the persistent, repo-committed option — once set, every commit and every CI run enforces it, with no flag or env-var needed elsewhere. A newly scaffolded App ships this line commented out in its GlobalConfig.ts; uncomment it when you’re ready.
If none of the three is set, the framework falls back to the default described above — R2, R3, and R4 stay Skeleton-only; R1 and R5 stay active everywhere regardless.
What changes when it’s on
R2, R3, and R4 now run against every file under 2_Apps/**, not just the Skeleton. In practice, this catches:
- Self-Healing writeback drift. A healed locator comes from a Vision call and can occasionally propose an
@id- or[data-testid]-style XPath even though the rest of your Control follows the structural style. See Self-Healing Locators for how that interacts withstrictConventions. - Hand-edit drift. A teammate renaming a step or adjusting a signature by hand is checked the same way a Skeleton file already is.
What this does not catch
strictConventions runs at commit-time and in CI — it validates files that already exist on disk. It does not catch Authoring-Agent-generated Custom-Step code before that code is written to your source file in the first place; that’s a separate, earlier checkpoint described in How generated code is verified.
Where to go next
- Writing Your First TestCase — the naming convention this validator enforces
- Custom Steps — hand-written or agent-generated steps that still follow R1 and R5
- Step-Description Localization — a deep dive into the
.i18n.jsoncatalog format R1 validates - Self-Healing Locators — how
strictConventionsguards against writeback drift
📧 Questions? Contact: jens.szelag@itsbusiness.ch
itsbusiness AG · Bern · Switzerland