feat: add guide navigation integration and tests (refs #203)
- Add Guide link to public nav bar (desktop + mobile) in HomePage - Add Guide link to authenticated sidebar in Layout.tsx - Add Guide link to HamburgerDrawer with window.location guard - Add GuidePage integration tests (6 test scenarios) - Remove old PDF user guide at public/docs/v2026-01-03.pdf Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -89,6 +89,12 @@ export const HomePage = () => {
|
||||
<a href="#about" className="text-white/75 hover:text-white transition-colors">
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="/guide"
|
||||
className="text-white/75 hover:text-white transition-colors"
|
||||
>
|
||||
Guide
|
||||
</a>
|
||||
<button
|
||||
onClick={handleSignup}
|
||||
className="border border-primary-500/90 text-primary-500 hover:bg-primary-500/10 hover:border-primary-500 font-semibold py-2 px-6 rounded-lg transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-primary-500/50"
|
||||
@@ -160,6 +166,12 @@ export const HomePage = () => {
|
||||
>
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="/guide"
|
||||
className="block text-white/75 hover:text-white transition-colors py-2"
|
||||
>
|
||||
Guide
|
||||
</a>
|
||||
<button
|
||||
onClick={handleSignup}
|
||||
className="w-full border border-primary-500/90 text-primary-500 hover:bg-primary-500/10 font-semibold py-2 px-6 rounded-lg transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-primary-500/50"
|
||||
|
||||
98
frontend/src/pages/__tests__/GuidePage.test.tsx
Normal file
98
frontend/src/pages/__tests__/GuidePage.test.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
jest.mock('@auth0/auth0-react', () => ({
|
||||
useAuth0: () => ({
|
||||
isAuthenticated: false,
|
||||
loginWithRedirect: jest.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
useNavigate: () => jest.fn(),
|
||||
}));
|
||||
|
||||
// Mock MUI Accordion to avoid jsdom layout issues
|
||||
jest.mock('@mui/material', () => {
|
||||
const actual = jest.requireActual('@mui/material');
|
||||
return {
|
||||
...actual,
|
||||
Accordion: ({ children, expanded }: any) => (
|
||||
<div data-testid="accordion" data-expanded={expanded}>
|
||||
{children}
|
||||
</div>
|
||||
),
|
||||
AccordionSummary: ({ children }: any) => <div>{children}</div>,
|
||||
AccordionDetails: ({ children }: any) => <div>{children}</div>,
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@mui/icons-material/ExpandMore', () => ({
|
||||
__esModule: true,
|
||||
default: () => <span data-testid="expand-icon" />,
|
||||
}));
|
||||
|
||||
import { GuidePage } from '../GuidePage/GuidePage';
|
||||
import { guideSections } from '../GuidePage/guideTypes';
|
||||
|
||||
describe('GuidePage', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders page heading and subheading', () => {
|
||||
render(<GuidePage />);
|
||||
expect(screen.getByText('User Guide')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/Precision Vehicle Management/)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders all 10 section headings', () => {
|
||||
render(<GuidePage />);
|
||||
|
||||
const expectedHeadings = [
|
||||
'1. Getting Started',
|
||||
'2. Dashboard',
|
||||
'3. Vehicles',
|
||||
'4. Fuel Logs',
|
||||
'5. Maintenance',
|
||||
'6. Gas Stations',
|
||||
'7. Documents',
|
||||
'8. Settings',
|
||||
'9. Subscription Tiers and Pro Features',
|
||||
'10. Mobile Experience',
|
||||
];
|
||||
|
||||
expectedHeadings.forEach((heading) => {
|
||||
expect(screen.getByRole('heading', { name: heading })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders TOC with correct section titles', () => {
|
||||
render(<GuidePage />);
|
||||
|
||||
guideSections.forEach((section) => {
|
||||
const matches = screen.getAllByText(section.title);
|
||||
expect(matches.length).toBeGreaterThanOrEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders navigation bar with Guide link highlighted', () => {
|
||||
render(<GuidePage />);
|
||||
|
||||
const guideLinks = screen.getAllByText('Guide');
|
||||
expect(guideLinks.length).toBeGreaterThanOrEqual(1);
|
||||
});
|
||||
|
||||
it('renders GuideScreenshot components with loading="lazy"', () => {
|
||||
render(<GuidePage />);
|
||||
|
||||
const images = document.querySelectorAll('img[loading="lazy"]');
|
||||
expect(images.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('renders footer with copyright', () => {
|
||||
render(<GuidePage />);
|
||||
expect(screen.getByText(/FB Technologies LLC/)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user