diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 103a980..bae047a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Build & Lint Extension +name: Build & Release Extension on: push: @@ -9,28 +9,74 @@ on: jobs: build: runs-on: ubuntu-latest + permissions: + contents: write # needed to create releases and upload assets steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 - - name: Use Node.js 20 - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: 'npm' + - name: Set up Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' - - name: Install dependencies - run: npm ci + - name: Install dependencies + run: npm ci - - name: Type Check - run: npm run type-check + - name: Type check + run: npm run type-check - - name: Build Extension - run: npm run build + - name: Build extension + run: npm run build - - name: Upload Build Artifact - uses: actions/upload-artifact@v4 - with: - name: testpilot-extension - path: dist/ - retention-days: 5 + # ── Build info ────────────────────────────────────────────────────────── + - name: Generate build info + id: build_info + run: | + SHA_SHORT=$(git rev-parse --short HEAD) + DATE=$(date -u +"%Y-%m-%d") + echo "sha_short=$SHA_SHORT" >> $GITHUB_OUTPUT + echo "date=$DATE" >> $GITHUB_OUTPUT + echo "zip_name=testpilot-${SHA_SHORT}.zip" >> $GITHUB_OUTPUT + + # ── Zip the dist folder ───────────────────────────────────────────────── + - name: Zip dist folder + run: | + cd dist + zip -r "../${{ steps.build_info.outputs.zip_name }}" . + cd .. + echo "Created ${{ steps.build_info.outputs.zip_name }}" + ls -lh "${{ steps.build_info.outputs.zip_name }}" + + # ── Upload zip as a workflow artifact (available on every PR + push) ──── + - name: Upload extension zip (artifact) + uses: actions/upload-artifact@v4 + with: + name: testpilot-${{ steps.build_info.outputs.sha_short }} + path: ${{ steps.build_info.outputs.zip_name }} + retention-days: 14 + + # ── On main: create/update a "latest" GitHub Release with the zip ─────── + - name: Create or update latest Release + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + uses: softprops/action-gh-release@v2 + with: + tag_name: latest + name: "TestPilot – Latest Build (${{ steps.build_info.outputs.date }})" + body: | + ## ⬇️ Install TestPilot + + 1. Download `testpilot-${{ steps.build_info.outputs.sha_short }}.zip` below + 2. Unzip it anywhere on your machine + 3. Open `chrome://extensions` in Chrome + 4. Enable **Developer mode** (top-right toggle) + 5. Click **Load unpacked** and select the unzipped folder + + --- + **Commit:** `${{ steps.build_info.outputs.sha_short }}` + **Built:** ${{ steps.build_info.outputs.date }} + files: ${{ steps.build_info.outputs.zip_name }} + prerelease: false + make_latest: true diff --git a/README.md b/README.md index f99f863..f63cad6 100644 --- a/README.md +++ b/README.md @@ -1,86 +1,197 @@ # 🧪 TestPilot -**Intelligent Bug Detection & Telemetry Extension for Modern Web Apps** - -TestPilot is a powerful, production-grade Chrome extension designed to catch bugs before your users do. It acts as a black-box flight recorder for your web application, capturing console errors, network failures, slow APIs, performance metrics, and security risks in real-time. - -![TestPilot Banner](https://via.placeholder.com/800x200?text=TestPilot+Extension) - -## ✨ Key Features - -- **🚀 Real-time Telemetry**: Captures `console.error`, `console.warn`, unhandled exceptions, and promise rejections. -- **🌐 Network Intelligence**: - - Detects **Slow APIs** (>1000ms by default) - - Identifies **Retry Storms** (rapid repeated failures) - - Captures **CORS Errors** and HTTP 4xx/5xx failures -- **⚡ Performance Monitoring**: - - **Long Task Detection**: Flags UI freezes (>200ms) - - **White Screen Detection**: Alerts on potential rendering crashes -- **🛡️ Security Scanner**: - - Detects sensitive data leaks (JWTs, API keys, PII) in console/storage - - Monitors unsafe storage access -- **📱 Smart Context**: Captures environment details (User Agent, Viewport, Route Changes) for actionable bug reports. -- **🧠 Adaptive Severity**: Automatically escalates issue severity based on frequency (e.g., repeating errors become Critical). - -## 🛠️ Usage - -1. **Install the Extension** (Developer Mode): - - Clone this repo - - Run `npm install` and `npm run build` - - Open `chrome://extensions` - - Enable "Developer mode" - - Click "Load unpacked" and select the `dist` folder - -2. **Start a Session**: - - Click the extension icon - - Hit **Start Session** - - Interact with your web application - - TestPilot records all hidden issues in the background - -3. **Analyze & Export**: - - Open the popup to see a categorized list of issues - - Use **Filters** to focus on Critical/High severity bugs - - Click **Export JSON** or **Export Markdown** to generate a bug report +**Intelligent Bug Detection & Telemetry Chrome Extension for Modern Web Apps** + +TestPilot is a production-grade Chrome extension that acts as a silent flight recorder for your web application. It captures bugs, network failures, security risks, and performance issues in real-time — before your users report them. + +--- + +## ✨ Features + +### 🖥️ Console Monitoring +- Intercepts `console.error` and `console.warn` calls from deep inside the page (via a **Main World bridge script** that runs before any other JS) +- Captures the **caller file, line, and column** from the stack trace automatically +- Passes every console message through the **Security Scanner** before logging + +### 🌐 Network Intelligence +- Wraps both **`window.fetch`** and **`XMLHttpRequest`** to intercept all outgoing requests +- Captures **HTTP 4xx / 5xx** failures as `network_failure` issues +- Detects **Slow APIs** — requests exceeding the configurable threshold (default: 1000ms) +- Detects **API Retry Storms** — automatically escalates to `retry_storm` (Critical) when the same endpoint fails 3+ times within 5 seconds +- Records **request payload**, **response status**, and **response body** (up to 2000 chars) for every failing or slow request + +### ⚡ Runtime Crash Detection +- Listens for `window.onerror` to catch **unhandled JavaScript exceptions** with full file/line/column/stack metadata +- Listens for `window.onunhandledrejection` to catch **unhandled Promise rejections** + +### 📦 Broken Resource Detection +- Listens on the capture phase for failed loads of ``, `