mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-15 13:00:58 -04:00
101 lines
3.0 KiB
TypeScript
101 lines
3.0 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('Content outline - Desktop', () => {
|
|
test.skip(({ isMobile }) => isMobile, 'Only test on desktop');
|
|
|
|
test('shows section headings without a top menu header item', async ({
|
|
page
|
|
}) => {
|
|
await page.goto(
|
|
'/learn/responsive-web-design-v9/review-semantic-html/review-semantic-html'
|
|
);
|
|
|
|
await expect(
|
|
page.getByRole('heading', { name: 'Semantic HTML Review' })
|
|
).toBeVisible();
|
|
|
|
const toggleButton = page.getByRole('button', { name: 'Outline' });
|
|
await toggleButton.click();
|
|
await expect(toggleButton).toHaveAttribute('aria-expanded', 'true');
|
|
|
|
const outlinePanel = page.getByRole('navigation', {
|
|
name: 'Content outline'
|
|
});
|
|
await expect(outlinePanel).toBeVisible();
|
|
|
|
const outlineItems = outlinePanel.getByRole('listitem');
|
|
expect(await outlineItems.count()).toBeGreaterThan(0);
|
|
|
|
await expect(
|
|
outlinePanel.getByRole('link', { name: 'Semantic HTML Review' })
|
|
).toHaveCount(0);
|
|
});
|
|
|
|
test('keeps active nav item in view while scrolling', async ({ page }) => {
|
|
await page.goto(
|
|
'/learn/responsive-web-design-v9/review-semantic-html/review-semantic-html'
|
|
);
|
|
|
|
await page.getByRole('button', { name: 'Outline' }).click();
|
|
|
|
const outlinePanel = page.getByRole('navigation', {
|
|
name: 'Content outline'
|
|
});
|
|
await expect(outlinePanel).toBeVisible();
|
|
|
|
const firstOutlineLink = outlinePanel.locator('a').first();
|
|
await firstOutlineLink.click();
|
|
await expect(firstOutlineLink).toHaveClass(/active/);
|
|
|
|
await page.evaluate(() => {
|
|
window.scrollTo({
|
|
top: document.body.scrollHeight,
|
|
behavior: 'auto'
|
|
});
|
|
});
|
|
|
|
const activeLink = outlinePanel
|
|
.locator('.content-outline-link.active')
|
|
.first();
|
|
await expect(activeLink).toBeVisible();
|
|
|
|
const inView = await activeLink.evaluate(item => {
|
|
const panel = item.closest('nav');
|
|
if (!panel) return false;
|
|
|
|
const panelRect = panel.getBoundingClientRect();
|
|
const itemRect = item.getBoundingClientRect();
|
|
return (
|
|
itemRect.top >= panelRect.top && itemRect.bottom <= panelRect.bottom
|
|
);
|
|
});
|
|
|
|
expect(inView).toBe(true);
|
|
});
|
|
});
|
|
|
|
test.describe('Content outline - Mobile', () => {
|
|
test.skip(({ isMobile }) => !isMobile, 'Only test on mobile');
|
|
|
|
test('sidebar closes on mobile when an item is clicked', async ({ page }) => {
|
|
await page.goto(
|
|
'/learn/responsive-web-design-v9/review-semantic-html/review-semantic-html'
|
|
);
|
|
|
|
const toggleButton = page.getByRole('button', { name: 'Outline' });
|
|
await toggleButton.click();
|
|
await expect(toggleButton).toHaveAttribute('aria-expanded', 'true');
|
|
|
|
const outlinePanel = page.getByRole('navigation', {
|
|
name: 'Content outline'
|
|
});
|
|
await expect(outlinePanel).toBeVisible();
|
|
|
|
const firstLink = outlinePanel.locator('a').first();
|
|
await firstLink.click();
|
|
|
|
// panel should hide after click
|
|
await expect(outlinePanel).toBeHidden();
|
|
});
|
|
});
|