Tests & quality¶
AMW has three layers of automated tests, all run by CI on every pull request.
| Layer | Command | Runs against | Location |
|---|---|---|---|
| Unit | npm test (npm run test:ci in CI, with coverage) |
the real src/ modules, with mocked config, Redis and Amazon SDK |
tests/*.test.ts |
| API end-to-end | npm run test:e2e |
the compiled server (dist/main.js) and a mock Amazon API |
tests/e2e/*.e2e.test.ts |
| Browser end-to-end | npm run test:e2e:browser |
Chromium (Playwright) rendering the widget from the compiled server | tests/e2e/browser/*.spec.ts |
Unit tests¶
npm test # all suites
npx jest tests/server.test.ts -t "rate limit" # one suite / one test name
npm run test:coverage # with a coverage report in coverage/
| Suite | Covers |
|---|---|
server.test.ts |
/product validation, Redis cache, rate limiting and failures; /health, /widget.js, other routes and middleware; configuration; startup and shutdown |
amwApi.test.ts |
Amazon call timeout and error mapping |
settings.test.ts |
Typed settings: defaults, coercions, validation, injection without node-config |
paapi.test.ts |
Creators API client: requests, response mapping (buildProduct), error handling |
swagger.test.ts |
OpenAPI document validity, Swagger UI enabled/disabled routes, CSP, redirect |
configLog4j.test.ts |
Logger levels |
widget.dom.test.ts |
Widget in jsdom: rendering, structured data, XSS protection, error handling, client cache, lazy loading |
widget.build.test.ts |
Minified build output (dist/widgets/widget.js, needs npm run build) |
The configuration is read once into a typed Settings object (src/server/Settings.ts) and
passed to AmwServer, AmwApi, Paapi and AdminApi. A test can build it with
loadSettings({ get, has }) from plain values and inject it, without mocking node-config
(see tests/settings.test.ts). When a constructor gets no settings it calls loadSettings()
itself: tests/helpers/mocks.ts resets the module registry and installs a config mock for
the tests written that way.
Coverage thresholds¶
Coverage is collected from src/**/*.ts and src/widgets/**/*.js (except
src/main.ts). jest.config.js enforces minimums slightly below the measured values,
so any regression fails CI:
| Scope | Statements | Branches | Functions | Lines |
|---|---|---|---|---|
| Global | 95 % | 85 % | 95 % | 95 % |
src/server/ |
98 % | 90 % | 98 % | 98 % |
The README coverage badge shows the line coverage of develop, published by the
documentation workflow.
End-to-end tests¶
npm run build # the e2e suites run dist/main.js
npm run test:e2e # API suites
npx playwright install --with-deps chromium # once
npm run test:e2e:browser # browser suite
tests/e2e/support/mockAmazonApi.tsis a small Express stand-in for the Creators API (OAuth2 token endpoint,getItems,searchItems). Magic ASINs simulate upstream behaviours:B0NOTFOUND(404),B0ERROR500(Amazon 500, answered 502),B0XSSPAYLO(malicious data);getItemsaccepts several ASINs (/productsbatches); an optionalcatalogreturns realistic products (used by the documentation screenshots).npm run dev:mockalso runs it on a fixed port to develop without Amazon credentials.tests/e2e/support/amwServer.tsspawns the compiled server on a free port withtests/e2e/config/e2e.yml, pointing it to the mock through the test-onlyAmazon.apiBasePathandAmazon.authEndpointsettings.cache.e2e.test.tsneeds a Redis server: it runs only whenREDIS_HOSTis set (CI provides a Redis service), and is skipped otherwise.- The browser suite serves a blog article from the AMW origin, checks the rendered card
(title, price, savings badge,
sponsoredlink) and thatjavascript:URLs and HTML from the API or the element id are neutralized.
Note
The project directory must not contain hidden (dot) directories in its absolute
path: the server would refuse to serve widget.js (see
Configuration).
Lint and audit¶
npm run lint # ESLint on src/**/*.ts
npm run lint:fix
npm audit --audit-level high # CI blocks on high and critical advisories