Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
claude/adoring-hopper-5x74bqclaude/affectionate-feynman-ykrf1hclaude/architecture-audit-design-wxprenclaude/build-status-update-3MXsfclaude/charming-meitner-mllb5rclaude/compare-gate-gluecron-s4mFQclaude/confident-faraday-tikcwbclaude/continue-work-XMTlIclaude/crontech-gluecron-deploy-7MIECclaude/crontech-platform-setup-SeKfwclaude/design-2026claude/ecstatic-ptolemy-jMdigclaude/enhance-github-integration-QNHdGclaude/fix-aa-loop-issue-PonMQclaude/fix-actions-and-processclaude/fix-desktop-errors-XqoW8claude/fix-red-workflowsclaude/fix-website-access-6FKJNclaude/gatetest-integration-hardeningclaude/github-audit-improvements-bDFr9claude/gluecron-launch-status-FoMRlclaude/hopeful-lamport-olfCTclaude/issue-to-pr-and-protectionsclaude/jolly-heisenberg-2sg1Qclaude/launch-preparation-QmTb6claude/new-session-xk1l7claude/plan-platform-architecture-kkN4yclaude/platform-analysis-roadmap-1nUGLclaude/platform-launch-assessment-8dWV8claude/polish-platform-release-AeDrUclaude/resume-previous-work-KzyLwclaude/review-crontech-handoff-qYEVqclaude/review-project-completeness-lHhS2claude/review-readme-docs-ulqPKclaude/serene-edison-rj87weclaude/setup-multi-repo-dev-BCwNQclaude/ship-fixes-and-tests-Jvz1cclaude/site-audit-competitive-pctlwgclaude/site-migration-vercel-XstpKclaude/standalone-product-repos-XHFTDcopilot/feat-smart-empty-states-keyboard-first-enhancementcopilot/feat-smart-morning-digest-review-context-restorecopilot/fix-and-process-workflowscopilot/update-ai-powered-code-reviewfeat/debt-mapfeat/push-policy-codeowners-hardeningfeat/smart-digest-contextfeat/stage-impactfeat/t1-secret-migrationfeat/u-polishfeat/w-self-hostfeat/w2-claude-configfix/agent-journey-orphan-sweepgatetest/auto-fix-1776586424172gatetest/auto-fix-1776586534814gatetest/auto-fix-1776590685143gatetest/auto-fix-1776590808199mainops/redeploy-retriggerstyle/dxt-cta-themeworktree-agent-a3377aad30d55da26worktree-agent-a7ef607b7ee1d6c74
visual-coherence.test.tsx6.4 KB · 189 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/**
 * Block O3 — visual coherence tests.
 *
 * Asserts the design-token + component contract introduced by the O3
 * pass.
 *
 * 2026-06-10: token assertions moved from "/" to "/help" — the home
 * route now serves the self-contained Landing2030Page without the
 * master Layout CSS.
 *
 * NOTE: This test runs WITHOUT mock pollution — no `mock.module()`,
 * no shared global state, no DB. It only hits in-process HTTP routes
 * via `app.request()` and renders the canonical components directly
 * to strings via hono/jsx's built-in stringifier.
 */

import { describe, it, expect } from "bun:test";
import app from "../app";
import { Card } from "../views/ui";
import { Layout } from "../views/layout";

// hono/jsx exposes a stringifier on every node.
async function renderToString(node: any): Promise<string> {
  if (node && typeof node.toString === "function") {
    return String(await node.toString());
  }
  return String(node);
}

describe("O3 — design token aliases in master CSS", () => {
  it("layout.tsx exposes the --space-* alias scale", async () => {
    const res = await app.request("/help");
    const body = await res.text();
    expect(body).toContain("--space-1:");
    expect(body).toContain("--space-2:");
    expect(body).toContain("--space-3:");
    expect(body).toContain("--space-4:");
    expect(body).toContain("--space-6:");
    expect(body).toContain("--space-8:");
  });

  it("layout.tsx exposes the --radius-* alias scale", async () => {
    const res = await app.request("/help");
    const body = await res.text();
    expect(body).toContain("--radius-sm:");
    expect(body).toContain("--radius-md:");
    expect(body).toContain("--radius-lg:");
    expect(body).toContain("--radius-full:");
  });

  it("layout.tsx exposes the --font-size-* alias scale", async () => {
    const res = await app.request("/help");
    const body = await res.text();
    expect(body).toContain("--font-size-xs:");
    expect(body).toContain("--font-size-sm:");
    expect(body).toContain("--font-size-base:");
    expect(body).toContain("--font-size-lg:");
    expect(body).toContain("--font-size-xl:");
  });

  it("layout.tsx exposes the --leading-* aliases", async () => {
    const res = await app.request("/help");
    const body = await res.text();
    expect(body).toContain("--leading-tight:");
    expect(body).toContain("--leading-normal:");
    expect(body).toContain("--leading-loose:");
  });

  it("layout.tsx exposes the --z-* index scale", async () => {
    const res = await app.request("/help");
    const body = await res.text();
    expect(body).toContain("--z-nav:");
    expect(body).toContain("--z-modal:");
    expect(body).toContain("--z-toast:");
  });

  it("ships the notice / email-preview / code-block utility classes", async () => {
    const res = await app.request("/help");
    const body = await res.text();
    expect(body).toContain(".notice");
    expect(body).toContain(".notice-warn");
    expect(body).toContain(".email-preview");
    expect(body).toContain(".code-block");
  });
});

describe("O3 — site-wide footer renders on every page", () => {
  // /explore queries the DB which is not available in the unit-test
  // process. Footer presence is well-covered by the other four pages.
  const PAGES = ["/", "/help", "/status", "/pricing"];

  for (const path of PAGES) {
    it(`GET ${path} includes the canonical footer`, async () => {
      const res = await app.request(path);
      expect(res.status).toBeLessThan(500);
      const body = await res.text();
      expect(body).toContain("<footer");
      expect(body.toLowerCase()).toContain("gluecron");
    });
  }
});

describe("O3 — Card component padding + variant props", () => {
  it("renders without props (legacy default)", async () => {
    const html = await renderToString(<Card>hello</Card>);
    expect(html).toContain('class="card"');
    expect(html).toContain("hello");
  });

  it('supports padding="none"', async () => {
    const html = await renderToString(<Card padding="none">x</Card>);
    expect(html).toContain("card-p-none");
  });

  it('supports padding="sm"', async () => {
    const html = await renderToString(<Card padding="sm">x</Card>);
    expect(html).toContain("card-p-sm");
  });

  it('supports padding="md"', async () => {
    const html = await renderToString(<Card padding="md">x</Card>);
    expect(html).toContain("card-p-md");
  });

  it('supports padding="lg"', async () => {
    const html = await renderToString(<Card padding="lg">x</Card>);
    expect(html).toContain("card-p-lg");
  });

  it('supports variant="elevated"', async () => {
    const html = await renderToString(<Card variant="elevated">x</Card>);
    expect(html).toContain("card-elevated");
  });

  it('supports variant="gradient"', async () => {
    const html = await renderToString(<Card variant="gradient">x</Card>);
    expect(html).toContain("card-gradient");
  });

  it("composes padding and variant together", async () => {
    const html = await renderToString(
      <Card padding="lg" variant="elevated">x</Card>
    );
    expect(html).toContain("card-p-lg");
    expect(html).toContain("card-elevated");
  });
});

describe("O3 — flag-gated footer banner", () => {
  it("does NOT render the .footer-banner stripe when siteBannerText is empty", async () => {
    const html = await renderToString(
      <Layout title="t">
        <p>body</p>
      </Layout>
    );
    expect(html).not.toContain('class="footer-banner');
  });

  it("renders the .footer-banner stripe when siteBannerText is non-empty", async () => {
    const html = await renderToString(
      <Layout title="t" siteBannerText="Scheduled maintenance tonight">
        <p>body</p>
      </Layout>
    );
    expect(html).toContain("footer-banner");
    expect(html).toContain("Scheduled maintenance tonight");
  });

  it("honours the siteBannerLevel modifier", async () => {
    const html = await renderToString(
      <Layout title="t" siteBannerText="x" siteBannerLevel="warn">
        <p>body</p>
      </Layout>
    );
    expect(html).toContain("footer-banner-warn");
  });
});

describe("O3 — no critical page leaks a banner stripe by default", () => {
  const PAGES = ["/", "/help", "/pricing"];

  for (const path of PAGES) {
    it(`GET ${path} does not render the footer-banner stripe by default`, async () => {
      const res = await app.request(path);
      const body = await res.text();
      expect(body).not.toContain('class="footer-banner');
    });
  }
});