Filip Gačić

QA Engineer

I break things on purpose so users don't have to.

↓ scroll

I break things on purpose
so production doesn't.

QA Engineer with a focus on building automated quality gates that catch regressions before they reach users. I work across the full testing pyramid from fast Playwright E2E suites to API contract tests and k6 load scenarios, I own the CI pipeline that runs them on every push.

5+
Years in QA
3
Test disciplines
100%
Test-owned site

Sites I've helped ship

A selection of products I've contributed quality assurance across Web3, real estate, and enterprise engineering.

How AI accelerates my QA

I treat frontier AI tooling the way I treat any test infrastructure: leverage, with a human owning the verdict. It sits inside my daily QA loop, not around it: gathering ticket context, exploring solutions, generating coverage, reviewing changes, and chasing down failures faster.

Research
Codex
Explore the codebase, connect ticket context to the implementation, and compare solution options. I review the findings and own the final decisions.
Explore Codex ↗
Gather context
Azure DevOps MCP + Jira MCP
Pull requirements, acceptance criteria, comments, history, and linked work into one view. Faster context gathering supports investigation, solution planning, and routine ticket administration.
Azure DevOps MCP ↗Jira MCP ↗
Generate
Playwright MCP
Draft Playwright specs and ticket scaffolding straight from intent. I then own, prune, and harden every line.
Playwright MCP ↗
Run
Playwright CLI
Execute the suite locally and in CI, with sharding, retries, traces, and a shareable HTML report on every run.
Playwright CLI ↗
Review
Claude Code (CLI)
A first-pass review on every change before mine, catching the obvious before it reaches a human reviewer.
Claude Code ↗
Investigate
Chrome DevTools MCP
Drive a real browser to reproduce a failure, walk the DOM and network, and pin down the root cause.
Chrome DevTools MCP ↗

The Playwright suite and CI you're looking at were authored in exactly this loop: generated, reviewed, and triaged with these tools, then signed off by me.

What I test with

Playwright
E2E Testing
Cypress
E2E Testing
k6
Load & Performance
Postman / Bruno
API Testing
TypeScript
Language
GitHub Actions
CI/CD
Docker
Infrastructure
REST / GraphQL
Protocols
Allure Reports
Reporting
BrowserStack
Cross-browser Testing
Azure DevOps
CI/CD
Percy
Visual Regression
Lighthouse
Performance / A11y

This site is the test subject

Four test suites live in the same repo as this site. CI runs on pull requests and pushes to main.

End-to-End
Playwright
● CI runs

Full browser automation covering navigation, form interactions, visual regression, and cross-browser checks. Runs on every push via GitHub Actions.

test('hero renders correctly', async ({ page }) => {
  await page.goto('/')
  await expect(page.locator('h1')).toBeVisible()
  await expect(page).toHaveTitle(/QA Engineer/)
})
View latest Playwright report →
API Testing
Playwright request
● CI runs

Request-level validation of all API routes - status codes, response schemas, error handling, and latency budgets. No browser overhead.

test('health endpoint', async ({ request }) => {
  const res = await request.get('/api/health')
  expect(res.status()).toBe(200)
  const body = await res.json()
  expect(body).toMatchObject({ status: 'ok' })
})
View latest Playwright report →
Load & Performance
k6
● CI runs

Smoke tests (5 VUs) run in CI. Load scenarios (100 VUs, 2 min) validate p95 latency under realistic traffic.

export const options = { vus: 5, duration: '30s' }

export default function () {
  const res = http.get(__ENV.BASE_URL)
  check(res, { 'status 200': (r) => r.status === 200 })
  sleep(1)
}
View test report →
Visual Regression
Percy
● CI runs

Per-section and stateful DOM snapshots at mobile, tablet, and desktop widths. Pixel diffs surface unintentional layout shifts before they ship - animations are frozen and the globe is masked for determinism.

await percySnapshot(page, 'Home / Hero', {
  scope: sel(testIds.sections.hero),
})
// drive the UI into a state, then snapshot
await page.getByTestId(testIds.contact.submit).click()
await percySnapshot(page, 'Contact / Validation errors')
View visual snapshots →

Get in touch

Have a project in mind or want to talk QA? Send me a message.

0 / 500