Skip to content
Go back

Guarding the Guards: Building a Pre-Merge Quality Gate for Your TypeScript Automation Framework

Published:

Introduction: The Automation Paradox

We invest thousands of hours building robust automation frameworks to protect our products from regressions. But what protects our automation framework from itself?

This is the automation paradox: we build sophisticated quality gates for our application code, yet often leave the automation codebase itself exposed to the very chaos we’re trying to prevent. A single bad merge—a broken dependency, a syntax error, a misconfigured CI step—can bring the entire testing pipeline to a grinding halt, wasting hours of engineering time.

In a previous article, I detailed how to build a pre-merge pipeline for a Selenium/Python project. Today, we’ll take that philosophy and apply it to a modern stack: Playwright, TypeScript, and GitHub Actions. This isn’t just about different tools; it’s about a more integrated, developer-centric approach to quality.

This guide is based on the live CI/CD pipeline from my Playwright-TypeScript-Example project on GitHub.

Why Your Automation Project Needs Its Own Quality Gate

Manual code reviews are not enough. An automation framework is a mission-critical software product in its own right. It deserves the same level of protection as our main application. A solid pre-merge pipeline for your automation project achieves three critical goals:

  1. It Protects Your CI/CD: It ensures that a broken test framework never reaches the main branch, preventing catastrophic failures of your nightly regressions.
  2. It Enforces Standards: It automates code formatting, linting, and best practices, freeing up your code reviews to focus on logic and architecture, not style debates.
  3. It Builds Confidence: It gives every contributor the confidence to make changes, knowing that a safety net is there to catch basic mistakes before they become major problems.

Building the Gate: A Step-by-Step Guide with GitHub Actions

Our Quality Gate is a GitHub Actions workflow that runs on every Pull Request targeting the main branch. It’s a series of automated checks that must pass before any code can be merged.

You can find the full workflow YAML file here.

Step 1: The Trigger – When to Guard?

We configure the workflow to run only when it matters: on any PR that touches critical files.

on:
  pull_request:
    branches: [main]
    paths:
      - '**/*.ts'
      - 'package.json'
      - 'playwright.config.ts'
      - '.github/workflows/devRun.yml'

This is crucial. We’re not running this on every documentation change. We’re focusing the gate on what can actually break the system.

Step 2: The Environment – Consistency is Key

We run our entire workflow inside a container that mirrors our production testing environment.

container:
  image: mcr.microsoft.com/playwright:v1.54.2

This eliminates the “it works on my machine” problem. If it passes here, it will pass in the nightly run.

Step 3: The Checks – From Style to Sanity

This is the heart of the Quality Gate. We run a series of checks in order:

  1. Dependency Installation: We use pnpm install --frozen-lockfile to ensure that the dependencies are installed exactly as defined in the lock file. This prevents unexpected package updates from breaking the build.
  2. (Optional but Recommended) Linting & Formatting: Before even running a test, we can add steps to run ESLint and Prettier. This catches style issues and potential bugs without even launching a browser.
  3. The Sanity Test: This is the most critical step. We run a small, fast, and ultra-reliable E2E test. Its only job is to confirm that the core of the framework is functional.

Our Sanity Test (@devRun):

test(
  "get started link",
  { tag: "@devRun" },
  async ({ page, homePage }) => {
    // This test doesn't check a complex business flow.
    // It checks if the framework can:
    // 1. Launch a browser.
    // 2. Navigate to a page.
    // 3. Interact with a basic element.
    // 4. Perform a simple assertion.
    await page.goto("/");
    await homePage.clickGetStarted();
    await expect(
      page.getByRole("heading", { name: "Installation" })
    ).toBeVisible();
  },
);

This test is not about product quality. It’s about framework health. If it passes, we know that the core machinery of our automation is working.

Step 4: The Feedback Loop – Reporting

Even for this small run, we generate an Allure report. This provides immediate, visual feedback on the PR, and ensures our reporting infrastructure itself is working correctly.

The Bigger Picture: This is Not a Product Quality Gate

It is crucial to understand the distinction:

You must protect your protectors. Building a Quality Gate for your automation is the first, non-negotiable step toward building a culture of quality at scale.

Conclusion

Stop treating your automation code as a second-class citizen. It is a critical piece of infrastructure that deserves the same engineering rigor as your main product. By implementing a simple, automated Pre-Merge Testing pipeline, you reduce noise, increase confidence, and free up your team to focus on what really matters: not fixing the automation, but using it to find real bugs in your product.


Suggest Changes

Ready to build your quality roadmap? Start Here


Previous Post
From Selenium to Playwright: A Data-Driven Look at the Shifting Landscape of Test Automation