<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gabriel Holmes</title>
    <description>The latest articles on DEV Community by Gabriel Holmes (@gabrielholmesqa).</description>
    <link>https://dev.to/gabrielholmesqa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4012979%2Fc96ee13f-2878-452c-9012-8083dbacd9c4.png</url>
      <title>DEV Community: Gabriel Holmes</title>
      <link>https://dev.to/gabrielholmesqa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gabrielholmesqa"/>
    <language>en</language>
    <item>
      <title>Your E2E tests live in a separate repo. That's why nobody sees the breakage coming.</title>
      <dc:creator>Gabriel Holmes</dc:creator>
      <pubDate>Fri, 03 Jul 2026 13:57:00 +0000</pubDate>
      <link>https://dev.to/gabrielholmesqa/your-e2e-tests-live-in-a-separate-repo-thats-why-nobody-sees-the-breakage-coming-ehd</link>
      <guid>https://dev.to/gabrielholmesqa/your-e2e-tests-live-in-a-separate-repo-thats-why-nobody-sees-the-breakage-coming-ehd</guid>
      <description>&lt;p&gt;Many QA teams keep end-to-end automation in a dedicated repo — separate from the app it tests. It's good hygiene: different owners, different release cadence, no test churn polluting app history.&lt;/p&gt;

&lt;p&gt;It also quietly removes the one signal that would tell a developer their change broke a test.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boundary problem
&lt;/h2&gt;

&lt;p&gt;When tests and app share a repo, at least the failing spec shows up in the same CI run and the same blame history. Split them, and the connection vanishes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The frontend dev opens a PR in the &lt;strong&gt;app&lt;/strong&gt; repo. CI there is green — there are no E2E tests to run.&lt;/li&gt;
&lt;li&gt;The PR merges. A scheduled or downstream run in the &lt;strong&gt;automation&lt;/strong&gt; repo goes red hours later.&lt;/li&gt;
&lt;li&gt;The QA engineer who owns that repo inherits a failure with no link back to the PR that caused it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dev never sees it. The reviewer never sees it. The cost lands on whoever owns the other repo, after the fact. If you're the automation owner, you know this loop: &lt;em&gt;what changed vs what broke vs which specs do I update.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why normal tooling can't help here
&lt;/h2&gt;

&lt;p&gt;Coverage tools, "affected test" selectors, and CI test-splitting all operate &lt;em&gt;within a single repo and a single test run&lt;/em&gt;. They have no concept of "a change here breaks a test there." GitHub's own PR view shows the diff and that repo's checks — nothing about a sibling repo.&lt;/p&gt;

&lt;p&gt;The boundary that makes the split clean is the same boundary the tooling can't cross.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually connects them: text
&lt;/h2&gt;

&lt;p&gt;Here's the useful observation: your E2E specs are coupled to the app through a small set of &lt;em&gt;textual anchors&lt;/em&gt; — &lt;code&gt;data-testid&lt;/code&gt; / &lt;code&gt;data-cy&lt;/code&gt; attributes, &lt;code&gt;getByRole&lt;/code&gt;/&lt;code&gt;getByText&lt;/code&gt; targets, aria-labels, element ids, route strings, visible copy.&lt;/p&gt;

&lt;p&gt;A PR that renames &lt;code&gt;data-testid="login-btn"&lt;/code&gt; or moves &lt;code&gt;/dashboard&lt;/code&gt; to &lt;code&gt;/home&lt;/code&gt; endangers every spec that references those strings — regardless of which repo the spec lives in. Text doesn't care about repo boundaries. So the check is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Extract the anchors a PR's diff touches (added/removed lines only).&lt;/li&gt;
&lt;li&gt;Search the automation repo's spec files for those anchors.&lt;/li&gt;
&lt;li&gt;Anything that matches is a break candidate — surfaced on the PR, at review time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's cheap, static, and crosses the boundary that execution-based tooling can't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating it
&lt;/h2&gt;

&lt;p&gt;I'm a QA automation engineer and I built this into a GitHub App — &lt;a href="https://testward.app" rel="noopener noreferrer"&gt;Testward&lt;/a&gt;. You add a one-line &lt;code&gt;.testward.yml&lt;/code&gt; to the app repo listing your automation repo(s); on every PR it extracts the anchors, scans the linked repos' specs (code search + a tree-grep fallback for large suites), runs an LLM pass to filter candidates that don't actually break, and posts one comment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🚨 Automation this PR may break:
- acme/web-e2e → tests/login.spec.ts — clicks [data-testid=login-btn]
  (renamed to signin-btn) and asserts the /dashboard redirect (changed to /home)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dev sees the consequence while they still have the context — and either fixes the selector or pings the automation owner &lt;em&gt;before&lt;/em&gt; the merge, not after the red.&lt;/p&gt;

&lt;p&gt;Being upfront about the limits: the matching is textual, so dynamic selectors (&lt;code&gt;`row-${id}`&lt;/code&gt;) won't match — that's the known gap. And if you want to poke at the anchor-extraction idea without installing anything, there's a &lt;a href="https://testward.app/diff-scanner" rel="noopener noreferrer"&gt;free in-browser diff scanner&lt;/a&gt; that runs entirely client-side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;If your automation lives in its own repo, no amount of in-repo tooling will warn the app team they're about to break it. The dependency is textual, so the check can be too — and it belongs at review time, where the fix costs a comment instead of an afternoon.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If your team runs a separate automation repo, I'd genuinely like to hear how you handle this today — scheduled runs and hope? A sync meeting? Something smarter?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>qa</category>
      <category>automation</category>
      <category>devops</category>
    </item>
    <item>
      <title>How to know which tests a PR will break — before CI runs</title>
      <dc:creator>Gabriel Holmes</dc:creator>
      <pubDate>Fri, 03 Jul 2026 05:00:53 +0000</pubDate>
      <link>https://dev.to/gabrielholmesqa/how-to-know-which-tests-a-pr-will-break-before-ci-runs-44b8</link>
      <guid>https://dev.to/gabrielholmesqa/how-to-know-which-tests-a-pr-will-break-before-ci-runs-44b8</guid>
      <description>&lt;p&gt;Every team has lived this: a pull request looks clean, gets approved, merges — and twenty minutes later the test suite is red. The change was in &lt;code&gt;src/&lt;/code&gt;. The failure is in &lt;code&gt;tests/&lt;/code&gt;. And nothing in the review surfaced the connection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why code review misses it
&lt;/h2&gt;

&lt;p&gt;Code review shows you the diff. It does not show you what &lt;em&gt;depends on&lt;/em&gt; the diff. A reviewer reading a one-line selector rename has no way to know that three end-to-end specs select on that exact attribute — especially if those specs live in a folder they never open, or a repo they don't have checked out.&lt;/p&gt;

&lt;p&gt;So the breakage is discovered by the most expensive possible detector: a full CI run, after merge, by whoever is on call for the red build. The person with the most context — the author, mid-review — never saw it coming.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three ways teams try to close the gap
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Run the whole suite on every PR.&lt;/strong&gt; Correct, but slow and expensive, and it tells you &lt;em&gt;after&lt;/em&gt; the fact — you still wait for the red. On large suites it's minutes-to-hours of feedback latency per push.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Coverage-based test selection.&lt;/strong&gt; Map code to the tests that execute it and run only those. Powerful for unit tests, but it needs instrumentation, breaks down for E2E (where the "coverage" is a running browser), and says nothing across repo boundaries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Static impact analysis at review time.&lt;/strong&gt; Read the diff, extract what it changes that tests depend on — selectors, routes, ids, visible text — and match those against the test files. This is cheap, needs no instrumentation, and runs the moment the PR opens.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "what tests depend on" actually means
&lt;/h2&gt;

&lt;p&gt;End-to-end and integration tests are coupled to the app through a small, identifiable set of anchors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Selectors / test ids&lt;/strong&gt; — &lt;code&gt;data-testid&lt;/code&gt;, &lt;code&gt;data-cy&lt;/code&gt;, &lt;code&gt;getByRole&lt;/code&gt;, CSS, XPath&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routes&lt;/strong&gt; — URL literals the test navigates to or asserts on&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visible text &amp;amp; labels&lt;/strong&gt; — button copy, headings, aria-labels the test queries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Element ids and names&lt;/strong&gt; — the locators page objects hang off&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a PR changes one of these, any test referencing it is a break candidate. That's a tractable matching problem you can run in seconds — no test execution required.&lt;/p&gt;

&lt;p&gt;Want to see it on a real diff? I built a free scanner that runs this extraction entirely in your browser (nothing gets uploaded): &lt;a href="https://testward.app/diff-scanner" rel="noopener noreferrer"&gt;testward.app/diff-scanner&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The cross-repo blind spot
&lt;/h2&gt;

&lt;p&gt;Here's where it gets interesting for QA teams specifically. Many of us keep automation in a &lt;strong&gt;dedicated repo&lt;/strong&gt; — separate from the app it tests. Good hygiene, but it severs the only signal: the frontend dev's PR is green (no E2E tests live there), and the automation repo goes red hours later with no link back to the cause.&lt;/p&gt;

&lt;p&gt;Coverage tools, affected-test selectors, and CI test-splitting all operate within a single repo and a single test run. None of them can say "a change &lt;em&gt;here&lt;/em&gt; breaks a test &lt;em&gt;there&lt;/em&gt;."&lt;/p&gt;

&lt;h2&gt;
  
  
  How I automated this
&lt;/h2&gt;

&lt;p&gt;I'm a QA automation engineer, and this loop ate enough of my afternoons that I built a GitHub App for it — &lt;a href="https://testward.app" rel="noopener noreferrer"&gt;Testward&lt;/a&gt;. On every PR it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reads the diff and extracts the anchors the change touches.&lt;/li&gt;
&lt;li&gt;Scans your test files — same repo, or a separately-linked automation repo (one line of config).&lt;/li&gt;
&lt;li&gt;Runs an LLM confirmation pass that names the specific specs likely to break and why.&lt;/li&gt;
&lt;li&gt;Posts one sticky comment: risk level, affected specs, reasons.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The reviewer sees the consequence next to the cause, while the author still has the context to fix it — or update the test in the same PR.&lt;/p&gt;

&lt;p&gt;Known limitation worth being upfront about: dynamic selectors (&lt;code&gt;`row-${id}`&lt;/code&gt;) can't be matched statically — that's the gap I'm working on. If your suite leans on template-literal test ids, the anchor model will miss those.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;You don't need to run tests to know a PR endangers them. The dependency between app code and test code is mostly &lt;em&gt;textual&lt;/em&gt; — selectors, routes, labels — and you can check it at review time, when the fix is cheapest. Whether you script it yourself or use a tool, moving that signal left is one of the highest-leverage things a QA team can do.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Questions or war stories about PRs silently breaking your suite? I'd genuinely like to hear them — especially from teams whose automation lives in a separate repo.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>qa</category>
      <category>automation</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
