Skip to content

Repository files navigation

InspectorBooster

A Chrome extension for QA engineers — ultra CSS/XPath inspector with smart selectors, aliases, scopes, interaction recording, and framework-ready exports for Playwright and Cypress.


Features

Inspect Mode

  • One-click element inspection from the side panel — hover any element to see ranked selector options
  • Smart selector engine — generates testid, id, role, aria-label, placeholder, class, CSS path, XPath, and text selectors — each scored 0-100 by stability and uniqueness
  • Role-based selectors — detects implicit ARIA roles from HTML tags (button, link, heading, textbox, etc.) combined with accessible name
  • Placeholder selectors — captures placeholder attribute for inputs and textareas
  • Partial class matching[class*="product-card"] for BEM/semantic class fragments, skipping utility classes (Tailwind, state)
  • Contains text//tag[contains(normalize-space(.), "...")] for partial text matching on longer content
  • Missing testid tip — warns when an element lacks a data-testid attribute
  • Preferred type picker — set your default selector type (AUTO / TESTID / ROLE / ARIA / PLACE / ID / CSS / XPATH / TEXT) — auto-selects on every click

Display Modes

  • RAW — raw selector values as-is
  • PW (Playwright)page.getByTestId(...), page.getByRole(...), page.getByLabel(...), page.getByPlaceholder(...), page.getByText(...), page.locator(...)
  • CY (Cypress)cy.get(...), cy.contains(...), cy.xpath(...), cy.get('[placeholder="..."]')
  • Global switcher in the header — applies to Inspect, Library, and Recordings views
  • Copy button always copies the formatted string, ready to paste into test code

Library

  • Scopes — organise elements into named scopes (Login Page, Header, Product List, etc.) with nesting
  • Scope container selector — optional DOM selector on a scope (e.g. [data-testid="product-card"]); exports chain through it: page.locator('[data-testid="card"]').getByTestId('buy-btn')
  • Aliases — human-readable names mapped to selectors (e.g. login-button -> [data-testid="login-btn"])
  • Search — filter elements by alias, description, selector value, or tags
  • Inline editing — rename alias, update description, change tags, switch active selector
  • Scope tree — recursive sidebar with color-coded icons, delete (orphans elements, doesn't delete them)

Recording

  • Interaction capture — records clicks, inputs, keypresses, navigation with full ranked selector options per step
  • Live feed — real-time interaction stream while recording
  • Per-step editing — rename alias, choose active selector from ranked dropdown, exclude/remove steps
  • Export as test scripts — download as Playwright .spec.ts or Cypress .cy.js directly from a recording

Export / Import

  • 6 export formats: JSON (scoped), YAML (scoped), JSON (flat map), YAML (flat map), Playwright (TypeScript), Cypress (JavaScript)
  • Preferred selector type override — when exporting framework formats, force a specific type (e.g. always use testid) with fallback
  • Scope container chaining — framework exports chain selectors through the scope's container selector
  • Preview — preview export content before downloading
  • Import — paste JSON or YAML to import scopes and elements back into the library

Project Structure

inspectorbooster/
├── extension/                # Chrome MV3 extension
│   ├── src/
│   │   ├── background/       # Service worker — message routing, tab state, panel port management
│   │   ├── content/          # isolated.ts (chrome bridge + overlay) + main.ts (selector engine + recording)
│   │   ├── db/               # IndexedDB via idb — scopes, elements, recordings stores
│   │   ├── lib/              # export.ts (serializers) + format-selector.ts (PW/CY formatters)
│   │   ├── panel/            # Side panel UI — InspectorView, LibraryView, RecordingView, ExportDialog
│   │   ├── popup/            # Extension popup — quick status + open panel
│   │   ├── store/            # Zustand stores — inspector (port/state), library (view/prefs)
│   │   └── types/            # All shared TypeScript types
│   ├── public/icons/         # Extension icons (SVG + PNG)
│   └── manifest.json         # MV3 manifest with sidePanel permission
├── e2e/                      # Playwright e2e tests
│   ├── app/                  # Test page (localhost:7777) with known selectors
│   ├── fixtures/             # Extension fixture (launchPersistentContext + --load-extension)
│   ├── pages/                # Page objects — PanelPage, PopupPage
│   └── tests/                # 76 tests: inspector, library, recording, export, popup
├── .github/workflows/        # PR checks, E2E, Release
├── lefthook.yml              # Pre-commit hooks (typecheck + build + structlint)
└── .structlint.yaml          # Project structure validation

Quick Start

cd extension && npm install && npm run build

Then load the extension:

  1. Open chrome://extensions
  2. Enable Developer mode
  3. Load unpacked -> select extension/dist/
  4. Click the extension icon or open the side panel

Development

# Watch mode — extension rebuilds on change
cd extension && npm run dev

# Run e2e tests (headed, parallel)
cd e2e && npm install && npx playwright install chromium --with-deps
npx playwright test

E2E Tests

76 Playwright tests covering:

Suite Tests What it covers
Inspector 20 Inspect mode, display modes (RAW/PW/CY), preferred type picker, role/placeholder selectors, content script communication
Library 10 Empty state, seeding, search, scopes, element cards, display mode in cards, scope container
Recording 22 Start/stop/discard, live feed, saved recordings, alias/exclude/remove, selector dropdown, PW/CY export
Export 17 All 6 formats, framework options, preferred type override, scope container chaining, preview, import
Popup 5 Header, tagline, button, hints, idle indicators
# Run all tests
cd e2e && npx playwright test

# Run specific suite
npx playwright test -g "library"

# Headed mode with UI
npx playwright test --headed --ui

Selector Engine

The content script generates selectors ranked by stability score:

Strategy Type Score (unique/non-unique) Example
data-testid testid 98 / 78 [data-testid="login-btn"]
#id id 92 / 52 #login-btn
Role + name role 88 / 65 role=button[name="Sign In"]
aria-label aria 83 / 56 button[aria-label="Close"]
placeholder placeholder 75 / 55 input[placeholder="Search..."]
Class chain css 72 / 30-65 button.btn.btn-primary
CSS path css 62 / 35 #login-form > div > button
Partial class css 58 / 38 [class*="product-card"]
Text (exact) text 44 //button[normalize-space(.)="Sign In"]
Text (contains) text 40 //button[contains(normalize-space(.), "Add to")]
Absolute XPath xpath 28 //html/body/div[1]/form/button[1]

Tech Stack

Layer Tech
Extension Chrome MV3, ISOLATED + MAIN world content scripts bridged via window.postMessage
Selector engine Custom — testid, role, aria, placeholder, class, CSS path, XPath, text (exact + contains)
UI React 18, Zustand, TanStack Query v5, Tailwind CSS
Storage IndexedDB via idb (scopes, elements, recordings)
Export JSON, YAML (js-yaml), Playwright TS, Cypress JS
Bundler Vite + vite-plugin-web-extension
Testing Playwright e2e (76 tests, parallel, headed)
CI/CD GitHub Actions — PR checks, E2E, Release (releaseforge + reviewforge + structlint)
Hooks Lefthook — pre-commit (typecheck + build + structlint), commit-msg (conventional commits)

License

MIT

About

Ultra CSS/XPath inspector Chrome extension for QA — smart selectors, aliases, scopes, interaction recording

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages