localhost because that is where
the practice site runs. Nothing here is a real shop, and no real site was
scanned to make this page.
Two things read oddly precisely because the target is a local
practice site, and they are worth knowing before you run this on your own:
Domain authority and Performance are empty because both rate a
public domain — there is nothing for them to measure on localhost
(authority also wants a free OpenPageRank key). And every page scores
100 on PageRank because this little site links every page to every
other one, so the graph is perfectly symmetric; on a real site the scores
spread out and the ranking becomes meaningful.
linkgraph.json and linkgraph-edges.csv.This file should not be served to the internet. It usually gets exposed by deploying the whole working directory.
http://localhost:8099/.env
{
"status": 200,
"excerpt": "DB_PASSWORD=hunter2\nAPI_KEY=sk-test-123\n"
}This page is linked from the site but does not load successfully.
http://localhost:8099/broken
{
"status": 500
}A JavaScript exception was raised as a direct result of clicking this control, so the feature behind it is broken.
http://localhost:8099/
#boom
{
"message": "window.missingFunction is not a function",
"stack": "TypeError: window.missingFunction is not a function\n at HTMLButtonElement.<anonymous> (http://localhost:8099/:24:10)",
"control_html": "<button id=\"boom\">Show offers</button>"
}A sub-request returned HTTP 500 while loading this page. A 5xx means the server itself errored.
http://localhost:8099/
{
"request_url": "http://localhost:8099/api/offers",
"status": 500,
"method": "GET",
"resource_type": "fetch"
}All traffic, including anything typed into a form, is unencrypted and browsers will label the site 'Not secure'.
http://localhost:8099/
A link on the site points to a URL that answers 500.
http://localhost:8099/
{
"target": "http://localhost:8099/broken",
"status": 500,
"link_text": "Broken",
"found_on": [
"http://localhost:8099/",
"http://localhost:8099/about",
"http://localhost:8099/contact",
"http://localhost:8099/does-not-exist",
"http://localhost:8099/hidden-offer",
"http://localhost:8099/login",
"http://localhost:8099/pricing",
"http://localhost:8099/slow"
]
}The <img> resolved to a URL the browser could not render.
http://localhost:8099/
html > body > img:nth-of-type(1)
{
"images": [
{
"src": "http://localhost:8099/img/missing-photo.png",
"selector": "html > body > img:nth-of-type(1)"
}
]
}The browser's own required-field check was removed and the same empty submission was then accepted by the server. Anyone using a script, a modified page or an old browser can post empty/garbage records.
http://localhost:8099/pricing
#nl
{
"required_fields": [
"email"
],
"final_url": "http://localhost:8099/subscribe-newsletter"
}Text that should never reach production is rendered on the page.
http://localhost:8099/
{
"excerpt": "k This block is 1500px wide and overflows on mobile. Status: undefined"
}No navigation, no network request and no message appeared. The form looks non-functional.
http://localhost:8099/pricing
#noop
{
"fields": [
"promo"
]
}A sub-request returned HTTP 404 while loading this page. The resource is missing or forbidden.
http://localhost:8099/
{
"request_url": "http://localhost:8099/img/missing-photo.png",
"status": 404,
"method": "GET",
"resource_type": "image"
}A sub-request returned HTTP 404 while loading this page. The resource is missing or forbidden.
http://localhost:8099/team
{
"request_url": "http://localhost:8099/img/team.png",
"status": 404,
"method": "GET",
"resource_type": "image"
}TesterBot submitted the literal text '<b>TBQA7</b>' and the page rendered it as a real bold element instead of showing it as text. Anything a user types can therefore inject markup into the page.
http://localhost:8099/contact
html > body > form
{
"submitted": "<b>TBQA7</b>",
"rendered_back_as": "<b>TBQA7</b>"
}Screen-reader users get no description; broken images show nothing.
http://localhost:8099/
html > body > img:nth-of-type(1)
{
"images": [
{
"src": "http://localhost:8099/img/missing-photo.png",
"selector": "html > body > img:nth-of-type(1)"
}
]
}Icon-only or empty links are announced as 'link' with no context.
http://localhost:8099/
html > body > a:nth-of-type(2)
{
"links": [
{
"href": "http://localhost:8099/team",
"selector": "html > body > a:nth-of-type(2)"
}
]
}Text that should never reach production is rendered on the page.
http://localhost:8099/team
{
"excerpt": "m ContactPricingBroken SlowLogin Dead link Team Engineering Lorem ipsum dolor sit amet, consectetur adipiscing elit."
}None of the inputs are marked required, so a completely empty submission is accepted by the browser.
http://localhost:8099/login
html > body > form
{
"fields": [
"user",
"pass"
]
}A deliberately invalid path returned a normal 200 response. Search engines index junk pages and monitoring cannot tell real pages from typos.
http://localhost:8099/testerbot-does-not-exist-9f2c1a
{
"status": 200
}Time to first byte is dominated by server work, not the browser.
http://localhost:8099/slow
{
"load_ms": 2011,
"dom_ready_ms": 2011,
"ttfb_ms": 2003,
"transfer_kb": 1
}Content is 1524px wide in a 390px viewport, so the user has to scroll sideways. Usually one element with a fixed width or an unwrapped table.
http://localhost:8099/
{
"viewport_width": 390,
"content_width": 1524,
"overflow_px": 1134,
"widest_elements": [
{
"selector": "div.wide",
"width": 1500,
"right": 1524,
"text": "This block is 1500px wide and overflows on mobile."
}
]
}Content is 1524px wide in a 820px viewport, so the user has to scroll sideways. Usually one element with a fixed width or an unwrapped table.
http://localhost:8099/
{
"viewport_width": 820,
"content_width": 1524,
"overflow_px": 704,
"widest_elements": [
{
"selector": "div.wide",
"width": 1500,
"right": 1524,
"text": "This block is 1500px wide and overflows on mobile."
}
]
}Ensure all page content is contained by landmarks
http://localhost:8099/
{
"rule": "region",
"impact": "moderate",
"elements_affected": 7,
"examples": [
{
"target": "h1",
"html": "<h1>Buggy Demo Shop</h1>",
"summary": "Fix any of the following:\n Some page content is not contained by landmarks"
},
{
"target": "p:nth-child(4)",
"html": "<p>Everything on this page is broken on purpose.</p>",
"summary": "Fix any of the following:\n Some page content is not contained by landmarks"
},
{
"target": "img[src$=\"missing-photo.png\"]",
"html": "<img src=\"/img/missing-photo.png\" width=\"120\" height=\"80\">",
"summary": "Fix any of the following:\n Some page content is not contained by landmarks"
},
{
"target": "img[src$=\"logo.png\"]",
"html": "<img src=\"/img/logo.png\" alt=\"Logo\" width=\"60\" height=\"60\">",
"summary": "Fix any of the following:\n Some page content is not contained by landmarks"
},
{
"target": "a[target=\"_blank\"]",
"html": "<a href=\"https://example.com/definitely-missing-page-xyz\" target=\"_blank\">External broken link</a>",
"summary": "Fix any of the following:\n Some page content is not contained by landmarks"
},
{
"target": "div",
"html": "<div class=\"wide\">This block is 1500px wide and overflows on mobile.</div>",
"summary": "Fix any of the following:\n Some page content is not contained by landmarks"
}
],
"reference": "https://dequeuniversity.com/rules/axe/4.10/region?application=axeAPI"
}Ensure the document has a main landmark
http://localhost:8099/
{
"rule": "landmark-one-main",
"impact": "moderate",
"elements_affected": 1,
"examples": [
{
"target": "html",
"html": "<html lang=\"en\">",
"summary": "Fix all of the following:\n Document does not have a main landmark"
}
],
"reference": "https://dequeuniversity.com/rules/axe/4.10/landmark-one-main?application=axeAPI"
}Search engines will invent a snippet for this page.
http://localhost:8099/about
The placeholder disappears as soon as the user types, so the field loses its description.
http://localhost:8099/pricing
#noop > input
{
"fields": [
{
"selector": "#noop > input",
"type": "text",
"name": "promo",
"placeholderOnly": true
}
]
}Duplicate titles hurt search results and make browser tabs ambiguous.
http://localhost:8099/about
{
"pages": [
"http://localhost:8099/about",
"http://localhost:8099/team"
]
}Ensure the order of headings is semantically correct
http://localhost:8099/team
{
"rule": "heading-order",
"impact": "moderate",
"elements_affected": 1,
"examples": [
{
"target": "h4",
"html": "<h4>Engineering</h4>",
"summary": "Fix any of the following:\n Heading order invalid"
}
],
"reference": "https://dequeuniversity.com/rules/axe/4.10/heading-order?application=axeAPI"
}A link on the site points to a URL that answers 403. (external site)
http://localhost:8099/
{
"target": "https://example.com/definitely-missing-page-xyz",
"status": 403,
"link_text": "External broken link",
"found_on": [
"http://localhost:8099/"
]
}After clicking, the URL, the DOM, the network and the console were all unchanged. Either the handler is missing or the effect is invisible (e.g. copy-to-clipboard). Worth a manual look.
http://localhost:8099/
#dead
{
"html": "<button id=\"dead\">Click me</button>"
}After clicking, the URL, the DOM, the network and the console were all unchanged. Either the handler is missing or the effect is invisible (e.g. copy-to-clipboard). Worth a manual look.
http://localhost:8099/
html > body > button:nth-of-type(3)
{
"html": "<button aria-hidden=\"false\"><span class=\"icon\">☰</span></button>"
}No top-level heading was found in the rendered page.
http://localhost:8099/team
target="_blank" without rel="noopener" lets the opened page reach back through window.opener in older browsers.
http://localhost:8099/
html > body > a:nth-of-type(1)
{
"links": [
{
"href": "https://example.com/definitely-missing-page-xyz",
"selector": "html > body > a:nth-of-type(1)"
}
]
}The site does not send the Content-Security-Policy response header.
http://localhost:8099/
{
"present_headers": [
"content-length",
"content-type",
"date",
"server"
]
}The site does not send the X-Content-Type-Options response header.
http://localhost:8099/
{
"present_headers": [
"content-length",
"content-type",
"date",
"server"
]
}The site does not send the X-Frame-Options response header.
http://localhost:8099/
{
"present_headers": [
"content-length",
"content-type",
"date",
"server"
]
}e.g. an H2 is followed directly by an H4, which confuses screen-reader navigation.
http://localhost:8099/team
{
"skips": [
{
"from": 2,
"to": 4,
"text": "Engineering"
}
]
}http://localhost:8099/
Links shared on social media / chat apps will have no preview.
http://localhost:8099/
The site does not send the Referrer-Policy response header.
http://localhost:8099/
{
"present_headers": [
"content-length",
"content-type",
"date",
"server"
]
}Server/X-Powered-By reveals: BaseHTTP/0.6 Python/3.11.15
http://localhost:8099/
{
"server": "BaseHTTP/0.6 Python/3.11.15",
"x_powered_by": ""
}TesterBot avoids controls that look like delete / pay / logout so it cannot damage real data. Re-run with --danger-mode on a staging copy to include them.
http://localhost:8099/pricing
html > body > button
{
"html": "<button>Delete my account</button>"
}| URL | Title | Status | Load | Links | Clicks | Forms | Findings |
|---|---|---|---|---|---|---|---|
| http://localhost:8099/ | Buggy Demo Shop | 200 | 60 ms | 11 | 3 | 0 | 21 |
| http://localhost:8099/about | Company | 200 | 11 ms | 9 | 0 | 0 | 3 |
| http://localhost:8099/hidden-offer | Secret Offer | 200 | 13 ms | 9 | 0 | 0 | 3 |
| http://localhost:8099/pricing | Pricing | 200 | 13 ms | 9 | 0 | 2 | 7 |
| http://localhost:8099/team | Company | 200 | 56 ms | 9 | 0 | 0 | 10 |
| http://localhost:8099/contact | Contact us | 200 | 10 ms | 9 | 0 | 1 | 6 |
| http://localhost:8099/broken | 500 | — | 0 | 0 | 0 | 1 | |
| http://localhost:8099/slow | Slow page | 200 | 2011 ms | 9 | 0 | 0 | 4 |
| http://localhost:8099/login | Login | 200 | 13 ms | 9 | 0 | 1 | 4 |
| http://localhost:8099/does-not-exist | Not found | 200 | 12 ms | 9 | 0 | 0 | 3 |