Developer-first ad diagnostics and logging toolkit for auditing live ad iframe behavior in real time.
Note
This repository currently ships as a Chrome Extension package. While this README frames the project as a logging-oriented diagnostics library, the runtime distribution is extension-based and executes in-browser through the Chrome Extensions API.
- Features
- Tech Stack & Architecture
- Getting Started
- Testing
- Deployment
- Usage
- Configuration
- License
- Support the Project
- Live DOM scanning for
iframe-based ad inventory on the active tab. - Heuristic ad-source detection based on known ad-serving domains:
- Google ad stack (
doubleclick.net,googlesyndication). - Header bidding / SSP indicators (
adnxs,rubicon,criteo).
- Google ad stack (
- Ad-slot shape heuristics for common display formats (for example
300x250,728x90). - Visual ad-slot marking with high-contrast border overlays for rapid debugging.
- Inline per-page metrics for:
- Total detected ad units.
- Google-attributed units.
- Prebid/header-bidding-attributed units.
- Popup-driven one-click execution model (
SCAN PAGE) for low-friction diagnostics. - Chrome Manifest V3-compatible architecture with least-privilege permissions (
activeTab,scripting). - Lightweight, dependency-free JavaScript implementation suitable for fast iteration.
Tip
Use this extension during QA sessions, ad tag migration rollouts, and demand-partner onboarding checks to quickly validate inventory rendering behavior without backend log access.
- Language: JavaScript (ES6)
- Runtime Model: Chrome Extension (Manifest V3)
- UI Layer: Static popup (
HTML,CSS) + event-driven script injection - APIs:
chrome.tabs.query(resolve active browser tab)chrome.scripting.executeScript(inject scanner logic into page context)
- Assets: Static extension icon and popup UI
AdOps-X-Ray/
├── content.js # In-page scanner logic prototype / helper function
├── popup.html # Extension popup user interface
├── popup.js # Popup controller and scanner injection pipeline
├── manifest.json # Extension metadata, permissions, and entrypoints
├── icons/
│ └── icon128.png # Extension icon asset
├── LICENSE # Open-source license
└── README.md # Project documentation
-
DOM-first diagnostics model
- The scanner inspects rendered elements directly instead of relying on network-only telemetry.
- This ensures you measure what the end user browser actually paints.
-
Heuristic detection strategy
- Source detection combines domain matching and slot-size checks.
- This balances implementation simplicity with practical debugging coverage.
-
Client-side visual logging
- Ad slots are highlighted in-place for immediate, human-verifiable feedback.
- Popup counters act as lightweight telemetry summaries.
-
Manifest V3 security baseline
- Uses scoped permissions and script injection via
chrome.scripting, aligned with modern Chrome extension constraints.
- Uses scoped permissions and script injection via
flowchart LR
A[User clicks SCAN PAGE] --> B[popup.js event handler]
B --> C[chrome.tabs.query active tab]
C --> D[chrome.scripting.executeScript]
D --> E[runScanner in page context]
E --> F[Collect iframe heuristics and counts]
F --> G[Apply visual highlight to detected ads]
G --> H[Return total/google/prebid metrics]
H --> I[Render counters in popup UI]
Important
Detection is heuristic-based and should be treated as an operational aid, not a source-of-truth billing/auditing system.
- Google Chrome (current stable version recommended)
- Access to
chrome://extensions - A target website containing display ad iframes for validation
- Optional local tooling for validation checks:
Node.js18+ (for JavaScript syntax checks)Python3.8+ (for JSON validation command)
- Clone the repository:
git clone https://github.com/<your-org>/AdOps-X-Ray.git
cd AdOps-X-Ray- Open Chrome extensions management:
chrome://extensions
- Enable Developer mode.
- Click Load unpacked.
- Select the repository root containing
manifest.json. - Pin AdOps X-Ray to your toolbar for faster access.
Warning
The extension requires a real browser context and cannot be validated fully via headless static analysis alone.
This project currently uses lightweight validation and manual QA instead of a full automated test harness.
python3 -m json.tool manifest.json > /dev/null
node --check popup.js
node --check content.js- Load extension in Developer Mode.
- Open a page with known ad iframes.
- Click SCAN PAGE in popup.
- Validate:
- Red borders appear on detected ad frames.
- Popup stats update (
Ad Units Found,Google Ads,Prebid/Header Bidding).
If you initialize Node tooling locally, add ESLint and run:
npm install --save-dev eslint
npx eslint .Caution
False positives/negatives are possible because ad ecosystems and iframe embedding patterns vary across publishers.
Because this project is packaged as a Chrome Extension, deployment typically means release packaging and browser distribution.
- Ensure
manifest.jsonversion is incremented. - Validate syntax and manifest format.
- Package repository contents for release artifact storage (excluding local tooling directories).
zip -r adops-xray-v1.0.0.zip . -x '*.git*' 'node_modules/*'In your CI pipeline, run at minimum:
python3 -m json.tool manifest.json > /dev/null
node --check popup.js
node --check content.jsOptional CI enhancements:
- Run
npx eslint .with a shared config. - Enforce version tagging from
manifest.json. - Publish signed extension artifacts per release tag.
- Navigate to a publisher page.
- Click the extension icon.
- Trigger
SCAN PAGE. - Interpret counters and on-page highlights.
// File: popup.js (injected function)
function runScanner() {
const frames = document.getElementsByTagName("iframe");
let adCount = 0;
let googleCount = 0;
let prebidCount = 0;
for (let i = 0; i < frames.length; i++) {
const frame = frames[i];
const src = frame.src || "";
const isAd =
src.includes("doubleclick.net") ||
src.includes("googlesyndication") ||
src.includes("adnxs") ||
(frame.width == 300 && frame.height == 250) ||
(frame.width == 728 && frame.height == 90);
if (isAd) {
adCount++;
if (src.includes("google")) googleCount++;
if (src.includes("adnxs") || src.includes("rubicon")) prebidCount++;
// Visual diagnostic marker in the DOM.
frame.style.border = "4px solid red";
}
}
return { total: adCount, google: googleCount, prebid: prebidCount };
}chrome.scripting.executeScript(
{
target: { tabId: tab.id },
function: runScanner,
},
(results) => {
if (results && results[0] && results[0].result) {
const data = results[0].result;
document.getElementById("adCount").innerText = data.total;
document.getElementById("googleCount").innerText = data.google;
document.getElementById("prebidCount").innerText = data.prebid;
}
}
);This extension has no .env file or external runtime config by default. Configuration is code-centric and manifest-centric.
manifest_version: Extension spec version (3).name,version,description: Extension identity metadata.permissions:activeTab: Access active tab context after user interaction.scripting: Script injection capability.
action.default_popup: Popup UI entrypoint.icons,action.default_icon: Branding assets.
In popup.js and/or content.js, tune these values:
- Domain indicators:
doubleclick.netgooglesyndicationadnxsrubiconcriteo
- Slot-size indicators:
300x250728x90
- Visual overlays:
- Border color/thickness
- Optional label injection behavior
No CLI startup flags are currently exposed because execution is UI-triggered via popup interaction.
Note
If you need enterprise-grade configurability, introduce a persistent settings layer using chrome.storage.sync and a dedicated options page.
This project is licensed under the MIT License. See the LICENSE file for full terms.
If you find this tool useful, consider leaving a star on GitHub or supporting the author directly.