feat(places): ItemList and BreadcrumbList, and the e2e gate
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 18s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 36s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 4m33s
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 18s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 36s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 4m33s
ItemList tells Google the page is a ranked set rather than prose; BreadcrumbList puts the place in a hierarchy. School URLs in the markup are absolute on the canonical host, since a relative URL in JSON-LD is ambiguous. Eight journeys covering all four families, the two-namespace guarantee, the threshold, the canonical, the sitemap and the local-versus-England line — the last because that comparison is the reason these pages are not a name dropped into a template. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
This commit is contained in:
1 parent
c981d89137
commit
6b871ce1e9
3 files changed
+140
No files matched your search
@@ -68,3 +68,26 @@ describe('PlaceView', () => {
|
||||
expect(screen.queryByTestId('local-vs-england')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('PlaceView structured data', () => {
|
||||
function jsonLd() {
|
||||
const { container } = render(<PlaceView detail={detail} phase="primary"
|
||||
englandAverage={61} neighbours={[]} />);
|
||||
const el = container.querySelector('script[type="application/ld+json"]');
|
||||
return JSON.parse(el!.textContent!);
|
||||
}
|
||||
|
||||
it('declares the page as a ranked list, not prose', () => {
|
||||
const types = jsonLd()['@graph'].map((n: { '@type': string }) => n['@type']);
|
||||
expect(types).toContain('ItemList');
|
||||
expect(types).toContain('BreadcrumbList');
|
||||
});
|
||||
|
||||
it('gives every listed school an absolute URL on the canonical host', () => {
|
||||
const list = jsonLd()['@graph'].find((n: { '@type': string }) => n['@type'] === 'ItemList');
|
||||
expect(list.itemListElement).toHaveLength(2);
|
||||
for (const item of list.itemListElement) {
|
||||
expect(item.url).toMatch(/^https:\/\/www\.schoolcompare\.co\.uk\/school\//);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user