@vitaliiboiko/magento-template-coverage
v1.1.0
Published
Directory and source-line execution reports for Magento HTML templates
Maintainers
Readme
Magento template coverage
Coverage for .html files in Magento test environments. Version 1.1.0
provides directory reports, source-line execution counts, and separate DOM presence
coverage. Originals stay untouched: instrument disposable copies and collect from Cypress.
Install
npm install --save-dev @vitaliiboiko/[email protected]Node.js 18.3+ and an existing Cypress installation are required.
Inventory → instrument → collect → report
Inventory every .html file under the selected roots, regardless of directory name.
The defaults are app/code and app/design. PHP, .phtml, .htm, and JS files are excluded.
npx --no-install magento-template-coverage inventory \
--source src --manifest coverage/template-manifest.json
npx --no-install magento-template-coverage instrument \
--source src --manifest coverage/template-manifest.json \
--map app/code=coverage/template-copy/app-code \
--map app/design=coverage/template-copy/app-designServe those disposable copies using your test environment and refresh Magento's
static assets and caches. The CLI rejects source-tree writes, symlinks, overlapping
destinations and changed source hashes. Repeated instrumentation starts from originals.
Use repeated --root and matching --map arguments to select other source directories.
Register the Cypress adapter before visiting the application:
const { registerTemplateCoverage } = require('@vitaliiboiko/magento-template-coverage/cypress');
registerTemplateCoverage({ outputDir: '.template-coverage' });After Cypress:
npx --no-install magento-template-coverage report \
--manifest coverage/template-manifest.json \
--hits .template-coverage --output coverage/templatesOpen coverage/templates/index.html. Directories have aggregated totals and
breadcrumb navigation, like a PHP coverage report. Each file links to its original
source with green/red/partial lines and statement counts. all.html provides a
searchable flat list. Every page works offline. coverage-summary.json includes
file and directory totals; directory percentages use summed covered/total counts.
HTML template syntax
| Syntax inside .html | Execution measured |
| --- | --- |
| Knockout data-bind and virtual ko comments | Binding value accessor evaluations; two-way property writers are preserved. |
| Magento UI shorthand | Standard renderer attributes and nodes, including if, each, render, translate, ko-value, and bare/default bindings. |
| Underscore / mage/template | <%= … %>, <%- … %>, and expressions in <% … %> code: conditions, loops, assignments, initializers, returns, and nested function bodies. |
| Legacy jQuery tmpl | ${…}, {{= …}}, if, else, each, html, tmpl, and wrap. The normal engine still handles escaping, function invocation and nested templates. |
| Magento UI literals | ${ $.expression }, including nested JavaScript expressions. |
| Plain HTML | DOM presence; static markup has no executable-line denominator. |
| Template bodies in an HTML file | Supported <script type="text/html">, text/x-magento-template, text/x-jquery-tmpl, text/x-template, and native <template> bodies remain unexecuted until consumed. |
The adapter installs counters before application code runs. Knockout and jQuery integration attaches through RequireJS; application tests do not need to require engines themselves. The legacy jQuery plugin is not installed into your application by this package. The browser harness tests its pinned upstream implementation.
Automatic detection recognizes Underscore and jQuery directives. ${ $.… } selects
Magento literals; other ${…} selects jQuery tmpl. For ambiguous syntax, override
an exact file or directory prefix during inventory; the most specific prefix wins:
npx --no-install magento-template-coverage inventory \
--source src --manifest coverage/template-manifest.json \
--engine app/code/Example/Module/view/frontend/web/fragments=literalAvailable engines: auto, knockout, underscore, jquery-tmpl, literal, html.
Choose html for DOM-only coverage. Unrecognized/malformed binding expressions in
automatic mode are retained with a visible DOM-only explanation. Explicit engine
selections fail on syntax errors. Server-rendered email directives also retain DOM-only
coverage; sending an email does not produce browser coverage.
Reading the numbers
Executable lines are distinct starting source lines of measured expressions or
directives. Statements count those individual expressions/directives. Static text,
continuation lines and non-expression JavaScript statements have no execution denominator.
A Knockout click hit records binding evaluation, not callback invocation. An if
hit does not prove its condition was true; jQuery else counts branch entry. Dynamic
bindings generated by another expression are not assigned invented Knockout source locations.
DOM presence is independent: the source marker entered the tested document. Hidden DOM counts; fetched files, detached caches and inert template bodies alone do not count. Compiling a template without rendering it produces no execution hits. Rendering a detached fragment can produce execution hits without DOM presence.
All physical .html files under the selected roots remain in the denominator,
including unused files. Module/theme applicability is not inferred. PHP rendering,
inline templates in PHP/JS files, database content, shadow roots, child frames, and
arbitrary third-party languages are outside the execution metric. Comments stripped
by minifiers/sanitizers can prevent DOM observation. Use Istanbul for application JS
and PCOV for PHP.
Repeat runs and upgrades
Use fresh manifests, disposable copies, static assets and raw records for each run.
Version 1.1 changes source identities; recreate 1.0 artifacts. JSON retains schema
version 2 with expanded expression syntax and directory summaries. Hits from old
source identities are rejected. The metric is now named template-execution.
Each test writes a unique .mtc record. Counters reset between tests, including
retained documents; observations survive navigation. Reports recursively merge shard
records and deduplicate copied record IDs. Stale IDs, conflicting records and invalid
counts fail the report. No records produces an explicitly labelled inventory baseline.
Keep generated artifacts and this package in test infrastructure.
Package development
npm test
npm run test:browser -- /path/to/magento /path/to/cypress/node_modules/cypress
npm pack --dry-runThe browser harness uses the supplied Magento checkout's real Knockout, renderer,
Underscore, mage/template, UI literal renderer and modal HTML. It fetches the legacy
jQuery engine at the revision and SHA-256 in test/browser/engines-lock.json, cached
in browser artifacts. It never modifies the Magento checkout. Tests assert exact
source IDs, real counters, false-body zeros, cached rerenders and unchanged rendering.
