____ _ _
| _ \ _ __ ___ __ _ _ __ __ _ _ __ ___ _ __ ___ __ _| |_(_) ___
| |_) | '__/ _ \ / _` | '__/ _` | '_ ` _ \| '_ ` _ \ / _` | __| |/ __|
| __/| | | (_) | (_| | | | (_| | | | | | | | | | | | (_| | |_| | (__
|_| |_| \___/ \__, |_| \__,_|_| |_| |_|_| |_| |_|\__,_|\__|_|\___|
|___/
_ _
/ \ __| | ___ ___ __ _ _ __ _ __ ___ _ __
/ _ \ / _` |_____/ __|/ __/ _` | '_ \| '_ \ / _ \ '__|
/ ___ \ (_| |_____\__ \ (_| (_| | | | | | | | __/ |
/_/ \_\__,_| |___/\___\__,_|_| |_|_| |_|\___|_|
A developer-first ad diagnostics and logging extension for inspecting live ad slots, SSP integrations, and runtime ad-tech signals directly in the browser.
- Features
- Tech Stack \& Architecture
- Getting Started
- Testing
- Deployment
- Usage
- Configuration
- License
- Contacts \& Community Support
- Real-time, in-page ad inventory scanning across
iframeand ad container elements. - Source classification against curated ad-server and SSP domain signatures:
- Google stack (
doubleclick,googlesyndication,googletagservices, etc.) - Header bidding ecosystems (Prebid-linked exchanges and adapters)
- Amazon APS
- Facebook, Taboola, and Outbrain signals
- Google stack (
- IAB standard size recognition (16 common ad dimensions), including fallback dimension extraction from bounding rectangles.
- Automatic ad container discovery using ad-focused CSS selectors (
div-gpt-ad,adsbygoogle,data-ad-slot, and similar patterns). - Runtime ad-tech signal detection from page globals:
- GPT and version
- Prebid.js and version
- Amazon APS
- AdSense
- Google Analytics /
gtag/dataLayer
- Visual instrumentation overlays with category-aware highlighting and top-left labels.
- Popup dashboard with:
- category counters
- detected technology chips
- truncated detected-unit list for quick triage
- Safe execution model that blocks scanner actions on restricted URLs (Chrome internal pages, extension pages, Web Store,
file://, etc.). - One-click cleanup workflow to remove all injected markers and style tags.
- Modular ES module codebase with clear separation between scanning logic and popup rendering logic.
Important
AdOps X-Ray executes scans in the active tabβs main world using chrome.scripting.executeScript, and only when URLs pass explicit allowability checks.
- Language: JavaScript (ES Modules)
- Runtime Target: Chrome Extension, Manifest V3
- UI Layer: Popup HTML/CSS/JS
- Static Analysis: ESLint (
^8.57.0) - Packaging: Native
zip-based artifact creation (adops-xray.zip)
ad-inspector-devtools/
βββ core/
β βββ constants.js # Signatures, selectors, styles, categories
β βββ detector.js # Pure detection/classification helpers
β βββ scanner.js # In-page scan + clear executables
βββ ui/
β βββ popup/
β βββ popup.html # Extension popup markup
β βββ popup.css # Popup styling and state visuals
β βββ popup.js # Popup controller and script injection flow
β βββ renderer.js # Result rendering, chips, and list formatting
βββ icons/
β βββ icon128.png
βββ manifest.json # MV3 metadata and permissions
βββ package.json # Scripts and dev dependencies
βββ .eslintrc.json # Linting rules
βββ README.md
- Detection first, UI second: ad classification and size matching are implemented as reusable pure helpers (
detector.js) to keep core logic testable and composable. - Non-invasive instrumentation: highlighting is done via temporary classes plus a dedicated style tag for deterministic cleanup.
- Fail-soft behavior: scanner and signal detection use defensive guards to avoid hard failures on restricted/cross-context access.
- Controlled DOM scope: a
WeakSettracks processed nodes to prevent duplicate counting during scans. - Operational safety: explicit URL restrictions prevent execution where browser policy disallows or where behavior would be ambiguous.
flowchart TD
A[User clicks Scan Page] --> B[Popup controller validates active tab URL]
B -->|Allowed| C[Inject runScannerInPage into MAIN world]
B -->|Restricted| R[Render blocked status]
C --> D[Inject highlight styles and clear stale markers]
D --> E[Scan iframes and classify source + size]
E --> F[Scan known ad container selectors]
F --> G[Detect ad-tech runtime signals]
G --> H[Return structured payload]
H --> I[Render counts, signal chips, and detected units]
Note
The scanner intentionally caps rendered units in the popup list to keep UI response time predictable on ad-heavy pages.
Google Chromeor another Chromium browser supporting extension developer modeNode.js18+ (recommended)npm9+ (recommended)
- Clone the repository:
git clone https://github.com/<your-org>/ad-inspector-devtools.git
cd ad-inspector-devtools- Install development dependencies:
npm install- Load the extension in Chrome:
chrome://extensions -> Enable Developer mode -> Load unpacked -> select repository root
- Pin
AdOps X-Rayfor quick access from the toolbar.
Tip
Keep DevTools open on the active tab while scanning to cross-check network activity and global runtime objects (window.pbjs, window.googletag, etc.).
Run the following commands from the repository root:
npm run validate:manifest
npm run validate:js
npm run validate
npm run lintvalidate:manifest: parses and validatesmanifest.jsonsyntax.validate:js: performs syntax checks on scanner, detector, constants, and popup modules.validate: full validation chain (manifest+jschecks).lint: ESLint-based quality checks for the source tree.
Warning
There is currently no dedicated unit/integration test harness (e.g., Jest/Vitest) in this repository. Validation relies on syntax and lint checks plus manual browser verification.
Create a distributable zip package:
npm run packageThis generates adops-xray.zip containing manifest.json, icons/, and source directories.
- Run validation and lint gates before packaging.
- Build the zip artifact.
- Smoke-test the unpacked extension and packaged artifact in a clean browser profile.
- Publish via your internal distribution channel or Chrome Web Store pipeline.
A minimal pipeline stage order:
npm cinpm run validatenpm run lintnpm run package- Upload
adops-xray.zipas a pipeline artifact
Caution
Do not publish builds that skip restricted-URL checks; those guards prevent common policy and runtime violations in browser extension environments.
- Open a target publisher page.
- Click the extension icon.
- Press
Scan Page. - Review counts, detected ad-tech signals, and unit list.
- Press
Clearto remove overlays.
import { runScannerInPage } from "./core/scanner.js";
// Executed in page context (via chrome.scripting in popup controller)
const result = runScannerInPage();
if (result.success) {
console.log("Total detected ad units:", result.counts.total); // Category totals
console.log("Signals:", result.signals); // GPT / Prebid / APS / Analytics flags
console.log("Units:", result.detectedUnits); // Individual unit metadata
} else {
console.error("Scan failed:", result.error);
}import { runClearInPage } from "./core/scanner.js";
const clearResult = runClearInPage();
if (!clearResult.success) {
console.warn("Failed to remove markers:", clearResult.error);
}AdOps X-Ray is intentionally zero-config at runtime, but behavior is driven by internal constants and manifest settings.
- Permissions:
activeTabscriptingstorage
- Popup entry point:
ui/popup/popup.html - Manifest version:
3
Managed in core/constants.js:
AD_SERVER_SIGNATURES: domain fragments for source/category classification.IAB_STANDARD_SIZES: canonical width/height pairs and human-readable labels.AD_CONTAINER_SELECTORS: CSS selectors used for non-iframe container detection.DETECTION_CATEGORIES: normalized category namespace.HIGHLIGHT_STYLES,MARKER_CLASS,LABEL_CLASS,STYLE_TAG_ID: overlay visualization contract.
Managed in ui/popup/popup.js:
RESTRICTED_URL_PATTERNS: regex list that blocks scans on unsupported URLs.
- No
.envfile is used. - No runtime environment variables are required.
- No CLI startup flags are required for extension execution.
This project is released under the MIT License. See LICENSE for full legal terms.
If you find this tool useful, consider leaving a star on GitHub or supporting the author directly.
