From 13c0e54b338ec4ef2363cae9490d35c0abfd1504 Mon Sep 17 00:00:00 2001 From: murilopmachado Date: Tue, 4 Aug 2026 20:43:06 +0200 Subject: [PATCH 1/2] feat: add dedicated marketing site GitHub Pages site at web/ following the AxeForge relay-flavor template (gumshoe/heyra/rsvp-m5): topbar, hero with a live simulated selector-ranking demo, mechanism feature grid, selector engine table, 4-step workflow, use-case cards, install steps, and cross-linking footer. Full SEO head block (meta/OG/Twitter/canonical/JSON-LD) and robots.txt/sitemap.xml included. og:image/twitter:image omitted -- no docs/assets logo exists yet. --- .github/workflows/pages.yml | 38 +++ web/axeforge-icon.png | Bin 0 -> 7008 bytes web/axeforge.css | 242 +++++++++++++++++++ web/favicon.png | Bin 0 -> 9475 bytes web/index.html | 446 ++++++++++++++++++++++++++++++++++++ web/robots.txt | 4 + web/sitemap.xml | 8 + 7 files changed, 738 insertions(+) create mode 100644 .github/workflows/pages.yml create mode 100644 web/axeforge-icon.png create mode 100644 web/axeforge.css create mode 100644 web/favicon.png create mode 100644 web/index.html create mode 100644 web/robots.txt create mode 100644 web/sitemap.xml diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..f726236 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,38 @@ +name: Deploy Pages + +on: + push: + branches: + - main + workflow_dispatch: + +concurrency: + group: pages-${{ github.repository }} + cancel-in-progress: true + +jobs: + deploy: + if: github.repository == 'AxeForging/inspectorbooster' + runs-on: ubuntu-latest + permissions: + contents: read + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Check out repository + uses: actions/checkout@v6 + + - name: Configure GitHub Pages + uses: actions/configure-pages@v5 + + - name: Upload GitHub Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: web + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/web/axeforge-icon.png b/web/axeforge-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..da16248d5e8e4f6d85a3cfcdbabc302b3c2464a8 GIT binary patch literal 7008 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 literal 0 HcmV?d00001 diff --git a/web/axeforge.css b/web/axeforge.css new file mode 100644 index 0000000..2c8b958 --- /dev/null +++ b/web/axeforge.css @@ -0,0 +1,242 @@ +/* ============================================================ + AxeForge Brand Kit v1 — https://tools.axeforge.io + Copy this file into your project. See BRAND.md for the spec. + + Works two ways from this one file: + - Tailwind v4: `@import "tailwindcss"; @import "./axeforge.css";` + (the @theme inline block maps tokens to axe-* utilities) + - Plain CSS / no Tailwind: just link it; browsers ignore @theme. + + Flavors (set on ): forge (default) | circuit | flux | relay | signal + Theme (set on ): dark (default, omit) | light — data-theme="light" + ============================================================ */ + +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=optional'); +/* display=optional (not swap): the browser decides once at layout time and + never swaps mid-session — kills the web-font-swap layout shift. Trade-off: + on a slow first load a visitor may get the fallback font for that session + instead of Inter/JetBrains Mono, since it never swaps in later. */ + +/* ---- Shell tokens: identical in every flavor except relay. Never override + otherwise -- relay's neutral-gray shell is a deliberate, one-time exception + (see the "new flavor discussion" note below), not a precedent for others. ---- */ +:root { + color-scheme: dark; + + --af-bg: #05070a; + --af-surface: #0a0f1a; + --af-surface-2: #0d1117; /* terminal body */ + --af-surface-3: #161b22; /* terminal header */ + --af-line: #1a2233; + --af-text: #ffffff; + --af-text-muted: #94a3b8; + + --af-font-sans: "Inter", ui-sans-serif, system-ui, sans-serif; + --af-font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, monospace; + + --af-radius: 0.5rem; + --af-radius-lg: 1rem; + + /* ---- Flavor tokens: the ONLY vars a flavor changes. Default = forge. ---- */ + --af-accent: #ff4e00; + --af-accent-hover: #e64600; + --af-accent-contrast: #ffffff; /* text placed ON the accent; white passes only on forge, bold/large */ +} + +[data-flavor="circuit"] { + --af-accent: #22d3ee; + --af-accent-hover: #06b6d4; + --af-accent-contrast: #05070a; +} + +[data-flavor="flux"] { + --af-accent: #a78bfa; + --af-accent-hover: #8b5cf6; + --af-accent-contrast: #05070a; +} + +/* relay: the one flavor that also overrides shell tokens (bg/surface/-2/-3/line), + not just the 3 accent vars -- "external tools/hardware/products" (Heyra, rsvp-m5, + ReplayRaccoon), inheriting ReplayRaccoon's neutral-gray shell instead of the + default blue-black. This is the "new flavor discussion" the Do/Don't section + below refers to, made real -- a deliberate one-time exception, not a precedent. */ +[data-flavor="relay"] { + --af-bg: #0a0a0a; + --af-surface: #1a1a1a; + --af-surface-2: #161616; /* terminal body */ + --af-surface-3: #202020; /* terminal header */ + --af-line: #2a2a2a; + + --af-accent: #ff6b00; + --af-accent-hover: #e56000; + --af-accent-contrast: #05070a; +} + +[data-flavor="signal"] { + --af-accent: #ffb000; + --af-accent-hover: #e69e00; + --af-accent-contrast: #05070a; +} + +/* ---- Light theme: opt-in via data-theme="light" on , alongside + data-flavor. Omit data-theme for dark (the default) — existing tools + that never set it are unaffected. Every accent below is the SAME hue as + its dark-mode counterpart, darkened only as far as needed to clear + 4.5:1 against the light shell bg (computed, not eyeballed) — verified + >=4.5:1 as button-fill-with-white-text at any size too, so light mode + drops dark mode's forge-only "bold/large" caveat entirely. + + --af-surface-2/-3 (terminal body/header) are deliberately NOT overridden + here: the terminal stays a dark console on a light page — a common + convention (docs sites, code blocks) that also sidesteps re-deriving + accent-as-text contrast for a component that's a fixed dark box in + every flavor already. ---- */ +[data-theme="light"] { + color-scheme: light; + --af-bg: #f7f8fa; + --af-surface: #ffffff; + --af-line: #dde1e6; + --af-text: #0a0f1a; + --af-text-muted: #475569; /* 7.13:1 on --af-bg */ +} + +[data-theme="light"][data-flavor="forge"] { + --af-accent: #cf3f00; /* 4.54:1 on --af-bg, 4.81:1 vs white button text */ + --af-accent-hover: #b63700; + --af-accent-contrast: #ffffff; +} + +[data-theme="light"][data-flavor="circuit"] { + --af-accent: #0b7c8d; /* 4.60:1 on --af-bg, 4.90:1 vs white button text */ + --af-accent-hover: #0a6d7c; + --af-accent-contrast: #ffffff; +} + +[data-theme="light"][data-flavor="flux"] { + --af-accent: #7a4ff7; /* 4.60:1 on --af-bg, 4.90:1 vs white button text */ + --af-accent-hover: #5e2af5; + --af-accent-contrast: #ffffff; +} + +/* relay-light: the neutral-gray shell exception carried into light mode too + — same reasoning as dark relay (matches ReplayRaccoon's own neutral + palette rather than the kit's blue-tinted default), so relay reads as + one consistent identity across both themes instead of only diverging + from the pack in dark mode. */ +[data-theme="light"][data-flavor="relay"] { + --af-bg: #f5f5f5; + --af-line: #e2e2e2; + --af-text: #0a0a0a; + --af-text-muted: #525252; /* 7.17:1 on --af-bg */ + --af-accent: #ba4e00; /* 4.61:1 on --af-bg, 6.12:1 hover vs white button text */ + --af-accent-hover: #a44500; + --af-accent-contrast: #ffffff; +} + +[data-theme="light"][data-flavor="signal"] { + --af-accent: #966800; /* 4.62:1 on --af-bg, 4.91:1 vs white button text */ + --af-accent-hover: #845c00; + --af-accent-contrast: #ffffff; +} + +/* ---- Tailwind v4 adapter. Inert (ignored at-rule) without Tailwind. + Must be `inline`: utilities then emit var(--af-*) directly, so a + [data-flavor] override below :root still wins. Plain @theme would + resolve the var() once at :root and pin every flavor to forge. ---- */ +@theme inline { + --font-sans: var(--af-font-sans); + --font-mono: var(--af-font-mono); + + --color-axe-black: var(--af-bg); + --color-axe-navy: var(--af-surface); + --color-axe-line: var(--af-line); + --color-axe-muted: var(--af-text-muted); + --color-axe-accent: var(--af-accent); + --color-axe-accent-hover: var(--af-accent-hover); + --color-axe-accent-contrast: var(--af-accent-contrast); + + /* deprecated — old hub names; use axe-accent / axe-accent-hover */ + --color-axe-orange: var(--af-accent); + --color-axe-orange-hover: var(--af-accent-hover); +} + +/* ---- Base ---- */ +body { + background: var(--af-bg); + color: var(--af-text); + font-family: var(--af-font-sans); + -webkit-font-smoothing: antialiased; +} + +:focus-visible { + outline: 2px solid var(--af-accent); + outline-offset: 2px; +} + +/* ---- Components (vanilla CSS — no Tailwind required) ---- */ + +.technical-grid { + background-size: 80px 80px; + background-image: radial-gradient(circle, var(--af-line) 1px, transparent 1px); +} + +.glass-card { + background: color-mix(in srgb, var(--af-surface) 60%, transparent); + -webkit-backdrop-filter: blur(24px); + backdrop-filter: blur(24px); + border: 1px solid var(--af-line); + border-radius: var(--af-radius-lg); + transition: border-color 0.5s ease, box-shadow 0.5s ease; +} +.glass-card:hover { + border-color: color-mix(in srgb, var(--af-accent) 50%, transparent); +} + +.terminal-window { + background: var(--af-surface-2); + border: 1px solid var(--af-line); + border-radius: var(--af-radius); + overflow: hidden; + font-family: var(--af-font-mono); + font-size: 0.75rem; + line-height: 1.5; + box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.5); +} +.terminal-header { + background: var(--af-surface-3); + padding: 0.5rem 1rem; + display: flex; + align-items: center; + gap: 0.5rem; + border-bottom: 1px solid var(--af-line); +} + +/* macOS traffic lights — semantic, not brand; fixed hexes on purpose */ +.dot { width: 10px; height: 10px; border-radius: 9999px; } +.dot-red { background: #ff5f56; } +.dot-yellow { background: #ffbd2e; } +.dot-green { background: #27c93f; } + +.glow-accent, +.glow-orange /* deprecated alias */ { + box-shadow: 0 0 20px color-mix(in srgb, var(--af-accent) 15%, transparent); +} + +.axe-button { + display: inline-flex; + align-items: center; + gap: 0.5rem; + background: var(--af-accent); + color: var(--af-accent-contrast); /* never hardcode white — fails on circuit/flux/signal */ + padding: 0.75rem 1.5rem; + border: 0; + border-radius: var(--af-radius); + font-family: var(--af-font-sans); + font-size: 1.25rem; /* WCAG "large text" floor (18.66px+ bold) — forge's white-on-accent (3.31:1) only clears AA at large-text's 3:1, not body text's 4.5:1 */ + font-weight: 700; + cursor: pointer; + text-decoration: none; + transition: background 0.15s ease, transform 0.15s ease; +} +.axe-button:hover { background: var(--af-accent-hover); } +.axe-button:active { transform: scale(0.95); } diff --git a/web/favicon.png b/web/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..51e1c34ef4992ad655228a2054920cdf96db5a94 GIT binary patch literal 9475 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 literal 0 HcmV?d00001 diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..e4ece45 --- /dev/null +++ b/web/index.html @@ -0,0 +1,446 @@ + + + + + +InspectorBooster — ultra CSS/XPath inspector for QA engineers + + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+
Chrome extension for QA engineers
+

Stop guessing at CSS selectors.

+

+ Open the side panel, hover any element, and InspectorBooster ranks every + selector strategy it can find — testid, id, role, aria-label, + placeholder, class, CSS path, XPath, text — each scored 0-100 by + stability and uniqueness. Organize what you find into scopes and + aliases, record whole interaction flows, and export straight to + Playwright or Cypress. +

+ +
+ +
+
Live demo (simulated output, not a real page)
+
+
+ + inspect: <button data-testid="login-btn"> +
+
+
+
+
+
+ +
+
+
+
How it works
+

One inspection, every selector strategy

+

The content script generates all viable selectors for the element under your cursor, scores each one, and hands you the ranked list — not just the first one that happens to match.

+
+
+
+

Smart selector engine

+

Generates testid, id, role, aria-label, placeholder, class, CSS path, XPath, and text selectors for every element, each scored 0-100 by stability and uniqueness.

+
+
+

Missing testid tip

+

Flags elements that lack a data-testid attribute so flaky selectors get caught before they ship into a test suite.

+
+
+

Scopes and aliases

+

Organize elements into named, nestable scopes (Login Page, Header, Product List) and give them human-readable aliases, searchable by name, description, or tag.

+
+
+

Interaction recording

+

Captures clicks, inputs, keypresses, and navigation with full ranked selector options per step, then exports the whole flow as a test script.

+
+
+
+
+ +
+
+
+
Selector engine
+

Ranked by stability, not by luck

+

Every strategy gets a score for a unique match and a lower score for a non-unique one, so the panel can auto-select your preferred type on every click.

+
+
+ + + + + + + + + + + + +
StrategyTypeScore (unique/non-unique)Example
data-testidtestid98 / 78[data-testid="login-btn"]
#idid92 / 52#login-btn
Role + namerole88 / 65role=button[name="Sign In"]
aria-labelaria83 / 56button[aria-label="Close"]
placeholderplaceholder75 / 55input[placeholder="Search..."]
Class chaincss72 / 30-65button.btn.btn-primary
CSS pathcss62 / 35#login-form > div > button
Partial classcss58 / 38[class*="product-card"]
Text (exact)text44//button[normalize-space(.)="Sign In"]
Absolute XPathxpath28//html/body/div[1]/form/button[1]
+
+
+
+ +
+
+
+
Workflow
+

Four views, one panel

+
+
+
+
01
+

Inspect

+

Hover any element from the side panel to see its ranked selector options. Switch RAW / Playwright / Cypress display mode globally, and copy the formatted string ready to paste into test code.

+
+
+
02
+

Library

+

Save elements into scopes and give them aliases. Set a scope container selector and framework exports chain through it automatically: page.locator('[data-testid="card"]').getByTestId('buy-btn').

+
+
+
03
+

Record

+

Capture clicks, inputs, keypresses, and navigation with a live feed while recording. Rename, exclude, or swap the active selector on any step afterward.

+
+
+
04
+

Export

+

Six formats: JSON and YAML (scoped or flat map), plus Playwright .spec.ts and Cypress .cy.js. Preview before download, or paste JSON/YAML back in to import.

+
+
+
+
+ +
+
+
+
Use cases
+

Why QA engineers reach for InspectorBooster

+
+
+
+

"This selector will break on the next deploy"

+

Skip the class-name guesswork — the panel ranks the stable options first and warns when an element has no data-testid at all.

+
+
+

Writing a Playwright suite

+

Switch the display mode to PW and every copy is already formatted, from a simple click target to a full role query.

+ page.getByRole('button', { name: 'Sign In' }) +
+
+

Recording a login flow

+

Click through the flow once with recording on, then export the whole interaction straight to a Playwright spec.

+ login-flow.spec.ts +
+
+

Scoping a repeated component

+

Give a product card scope its own container selector, and every element inside exports chained through it — no duplicated boilerplate.

+ cy.get('[data-testid="card"]').find('[data-testid="buy-btn"]') +
+
+
+
+ +
+
+
+
Install
+

Load it as an unpacked extension

+
+
+
+ +
+

Build the extension

+
cd extension && npm install && npm run build
+
+
+
+ +

Open chrome://extensions and enable Developer mode

+
+
+ +

Load unpacked — select extension/dist/

+
+
+ +

Open the side panel — click the extension icon, or open it from the panel button

+
+
+ Full instructions on GitHub +
+
+ + + + + + diff --git a/web/robots.txt b/web/robots.txt new file mode 100644 index 0000000..952cbc9 --- /dev/null +++ b/web/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://axeforging.github.io/inspectorbooster/sitemap.xml diff --git a/web/sitemap.xml b/web/sitemap.xml new file mode 100644 index 0000000..cc3503f --- /dev/null +++ b/web/sitemap.xml @@ -0,0 +1,8 @@ + + + + https://axeforging.github.io/inspectorbooster/ + monthly + 1.0 + + From 98abd388cd37e7de82802e0b7d3a3c091ee66daf Mon Sep 17 00:00:00 2001 From: murilopmachado Date: Tue, 4 Aug 2026 21:04:06 +0200 Subject: [PATCH 2/2] fix: remove individual attribution from public credit Team credit should stay at the org level, not name a specific contributor -- more people than one work on AxeForging repos. --- web/index.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/index.html b/web/index.html index e4ece45..738df00 100644 --- a/web/index.html +++ b/web/index.html @@ -393,8 +393,7 @@

Load it as an unpacked extension