Skip to content

Commit 37e64e4

Browse files
Copilotmnkiefer
andauthored
feat: address review comments - add Node.js engine requirement and Playwright test coverage
Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com>
1 parent acff070 commit 37e64e4

2 files changed

Lines changed: 129 additions & 0 deletions

File tree

docs/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
"name": "docs",
33
"type": "module",
44
"version": "0.0.1",
5+
"engines": {
6+
"node": ">=22.13.0"
7+
},
58
"scripts": {
69
"dev": "astro dev",
710
"start": "astro dev",

docs/tests/slide-preview.spec.ts

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test.describe('Slide Preview on Homepage', () => {
4+
test.beforeEach(async ({ page }) => {
5+
await page.goto('/gh-aw/');
6+
await page.waitForLoadState('networkidle');
7+
});
8+
9+
test('should render slide preview component', async ({ page }) => {
10+
// Verify the slide hero component exists
11+
const slideHero = page.locator('[data-slide-hero]');
12+
await expect(slideHero).toBeVisible();
13+
14+
// Verify the canvas element exists
15+
const canvas = page.locator('[data-slide-canvas]');
16+
await expect(canvas).toBeVisible();
17+
});
18+
19+
test('should load and render PDF slides', async ({ page }) => {
20+
// Wait for the loading state to be hidden
21+
const loading = page.locator('[data-slide-loading]');
22+
await expect(loading).toBeHidden({ timeout: 10000 });
23+
24+
// Verify the canvas has been rendered with content
25+
const canvas = page.locator('[data-slide-canvas]');
26+
await expect(canvas).toBeVisible();
27+
28+
// Check that the canvas has width and height set (indicating PDF has been rendered)
29+
const canvasElement = await canvas.elementHandle();
30+
const width = await canvasElement?.evaluate((el) => (el as HTMLCanvasElement).width);
31+
const height = await canvasElement?.evaluate((el) => (el as HTMLCanvasElement).height);
32+
33+
expect(width).toBeGreaterThan(0);
34+
expect(height).toBeGreaterThan(0);
35+
36+
// Verify the hero has the 'is-ready' class indicating successful load
37+
const slideHero = page.locator('[data-slide-hero]');
38+
await expect(slideHero).toHaveClass(/is-ready/);
39+
});
40+
41+
test('should be keyboard accessible', async ({ page }) => {
42+
// Wait for slides to load
43+
const loading = page.locator('[data-slide-loading]');
44+
await expect(loading).toBeHidden({ timeout: 10000 });
45+
46+
// Verify the stage has proper accessibility attributes
47+
const stage = page.locator('[data-slide-stage]');
48+
await expect(stage).toHaveAttribute('tabindex', '0');
49+
await expect(stage).toHaveAttribute('role', 'link');
50+
await expect(stage).toHaveAttribute('aria-label', 'Open slide presentation');
51+
52+
// Verify canvas has aria-label
53+
const canvas = page.locator('[data-slide-canvas]');
54+
await expect(canvas).toHaveAttribute('role', 'img');
55+
await expect(canvas).toHaveAttribute('aria-label');
56+
});
57+
58+
test('should navigate to PDF when Enter key is pressed', async ({ page }) => {
59+
// Wait for slides to load
60+
const loading = page.locator('[data-slide-loading]');
61+
await expect(loading).toBeHidden({ timeout: 10000 });
62+
63+
// Focus on the stage
64+
const stage = page.locator('[data-slide-stage]');
65+
await stage.focus();
66+
67+
// Listen for navigation
68+
const [response] = await Promise.all([
69+
page.waitForEvent('popup', { timeout: 5000 }).catch(() => null) ||
70+
page.waitForNavigation({ timeout: 5000 }).catch(() => null),
71+
stage.press('Enter'),
72+
]);
73+
74+
// If navigation happened, verify the URL contains the PDF path
75+
if (response) {
76+
const url = typeof response === 'object' && 'url' in response ?
77+
await response.url() :
78+
page.url();
79+
expect(url).toContain('slides/github-agentic-workflows.pdf');
80+
}
81+
});
82+
83+
test('should navigate to PDF when Space key is pressed', async ({ page }) => {
84+
// Wait for slides to load
85+
const loading = page.locator('[data-slide-loading]');
86+
await expect(loading).toBeHidden({ timeout: 10000 });
87+
88+
// Focus on the stage
89+
const stage = page.locator('[data-slide-stage]');
90+
await stage.focus();
91+
92+
// Listen for navigation
93+
const [response] = await Promise.all([
94+
page.waitForEvent('popup', { timeout: 5000 }).catch(() => null) ||
95+
page.waitForNavigation({ timeout: 5000 }).catch(() => null),
96+
stage.press('Space'),
97+
]);
98+
99+
// If navigation happened, verify the URL contains the PDF path
100+
if (response) {
101+
const url = typeof response === 'object' && 'url' in response ?
102+
await response.url() :
103+
page.url();
104+
expect(url).toContain('slides/github-agentic-workflows.pdf');
105+
}
106+
});
107+
108+
test('should handle PDF fetch failures gracefully', async ({ page }) => {
109+
// Override the PDF request to fail
110+
await page.route('**/slides/github-agentic-workflows.pdf', (route) => {
111+
route.abort('failed');
112+
});
113+
114+
// Reload the page
115+
await page.goto('/gh-aw/');
116+
await page.waitForLoadState('networkidle');
117+
118+
// Wait a bit for the error to be displayed
119+
await page.waitForTimeout(2000);
120+
121+
// Verify error message is displayed
122+
const loading = page.locator('[data-slide-loading]');
123+
const errorText = await loading.textContent();
124+
expect(errorText).toContain('Unable to load slides');
125+
});
126+
});

0 commit comments

Comments
 (0)