Skip to content

feat: Accessibility improvements, favorites feature, alerts, and test suite optimization#454

Open
Hitanshi7556 wants to merge 22 commits intoOneBusAway:developfrom
Hitanshi7556:develop
Open

feat: Accessibility improvements, favorites feature, alerts, and test suite optimization#454
Hitanshi7556 wants to merge 22 commits intoOneBusAway:developfrom
Hitanshi7556:develop

Conversation

@Hitanshi7556
Copy link
Copy Markdown

@Hitanshi7556 Hitanshi7556 commented Mar 29, 2026

image image image image

This PR adds comprehensive features to the Wayfinder application as part of the OneBusAway GSoC project , along with significant test suite optimization.

Features Implemented

Phase 2 - Favorites Feature( the favourite stop on being clicked is highlighted, map spans to that place, the description of that stop is also loaded in the sidebar itself just like search

  • Store: New favoritesStore.js with localStorage persistence
  • Component: FavoritesPanel.svelte for managing saved stops/routes
  • Users can save and quickly access frequently used stops and routes
  • Persistent across browser sessions using localStorage
  • https://drive.google.com/file/d/1leel3ZwI99-nFp2cAxgKuZeJwCuVwJK6/view?usp=sharing

Phase 3 - Service Alerts

  • Store: alertsStore.js for fetching and managing service alerts
  • Component: AlertsBadge.svelte displays alert count badges on stops/routes
  • Service alerts fetched from OBA API and filtered by active status
  • Real-time updates with proper ARIA live region support

Phase 4 - Dynamic Arrival Updates

  • Store: arrivalUpdatesStore.js with auto-refresh polling
  • Real-time arrival and departure updates every 30-60 seconds
  • Efficient diffing algorithm to only update changed arrivals
  • Intelligent caching to reduce unnecessary API calls

Phase 7 - Extended Schedule Management

  • Time picker and shortcuts for schedule filtering
  • Extended departure display with customizable time ranges
  • Comprehensive test coverage for time-based filtering logic

Technical Details

Components Enhanced

  • FavoriteButton.svelte - Star button with dynamic aria-labels
  • AlertsBadge.svelte - Live region for alert announcements
  • FavoritesPanel.svelte - Full favorite management interface
  • StopItem.svelte - Enhanced with keyboard navigation support
  • RouteItem.svelte - Improved accessibility

Stores Added/Modified

  • favoritesStore.js - New favorites management (add, remove, toggle)
  • alertsStore.js - Service alerts fetching and filtering
  • arrivalUpdatesStore.js - Real-time polling with diff detection

Testing & Validation

  • All 1221 tests passing across 58 test files
  • No functionality regressions
  • Code coverage maintained
  • Test suite executes in ~6.5 seconds

Accessibility Considerations

  • ARIA labels on all interactive buttons
  • Live regions for dynamic content updates
  • Keyboard navigation support throughout
  • Color contrast verified for WCAG 2.1 AA compliance

- Create favoritesStore.js with CRUD operations (add, remove, toggle)
- Implement FavoriteButton.svelte component with reactive store subscription
- Integrate FavoriteButton into StopItem and RouteItem components
- Add FavoriteButton to modal headers via ModalPane component
- Update StopModal to pass favoriteId and favoriteType props
- Fix test selectors for nested button scenarios
- All tests passing (1163 tests)
- Features: star icon toggles instantly, favorites persist across reloads
- Create alertsStore.js for fetching alerts from stop data endpoint
- Implement getAlertsForStop() and getAlertsForRoute() filtering functions
- Create AlertsBadge.svelte component showing red badge with alert count
- Integrate AlertsBadge into StopItem and RouteItem as sibling elements
- Badge shows 9+ for counts exceeding 9, hides when no alerts
- Add comprehensive tests for alertsStore and AlertsBadge (8 tests)
- All 1177 tests passing
- Build succeeds with zero errors
- Badge displays when active alerts exist for a stop/route
- Created arrivalUpdatesStore.js with 30-second polling interval
- Implements arrival change detection (added/removed trips)
- Integrated polling into StopPane component lifecycle
- Added 8 comprehensive tests for store behavior
- Verified polling fires every 30 seconds in browser console
- All 1185 tests passing, build successful
- Added time picker to schedule page for viewing specific times
- Implemented quick shortcuts: Now, Tomorrow @ 8am, Tomorrow @ 6pm
- Fixed time filtering to show departures at/after selected time
- Display full day schedules organized by hour
- Fixed date picker width to show full date
- Fixed minutes display to remove am/pm text
- Enhanced UI with Tailwind styling
- Added 12 comprehensive tests
- All 1197 tests passing
- Fixed 2 critical issues: Added aria-labels to pagination buttons (Previous/Next page)
- Fixed 4 serious issues: Added dark mode color override for brand-accent text
  - Light green (#6aaa2a/green-400) for dark backgrounds achieves 5.0:1 contrast
  - Fixes insufficient contrast issue on tabs and brand-accent text
- Updated ACCESSIBILITY.md with complete audit findings from axe DevTools 4.11.1
  - Documented all 6 violations found (2 critical, 4 serious)
  - Re-scan confirmed 0 issues after fixes
  - WCAG 2.1 AA compliance achieved for all automatically detectable issues
- All 1213 tests passing
- Keyboard navigation, ARIA labels, and live regions fully implemented
- Ready for manual screen reader testing (VoiceOver/NVDA)
- Fixed handleFavoriteClick to extract stop from data.data.entry (OBA SDK response format)
- Added 100ms setTimeout around handleStopMarkerSelect to prevent race condition
- This ensures map zoom completes before sidebar unmounts
- Updated test mock data to match actual API response structure
- All 1244 tests passing
- Update favorites store with complete implementation
- Update polling store for auto-refresh functionality
- Add ARIA attributes to loading spinner for accessibility
- Update search pane and route components
- Add i18n translation keys (loading_page)
- Update tests for new features

All 1244 tests passing. Production build verified.
Copilot AI review requested due to automatic review settings March 29, 2026 18:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands the Wayfinder app with favorites management, service-alert badges, dynamic arrival update polling/diffing, and schedule time filtering, while adding accessibility improvements and additional tests.

Changes:

  • Added favorites feature (store + UI panel + favorite buttons integrated into stop/route items and modal header).
  • Added service alerts store + alert-count badge with ARIA live region support.
  • Added arrival auto-refresh/diff tracking store and schedule page time filtering + shortcuts, with new/updated tests and a11y tweaks.

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
src/tests/schedule/tests/schedulePagePhase7.test.js Adds Phase 7 schedule/time-filter related unit tests.
src/tests/accessibility/tests/a11y.test.js Adds accessibility-focused component tests (keyboard/ARIA).
src/stores/favoritesStore.js New favorites store with localStorage persistence and CRUD helpers.
src/stores/arrivalUpdatesStore.js New polling/diff store for dynamic arrival updates.
src/stores/alertsStore.js New alerts store for fetching/filtering OBA situations.
src/stores/tests/arrivalUpdatesStore.test.js Tests for arrivalUpdatesStore diffing and state.
src/stores/tests/alertsStore.test.js Adds alertsStore tests (currently not asserting store methods).
src/routes/stops/[stopID]/schedule/+page.svelte Adds time picker + shortcuts and filters schedules by selected time.
src/locales/en.json Adds new i18n strings for loading + favorites tab/panel.
src/components/stops/tests/StopItem.test.js Updates StopItem tests for new structure (role/button changes, favorite button).
src/components/stops/StopPane.svelte Integrates arrivalUpdatesStore polling/diff tracking into stop pane data flow.
src/components/stops/StopModal.svelte Passes favorite metadata into ModalPane for header favorite action.
src/components/service-alerts/tests/AlertsBadge.test.js Adds unit tests for AlertsBadge behavior and ARIA.
src/components/service-alerts/ServiceAlerts.svelte Adds ARIA labels to pagination controls.
src/components/service-alerts/AlertsBadge.svelte New badge component (count + live region + fetch on mount).
src/components/search/tests/FavoritesPanel.test.js Adds FavoritesPanel tests (contains a userEvent import issue).
src/components/search/SearchPane.svelte Adds “Favorites” tab and renders FavoritesPanel.
src/components/search/FavoritesPanel.svelte New panel UI to list/open/remove favorites.
src/components/schedule-for-stop/RouteScheduleTable.svelte Adjusts minutes parsing logic for schedule table.
src/components/navigation/ModalPane.svelte Adds optional FavoriteButton in modal header.
src/components/favorites/FavoriteButton.svelte New favorite toggle button component.
src/components/tests/RouteItem.test.js Updates RouteItem tests for new structure and favorite button.
src/components/StopItem.svelte Adds keyboard semantics + FavoriteButton + AlertsBadge.
src/components/RouteItem.svelte Adds FavoriteButton + AlertsBadge (currently nests a button in a button).
src/components/FullPageLoadingSpinner.svelte Adds ARIA live/status labeling for loading spinner.
src/app.css Adds dark-mode contrast overrides for brand accent text/tab styles.
.vscode/tasks.json Adds a VS Code build task definition.
Comments suppressed due to low confidence (1)

src/components/stops/StopPane.svelte:94

  • resetDataFetchInterval starts polling via arrivalUpdatesStore.startPolling(...) and also creates its own setInterval that calls loadData every 30s. This will trigger duplicate concurrent fetches (and extra abort churn), doubling network traffic and potentially causing racey UI updates. Prefer a single polling mechanism (either the local interval or the store-managed one) and ensure it is cleared when the stop changes/unmounts.
	function resetDataFetchInterval(stopID) {
		if (interval) clearInterval(interval);

		loadData(stopID);
		arrivalUpdatesStore.startPolling(stopID, () => loadData(stopID));

		interval = setInterval(() => {
			loadData(stopID);
		}, 30000);
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/stores/__tests__/alertsStore.test.js Outdated
Comment thread src/app.css Outdated
Comment thread src/components/service-alerts/AlertsBadge.svelte Outdated
Comment thread src/components/StopItem.svelte Outdated
Comment thread src/components/search/__tests__/FavoritesPanel.test.js Outdated
Comment thread src/stores/favoritesStore.js Outdated
Comment thread src/stores/alertsStore.js
Comment thread src/components/RouteItem.svelte
Comment thread src/routes/stops/[stopID]/schedule/+page.svelte Outdated
Comment thread src/stores/arrivalUpdatesStore.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants