Skip to content

Commit 16286e0

Browse files
berntpoppclaude
andauthored
fix: address all Copilot PR review findings (#2)
* fix: address all Copilot PR review findings - Fix em dashes (--) to hyphens (-) in ideas.md per style guide - Fix Tailwind @source path resolving to nonexistent docs/docs/ - Track Playwright config and test specs in git (.gitignore update) - Add withBase() to Timeline.vue links for correct GitHub Pages URLs - Add .vue files to Prettier format/check globs - Add --port 4321 to docs:dev script per convention - Fix repo URLs from berntpopp to halbritter-lab org Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: normalize line endings and format all files Run Prettier across all source files to fix pre-existing CRLF/LF inconsistencies and formatting drift. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e6ac374 commit 16286e0

11 files changed

Lines changed: 244 additions & 48 deletions

File tree

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
node_modules
22
docs/.vitepress/cache
33
docs/.vitepress/dist
4-
.playwright/
4+
.playwright/docs/
5+
.playwright/screenshots/
6+
.playwright/test-results/
57
playwright-report/
68
test-results/

.playwright/links.spec.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { test, expect } from '@playwright/test'
2+
3+
const sitePages = [
4+
'/',
5+
'/setup',
6+
'/agenda',
7+
'/ideas',
8+
'/resources',
9+
'/ai-tools',
10+
'/hands-on',
11+
'/slides',
12+
]
13+
14+
for (const pagePath of sitePages) {
15+
test(`internal links on ${pagePath}`, async ({ page }) => {
16+
await page.goto(pagePath)
17+
await page.waitForLoadState('networkidle')
18+
19+
const allLinks = await page.locator('a[href]').all()
20+
const hrefs = await Promise.all(
21+
allLinks.map((link) => link.getAttribute('href'))
22+
)
23+
24+
// Filter to internal links only (start with / or are relative)
25+
const internalHrefs = hrefs.reduce((links, href) => {
26+
if (
27+
href &&
28+
!href.startsWith('http') &&
29+
!href.startsWith('mailto:') &&
30+
!href.startsWith('#')
31+
) {
32+
const resolved = new URL(href, page.url()).href
33+
links.add(resolved)
34+
}
35+
return links
36+
}, new Set<string>())
37+
38+
for (const url of internalHrefs) {
39+
const response = await page.request.get(url)
40+
expect
41+
.soft(response.status(), `${url} should return 200-299`)
42+
.toBeGreaterThanOrEqual(200)
43+
expect
44+
.soft(response.status(), `${url} should return 200-299`)
45+
.toBeLessThan(400)
46+
}
47+
})
48+
}

.playwright/playwright.config.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { defineConfig, devices } from '@playwright/test'
2+
3+
export default defineConfig({
4+
testDir: '.',
5+
fullyParallel: true,
6+
forbidOnly: !!process.env.CI,
7+
retries: process.env.CI ? 2 : 0,
8+
workers: process.env.CI ? 1 : undefined,
9+
reporter: 'html',
10+
11+
use: {
12+
baseURL: 'http://localhost:4321',
13+
trace: 'on-first-retry',
14+
},
15+
16+
webServer: {
17+
command: 'npx vitepress dev docs --port 4321',
18+
cwd: '..',
19+
url: 'http://localhost:4321/AI-Teachathon/',
20+
reuseExistingServer: !process.env.CI,
21+
timeout: 120000,
22+
stdout: 'pipe',
23+
stderr: 'pipe',
24+
},
25+
26+
projects: [
27+
{
28+
name: 'desktop',
29+
use: { ...devices['Desktop Chrome'] },
30+
testMatch: 'links.spec.ts',
31+
},
32+
{
33+
name: 'mobile',
34+
use: { ...devices['Pixel 5'] },
35+
testMatch: 'responsive.spec.ts',
36+
testIgnore: '**/Presentation/**',
37+
},
38+
{
39+
name: 'presentation',
40+
use: {
41+
viewport: { width: 1024, height: 768 },
42+
deviceScaleFactor: 1,
43+
},
44+
testMatch: 'responsive.spec.ts',
45+
grep: /Presentation/,
46+
},
47+
],
48+
})

.playwright/responsive.spec.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { test, expect } from '@playwright/test'
2+
3+
test.describe('Responsive design', () => {
4+
test('no horizontal scroll on ideas page', async ({ page }) => {
5+
await page.goto('/ideas')
6+
await page.waitForLoadState('networkidle')
7+
8+
// Check if horizontal scrolling is actually possible (accounts for VitePress sidebar hidden off-screen)
9+
const hasHorizontalScroll = await page.evaluate(
10+
() =>
11+
document.documentElement.scrollWidth >
12+
document.documentElement.clientWidth,
13+
)
14+
expect(hasHorizontalScroll).toBe(false)
15+
})
16+
17+
test('no horizontal scroll on resources page', async ({ page }) => {
18+
await page.goto('/resources')
19+
await page.waitForLoadState('networkidle')
20+
21+
const hasHorizontalScroll = await page.evaluate(
22+
() =>
23+
document.documentElement.scrollWidth >
24+
document.documentElement.clientWidth,
25+
)
26+
expect(hasHorizontalScroll).toBe(false)
27+
})
28+
29+
test('all main pages render without errors', async ({ page }) => {
30+
const pages = ['/', '/setup', '/agenda', '/ideas', '/resources']
31+
for (const pagePath of pages) {
32+
const errors: string[] = []
33+
page.on('pageerror', (err) => errors.push(err.message))
34+
35+
await page.goto(pagePath)
36+
await page.waitForLoadState('networkidle')
37+
38+
expect.soft(errors, `${pagePath} should have no JS errors`).toEqual([])
39+
}
40+
})
41+
})
42+
43+
test.describe('Presentation', () => {
44+
test('renders Marp slides at 1024x768', async ({ page }) => {
45+
await page.goto('/presentation.html', { waitUntil: 'networkidle' })
46+
47+
// Verify Marp slides rendered
48+
const slides = page.locator('svg[data-marpit-svg]')
49+
await expect(slides.first()).toBeVisible({ timeout: 10000 })
50+
51+
// Verify multiple slides exist
52+
const slideCount = await slides.count()
53+
expect(slideCount).toBeGreaterThan(1)
54+
})
55+
})
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { test, devices } from '@playwright/test'
2+
3+
const BASE = 'http://localhost:4321/AI-Teachathon'
4+
5+
test('ideas desktop', async ({ browser }) => {
6+
const ctx = await browser.newContext({
7+
viewport: { width: 1440, height: 900 },
8+
colorScheme: 'dark',
9+
})
10+
const p = await ctx.newPage()
11+
await p.goto(`${BASE}/ideas`, { waitUntil: 'networkidle' })
12+
await p.waitForTimeout(1500)
13+
await p.screenshot({
14+
path: '.playwright/screenshots/ideas-current.png',
15+
fullPage: true,
16+
})
17+
await ctx.close()
18+
})
19+
20+
test('ideas mobile', async ({ browser }) => {
21+
const ctx = await browser.newContext({
22+
...devices['iPhone 13'],
23+
colorScheme: 'dark',
24+
})
25+
const p = await ctx.newPage()
26+
await p.goto(`${BASE}/ideas`, { waitUntil: 'networkidle' })
27+
await p.waitForTimeout(1500)
28+
await p.screenshot({
29+
path: '.playwright/screenshots/ideas-mobile-current.png',
30+
fullPage: true,
31+
})
32+
await ctx.close()
33+
})

docs/.vitepress/config.mts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ export default defineConfig({
6363
},
6464

6565
editLink: {
66-
pattern: 'https://github.com/berntpopp/AI-Teachathon/edit/main/docs/:path',
66+
pattern:
67+
'https://github.com/halbritter-lab/AI-Teachathon/edit/main/docs/:path',
6768
text: 'Edit this page on GitHub',
6869
},
6970

@@ -82,13 +83,16 @@ export default defineConfig({
8283
],
8384

8485
socialLinks: [
85-
{ icon: 'github', link: 'https://github.com/berntpopp/AI-Teachathon' },
86+
{
87+
icon: 'github',
88+
link: 'https://github.com/halbritter-lab/AI-Teachathon',
89+
},
8690
],
8791

8892
footer: {
8993
message: 'Halbritter Lab · CeRKiD · Charite Berlin',
9094
copyright:
91-
'<a href="https://github.com/berntpopp/AI-Teachathon">Contribute on GitHub</a>',
95+
'<a href="https://github.com/halbritter-lab/AI-Teachathon">Contribute on GitHub</a>',
9296
},
9397
},
9498
})

docs/.vitepress/theme/components/Timeline.vue

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@
99
<!-- Timeline dot -->
1010
<span
1111
class="absolute -start-[11px] flex h-5 w-5 items-center justify-center rounded-full ring-4 ring-[var(--vp-c-bg)]"
12-
:class="segment.highlight
13-
? 'bg-[var(--vp-c-brand-1)]'
14-
: 'bg-[var(--vp-c-divider)]'"
12+
:class="
13+
segment.highlight
14+
? 'bg-[var(--vp-c-brand-1)]'
15+
: 'bg-[var(--vp-c-divider)]'
16+
"
1517
/>
1618

1719
<!-- Time label -->
18-
<time class="mb-1 block text-sm font-normal leading-none text-[var(--vp-c-text-3)]">
20+
<time
21+
class="mb-1 block text-sm font-normal leading-none text-[var(--vp-c-text-3)]"
22+
>
1923
{{ segment.time }}
2024
</time>
2125

@@ -32,7 +36,7 @@
3236
<!-- Optional link -->
3337
<a
3438
v-if="segment.link"
35-
:href="segment.link"
39+
:href="withBase(segment.link)"
3640
class="mt-2 inline-flex items-center text-sm font-medium text-[var(--vp-c-brand-1)] hover:underline"
3741
>
3842
{{ segment.linkText || 'Learn more' }} →
@@ -43,6 +47,8 @@
4347
</template>
4448

4549
<script setup lang="ts">
50+
import { withBase } from 'vitepress'
51+
4652
interface TimelineSegment {
4753
time: string
4854
title: string

docs/.vitepress/theme/style.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@import 'tailwindcss';
22

3-
@source "../../docs/**/*.md";
3+
@source "../../**/*.md";
44
@source "../**/*.{vue,ts}";
55

66
/* === Dark Theme: Playful Hackathon Energy === */

docs/ideas.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# Project Ideas
22

3-
These are real project ideas from participants. Pick one that sounds interesting, or bring your own -- the goal is to learn Git, GitHub, and AI tools by building something you care about.
3+
These are real project ideas from participants. Pick one that sounds interesting, or bring your own - the goal is to learn Git, GitHub, and AI tools by building something you care about.
44

55
## Featured Project: KidneyQuest
66

77
<div class="featured-card">
88

99
**An educational game about rare kidney diseases, built with web technologies and AI assistance.**
1010

11-
KidneyQuest is an interactive game that teaches players about rare kidney diseases. It connects to the CeRKiD zebra mascot (because rare diseases are like zebras -- not horses). We'll build it together during the workshop using modern web tools and AI assistance.
11+
KidneyQuest is an interactive game that teaches players about rare kidney diseases. It connects to the CeRKiD zebra mascot (because rare diseases are like zebras - not horses). We'll build it together during the workshop using modern web tools and AI assistance.
1212

1313
This is the main project everyone will work on together. Follow the [hands-on guide](/hands-on) to get started.
1414

@@ -155,4 +155,4 @@ Describe what you want to show, and AI can suggest plot types and generate the c
155155

156156
## Contribute Your Ideas
157157

158-
Have a project idea? [Edit this page](https://github.com/berntpopp/AI-Teachathon/edit/main/docs/ideas.md) and add it -- that's what contributing on GitHub looks like.
158+
Have a project idea? [Edit this page](https://github.com/halbritter-lab/AI-Teachathon/edit/main/docs/ideas.md) and add it - that's what contributing on GitHub looks like.

0 commit comments

Comments
 (0)