.gitignore for Test Projects

7 min read

A clean Git repo is small, secret-free, and contains only the files that matter. A messy one is bloated with screenshots, videos, dependency folders, and (worse) credentials. The line between the two is a single text file at the root of your project: .gitignore. This lesson covers the patterns that keep test automation repos clean, the recovery move for the file you accidentally committed last week, and the rule that has saved more careers than any other Git skill: never commit secrets.

What .gitignore does

.gitignore is a plain-text file you create at the root of your repository. Each line is a pattern. Any file or folder matching a pattern is invisible to Git — it doesn't show up in git status, can't be staged with git add, can't be committed.

Create it once:

cd your-test-repo
touch .gitignore        # macOS/Linux/Git Bash
# or on Windows PowerShell:
# New-Item .gitignore

Open it in your editor and start adding patterns.

Why test projects need it badly

Run a Cypress or Playwright suite once and look at what your test directory contains:

  • node_modules/ — hundreds of MB of dependencies, restored on demand by npm install.
  • cypress/screenshots/ — hundreds of PNGs from failed runs.
  • cypress/videos/ — multi-megabyte recordings of every test.
  • playwright-report/ — generated HTML reports.
  • test-results/ — raw artefacts from each run.
  • .env — contains the staging API token, the seeded test password, the bot account credentials.

Without .gitignore, all of that gets pulled into your first commit. Your "small test repo" balloons to a gigabyte; your secrets land in a public PR; your teammates' clones take 20 minutes. The fix is half a minute of .gitignore work before the first commit.

A starter .gitignore for a Cypress/Playwright project

Drop this into the root of any test automation repo and tweak from there:

# Dependencies
node_modules/

# Cypress artefacts
cypress/screenshots/
cypress/videos/
cypress/downloads/

# Playwright artefacts
test-results/
playwright-report/
playwright/.cache/

# Test reports
reports/
mochawesome-report/
allure-results/
coverage/

# Environment and secrets
.env
.env.local
.env.*.local
cypress.env.json

# IDE
.vscode/settings.json
.idea/

# OS files
.DS_Store
Thumbs.db

# Logs
*.log
npm-debug.log*

Commit this on day one. Future you and every teammate will thank you.

Pattern syntax — what each symbol means

.gitignore patterns are not full regex; they're a small dedicated mini-language:

PatternMatchesExample
node_modules/A folder anywhere in the reponode_modules/, cypress/node_modules/
*.logAny file ending in .lognpm-debug.log, cypress.log
**/*.tmpAny .tmp file at any depthtmp/foo.tmp, a/b/c/foo.tmp
/distOnly dist at the rootdist/ (root only, not tests/dist/)
!keep.logNegate — include this file even if other patterns ignore itwith *.log and !keep.log, every .log is ignored except keep.log
# commentA comment(purely human-readable)

A real combined example — ignore all of cypress/screenshots/ but keep one reference image used by visual tests:

cypress/screenshots/
!cypress/screenshots/baseline-login.png

Verifying your .gitignore is working

After adding patterns, check what Git now sees:

git status

If node_modules/ no longer appears as untracked, you're set. If it still appears, your pattern is wrong (or the file was already tracked — read on).

To debug a single file:

git check-ignore -v cypress/screenshots/login.png
.gitignore:5:cypress/screenshots/    cypress/screenshots/login.png

Git tells you exactly which line of which file matched. If nothing prints, the file isn't ignored — your pattern hasn't matched.

The "I already committed it" recovery

.gitignore only affects files that haven't been tracked yet. If you committed node_modules/ last week and then added node_modules/ to .gitignore, the folder is still tracked. Adding the pattern does nothing retroactively.

The fix: untrack the file (or folder) in Git while keeping it on disk:

git rm --cached -r node_modules/
git commit -m "Stop tracking node_modules; rely on .gitignore"

--cached removes from Git's index but leaves the actual file alone. -r recurses into folders. Push the commit; teammates' next pull will delete the folder from their copies (locally on their disks) — they'll need to npm install again to restore it. Communicate the change before pushing.

Never commit secrets

The single most expensive mistake in .gitignore discipline. Once a secret hits Git history — even briefly, even on a private repo — it should be considered compromised:

  • API tokens, OAuth secrets, AWS keys.
  • Database connection strings with passwords.
  • Any .env file containing real values.
  • TLS private keys, signing keys, JWT secrets.
  • Test account passwords if they grant any meaningful access.

If you spot a leak, the order is non-negotiable:

  1. Rotate / revoke the secret first. It's in history; assume it's been seen.
  2. Add the pattern to .gitignore.
  3. git rm --cached <file> and commit.
  4. For genuinely sensitive cases, rewrite history with git filter-repo or BFG and force-push. Coordinate with the team.

The companion convention: commit a .env.example (no real values) so new joiners know what variables exist:

# .env.example — copy to .env and fill in real values
CYPRESS_BASE_URL=https://staging.example.com
CYPRESS_TEST_USERNAME=
CYPRESS_TEST_PASSWORD=

.env.example is tracked. .env is in .gitignore. Everyone wins.

GitHub's template .gitignore files

You don't need to write one from scratch. GitHub maintains github.com/github/gitignore — official templates for Node.js, Python, Java, and dozens of other ecosystems. When you create a new repo on GitHub, the "Add .gitignore" dropdown lets you pick one. Pick Node for a Cypress/Playwright project, then add the test-specific lines from the starter above.

The Git for QA cheat sheet has the most-used QA .gitignore patterns as a quick reference.

What to ignore — at a glance

.gitignore for test projects
  • – node_modules/
  • – .pnpm-store/
  • – vendor/
  • – cypress/screenshots/
  • – cypress/videos/
  • – playwright-report/
  • – test-results/
  • – allure-results/
  • – .env
  • – cypress.env.json
  • – *.pem
  • – credentials.json
  • .DS_Store –
  • Thumbs.db –
  • .vscode/settings.json –
  • .idea/ –
  • *.log –
  • npm-debug.log* –
  • .cache/ –

⚠️ Common mistakes

  • Adding .gitignore after the first commit. A file already tracked stays tracked, no matter what .gitignore says. Always create .gitignore before the first git add . — and if you missed it, use git rm --cached -r <path> to untrack and commit the cleanup.
  • Committing .env with real credentials. The "I'll just remove it later" mistake — by the time you remove it, anyone watching the repo has a copy. Treat .env as radioactive: keep it ignored from day one and commit a .env.example template instead.
  • Ignoring node_modules/ but then including it in a Docker image somehow. A common follow-on confusion: the file is gitignored (correct) but somehow ends up in CI artefacts (wrong). .gitignore only affects Git; CI tools, Docker, and bundlers each have their own ignore files (.dockerignore, .npmignore). They aren't synced; you may need to mirror patterns.

🎯 Practice task

Set up a clean .gitignore on a real test repo. 20-25 minutes.

  1. In your qa-sandbox repo (or a real test repo if you have one), open the root and create .gitignore. Paste the starter list above.
  2. Commit and push: git add .gitignore && git commit -m "Add .gitignore for test artefacts and secrets" && git push.
  3. Create a fake .env file: echo "CYPRESS_TEST_PASSWORD=hunter2" > .env. Run git status. Confirm .env does NOT appear.
  4. Run git check-ignore -v .env and read which line of .gitignore matched.
  5. Create cypress/screenshots/test.png (any placeholder). Run git status. Confirm it's not listed.
  6. Negation: add cypress/screenshots/baseline-login.png (placeholder). Add !cypress/screenshots/baseline-login.png to .gitignore. Run git status again — confirm only the baseline appears.
  7. Recovery drill: intentionally commit a file (e.g., notes.txt). Then add notes.txt to .gitignore. Run git rm --cached notes.txt && git commit -m "Stop tracking notes.txt". Confirm git status no longer shows the file.
  8. Stretch: start a brand new project with npm init -y && npm install cypress. Run ls. Add a .gitignore so that git status shows only the source files you'd actually want to commit.

The next lesson covers the test data that should live in Git — fixtures — and how to organise them so they help rather than hurt.

// tip to track lessons you complete and pick up where you left off across devices.