Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
168 commits
Select commit Hold shift + click to select a range
264c384
Merge pull request #2 from linaro-marketing/deploy-workflow
parker23b Jan 21, 2026
10e0ecd
Merge pull request #3 from linaro-marketing/deploy-workflow
parker23b Jan 21, 2026
c95f55f
Merge pull request #4 from linaro-marketing/deploy-workflow
parker23b Jan 21, 2026
728dbe5
Merge pull request #1 from linaro-marketing/main-webdev-2703
parker23b Jan 21, 2026
e1ef1fd
fix mobile view
parker23b Jan 21, 2026
a2221ba
Merge pull request #6 from linaro-marketing/fix-mobile-view
parker23b Jan 21, 2026
df6b05d
update deploy and sst config for staging
parker23b Jan 26, 2026
98e7908
Merge pull request #7 from linaro-marketing/update-staging
parker23b Jan 26, 2026
2cf9654
update coming soon
parker23b Feb 4, 2026
34d8954
update copy of CoC and AiP
parker23b Feb 4, 2026
62833cc
Merge pull request #9 from linaro-marketing/webdev-2721
parker23b Feb 4, 2026
708dec0
add figtree font
parker23b Feb 4, 2026
7d385da
Merge pull request #10 from linaro-marketing/webdev-2721
parker23b Feb 4, 2026
b026202
changes to comming soon page
parker23b Feb 5, 2026
5b11678
update corecollective page
parker23b Feb 5, 2026
e822f2f
Merge pull request #11 from linaro-marketing/webdev-2721
parker23b Feb 5, 2026
9a63abf
remove scale on bg
parker23b Feb 5, 2026
399e85a
Merge pull request #12 from linaro-marketing/webdev-2721
parker23b Feb 5, 2026
c77b57a
add anti trust page
parker23b Feb 5, 2026
7fc41fe
Merge pull request #13 from linaro-marketing/webdev-2721
parker23b Feb 5, 2026
6d8ad7a
add 404 page
parker23b Feb 5, 2026
8636087
Merge pull request #14 from linaro-marketing/webdev-2721
parker23b Feb 5, 2026
66bb433
update 404 page
parker23b Feb 5, 2026
0af6aab
Merge pull request #15 from linaro-marketing/webdev-2721
parker23b Feb 5, 2026
f5d8f70
changes
parker23b Feb 5, 2026
1be9e21
Merge pull request #16 from linaro-marketing/webdev-2721
parker23b Feb 5, 2026
b4af33c
add domain
parker23b Feb 5, 2026
02dda37
Merge pull request #17 from linaro-marketing/add-domain
parker23b Feb 5, 2026
b0a1ea5
Merge pull request #18 from linaro-marketing/staging
parker23b Feb 5, 2026
32c84ed
update logo and fixes
parker23b Feb 6, 2026
fb4f860
Merge pull request #19 from linaro-marketing/update-logo
parker23b Feb 6, 2026
b9ba321
Merge pull request #20 from linaro-marketing/staging
parker23b Feb 6, 2026
203de34
add react, navbar, pages
parker23b Jan 26, 2026
50fa28b
add footer component
parker23b Jan 26, 2026
e420c91
add remaining pages
parker23b Jan 27, 2026
935d3ca
update homepage
parker23b Feb 9, 2026
a29f81d
update about and working groups pages
parker23b Feb 10, 2026
cbe7984
add join, charter pages
parker23b Feb 11, 2026
f2e8442
tweaks
parker23b Feb 11, 2026
f0d9dc5
add blog page
parker23b Feb 11, 2026
1576da5
add blog page
parker23b Feb 11, 2026
d823731
Merge pull request #8 from linaro-marketing/webdev-2709
parker23b Feb 11, 2026
764eaa2
staging changes
parker23b Feb 16, 2026
0a59641
add logo
parker23b Feb 18, 2026
2adcd06
Delete src/assets/logos/amd.svg
parker23b Feb 18, 2026
abd8f19
delete logos
parker23b Feb 18, 2026
3c5439f
Merge pull request #21 from linaro-marketing/staging-changes
parker23b Feb 18, 2026
b5d422d
remove about line breaks
parker23b Feb 18, 2026
0fb97b1
Merge pull request #22 from linaro-marketing/staging-changes
parker23b Feb 18, 2026
7dfac3d
update homepage copy
parker23b Feb 18, 2026
08810f2
Merge pull request #23 from linaro-marketing/staging-changes
parker23b Feb 18, 2026
4ca7491
update logos and page title sizes
parker23b Feb 20, 2026
28aace3
update logos and add leadership team
parker23b Feb 20, 2026
ef7ca25
update blog and working groups
parker23b Feb 24, 2026
89abdee
Merge pull request #24 from linaro-marketing/staging-changes
parker23b Feb 24, 2026
bbd0d24
updated to blog, working groups, trailing slashes
parker23b Feb 24, 2026
2e796a4
Merge pull request #25 from linaro-marketing/staging-changes
parker23b Feb 24, 2026
c317411
add social media icons and ebba changes
parker23b Feb 24, 2026
878ffb2
Merge pull request #27 from linaro-marketing/staging-changes
parker23b Feb 24, 2026
96aea72
add social links, add linaro, arm logos, fix logo padding
parker23b Feb 25, 2026
3731cf2
Merge pull request #28 from linaro-marketing/staging-changes
parker23b Feb 25, 2026
e0e48f2
Merge pull request #26 from linaro-marketing/staging
parker23b Feb 25, 2026
6881e2a
update page title images to png
parker23b Feb 25, 2026
872c9ad
Merge pull request #29 from linaro-marketing/staging-changes
parker23b Feb 25, 2026
468b1ec
Merge pull request #30 from linaro-marketing/staging
parker23b Feb 25, 2026
496696f
updates to readme
parker23b Feb 25, 2026
748962c
add huawei logo
parker23b Feb 25, 2026
40f7e99
Merge pull request #31 from linaro-marketing/staging-changes
parker23b Feb 25, 2026
361956c
Merge pull request #32 from linaro-marketing/staging
parker23b Feb 25, 2026
ff55ecc
delete blog
parker23b Feb 25, 2026
3707953
Merge pull request #33 from linaro-marketing/remove-blog-main
parker23b Feb 25, 2026
561e692
set up blog and cron job to rebuild at time
parker23b Feb 25, 2026
f51d513
update update andrew wafaa title
parker23b Feb 25, 2026
80b4347
Merge pull request #34 from linaro-marketing/remove-blog-main
parker23b Feb 25, 2026
faf89cf
remove blog
parker23b Feb 25, 2026
95410e5
Merge pull request #35 from linaro-marketing/staging
parker23b Feb 25, 2026
d3f6da8
change blog filter logic
parker23b Feb 25, 2026
e68ba0f
change blog time
parker23b Feb 25, 2026
beeafbd
change blog filter logic
parker23b Feb 25, 2026
ceb2a2a
change blog time
parker23b Feb 25, 2026
76857c8
fix blog filter to show on staging
parker23b Feb 25, 2026
e2b6ead
Merge pull request #37 from linaro-marketing/fix-blog-filter
parker23b Feb 25, 2026
dad4609
Merge branch 'main' into staging
parker23b Feb 25, 2026
6ae81c6
Merge pull request #36 from linaro-marketing/staging
parker23b Feb 25, 2026
7f2eac5
update ditch deck
parker23b Feb 25, 2026
5e278bb
Merge pull request #38 from linaro-marketing/staging
parker23b Feb 25, 2026
4ce1754
replace edge platforms with edge compute
parker23b Feb 25, 2026
05b938e
Merge pull request #39 from linaro-marketing/staging
parker23b Feb 25, 2026
f731c60
update blog list
parker23b Feb 25, 2026
a9b396e
Merge pull request #40 from linaro-marketing/staging
parker23b Feb 25, 2026
6885968
update pitch file
parker23b Feb 26, 2026
66805b7
Merge pull request #41 from linaro-marketing/staging
parker23b Feb 26, 2026
7f2c318
Add FAQ page
philip-linaro Mar 5, 2026
76cc64f
Update GitHub workflows
philip-linaro Mar 5, 2026
5d596b3
Fix URL matching
philip-linaro Mar 5, 2026
01669ed
Left-align answer text
philip-linaro Mar 5, 2026
ba70bb1
Implement carousel for member logos
philip-linaro Mar 5, 2026
039c4fb
Improve FAQ handling
philip-linaro Mar 6, 2026
aaff6fc
Merge pull request #44 from CoreCollective-dev/COR-66
dbharbin Mar 6, 2026
fc9561d
Merge pull request #43 from CoreCollective-dev/COR-60
dbharbin Mar 6, 2026
0436434
Adjust navigation breakpoints
philip-linaro Mar 5, 2026
ce9fe0d
Improve text layout on mobile
philip-linaro Mar 5, 2026
1879cf6
Update README per COR-70
philip-linaro Mar 5, 2026
89b1bf7
Deploy width fix
philip-linaro Mar 6, 2026
68dc2f4
Temporary change to home page
philip-linaro Mar 6, 2026
8f1184c
More work on layout sizing.
philip-linaro Mar 6, 2026
16668a6
Fix dropdown menu positioning
philip-linaro Mar 9, 2026
501574c
More layout fixes
philip-linaro Mar 9, 2026
b62f954
Adjust About
philip-linaro Mar 9, 2026
4e8e8c6
Revert frontpage text
philip-linaro Mar 9, 2026
c0dea31
Merge pull request #45 from CoreCollective-dev/COR-68
dbharbin Mar 9, 2026
594a239
Add Google Analytics
philip-linaro Mar 11, 2026
c183f03
Merge pull request #46 from CoreCollective-dev/COR-71
philip-linaro Mar 11, 2026
b1d48af
Update FAQ with CoreCollective joining information
glikely Mar 11, 2026
69c9a5a
Add working groups google group links to the index
glikely Mar 11, 2026
737538b
Update src/content/faq/faq.yaml
glikely Mar 11, 2026
c7f9d85
Update src/content/faq/faq.yaml
glikely Mar 11, 2026
42edab3
Update src/content/faq/faq.yaml
glikely Mar 11, 2026
948f864
Update src/pages/working-groups/index.astro
glikely Mar 11, 2026
ca3b4e2
Merge pull request #47 from glikely/faq-and-wg-update
dbharbin Mar 11, 2026
df7fc78
Remove the "And more" entry from the working groups list
glikely Mar 12, 2026
efb2de0
faq: Add entries describing how CoreCollective is organized
glikely Mar 13, 2026
a60fdc1
Merge pull request #48 from glikely/faq-and-wg-update
dbharbin Mar 13, 2026
fe33c2f
Added Categories to FAQs and updated README instructions
dbharbin Mar 13, 2026
4f6810a
Merge pull request #49 from CoreCollective-dev/dons-faq
dbharbin Mar 14, 2026
f2189f2
Update README.md
dbharbin Mar 14, 2026
57ef8af
Update README.md
dbharbin Mar 14, 2026
7d57619
Update README.md
dbharbin Mar 14, 2026
ee8645b
cleaned up FAQ question
dbharbin Mar 18, 2026
661afb4
Merge pull request #50 from CoreCollective-dev/faq_update
dbharbin Mar 18, 2026
1529bfa
fixed FAQ detail, sigh
dbharbin Mar 18, 2026
b10071e
Merge pull request #51 from CoreCollective-dev/faq_update2
dbharbin Mar 18, 2026
d8e925a
New pitch deck
philip-linaro Mar 19, 2026
91ff624
Add more logos and fix processing size
philip-linaro Mar 19, 2026
96b02c0
Merge pull request #53 from CoreCollective-dev/COR-74
dbharbin Mar 19, 2026
9c17094
Merge pull request #52 from CoreCollective-dev/COR-76
dbharbin Mar 19, 2026
83a48b4
Remove Google Analytics, add Google Tag Manager
philip-linaro Mar 26, 2026
ff1787f
Merge pull request #54 from CoreCollective-dev/COR-79
philip-linaro Mar 26, 2026
c71c9fa
clarified how to join message further
dbharbin Mar 27, 2026
039d048
Merge pull request #55 from CoreCollective-dev/faqs-subscribing
dbharbin Mar 27, 2026
e8207a1
Add logo and update pitch deck
philip-linaro Apr 2, 2026
0a1b8b1
Merge pull request #56 from CoreCollective-dev/COR-82
dbharbin Apr 2, 2026
38aad33
Updated description of CCA WG per instruction from chairman
JLLinaro Apr 9, 2026
bb032e5
Merge pull request #57 from JLLinaro/update_cca_wg_description
pcolmer Apr 10, 2026
d14fe7e
Add vivo
philip-linaro Apr 17, 2026
e6c00b3
Merge pull request #58 from CoreCollective-dev/COR-84
dbharbin Apr 17, 2026
76fdb2b
Updated FAQ proposal Q & A to include initiatives as well
dbharbin Apr 17, 2026
428996b
Merge pull request #59 from CoreCollective-dev/faq-initiative-proposals
dbharbin Apr 17, 2026
1dfdd5e
New pitch deck
philip-linaro Apr 28, 2026
7e26951
Fix filename
philip-linaro Apr 28, 2026
5f8083b
Merge pull request #60 from CoreCollective-dev/COR-90
dbharbin Apr 28, 2026
0804a68
Update faq and Virtualization purpose statement
dbharbin May 4, 2026
3a646b7
Merge pull request #61 from CoreCollective-dev/update-virt-purpose
dbharbin May 4, 2026
9918c6e
Updated the CCA working group link to point to the private Google Gro…
JLLinaro May 19, 2026
485f6aa
Add member and update deck
philip-linaro May 26, 2026
c531392
Merge pull request #63 from CoreCollective-dev/COR-95
dbharbin May 26, 2026
1372d6b
Merge pull request #62 from JLLinaro/Update_cca_wg_link
dbharbin May 27, 2026
635035d
New company, new slide deck
philip-linaro Jun 1, 2026
1976d23
Merge pull request #64 from CoreCollective-dev/COR-98
dbharbin Jun 1, 2026
6e6dfe4
Implement WEBDEV-2935
philip-linaro Jun 4, 2026
5e06d79
Fix contrast issues
philip-linaro Jun 4, 2026
eca4944
More visibility fixes
philip-linaro Jun 4, 2026
39ecac1
More colour adjustments
philip-linaro Jun 4, 2026
f2625e4
Implement WEBDEV-2935
philip-linaro Jun 4, 2026
4e2d633
Fix contrast issues
philip-linaro Jun 4, 2026
92ecef3
More visibility fixes
philip-linaro Jun 4, 2026
ae3f90b
More colour adjustments
philip-linaro Jun 4, 2026
0fb0bfd
Merge branch 'webdev-2935' of github.com:CoreCollective-dev/cc-websit…
philip-linaro Jun 4, 2026
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
2,054 changes: 1,967 additions & 87 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
"astro": "astro",
"build": "astro build",
"dev": "astro dev",
"preview": "astro preview"
"preview": "astro preview",
"test": "vitest --run"
},
"dependencies": {
"@astrojs/check": "^0.9.9",
"@astrojs/mdx": "^4.3.13",
"@astrojs/react": "^4.4.2",
"@fontsource-variable/figtree": "^5.2.10",
Expand All @@ -24,12 +26,17 @@
"react": "^19.2.4",
"react-dom": "^19.2.4",
"sst": "^3.17.25",
"tailwindcss": "^4.1.18"
"tailwindcss": "^4.1.18",
"typescript": "^5.9.3",
"vanilla-cookieconsent": "^3.1.0"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.19",
"fast-check": "^3.23.2",
"jsdom": "^25.0.1",
"prettier": "^3.8.0",
"prettier-plugin-astro": "^0.14.1",
"prettier-plugin-tailwindcss": "^0.6.14"
"prettier-plugin-tailwindcss": "^0.6.14",
"vitest": "^3.2.3"
}
}
137 changes: 137 additions & 0 deletions src/components/CookieConsent.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
import "vanilla-cookieconsent/dist/cookieconsent.css";
import "../styles/cookies.css";
---

<script>
import * as CookieConsent from "vanilla-cookieconsent";

CookieConsent.run({
manageScriptTags: true,

guiOptions: {
consentModal: {
layout: "cloud",
position: "bottom center",
flipButtons: false,
},
preferencesModal: {
layout: "box",
},
},

categories: {
necessary: {
readOnly: true,
},
analytics_cookies: {},
marketing_cookies: {},
},

onConsent: ({ cookie }) => {
// Fires after initial consent or on page load with existing consent
},

onChange: ({ cookie, changedCategories }) => {
for (const category of changedCategories) {
if (!CookieConsent.acceptedCategory(category)) {
CookieConsent.eraseCookies(getCookiesForCategory(category));
}
}
},

language: {
default: "en",
translations: {
en: {
consentModal: {
title: "Cookies & Privacy",
description:
"We use cookies to enhance your experience. You can accept all cookies, reject optional ones, or customise your preferences.",
acceptAllBtn: "Accept all Cookies",
acceptNecessaryBtn: "Reject all",
showPreferencesBtn: "Customise Cookies",
},
preferencesModal: {
title: "Cookie Settings",
savePreferencesBtn: "Save settings",
acceptAllBtn: "Accept all",
acceptNecessaryBtn: "Reject all",
closeIconLabel: "Close",
sections: [
{
title: "Cookie Usage",
description:
"We use cookies to ensure basic site functionality and enhance your experience. Choose which categories to allow.",
},
{
title: "Necessary Cookies",
description:
"These cookies are essential for the website to function and cannot be disabled.",
linkedCategory: "necessary",
},
{
title: "Analytics Cookies",
description:
"These cookies help us understand how visitors interact with the website by collecting anonymous data.",
linkedCategory: "analytics_cookies",
cookieTable: {
headers: {
name: "Name",
domain: "Domain",
expiration: "Expiration",
description: "Description",
},
body: [
{
name: "_ga",
domain: "google.com",
expiration: "2 years",
description: "Distinguishes unique users.",
},
{
name: "_gid",
domain: "google.com",
expiration: "1 day",
description: "Distinguishes unique users.",
},
],
},
},
{
title: "Marketing Cookies",
description:
"These cookies are used to deliver relevant advertisements and track campaign effectiveness.",
linkedCategory: "marketing_cookies",
cookieTable: {
headers: {
name: "Name",
domain: "Domain",
expiration: "Expiration",
description: "Description",
},
body: [
{
name: "_gcl_au",
domain: "google.com",
expiration: "90 days",
description: "Stores conversion data for Google Ads.",
},
],
},
},
],
},
},
},
},
});

function getCookiesForCategory(category: string): string[] {
const cookieMap: Record<string, string[]> = {
analytics_cookies: ["_ga", "_gid", "_gat"],
marketing_cookies: ["_gcl_au"],
};
return cookieMap[category] ?? [];
}
</script>
27 changes: 23 additions & 4 deletions src/components/nav/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import React, { useState, useEffect, useRef } from 'react';
import LogoImg from '../../assets/CoreCollective_White-Wordmark.png';
import { pushEvent } from '../../lib/dataLayer';

export function trackNavClick(e: React.MouseEvent<HTMLAnchorElement>): void {
const anchor = e.currentTarget;
const img = anchor.querySelector("img");
const linkText = anchor.textContent?.trim() || img?.alt || "";
const linkUrl = anchor.getAttribute("href") || "";

pushEvent({ event: "nav_click", linkText, linkUrl });
// Do NOT call e.preventDefault() — default navigation must proceed
}

type NavLink =
| { name: string; href: string }
Expand Down Expand Up @@ -50,7 +61,7 @@ export default function Navbar() {
<header className="bg-cc-blue fixed inset-x-0 top-0 z-50 h-30 text-white">
<nav className="mx-auto flex h-full items-center justify-between gap-4 px-4 lg:gap-8 lg:px-8">
<div className="flex h-full min-w-0 max-w-75 items-center">
<a href="/">
<a href="/" onClick={trackNavClick}>
<img src={LogoImg.src} alt="Logo" className="h-auto w-full" />
</a>
</div>
Expand Down Expand Up @@ -101,7 +112,10 @@ export default function Navbar() {
? 'text-cc-cyan font-bold'
: 'text-white'
}`}
onClick={() => setDropdownOpen(null)}
onClick={(e) => {
trackNavClick(e);
setDropdownOpen(null);
}}
>
{child.name}
</a>
Expand All @@ -127,6 +141,7 @@ export default function Navbar() {
className={`hover:text-cc-cyan transition-colors ${
isActive ? 'text-cc-cyan font-bold' : 'text-white'
}`}
onClick={trackNavClick}
>
{link.name}
</a>
Expand Down Expand Up @@ -211,7 +226,8 @@ export default function Navbar() {
? 'text-cc-cyan'
: 'text-white'
}`}
onClick={() => {
onClick={(e) => {
trackNavClick(e);
setIsOpen(false);
setDropdownOpen(null);
}}
Expand All @@ -236,7 +252,10 @@ export default function Navbar() {
className={`hover:text-cc-cyan block py-4 ${
currentPath === link.href ? 'text-cc-cyan' : 'text-white'
}`}
onClick={() => setIsOpen(false)}
onClick={(e) => {
trackNavClick(e);
setIsOpen(false);
}}
>
{link.name}
</a>
Expand Down
146 changes: 146 additions & 0 deletions src/components/nav/__tests__/Navbar.pbt.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { describe, it, expect, vi, beforeEach } from "vitest";
import fc from "fast-check";
import { trackNavClick } from "../Navbar";

vi.mock("../../../lib/dataLayer", () => ({
pushEvent: vi.fn(),
}));

import { pushEvent } from "../../../lib/dataLayer";

const mockedPushEvent = vi.mocked(pushEvent);

function createMockEvent(
anchor: HTMLAnchorElement
): React.MouseEvent<HTMLAnchorElement> {
return {
currentTarget: anchor,
preventDefault: vi.fn(),
} as unknown as React.MouseEvent<HTMLAnchorElement>;
}

describe("Feature: consent-banner-datalayer, Property 2: Navigation link text extraction", () => {
/**
* **Validates: Requirements 8.2, 8.3, 8.4**
*
* For any anchor element containing arbitrary text content (including
* leading/trailing whitespace) or an image with an alt attribute, the
* trackNavClick extraction logic SHALL produce a linkText equal to the
* trimmed textContent of the anchor (or the alt attribute of the contained
* img if textContent is empty), and a linkUrl equal to the exact href
* attribute value.
*/

beforeEach(() => {
mockedPushEvent.mockClear();
});

it("extracts trimmed textContent as linkText and preserves href exactly", () => {
const arbWhitespace = fc.stringOf(fc.constantFrom(" ", "\t", "\n", "\r"));
const arbVisibleText = fc.string({ minLength: 1 }).filter((s) => s.trim().length > 0);
const arbHref = fc.string();

fc.assert(
fc.property(
arbWhitespace,
arbVisibleText,
arbWhitespace,
arbHref,
(leadingWs, text, trailingWs, href) => {
mockedPushEvent.mockClear();

const anchor = document.createElement("a");
anchor.setAttribute("href", href);
anchor.textContent = leadingWs + text + trailingWs;

trackNavClick(createMockEvent(anchor));

expect(mockedPushEvent).toHaveBeenCalledTimes(1);
const call = mockedPushEvent.mock.calls[0][0];
expect(call).toEqual({
event: "nav_click",
linkText: (leadingWs + text + trailingWs).trim(),
linkUrl: href,
});
}
),
{ numRuns: 100 }
);
});

it("falls back to img alt when textContent is empty or whitespace-only", () => {
const arbWhitespaceOnly = fc.stringOf(fc.constantFrom(" ", "\t", "\n", "\r"));
const arbAlt = fc.string({ minLength: 1 });
const arbHref = fc.string();

fc.assert(
fc.property(
arbWhitespaceOnly,
arbAlt,
arbHref,
(whitespace, alt, href) => {
mockedPushEvent.mockClear();

const anchor = document.createElement("a");
anchor.setAttribute("href", href);
// Add whitespace-only text node (if any) so textContent.trim() is empty
if (whitespace.length > 0) {
anchor.appendChild(document.createTextNode(whitespace));
}
const img = document.createElement("img");
img.alt = alt;
anchor.appendChild(img);

trackNavClick(createMockEvent(anchor));

expect(mockedPushEvent).toHaveBeenCalledTimes(1);
const call = mockedPushEvent.mock.calls[0][0];

// textContent includes alt text from img element in jsdom
// The actual behavior: anchor.textContent includes the img alt text
// in the DOM (img elements don't have textContent visible),
// but whitespace + alt scenario depends on the DOM behavior.
// The logic is: textContent?.trim() || img?.alt || ""
const anchorTextContent = anchor.textContent?.trim() || "";
const expectedLinkText = anchorTextContent || img.alt || "";

expect(call).toEqual({
event: "nav_click",
linkText: expectedLinkText,
linkUrl: href,
});
}
),
{ numRuns: 100 }
);
});

it("preserves href attribute value exactly", () => {
// Generate various href patterns including special characters
const arbHref = fc.oneof(
fc.webUrl(),
fc.string(),
fc.constant("/"),
fc.constant("#"),
fc.constantFrom("/about/", "/contact?q=hello#top", "https://example.com/path")
);
const arbText = fc.string({ minLength: 1 }).filter((s) => s.trim().length > 0);

fc.assert(
fc.property(arbHref, arbText, (href, text) => {
mockedPushEvent.mockClear();

const anchor = document.createElement("a");
anchor.setAttribute("href", href);
anchor.textContent = text;

trackNavClick(createMockEvent(anchor));

expect(mockedPushEvent).toHaveBeenCalledTimes(1);
const call = mockedPushEvent.mock.calls[0][0];
expect((call as any).linkUrl).toBe(href);
}),
{ numRuns: 100 }
);
});
});
Loading
Loading