Skip to content
Merged
Show file tree
Hide file tree
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
21 changes: 16 additions & 5 deletions tests/landing-pricing.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,26 @@ const livePayload = (interval, label) => ({
console.log('landing pricing contract');

// ── 1. the page must never carry a price of its own ───────────────────────
await test('no retired plan names survive in the markup', () => {
const body = HTML.split('<script>')[0];
for (const dead of ['Explorer', 'Creator', 'Operator']) {
assert.ok(!body.includes(`>${dead}<`), `retired plan "${dead}" is still rendered`);
//
// These scan the WHOLE file, comments included. web/index.html is the website:
// Cloudflare Workers serves ./web directly and the Pages job copies it
// wholesale, so a source comment explaining our old prices is published to
// anyone who hits View Source. Internal history belongs in this file, which is
// not served. (The first cut of this suite stripped `//` comments and therefore
// passed while the page still shipped that history.)
await test('no retired plan names anywhere in the published file', () => {
for (const gone of ['Explorer', 'Creator', 'Operator']) {
assert.ok(!HTML.includes(gone), `retired plan "${gone}" is still published`);
}
});

await test('no refund promise anywhere (the terms say no refunds)', () => {
assert.ok(!/money-back|money back/i.test(HTML.replace(/\/\/[^\n]*/g, '')), 'a money-back promise is still on the page');
assert.ok(!/money-back|money back/i.test(HTML), 'a money-back promise is still published');
});

await test('no retired price literal anywhere in the published file', () => {
const literals = HTML.match(/\$\d{2,4}\b/g) || [];
assert.deepEqual(literals, [], `hardcoded USD amounts are published: ${literals.join(', ')}`);
});

await test('the annual toggle badge names no number of months', () => {
Expand Down
15 changes: 7 additions & 8 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,12 @@ <h2 class="section-title">What happens next</h2>
</section>


<!-- PRICING. Rendered from the LIVE pricing API, never hardcoded.
<!-- PRICING. Rendered from the live pricing API, never hardcoded.
https://tytus.traylinx.com/public/pricing is the single source of
truth (payments -> Provider proxy); a price change is Stripe +
catalog only, with zero edits here. This section used to hardcode
Explorer/Creator/Operator at $39/$79/$149 -- plans that no longer
exist -- which is exactly the drift this removes. -->
truth; a price change is Stripe + catalog only, with zero edits
here. Rationale and regression history live in
tests/landing-pricing.test.mjs -- deliberately outside web/, which
is the published asset root. -->
<section id="pricing">
<div class="pricing-intro">
<h2>Private pod pricing.</h2>
Expand Down Expand Up @@ -345,9 +345,8 @@ <h2 class="section-title">Built for your agents</h2>
// ── LIVE PRICING ────────────────────────────────────────────────────
// Single source of truth: payments -> Provider proxy. Nothing about the
// price ladder is hardcoded here, so changing a price is Stripe + catalog
// only. Before 2026-07-26 this page hardcoded Explorer/Creator/Operator at
// $39/$79/$149 with a "7-day money-back guarantee" -- three retired plans,
// prices we do not charge, and a refund promise the terms contradict.
// only. Everything in this file is served to the public verbatim, so keep
// internal history in tests/landing-pricing.test.mjs, not here.
const PRICING_ENDPOINT = 'https://tytus.traylinx.com/public/pricing';

// Bundled snapshot of the live values (2026-07-26). Used ONLY when the API
Expand Down
Loading