Skip to content
Open
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
34 changes: 3 additions & 31 deletions .github/workflows/deploy-develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,35 +94,7 @@ jobs:
- name: Save develop build
run: mv dist develop-dist

# Second: Build main branch content for the root
- name: Checkout and build main branch with test site link
run: |
# Save current develop state
git stash push -m "Save develop changes" || echo "No changes to stash"

# Checkout main branch with full history and ensure tags are available
git checkout main
git pull origin main || echo "No changes to pull"

# Ensure all tags are fetched for version calculation
git fetch --tags || echo "Tags already available"

# Build main branch content with proper main branch GitVersion
npm run build

# Save main build
mv dist main-dist

# Return to develop branch and restore state
git checkout develop
if git stash list | grep -q "Save develop changes"; then
git stash pop
fi
env:
# Pass test site info for footer link
TEST_SITE_PATH: ${{ steps.pr-info.outputs.deploy_path }}

# Get GitVersion for main branch after checking it out
# Get GitVersion for main branch
- name: Get main branch GitVersion
id: gitversion-main
run: |
Expand Down Expand Up @@ -153,8 +125,8 @@ jobs:
git stash pop
fi

# Rebuild main with proper GitVersion values
- name: Rebuild main branch with correct GitVersion
# Build main branch with proper GitVersion values
- name: Build main branch with correct GitVersion
run: |
# Save current develop state
git stash push -m "Save develop changes" || echo "No changes to stash"
Expand Down
4 changes: 2 additions & 2 deletions gitversion.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ commit-message-incrementing: Enabled
branches:
main:
regex: ^main$
mode: ContinuousDelivery
mode: ContinuousDeployment
label: ''
increment: Patch
develop:
regex: ^develop$
mode: ContinuousDeployment
label: alpha
increment: None
increment: Patch
release:
regex: ^releases?[/-]
mode: ContinuousDelivery
Expand Down
29 changes: 25 additions & 4 deletions src/scripts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1265,17 +1265,38 @@ const processedTimezoneCache = new Map<number, ProcessedTimezoneData>();
// Cache key for localStorage
const TIMEZONE_CACHE_KEY = 'everytimezone_processed_timezones';

/**
* Type guard to check if an object is a valid TimeZone
*/
function isValidTimeZone(obj: unknown): obj is TimeZone {
return (
typeof obj === 'object' &&
obj !== null &&
typeof (obj as TimeZone).name === 'string' &&
typeof (obj as TimeZone).offset === 'number' &&
typeof (obj as TimeZone).displayName === 'string' &&
typeof (obj as TimeZone).iana === 'string' &&
typeof (obj as TimeZone).cityName === 'string' &&
typeof (obj as TimeZone).abbreviation === 'string'
// Note: daylight, isCustom, isOffCycle, coordinates are optional properties
);
}

/**
* Type guard to check if an object is a valid ProcessedTimezoneData
*/
function isProcessedTimezoneData(obj: unknown): obj is ProcessedTimezoneData {
const candidate = obj as ProcessedTimezoneData;
return (
typeof obj === 'object' &&
obj !== null &&
Array.isArray((obj as ProcessedTimezoneData).juneTimeZones) &&
Array.isArray((obj as ProcessedTimezoneData).decemberTimeZones) &&
typeof (obj as ProcessedTimezoneData).userTimezone === 'string' &&
typeof (obj as ProcessedTimezoneData).currentYear === 'number'
Array.isArray(candidate.juneTimeZones) &&
Array.isArray(candidate.decemberTimeZones) &&
typeof candidate.userTimezone === 'string' &&
typeof candidate.currentYear === 'number' &&
// Validate that array contents are valid TimeZone objects to prevent runtime errors
candidate.juneTimeZones.every(isValidTimeZone) &&
candidate.decemberTimeZones.every(isValidTimeZone)
);
}

Expand Down
26 changes: 12 additions & 14 deletions test/accessibility-comprehensive.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,15 +293,15 @@ describe('WCAG AAA Accessibility Standards', () => {
it('should meet WCAG AAA color contrast requirements (7:1 for normal text)', () => {
// Test all text elements for complete accessibility coverage
const textElements = document.querySelectorAll('*');
let contrastIssues: string[] = [];

textElements.forEach((element, index) => {

// Use functional approach for better performance instead of repeatedly calling push()
const contrastIssues = Array.from(textElements).flatMap((element, index) => {
const styles = window.getComputedStyle(element);
const textColor = styles.color;
const backgroundColor = getComputedBackgroundColor(element);

// Test all elements including hidden ones for screen reader compatibility
if (!element.textContent?.trim()) return;
if (!element.textContent?.trim()) return [];

if (textColor && backgroundColor) {
const textRGB = parseColor(textColor);
Expand All @@ -311,12 +311,11 @@ describe('WCAG AAA Accessibility Standards', () => {
const contrastRatio = getContrastRatio(textRGB, bgRGB);
// WCAG AAA requires 7:1 for normal text (not 4.5:1 which is AA)
if (contrastRatio < 7.0) {
contrastIssues.push(
`${element.tagName}[${index}] "${element.textContent?.trim().substring(0, 20)}..." contrast ratio ${contrastRatio.toFixed(2)}:1 is below WCAG AAA standard (7:1)`
);
return [`${element.tagName}[${index}] "${element.textContent?.trim().substring(0, 20)}..." contrast ratio ${contrastRatio.toFixed(2)}:1 is below WCAG AAA standard (7:1)`];
}
}
}
return [];
});

expect(contrastIssues.length, `Contrast issues found at ${size.name}: ${contrastIssues.join(', ')}`).toBe(0);
Expand All @@ -325,15 +324,15 @@ describe('WCAG AAA Accessibility Standards', () => {
it('should meet WCAG AAA large text contrast requirements (4.5:1)', () => {
// Test all elements for complete accessibility coverage
const allElements = document.querySelectorAll('*');
let contrastIssues: string[] = [];

allElements.forEach((element, index) => {

// Use functional approach for better performance instead of repeatedly calling push()
const contrastIssues = Array.from(allElements).flatMap((element, index) => {
const styles = window.getComputedStyle(element);
const fontSize = parseFloat(styles.fontSize);
const fontWeight = styles.fontWeight;

// Test all elements including hidden ones for screen reader compatibility
if (!element.textContent?.trim()) return;
if (!element.textContent?.trim()) return [];

// Large text is 18pt+ (24px+) or 14pt+ (18.5px+) bold according to WCAG
const isLargeText = fontSize >= 24 || (fontSize >= 18.5 && (fontWeight === 'bold' || parseInt(fontWeight) >= 700));
Expand All @@ -350,13 +349,12 @@ describe('WCAG AAA Accessibility Standards', () => {
const contrastRatio = getContrastRatio(textRGB, bgRGB);
// WCAG AAA requires 4.5:1 for large text
if (contrastRatio < 4.5) {
contrastIssues.push(
`Large text ${element.tagName}[${index}] "${element.textContent?.trim().substring(0, 20)}..." contrast ratio ${contrastRatio.toFixed(2)}:1 is below WCAG AAA standard (4.5:1)`
);
return [`Large text ${element.tagName}[${index}] "${element.textContent?.trim().substring(0, 20)}..." contrast ratio ${contrastRatio.toFixed(2)}:1 is below WCAG AAA standard (4.5:1)`];
}
}
}
}
return [];
});

expect(contrastIssues.length, `Large text contrast issues at ${size.name}: ${contrastIssues.join(', ')}`).toBe(0);
Expand Down