Files
vue-seo-layer/testing/expect-seo.txt
Jakub Zych aee6957bd6 feat: HTML sitemap pages and footer link
- the module registers seo-sitemap-<locale> at seo.htmlSitemap.paths
  (defaults pl /mapa-strony, en /sitemap) and seo-sitemap-group-<locale>
  at <path>/:group (plus <path>/:group/<segment>/:page in the path form);
  a path an app page already has stays the app's
- SeoHtmlSitemapPage (global, overridable): H1, an H2 per non-empty
  group, categories nested, a large group's link to its group page,
  sitemap.empty; group pages with a built trail, page suffix and
  <SeoPagination>; 404 for an unknown group or a page past the last,
  301 for ?page=1, 503 when the sitemap API fails
- GET /api/__seo__/sitemap proxies the sitemap plugin's HTML API (only
  while the CMS has the HTML sitemap on for the locale)
- <SeoSitemapLink>: the footer link while the HTML sitemap is on
- L3 default styles
2026-11-04 12:00:00 +01:00

128 lines
8.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SSR expectations of the SEO layer's v0.2.0 features against the fixture
# SEO API (testing/fixtures, answers in testing/fixtures/seo). Grammar in
# testing/smoke-ssr.mjs. testing/expect.txt keeps the v0.1.1 behaviour and
# runs against a backend without /site (--no-site).
# Tracer: a page rendered by Nuxt carries the CMS title, canonical, hreflang
# and one JSON-LD graph from the resolve answer.
200 /blog/lwia-grzywa contains=<title>Lwia grzywa | Example</title> count=application/ld+json:1 count=rel="canonical":1 contains=hreflang="x-default" contains=lang="pl"><head>
200 /blog/lwia-grzywa contains=<link rel="alternate" hreflang="en" href="https://example.test/en/blog/lions-mane" contains=hreflang="pl"
200 /blog/lwia-grzywa contains=<meta property="og:locale" content="pl_PL"> contains=<meta property="og:locale:alternate" content="en_US">
200 /blog/lwia-grzywa notcontains=Own catch-all title
# One graph: the CMS nodes, the layer's node merged by @id (CMS values win),
# a new layer node appended; "<" inside the JSON cannot end the script.
200 /blog/lwia-grzywa count=data-hid="seo-jsonld":1 count="@type":"WebPage":1 contains="name":"Lwia grzywa" notcontains=Layer name loses contains="inLanguage":"pl" contains=#itemlist
200 /blog/lwia-grzywa notcontains=</script><script>alert
# Redirect decision before the page (and its route cache): the Location
# comes from the answer only; a target on the site's origin becomes a path,
# another host stays absolute; a crafted Host or X-Forwarded-Host changes
# nothing. No X-Robots-Tag on a redirect.
301 /stary header=Location: /nowy noheader=X-Robots-Tag
301 /stary reqheader=Host: evil.test reqheader=X-Forwarded-Host: evil.test reqheader=X-Forwarded-Proto: http header=Location: /nowy
302 /stary-zewnetrzny header=Location: https://partner.test/oferta?a=1
# 410 with the app's error page, also on staging with the noindex header.
410 /usuniety
410 /usuniety-staging header=X-Robots-Tag: noindex, nofollow
# A page's x_robots_tag becomes the header.
200 /blog/ukryty header=X-Robots-Tag: noindex, nofollow contains=<meta name="robots" content="noindex, nofollow">
# not_found: a pagination.invalid answer is a 404 (also on a page that would
# render); any other not_found is left to Nuxt's routing.
404 /plain?page=abc
200 /plain?page=2 contains=<title>Plain page | Playground</title>
404 /nieznana-strona
# The resolve cache: every request above to the tracer page made one call.
resolves /blog/lwia-grzywa 1
resolves /stary 1
# The Nuxt-server resolve route answers through the same cache.
200 /api/__seo__/resolve?url=/blog/lwia-grzywa contains="title":"Lwia grzywa | Example" header=X-Robots-Tag: noindex
resolves /blog/lwia-grzywa 1
422 /api/__seo__/resolve?url=https://evil.test/
# Root files from the backend, with its status, content type and
# X-Robots-Tag; a backend failure is 503 with Retry-After.
200 /robots.txt contains=Disallow: /konto type=text/plain header=X-Content-Type-Options: nosniff
200 /sitemap.xml contains=<sitemapindex type=application/xml
200 /sitemap-posts-1.xml contains=<urlset type=application/xml header=X-Robots-Tag: noindex
200 /llms.txt contains=Fixture llms.txt header=X-Robots-Tag: noindex
404 /sitemap-missing-1.xml
503 /sitemap-fail-1.xml header=Retry-After: 60
# Listed root files: a verification file and the IndexNow key file.
200 /google1234.html contains=google-site-verification: google1234.html header=X-Robots-Tag: noindex header=X-Content-Type-Options: nosniff
200 /a1b2c3d4e5f60718293a4b5c6d7e8f90.txt contains=a1b2c3d4e5f60718293a4b5c6d7e8f90 type=text/plain
# Not listed: passes through to Nuxt, which renders its 404 (the route
# middleware resolves it; no verification lookup is made).
404 /random.txt
404 /google0123.html
404 /kontakt
# 404 pages report themselves once with the bearer token; a 410 or a
# redirect does not.
report /kontakt
report /nieznana-strona
noreport /usuniety
noreport /stary
# Labels in the page's content locale (pl answer: the pl dictionary).
200 /blog/lwia-grzywa contains=<p class="seo-visually-hidden">Ścieżka nawigacji</p>
# Declared noindex without page code: a page whose meta requires sign-in,
# a page with its own seo.robots and a path under seo.noindexRoutes get the
# meta tag and the header; an ordinary page keeps the CMS robots.
200 /konto contains=<meta name="robots" content="noindex, nofollow"> count=name="robots":1 header=X-Robots-Tag: noindex, nofollow
200 /szkic contains=<meta name="robots" content="noindex, follow"> header=X-Robots-Tag: noindex, follow
200 /prywatne contains=<meta name="robots" content="noindex, nofollow"> header=X-Robots-Tag: noindex, nofollow
200 /plain noheader=X-Robots-Tag count=name="robots":0
200 /blog/lwia-grzywa contains=<meta name="robots" content="index, follow">
# The site answer through the layer's server, for useSeoSite().
200 /api/__seo__/site contains="site_url":"https://example.test" header=X-Robots-Tag: noindex
# The route report at server start: the static paths with the token, not
# the signed-in page, the page with a noindex seo.robots or the declared
# noindex route. The build matches the site answer: no drift warning.
routereport 1 has=/ has=/blog has=/plain has=/about lacks=/konto lacks=/szkic lacks=/prywatne lacks=/mapa-strony
log [vue-seo-layer] drift::0
# L1 breadcrumbs: a layout instance (app.vue) and a page instance render
# exactly one trail, server-rendered links, the last item as text with
# aria-current; none on the home page (one item) or a page without a trail.
200 /blog/lwia-grzywa count=<nav class="seo-breadcrumbs":1 contains=<a class="seo-breadcrumbs__link" href="/">Start</a> contains=<span class="seo-breadcrumbs__current" aria-current="page">Lwia grzywa</span> count=aria-current="page":1
200 / count=seo-breadcrumbs:0
200 /plain count=seo-breadcrumbs:0
# L2 pagination: numbered links in the CMS form, page 1 unnumbered, five
# pages around the current one plus the first and the last with two gaps,
# rel prev/next anchors and head links, and %pages% filled in the CMS title
# and description (the payload keeps the raw answer); one page renders
# none. aria-current: the current page and the breadcrumbs' last item.
200 /blog?page=5 count=<nav class="seo-pagination":1 contains=<a class="seo-pagination__prev" href="/blog?page=4" rel="prev"> contains=<a class="seo-pagination__next" href="/blog?page=6" rel="next"> contains=<span class="seo-pagination__current" aria-current="page">5</span> count=aria-current="page":2
200 /blog?page=5 contains=<a href="/blog" aria-label="Strona 1">1</a> contains=<a href="/blog?page=14" aria-label="Strona 14">14</a> count=seo-pagination__gap:2
200 /blog?page=5 contains=<link rel="prev" href="/blog?page=4" contains=<link rel="next" href="/blog?page=6" contains=<title>Blog – strona 5 z 14 | Example</title> contains=content="Wpisy o grzybach, strona 5 z 14" notcontains=z %pages% |</title> notcontains=content="Wpisy o grzybach, strona 5 z %pages%"
200 /blog?page=14&sort=new contains=<a class="seo-pagination__prev" href="/blog?sort=new&amp;page=13" rel="prev"> count=seo-pagination__next:0 count=rel="next":0
200 /blog?pages=1 count=seo-pagination:0 count=rel="prev":0
# L3 HTML sitemap: H1, one H2 per non-empty group (the empty one left out),
# the category tree nested, a large group's link to its group page; a URL
# that is not http(s) renders as text; long titles stay whole.
200 /mapa-strony contains=<h1 class="seo-sitemap__title">Mapa strony</h1> count=<h2:3 notcontains=Tagi contains=<a href="/mapa-strony/posts" class="">Wpisy: wszystkie (1234)</a> notcontains=href="javascript: notcontains=<script>alert
200 /mapa-strony contains=Grzyby</a><ul class="seo-sitemap__list"> contains=<a href="/grzyby/lecznicze" contains=musi się zawinąć</a> count=<h1:1
# A group page: built trail, H1 with the page suffix, pagination; ?page=1
# is a 301 to the unnumbered URL; an unknown group or a page past the last
# is a 404; a failing sitemap API is a 503 (never an empty cached page).
200 /mapa-strony/posts?page=2 contains=<h1 class="seo-sitemap__title">Mapa strony: Wpisy · Strona 2</h1> contains=<a class="seo-breadcrumbs__link" href="/mapa-strony">Mapa strony</a> contains=<span class="seo-breadcrumbs__current" aria-current="page">Wpisy</span> count=<nav class="seo-breadcrumbs":1 count=<nav class="seo-pagination":1 contains=href="/mapa-strony/posts?page=3"
200 /mapa-strony/posts contains=<h1 class="seo-sitemap__title">Mapa strony: Wpisy</h1> contains=Lwia grzywa
301 /mapa-strony/posts?page=1 header=Location: /mapa-strony/posts
404 /mapa-strony/nope
404 /mapa-strony/posts?page=9
404 /mapa-strony/posts?page=abc
503 /mapa-strony/fail
# Every group empty: the empty message (en labels on the en path).
200 /en/sitemap contains=<h1 class="seo-sitemap__title">Sitemap</h1> contains=<p class="seo-sitemap__empty">There are no pages to list yet.</p> count=<h2:0
# A locale the CMS has no HTML sitemap path for.
404 /sitemap
# L4: the footer link to the locale's HTML sitemap.
200 /blog/lwia-grzywa contains=<footer><a href="/mapa-strony" class="seo-sitemap-link">Mapa strony</a></footer>