- renderJournalBody runs the UI-SPEC L7 order on the sanitized body: h1 demotion, the CMS phrase auto-links, the outbound rules and lazy, async images, with vue-seo-layer's autolink, applyOutbound and imageAttrs; PostBody feeds it the page's resolve answer (autolinks, autolink_max, outbound, url) and the seo.links.newTabHint option - the sanitizer keeps a link rel of only nofollow, sponsored and ugc (the Blog Editor's link form, as the Journal plugin's policy does); target is never kept, the outbound rules add it - editor-corpus.json copied again from sm-journal-plugin (link-rel and image-decorative entries) - smoke:ssr script; expectations for auto-links, both new-tab modes and the hint switched off
90 lines
5.3 KiB
Plaintext
90 lines
5.3 KiB
Plaintext
# SSR expectations against the acme fixtures (testing/fixtures/acme).
|
|
# Grammar: STATUS PATH [contains=TEXT] [notcontains=TEXT] [count=TEXT:N]
|
|
# [type=PREFIX] [header=NAME: VALUE] [noheader=NAME]; resolves PATH N
|
|
# The consumer enables en (default, no prefix) and pl (/pl prefix). The
|
|
# fixture SEO API (fixtures/acme/seo) answers the site URL https://acme.test.
|
|
|
|
# The post page on the shared SEO layer: exactly one H1 in both Journal H1
|
|
# modes, one canonical and one JSON-LD script (UI-SPEC L6, D-97).
|
|
200 /blog/heading-on count=<h1:1 contains=<h1 class="journal-post__title" count=application/ld+json:1 count=rel="canonical":1
|
|
200 /blog/heading-on contains=<h2>Body heading one</h2> notcontains=<p class="journal-post__title"
|
|
200 /blog/heading-off count=<h1:1 contains=<p class="journal-post__title" count=application/ld+json:1 count=rel="canonical":1
|
|
200 /blog/heading-off contains=<h1>Body heading one</h1>
|
|
# The CMS head wins: its title, no second title.
|
|
200 /blog/heading-on contains=<title>Heading On Sample | Acme Blog</title> count=<title>:1
|
|
# Without a CMS answer the post's own title and description are the fallback.
|
|
200 /blog/uncategorised-note contains=<title>Uncategorised Note</title> contains=Uncategorised Note: a short summary.
|
|
|
|
# Single post
|
|
200 /blog/hello-acme contains=Hello Acme
|
|
200 /blog/hello-acme contains=https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ
|
|
404 /blog/missing-post
|
|
200 /blog/unsafe-sample contains=<p>Before</p><p>After</p> notcontains=alert(
|
|
404 /blog/draft-note
|
|
|
|
# Post index and pagination (9 per page, 13 published posts: 2 pages)
|
|
200 /blog contains=Hello Acme
|
|
200 /blog?page=2
|
|
404 /blog?page=3
|
|
404 /blog?page=abc
|
|
404 /blog?page=0
|
|
200 /pl/blog contains=Najnowsze wpisy
|
|
|
|
# Categories (include_empty=1; content renders above the list)
|
|
200 /blog/category/news contains=Acme news marker
|
|
200 /blog/category/quiet contains=There are no posts in this category yet.
|
|
404 /blog/category/nope
|
|
|
|
# Related posts fall back to the latest posts for a post without a category
|
|
200 /blog/uncategorised-note contains=Hello Acme
|
|
|
|
# Author (slug and login resolve) and tag pages
|
|
200 /blog/author/jane-doe contains=Jane Doe
|
|
200 /blog/author/jdoe contains=<link rel="canonical" href="https://acme.test/blog/author/jane-doe"
|
|
200 /blog/hello-acme contains=href="/blog/author/jane-doe" notcontains=/blog/author/jdoe
|
|
404 /blog/author/nobody
|
|
200 /blog/tag/release contains=Hello Acme
|
|
404 /blog/tag/nope
|
|
|
|
# RSS, canonical and meta (sitemaps come from the CMS, not the layer)
|
|
200 /rss.xml type=application/rss+xml
|
|
200 /blog contains=href="/rss.xml"
|
|
200 /blog?page=2 contains=?page=2
|
|
200 /blog?page=2 contains=<link rel="canonical" href="https://acme.test/blog?page=2">
|
|
200 /blog/hello-acme contains=og:title
|
|
200 /blog/hello-acme contains=Acme says hello and introduces its blog.
|
|
|
|
# Search (the playground sets journal.routes.search: '/search'). 11 posts
|
|
# match "acme": 2 pages of 9. Not route-cached (the playground caches /**)
|
|
# and noindex, follow.
|
|
200 /search?q=acme contains=Hello Acme
|
|
200 /search?q=acme contains=11 results
|
|
200 /search?q=acme contains=noindex, follow header=x-robots-tag: noindex, follow
|
|
200 /search?q=acme&page=2 contains=Acme Note 12
|
|
404 /search?q=acme&page=3
|
|
404 /search?q=acme&page=abc
|
|
200 /search?q=unsafe contains=Unsafe Sample notcontains=Hello Acme
|
|
200 /search?q=unsafe contains=1 result
|
|
200 /search?q=zzzzzz contains=Nothing found for “zzzzzz”.
|
|
200 /search?q=ac contains=Type at least 3 characters.
|
|
200 /search contains=Type what you are looking for.
|
|
# The term is text everywhere it is rendered (attributes may keep a bare <).
|
|
200 /search?q=%3Cscript%3Ealert(1)%3C%2Fscript%3E contains=Search results: <script>alert(1) notcontains=>Search results: <script>
|
|
200 /pl/search?q=acme contains=11 wyników
|
|
200 /pl/search?q=unsafe contains=1 wynik
|
|
# The header box renders its no-JS form to the search route on every page.
|
|
200 /blog contains=action="/search"
|
|
200 /pl/blog contains=action="/pl/search"
|
|
|
|
# Body links, outbound rules and images (UI-SPEC L7). hello-acme: new tab on
|
|
# with the default hint; auto-links in document order up to autolink_max 2,
|
|
# never in a heading, never to the page itself.
|
|
200 /blog/hello-acme contains=<a href="/blog/acme-note-07">anvils</a> contains=<a href="/blog/acme-note-05">rockets</a> notcontains=<a href="/blog/acme-note-03"> notcontains=<a href="/blog/acme-note-06"> notcontains=<a href="https://acme.test/blog/hello-acme"
|
|
200 /blog/hello-acme contains=<a href="https://partner.test/review" rel="ugc nofollow noopener" target="_blank">the review<span class="seo-visually-hidden"> (opens in a new tab)</span></a>
|
|
200 /blog/hello-acme contains=<a href="https://shop.ads.test/deal" target="_blank" rel="sponsored noopener">a deal<span class="seo-visually-hidden"> (opens in a new tab)</span></a>
|
|
200 /blog/hello-acme contains=<a href="/blog/acme-note-04">an older note</a>
|
|
200 /blog/hello-acme contains=<img src="/storage/app/uploads/public/acme/anvil.png" alt="" width="640" height="480" loading="lazy" decoding="async" />
|
|
# heading-off: new tab off keeps the editor rel and the domain-list nofollow,
|
|
# without target, noopener or the hint.
|
|
200 /blog/heading-off contains=<a href="https://partner.test/x" rel="ugc nofollow">the partner</a> contains=<a href="https://other.test/y">another site</a> notcontains=target="_blank" notcontains=noopener notcontains=(opens in a new tab)
|