Skip to content

Commit 4fdabb8

Browse files
committed
adds more tests and consistency with readme
1 parent bbc2a6a commit 4fdabb8

7 files changed

Lines changed: 740 additions & 6 deletions

File tree

.github/workflows/ci.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
verify:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v4
12+
- uses: actions/setup-node@v4
13+
with:
14+
node-version: 20
15+
- run: npm test

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Changelog
2+
3+
## Unreleased
4+
5+
- Added versioned consent storage with migration and expiry handling.
6+
- Added banner accessibility improvements and focus management.
7+
- Reworked the demo page to show the config-based bootstrap flow.
8+
- Added `npm test`, a repository verification script, and GitHub Actions CI.
9+
- Relicensed the project to MIT.
10+
11+
## 0.1.0
12+
13+
- Initial public packaging version for the MIT-licensed repository.

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,18 @@ The page exercises:
181181
- Malformed storage cleanup
182182
- Public API persistence via `window.cookieconsent.setConsent(selection)`
183183

184+
## Automation
185+
186+
Run the repo checks with:
187+
188+
```bash
189+
npm test
190+
```
191+
192+
That command runs the static repository verifier, the runtime consent harness, and `node --check` on `cookieconsent.js`.
193+
194+
CI is defined in [`.github/workflows/ci.yml`](/mnt/data/personal/cookieconsent/.github/workflows/ci.yml).
195+
184196
## DevTools Verification
185197

186198
Quick checks in browser devtools:

index.html

Lines changed: 243 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,261 @@
11
<!DOCTYPE html>
22
<html lang="en">
33
<head>
4+
<meta charset="utf-8">
45
<meta http-equiv="X-UA-Compatible" content="IE=edge">
5-
<meta name="viewport" content="shrink-to-fit=no,width=device-width,height=device-height,initial-scale=1,user-scalable=1">
6-
<title>Test Page</title>
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<title>Cookie Consent Demo</title>
8+
<meta name="description" content="Demo page for the Cookie Consent banner and Google Consent Mode bootstrap.">
79

8-
<link rel="stylesheet preload prefetch" href="cookieconsent.css" as="style" type="text/css" crossorigin="anonymous">
10+
<link rel="stylesheet" href="cookieconsent.css" type="text/css">
911

10-
<!-- Configure GTM container ID for cookieconsent.js -->
1112
<script>
1213
window.cookieconsentConfig = {
1314
gtmId: 'GTM-PT6WQ6HK'
1415
};
1516
</script>
1617

17-
<!-- Consent manager sets consent defaults, then loads GTM using the configured ID -->
1818
<script src="cookieconsent.js"></script>
19+
20+
<style>
21+
:root {
22+
color-scheme: light;
23+
--bg: #f4efe6;
24+
--panel: rgba(255, 255, 255, 0.78);
25+
--panel-border: rgba(22, 22, 22, 0.12);
26+
--text: #151515;
27+
--muted: #605950;
28+
--accent: #2457ff;
29+
--accent-2: #1b3fc0;
30+
--shadow: 0 18px 50px rgba(22, 22, 22, 0.14);
31+
}
32+
33+
body {
34+
margin: 0;
35+
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
36+
color: var(--text);
37+
background:
38+
radial-gradient(circle at top left, rgba(36, 87, 255, 0.12), transparent 28%),
39+
radial-gradient(circle at top right, rgba(15, 122, 61, 0.10), transparent 28%),
40+
linear-gradient(180deg, #f7f3ec 0%, var(--bg) 100%);
41+
}
42+
43+
.page {
44+
max-width: 1040px;
45+
margin: 0 auto;
46+
padding: 32px 20px 64px;
47+
}
48+
49+
.hero,
50+
.demo-panel,
51+
.notes {
52+
background: var(--panel);
53+
backdrop-filter: blur(10px);
54+
border: 1px solid var(--panel-border);
55+
border-radius: 24px;
56+
box-shadow: var(--shadow);
57+
}
58+
59+
.hero {
60+
padding: 32px;
61+
}
62+
63+
h1 {
64+
margin: 0 0 12px;
65+
font-size: clamp(2rem, 4vw, 3.35rem);
66+
line-height: 1.02;
67+
letter-spacing: -0.04em;
68+
}
69+
70+
p {
71+
margin: 0 0 14px;
72+
color: var(--muted);
73+
line-height: 1.6;
74+
}
75+
76+
.grid {
77+
display: grid;
78+
gap: 20px;
79+
margin-top: 22px;
80+
grid-template-columns: 1.15fr 0.85fr;
81+
}
82+
83+
.demo-panel,
84+
.notes {
85+
padding: 22px;
86+
}
87+
88+
.demo-panel h2,
89+
.notes h2 {
90+
margin: 0 0 12px;
91+
font-size: 1.1rem;
92+
}
93+
94+
.actions {
95+
display: flex;
96+
flex-wrap: wrap;
97+
gap: 12px;
98+
margin-top: 18px;
99+
}
100+
101+
.button {
102+
appearance: none;
103+
border: 1px solid transparent;
104+
border-radius: 12px;
105+
min-height: 46px;
106+
padding: 0 16px;
107+
font: inherit;
108+
font-weight: 700;
109+
cursor: pointer;
110+
transition: transform 120ms ease, background-color 120ms ease, border-color 120ms ease;
111+
}
112+
113+
.button:hover {
114+
transform: translateY(-1px);
115+
}
116+
117+
.button.primary {
118+
color: #fff;
119+
background: var(--accent);
120+
}
121+
122+
.button.primary:hover {
123+
background: var(--accent-2);
124+
}
125+
126+
.button.secondary {
127+
color: var(--text);
128+
background: #fff;
129+
border-color: var(--panel-border);
130+
}
131+
132+
.button.secondary:hover {
133+
background: #f6f6f6;
134+
}
135+
136+
.state {
137+
display: grid;
138+
gap: 12px;
139+
margin-top: 14px;
140+
}
141+
142+
.state pre {
143+
margin: 0;
144+
padding: 16px;
145+
border-radius: 16px;
146+
background: rgba(255, 255, 255, 0.84);
147+
border: 1px solid var(--panel-border);
148+
overflow: auto;
149+
font-size: 0.9rem;
150+
line-height: 1.45;
151+
}
152+
153+
.notes ul {
154+
margin: 0;
155+
padding-left: 20px;
156+
}
157+
158+
.notes li + li {
159+
margin-top: 10px;
160+
}
161+
162+
code {
163+
padding: 0.1em 0.35em;
164+
border-radius: 6px;
165+
background: rgba(22, 22, 22, 0.08);
166+
}
167+
168+
@media (max-width: 860px) {
169+
.grid {
170+
grid-template-columns: 1fr;
171+
}
172+
}
173+
</style>
19174
</head>
20175

21176
<body>
22-
<div class="cookie-consent-banner-open">[Open Cookie Prefs]</div>
177+
<main class="page">
178+
<section class="hero">
179+
<h1>Cookie Consent Demo</h1>
180+
<p>
181+
This page demonstrates the config-based bootstrap flow:
182+
<code>window.cookieconsentConfig</code>, then <code>cookieconsent.js</code>,
183+
then the banner and Consent Mode defaults.
184+
</p>
185+
<div class="actions">
186+
<button id="open-banner" class="button primary" type="button">Open cookie preferences</button>
187+
<button id="reset-consent" class="button secondary" type="button">Reset stored consent</button>
188+
</div>
189+
</section>
190+
191+
<section class="grid" aria-label="Demo content">
192+
<div class="demo-panel">
193+
<h2>Runtime state</h2>
194+
<p>
195+
Use the controls to open the banner, clear consent storage, and inspect the current
196+
consent record in the page.
197+
</p>
198+
<div class="state">
199+
<pre id="status">Loading…</pre>
200+
</div>
201+
</div>
202+
203+
<aside class="notes">
204+
<h2>What this demo covers</h2>
205+
<ul>
206+
<li>Consent defaults boot before other tags.</li>
207+
<li>GTM is loaded only when a container ID is configured.</li>
208+
<li>The banner can be reopened with the public API.</li>
209+
<li>Stored consent is visible in <code>localStorage['consentMode']</code>.</li>
210+
</ul>
211+
</aside>
212+
</section>
213+
</main>
214+
215+
<script>
216+
const statusEl = document.getElementById('status');
217+
const openBannerButton = document.getElementById('open-banner');
218+
const resetConsentButton = document.getElementById('reset-consent');
219+
220+
function readStoredConsent() {
221+
const raw = localStorage.getItem('consentMode');
222+
if (!raw) return null;
223+
try {
224+
return JSON.parse(raw);
225+
} catch (error) {
226+
return { parseError: true, raw };
227+
}
228+
}
229+
230+
function refreshStatus() {
231+
const consent = readStoredConsent();
232+
const api = window.cookieconsent || {};
233+
statusEl.textContent = JSON.stringify({
234+
bannerPresent: !!document.getElementById('cookie-consent-banner'),
235+
bannerVisible: !!document.getElementById('cookie-consent-banner') &&
236+
!document.getElementById('cookie-consent-banner').hidden,
237+
consentMode: api.consentMode || null,
238+
storedConsent: consent,
239+
gtmConfigured: !!(window.cookieconsentConfig && window.cookieconsentConfig.gtmId)
240+
}, null, 2);
241+
}
242+
243+
openBannerButton.addEventListener('click', () => {
244+
window.cookieconsent.show();
245+
refreshStatus();
246+
});
247+
248+
resetConsentButton.addEventListener('click', () => {
249+
localStorage.removeItem('consentMode');
250+
window.cookieconsent.show();
251+
refreshStatus();
252+
});
253+
254+
window.addEventListener('storage', refreshStatus);
255+
window.addEventListener('load', () => {
256+
refreshStatus();
257+
window.setInterval(refreshStatus, 500);
258+
});
259+
</script>
23260
</body>
24261
</html>

package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "cookieconsent",
3+
"version": "0.1.0",
4+
"private": true,
5+
"type": "module",
6+
"scripts": {
7+
"test": "node scripts/verify.mjs && node scripts/runtime-tests.mjs && node --check cookieconsent.js"
8+
}
9+
}

0 commit comments

Comments
 (0)