Every digital storefront is visible from the outside. Five public tools, one Python script, one benchmark. The composite tells you whether a brand's digital channel is a growth asset or a conversion leak.
Layered diagnostics are honest: no composite score hides a bad signal. Run each layer with its own tool, then read the composite. Each row below took ≤20 minutes per brand to capture.
| Layer | Diagnostic | Tool | What it measures | Time / brand |
|---|---|---|---|---|
| 01 | Funnel depth | Playwright | Clicks · friction flags · cart presence | 15 min |
| 02 | Technical performance | PageSpeed Insights + CrUX | Lighthouse mobile/desktop · Core Web Vitals | 2 API calls |
| 03 | Traffic efficiency | SimilarWeb-tier | Visits · bounce · session · paid mix | 1 lookup |
| 04 | Feature parity | Playwright + ScrapingBee | 18-feature rendered-DOM audit, regex-based | 20 min |
| 05 | Search visibility | SerpAPI | Organic + Google Shopping positions | 20–40 queries |
A headless Chromium walks each brand's path from homepage to checkout. The script counts every required click, flags friction (ZIP gates, dealer redirects, quote-form replacements), and records the configurator depth before "Add to Cart" enables.
from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page(viewport={"width": 1440, "height": 900}) # Walk: homepage → category → PDP → configure → cart page.goto("https://brand.com", wait_until="networkidle") page.click("text=Sofas") page.click(".product-card >> nth=0") # ... record every required interaction before Add to Cart enables # Flag if Add to Cart is absent (dealer redirect, ZIP gate, quote form)
Friction flags also captured: ZIP gate (price hidden behind a ZIP), dealer redirect (Add-to-Cart replaced by "Find a dealer"), login wall, quote form (no cart), configurator depth (count of required choices). Each is a board-level decision, not a UI bug.
PSI runs a single deterministic Lighthouse pass — useful for apples-to-apples lab comparison. CrUX gives 25 weeks of real-user Core Web Vitals. A brand that relaunched its site in 2023 shows a CrUX inflection point. A brand that's flat across 24 months hasn't invested.
def get_scores(url, strategy="mobile"): r = requests.get( "https://www.googleapis.com/pagespeedonline/v5/runPagespeed", params={"url": url, "strategy": strategy, "key": PSI_KEY}, ) audits = r.json()["lighthouseResult"]["audits"] return { "performance": audits["performance"]["score"] * 100, "lcp_ms": audits["largest-contentful-paint"]["numericValue"], "cls": audits["cumulative-layout-shift"]["numericValue"], "tbt_ms": audits["total-blocking-time"]["numericValue"], }
A $3B brand naturally gets more visits than a $300M brand. The honest signal is visits ÷ revenue ($M). Below: real SimilarWeb-tier data for ten furniture brands. Toggle the peer set — the medians and Bassett's percentile recompute live.
Each cell came from a rendered-DOM check — not a static-HTML scrape (which over-credits features that show up in framework chunks but never reach the user). Y = vendor signature matched (e.g. cylindo for AR/3D, Bazaarvoice for PDP reviews). P = weaker pattern. N = nothing detected in {home, category, PDP}.
deterministic Audit date 2026-04-30 · Each cell has a regex match + DOM snippet in the data bundle · 18 features ranked by category benchmark (Wayfair-defined customer expectations).
SerpAPI paginated 0–90 for organic ranks across pages 1–10, plus Google Shopping carousel positions. A brand absent from "sofa under $2,000" or "best dining table 2026" depends entirely on paid traffic to reach unaware buyers.
Stack the five layers on a single $450M, 100-year-old furniture manufacturer. The diagnostic surfaces a non-obvious story: features are fine; the storefront isn't broken. The gap is upper-funnel — acquisition, engagement, and the unstaffed top of the funnel.
Bassett ships 10 of 18 modern e-commerce features — above the peer median of 8. The infrastructure is adequate; the configurator is real; AR (Cylindo) and 3D viewers ship on every sofa PDP. The earlier "the legacy brand neglected features" narrative was wrong.
What's missing is upstream: 22% of peer median monthly traffic, a session length half the peer median, and a paid-traffic mix one-third of peer leaders. Each of those is a board-level allocation choice — not a developer-level accident. The diagnostic isn't a UX score. It's a capital-allocation x-ray.
What's expensive about competitive intelligence isn't access — it's framing. Knowing that funnel click count is the single most predictive variable, that visits-per-$M revenue is the right normalization (not raw visits), that lab data and field data tell different stories. The tools below are what we ran. The full data bundle includes the source xlsx and the detection JSON.
Headless Chromium that walks the funnel and counts every required click. Pure Python, runs overnight on a single machine.
playwright.dev →Lighthouse lab scores — performance, LCP, CLS, TBT in one call. Free (PSI_API_KEY, 25k req/day).
pagespeed.web.dev →Real-user Core Web Vitals — 28-day field data. 25-week history available via CrUX History API. Free.
developer.chrome.com/docs/crux →Visits, bounce rate, session duration, traffic-source mix. Public estimates carry ±20% noise on small sites — flagged as such.
similarweb.com →Programmatic Google results — organic + Shopping carousel + paid presence. ~$50/mo for ≤5k requests.
serpapi.com →Wrote the scrapers, the scoring rubric, the orchestration glue, and the audit reconciliation. The diagnostic took two evenings end-to-end.
claude.com/product/claude-code →Original xlsx for E1–E4, the merged JSON the site reads, and a methodology README. CC BY 4.0 — use it, audit it, run it on your own category.