A short document capturing a significant architectural decision: the context that made the decision necessary, the options considered, the chosen option, and the consequences. ADRs prevent future engineers from unknowingly reversing deliberate design choices — for example, reverting a ThreadLocal driver pattern to a static field because it 'looked simpler'.
Automation
End-to-end, unit, framework and CI execution concepts.
24 terms
A
A statement in a test that checks an expected condition holds. If it doesn't, the test fails. The core of every automated test.
A framework feature that pauses an action until the target element is actionable (visible, enabled, stable). Eliminates most need for explicit sleeps and reduces flake.
C
A structural code coverage criterion that requires every individual boolean sub-expression within a compound condition to evaluate to both true and false at least once. Stronger than statement or branch coverage, but weaker than MC/DC (Modified Condition/Decision Coverage), which additionally requires each condition to independently affect the decision outcome. Frequently required in safety-critical software standards such as DO-178C.
A unique identifier — typically a UUID — attached to a request when it first enters a system and propagated through every downstream service call, log entry, and event. Correlation IDs make it possible to trace a single user action across multiple services, relating all log entries to one root cause. QA engineers use them to diagnose failures in distributed systems: locate the correlation ID in a failing test's response header, then grep every service log for that ID to reconstruct the exact call chain. Absence of a correlation ID on any hop indicates a broken propagation point. CI pipelines increasingly inject a known correlation ID into test requests so that post-run log analysis can be scoped to a single test run's traffic.
Verifying a web application works correctly across different browsers (Chromium, Firefox, WebKit) and versions. Modern frameworks like Playwright cover all three rendering engines from one suite.
F
An organisational pattern for test automation code where concerns are separated into distinct layers — typically: Test Layer (what to verify), Page/Service Layer (how to interact), Utility Layer (shared helpers), Configuration Layer (environment settings), and Driver/Engine Layer (browser or API client setup). Dependencies flow downward only: tests import pages, pages import utilities, nothing imports from the test layer.
H
A real browser running without a visible UI. Used in CI for speed and reproducibility — same rendering engine as a normal browser, with no display required.
I
A value TypeScript falls back to typing as `any` because it can't infer a type and none was given — silently switching off type-checking for that value. The `noImplicitAny` compiler flag (part of `strict`) turns these into errors instead. In test code, an implicit `any` on an API response or a page-object return means typos and wrong-shaped assertions compile fine and only blow up at runtime.
A migration strategy where files are converted one at a time rather than all at once, using `allowJs: true` in `tsconfig.json` so JavaScript and TypeScript coexist during the transition. The project compiles and tests pass at every stage, so the team can pause between files. Preferred over big-bang migration for larger codebases because CI stays green and risk is contained to one file per commit.
K
An automation approach where test cases are described in tabular form using a controlled vocabulary of keywords (Click, Type, Verify), and a framework maps keywords to underlying actions. Lowers the barrier for non-developers to author tests.
L
A description of how to find an element on a page — by id, CSS, XPath, role, or test attribute. Modern frameworks prefer role and test-id locators because they're resilient to DOM changes.
The practice of recording timestamped events emitted by a running application — errors, warnings, informational messages, and debug traces — to a persistent or queryable store. Logs are one of the three pillars of observability, alongside metrics and traces. A well-structured log entry carries at minimum a timestamp, a severity level (ERROR, WARN, INFO, DEBUG), a message, and a correlation ID linking it to its originating request. In QA, logs are the primary post-hoc evidence for what happened during a test run: a failing end-to-end test rarely tells you which backend call failed — the logs do. Structured logging (JSON lines rather than free-form text) makes logs programmatically queryable without regex parsing. Common testing concerns include verifying that the correct log level is used (a caught exception should be WARN or ERROR, not INFO), that no PII appears in plain text, that correlation IDs are propagated to every service hop, and that security-relevant events (failed login, privilege escalation attempt) are logged at the right level with enough context to reconstruct the event.
O
The ability to understand the internal state of a system from the signals it emits externally, without needing to redeploy or modify the system. The three pillars are logs (timestamped records of discrete events), metrics (numeric measurements aggregated over time, such as request rate, error rate, and latency percentiles), and traces (end-to-end records of a request's path through distributed services, linked by a correlation ID). High observability means a QA engineer can diagnose a failure purely from existing output, without attaching a debugger or reproducing the issue locally. In test environments, observability enables post-run failure analysis: instead of re-running a flaky test with extra logging, query structured logs for the test's correlation ID and see exactly which service call failed and why. Contrast with monitoring, which alerts on known failure thresholds — observability enables exploration of previously unknown failure modes.
P
A design pattern that wraps page interactions in dedicated classes. Tests call methods like `loginPage.signIn(email, password)` instead of manipulating selectors directly. Improves maintainability when locators change.
Running multiple tests concurrently to reduce wall-clock time. Requires test independence — shared state will cause non-deterministic failures.
R
Re-running a failing test or step automatically. Useful for taming flake from infrastructure issues — but can mask real bugs if used as a band-aid for genuinely flaky tests.
S
A CSS or XPath expression that identifies one or more DOM elements. Often used interchangeably with 'locator', though locator is the broader concept.
Test automation that captures multiple element attributes during recording (id, class, position, text, accessibility role) and uses an AI matcher to find the closest replacement when the original locator stops working. Reduces locator-rot maintenance for minor UI changes but cannot recover from major redesigns and can silently mis-bind to wrong elements — healed selectors require human review. Common implementations include Mabl, Testim, Functionize, and the open-source Healenium.
Examining code for problems without running it — linters (ESLint), type-checkers (`tsc`), formatters, and security scanners (SAST) that read the source and flag bugs, style violations, type errors, or vulnerabilities. It's the cheapest, earliest quality gate: feedback in seconds on every file, before a single test executes. The counterpart to dynamic analysis, which finds issues by running the program.
T
A structured set of guidelines, abstractions, and shared infrastructure that supports the creation and execution of automated tests. A framework addresses concerns that individual tests cannot — driver lifecycle management, configuration across environments, reporting, and test data — so each test only describes what to verify, not how to set up and tear down the environment.
The configuration file (`tsconfig.json`) that tells the TypeScript compiler how to type-check and build a project — which files to include, how strict to be, and what module/target settings to use. For a test suite it's where you turn on `strict`, wire path aliases so specs import helpers cleanly, and pull in framework type definitions (Cypress, Playwright, Jest) so editor autocomplete and type errors work inside tests.
Static analysis that verifies type correctness at compile time rather than runtime. TypeScript's type checker compares the types of values passed to functions, assigned to variables, and returned from expressions against their declared types. In test suites, type checking catches property typos on fixture objects, wrong argument order on custom commands, and assertions against `undefined` values — before the tests ever run.
The process of converting a JavaScript codebase to TypeScript — renaming files from `.js` to `.ts`, adding type annotations, and configuring `tsconfig.json`. Done incrementally (one file at a time with `allowJs: true`) or all at once (big-bang). In QA contexts, migration targets test files, page objects, and support files, adding compile-time safety to previously untyped assertions and command signatures.