Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions scripts/check-public-live-deploy.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,69 @@ try {
}
}
}
console.log("H. shared-footer pages carry visitor-facing footer copy, not launch-prep (PR #35)")
{
// Same coverage and markers as scripts/test-public-footer-copy.mjs: every
// live path that carries the shared footer block must name the actual
// products and must not contain any fragment of the launch-prep footer
// line the June-20 bundle still serves.
const FOOTER_PATHS = [
"/contact/",
"/drishti/",
"/drishti/privacy/",
"/drishti/support/",
"/privacy-choices/",
"/privacy/",
"/promptly/",
"/promptly/privacy/",
"/promptly/support/",
"/support/",
"/terms/",
]
const LAUNCH_PREP_FRAGMENTS = [
"clean public foundation",
"foundation before launch",
"gives each product",
"before launch",
]
const VISITOR_FACING_FRAGMENTS = ["Promptly", "Drishti"]

const footerBlockOf = (html) => {
const start = html.indexOf("<footer")
const end = html.indexOf("</footer>")
return start >= 0 && end > start ? html.slice(start, end) : ""
}

const checkFooter = (label, html) => {
const footer = footerBlockOf(html)
ok(footer.length > 0, `${label} has a footer block`)
const copyBlock = footer.match(/<p class="footer-copy"[^>]*>([\s\S]*?)<\/p>/)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Match the footer-copy class independent of serialization

When a shared footer remains semantically unchanged but its attributes are reordered, use single quotes, or add another class (for example, <p style="..." class="footer-copy">), this regex fails to recognize the paragraph and blocks the post-deploy release lane. Match the class attribute regardless of attribute order and quoting, or parse the footer as HTML, so valid markup refactors do not produce a false deployment failure.

Useful? React with 👍 / 👎.

ok(copyBlock !== null, `${label} has a .footer-copy paragraph`)
if (copyBlock) {
const copy = copyBlock[1]
for (const fragment of VISITOR_FACING_FRAGMENTS) {
ok(copy.includes(fragment), `${label} footer copy names ${fragment}`)
}
for (const fragment of LAUNCH_PREP_FRAGMENTS) {
ok(!copy.includes(fragment), `${label} footer copy avoids "${fragment}"`)
Comment on lines +229 to +230

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Compare forbidden footer fragments case-insensitively

If a deployed footer contains a capitalization variant such as Before launch or Gives each product, every negative assertion passes because String.prototype.includes is case-sensitive, even though the launch-prep copy this acceptance check is intended to reject is still live. Normalize the extracted footer copy and fragments to a common case, or use case-insensitive expressions, so capitalization-only edits cannot produce a false-green deployment.

Useful? React with 👍 / 👎.

}
}
for (const fragment of LAUNCH_PREP_FRAGMENTS) {
ok(!footer.includes(fragment), `${label} footer has no "${fragment}"`)
}
}

for (const path of FOOTER_PATHS) {
const { status, body } = await get(path)
ok(status === 200, `${path} returns 200 (got ${status})`)
checkFooter(path, body)
}
const footerProbe = `/definitely-missing-footer-probe-${Date.now()}`
const { status, body } = await get(footerProbe)
ok(status === 404, `unknown URL returns 404 for footer probe (got ${status})`)
checkFooter("404 page", body)
}

} catch (error) {
failures++
console.error(` FAIL live request error: ${error.message}`)
Expand Down