Slight adjustment to tab styles + added spinner component
All checks were successful
Build, Test, and Publish (to Private NPM Registry) UI Components Library / publish (push) Successful in 1m2s
All checks were successful
Build, Test, and Publish (to Private NPM Registry) UI Components Library / publish (push) Successful in 1m2s
This commit is contained in:
parent
d85419a0d8
commit
d95bdda9ec
11 changed files with 407 additions and 14 deletions
|
|
@ -28,6 +28,10 @@ app.get('/test/tabs', (req: Request, res: Response) => {
|
|||
res.render('tabs', { toggleUnderline, toggleFilled });
|
||||
});
|
||||
|
||||
app.get('/test/spinner', (req: Request, res: Response) => {
|
||||
res.render('spinner');
|
||||
});
|
||||
|
||||
app.listen(3080, () => {
|
||||
console.log('Test server running on http://localhost:3080');
|
||||
});
|
||||
62
test-harness/tests/spinner.spec.ts
Normal file
62
test-harness/tests/spinner.spec.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
import { AxeBuilder } from '@axe-core/playwright';
|
||||
|
||||
test.describe('Accessible Spinner Component', () => {
|
||||
// Before each test, navigate to the specific EJS view serving the spinner
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// Assuming your test harness routes this to /test/spinner
|
||||
await page.goto('/test/spinner');
|
||||
});
|
||||
|
||||
test('should pass AAA accessibility audits', async ({ page }) => {
|
||||
// Wait for the component to be fully hydrated
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// Run the Axe-core engine against the page
|
||||
const accessibilityScanResults = await new AxeBuilder({ page })
|
||||
.withTags(['wcag2a', 'wcag2aa', 'wcag2aaa', 'best-practice'])
|
||||
.analyze();
|
||||
|
||||
// If there are violations, the test fails and prints them in the console
|
||||
expect(accessibilityScanResults.violations).toEqual([]);
|
||||
});
|
||||
|
||||
test('should render correct ARIA attributes and variant classes based on props', async ({ page }) => {
|
||||
// Test Default Spinner
|
||||
const defaultSpinner = page.locator('#example-spinner');
|
||||
await expect(defaultSpinner).toBeVisible();
|
||||
await expect(defaultSpinner).toHaveAttribute('aria-busy', 'true');
|
||||
// Ensure no extra variant classes leaked into the default spinner
|
||||
await expect(defaultSpinner).not.toHaveClass(/inline/);
|
||||
await expect(defaultSpinner).not.toHaveClass(/fast|slow/);
|
||||
|
||||
// Test Inline Spinner
|
||||
const inlineSpinner = page.locator('#inline-spinner');
|
||||
await expect(inlineSpinner).toHaveClass(/inline/);
|
||||
await expect(inlineSpinner).toHaveAttribute('aria-busy', 'true');
|
||||
|
||||
// Test Speed Variants
|
||||
const slowSpinner = page.locator('#slow-spinner');
|
||||
await expect(slowSpinner).toHaveClass(/slow/);
|
||||
|
||||
const fastSpinner = page.locator('#fast-spinner');
|
||||
await expect(fastSpinner).toHaveClass(/fast/);
|
||||
|
||||
// Test Combo (Slow + Inline)
|
||||
const comboSpinner = page.locator('#slow-inline-spinner');
|
||||
await expect(comboSpinner).toHaveClass(/inline/);
|
||||
await expect(comboSpinner).toHaveClass(/slow/);
|
||||
});
|
||||
|
||||
test('visual regression: component variants render correctly without layout shifts', async ({ page }) => {
|
||||
// We capture the entire <main> block to ensure all variants render correctly relative to standard text.
|
||||
const mainContent = page.locator('main');
|
||||
|
||||
// CRITICAL: Because spinners use CSS @keyframes, the rotation angle will be slightly different
|
||||
// every time Playwright takes a screenshot, causing the test to flake and fail.
|
||||
// `animations: 'disabled'` tells Playwright to pause all CSS animations and transitions instantly.
|
||||
await expect(mainContent).toHaveScreenshot('spinner-all-variants.png', {
|
||||
animations: 'disabled'
|
||||
});
|
||||
});
|
||||
});
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
36
test-harness/views/spinner.ejs
Normal file
36
test-harness/views/spinner.ejs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Spinner Test</title>
|
||||
<link rel="stylesheet" type="text/css" href="<%= componentsStyleHref %>">
|
||||
<script src="<%= componentsScriptSrc %>"></script>
|
||||
</head>
|
||||
<body>
|
||||
<main style="padding: 20px;">
|
||||
<h1>Spinner Test</h1>
|
||||
<p>The following is an example of a spinner component. It indicates a loading or processing state.</p>
|
||||
<section>
|
||||
<h2>Default Spinner</h2>
|
||||
<%- useComponent('spinner', { id: 'example-spinner', content: 'Loading...' }) %>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Inline Spinner</h2>
|
||||
<%- useComponent('spinner', { id: 'inline-spinner', content: 'Loading...', inline: true }) %>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Slow Spinner</h2>
|
||||
<%- useComponent('spinner', { id: 'slow-spinner', content: 'Loading...', speed: 'slow' }) %>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Fast Spinner</h2>
|
||||
<%- useComponent('spinner', { id: 'fast-spinner', content: 'Loading...', speed: 'fast' }) %>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Slow Inline Spinner</h2>
|
||||
<%- useComponent('spinner', { id: 'slow-inline-spinner', content: 'Loading...', inline: true, speed: 'slow' }) %>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue