Skip to content

How It Works ​

1. Get changed files ​

PropWatch runs a git diff to find files that changed between your branch and the base ref:

git diff --name-status origin/main HEAD

Files are filtered to extensions matched by your configured patterns (.tsx, .jsx, .html, etc.) before any parsing happens.

2. Extract IDs ​

For each changed file, PropWatch reads both versions:

  • Base — git show origin/main:path/to/file.tsx
  • Head — the file on disk

It then runs the configured parser over each version to extract every matching ID and the line it appears on.

3. Diff the ID sets ​

IDs from the base and head versions are compared using a value-aware algorithm:

  • IDs that exist in both versions unchanged are ignored
  • IDs that appear at the same line in both versions but with different values are marked Changed
  • IDs present in the base but absent from the head are marked Removed
  • IDs present in the head but absent from the base are marked Added

The line-level pairing minimises false positives from simple renames:

Base:  line 10 → testID="submit-btn"
Head:  line 10 → testID="submit-button"

Result: 1 Changed  (not 1 Removed + 1 Added)

4. Classify changes ​

StatusBreakingDescription
AddedNoNew IDs don't affect existing tests
ChangedYesExisting selectors will stop matching
RemovedYesExisting selectors will stop matching

hasBreakingChanges is true when any Changed or Removed results exist. With --exit-on-breaking, PropWatch exits with code 1.

5. Report ​

Results are passed to each configured reporter:

ReporterOutput
consoleANSI table in the terminal
junitpropwatch-junit.xml — JUnit XML for CI test management
jsonpropwatch-results.json — full structured output
githubGitHub Actions annotations + Markdown summary

Parsers ​

Regex ​

The default parser. Scans each line with one or more regex patterns and captures group 1 as the ID value.

json
{
  "parser": "regex",
  "propPatterns": [
    "testID=\"([^\"]+)\"",
    "data-testid=\"([^\"]+)\""
  ]
}

Babel AST ​

For JSX prop extraction, the Babel parser traverses the AST and finds JSXAttribute nodes matching the configured prop names. More reliable than regex for complex JSX (multiline props, template literals).

json
{
  "parser": "babel",
  "propNames": ["testID", "testId", "data-testid"]
}

File status handling ​

Git statusAction
Modified (M)Diff base vs head
Added (A)All IDs are reported as Added
Deleted (D)All IDs are reported as Removed
Renamed (R)Old path treated as Deleted, new path as Added

Released under the MIT License