@alliance-droid/svelte-docs-system 0.0.2 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/README.md +155 -23
  2. package/dist/components/APITable.svelte.d.ts +21 -0
  3. package/dist/components/Breadcrumbs.svelte.d.ts +14 -0
  4. package/dist/components/Callout.svelte.d.ts +15 -0
  5. package/dist/components/CodeBlock.svelte.d.ts +12 -0
  6. package/{src/lib → dist}/components/DocLayout.svelte +18 -6
  7. package/dist/components/DocLayout.svelte.d.ts +18 -0
  8. package/dist/components/DocsPage.svelte +39 -0
  9. package/dist/components/DocsPage.svelte.d.ts +8 -0
  10. package/dist/components/Documentation.svelte +639 -0
  11. package/dist/components/Footer.svelte.d.ts +10 -0
  12. package/dist/components/Image.svelte.d.ts +15 -0
  13. package/{src/lib → dist}/components/Navbar.svelte +4 -4
  14. package/dist/components/Navbar.svelte.d.ts +10 -0
  15. package/{src/lib → dist}/components/Search.svelte +2 -2
  16. package/dist/components/Search.svelte.d.ts +6 -0
  17. package/{template-starter/src/lib → dist}/components/Sidebar.svelte +2 -2
  18. package/dist/components/Sidebar.svelte.d.ts +9 -0
  19. package/dist/components/Tabs.svelte.d.ts +16 -0
  20. package/dist/config.d.ts +93 -0
  21. package/dist/config.js +89 -0
  22. package/dist/configLoader.d.ts +48 -0
  23. package/dist/configLoader.js +187 -0
  24. package/dist/configParser.d.ts +27 -0
  25. package/dist/configParser.js +208 -0
  26. package/{template-starter/src/lib/index.ts → dist/index.d.ts} +6 -7
  27. package/dist/index.js +18 -0
  28. package/dist/navigationBuilder.d.ts +64 -0
  29. package/dist/navigationBuilder.js +225 -0
  30. package/dist/plugin.d.ts +30 -0
  31. package/dist/plugin.js +172 -0
  32. package/dist/routing.d.ts +48 -0
  33. package/dist/routing.js +92 -0
  34. package/dist/stores/i18n.d.ts +20 -0
  35. package/dist/stores/i18n.js +119 -0
  36. package/dist/stores/nav.d.ts +20 -0
  37. package/dist/stores/nav.js +15 -0
  38. package/dist/stores/search.d.ts +49 -0
  39. package/dist/stores/search.js +127 -0
  40. package/dist/stores/theme.d.ts +7 -0
  41. package/dist/stores/theme.js +152 -0
  42. package/dist/stores/version.d.ts +18 -0
  43. package/dist/stores/version.js +93 -0
  44. package/dist/themeCustomization.d.ts +46 -0
  45. package/dist/themeCustomization.js +188 -0
  46. package/dist/utils/highlight.d.ts +13 -0
  47. package/dist/utils/highlight.js +83 -0
  48. package/dist/utils/index.d.ts +1 -0
  49. package/dist/utils/index.js +1 -0
  50. package/dist/utils/markdown.d.ts +40 -0
  51. package/dist/utils/markdown.js +165 -0
  52. package/package.json +45 -23
  53. package/COMPONENTS.md +0 -365
  54. package/COVERAGE_REPORT.md +0 -663
  55. package/SEARCH_VERIFICATION.md +0 -229
  56. package/TEST_SUMMARY.md +0 -344
  57. package/bin/init.js +0 -821
  58. package/docs/COMPONENT_LIBRARY_INTEGRATION_REPORT.md +0 -153
  59. package/docs/DARK_MODE_AUDIT_REPORT.md +0 -403
  60. package/docs/E2E_TESTS.md +0 -354
  61. package/docs/TESTING.md +0 -754
  62. package/docs/THEME_INHERITANCE.md +0 -192
  63. package/docs/de/index.md +0 -41
  64. package/docs/en/COMPONENTS.md +0 -443
  65. package/docs/en/api/examples.md +0 -100
  66. package/docs/en/api/overview.md +0 -69
  67. package/docs/en/components/index.md +0 -622
  68. package/docs/en/config/navigation.md +0 -505
  69. package/docs/en/config/theme-and-colors.md +0 -395
  70. package/docs/en/getting-started/integration.md +0 -406
  71. package/docs/en/guides/common-setups.md +0 -651
  72. package/docs/en/index.md +0 -243
  73. package/docs/en/markdown.md +0 -102
  74. package/docs/en/routing.md +0 -64
  75. package/docs/en/setup.md +0 -52
  76. package/docs/en/troubleshooting.md +0 -704
  77. package/docs/es/index.md +0 -41
  78. package/docs/fr/index.md +0 -41
  79. package/docs/ja/index.md +0 -41
  80. package/pagefind.toml +0 -8
  81. package/postcss.config.js +0 -5
  82. package/src/app.css +0 -119
  83. package/src/app.d.ts +0 -13
  84. package/src/app.html +0 -11
  85. package/src/lib/components/APITable.test.ts +0 -153
  86. package/src/lib/components/Breadcrumbs.test.ts +0 -148
  87. package/src/lib/components/Callout.test.ts +0 -100
  88. package/src/lib/components/CodeBlock.test.ts +0 -133
  89. package/src/lib/components/Image.test.ts +0 -163
  90. package/src/lib/components/Sidebar.svelte +0 -110
  91. package/src/lib/components/Tabs.test.ts +0 -102
  92. package/src/lib/config.test.ts +0 -140
  93. package/src/lib/config.ts +0 -179
  94. package/src/lib/configIntegration.test.ts +0 -272
  95. package/src/lib/configLoader.ts +0 -231
  96. package/src/lib/configParser.test.ts +0 -217
  97. package/src/lib/configParser.ts +0 -234
  98. package/src/lib/index.ts +0 -37
  99. package/src/lib/integration.test.ts +0 -426
  100. package/src/lib/navigationBuilder.test.ts +0 -338
  101. package/src/lib/navigationBuilder.ts +0 -268
  102. package/src/lib/performance.test.ts +0 -369
  103. package/src/lib/routing.test.ts +0 -202
  104. package/src/lib/routing.ts +0 -127
  105. package/src/lib/search-functionality.test.ts +0 -493
  106. package/src/lib/stores/i18n.test.ts +0 -180
  107. package/src/lib/stores/i18n.ts +0 -143
  108. package/src/lib/stores/nav.ts +0 -36
  109. package/src/lib/stores/search.test.ts +0 -140
  110. package/src/lib/stores/search.ts +0 -162
  111. package/src/lib/stores/theme.test.ts +0 -117
  112. package/src/lib/stores/theme.ts +0 -167
  113. package/src/lib/stores/version.test.ts +0 -139
  114. package/src/lib/stores/version.ts +0 -111
  115. package/src/lib/themeCustomization.test.ts +0 -223
  116. package/src/lib/themeCustomization.ts +0 -212
  117. package/src/lib/utils/highlight.test.ts +0 -136
  118. package/src/lib/utils/highlight.ts +0 -100
  119. package/src/lib/utils/index.ts +0 -7
  120. package/src/lib/utils/markdown.test.ts +0 -357
  121. package/src/lib/utils/markdown.ts +0 -77
  122. package/src/routes/+layout.server.ts +0 -1
  123. package/src/routes/+layout.svelte +0 -29
  124. package/src/routes/+page.svelte +0 -165
  125. package/src/routes/quote-demo/+page.svelte +0 -141
  126. package/static/robots.txt +0 -3
  127. package/svelte.config.js +0 -15
  128. package/tailwind.config.ts +0 -55
  129. package/template-starter/.github/workflows/build.yml +0 -40
  130. package/template-starter/.github/workflows/deploy-github-pages.yml +0 -47
  131. package/template-starter/.github/workflows/deploy-netlify.yml +0 -41
  132. package/template-starter/.github/workflows/deploy-vercel.yml +0 -64
  133. package/template-starter/NPM-PACKAGE-SETUP.md +0 -233
  134. package/template-starter/README.md +0 -320
  135. package/template-starter/docs/_config.json +0 -39
  136. package/template-starter/docs/api/components.md +0 -257
  137. package/template-starter/docs/api/overview.md +0 -169
  138. package/template-starter/docs/guides/configuration.md +0 -145
  139. package/template-starter/docs/guides/github-pages-deployment.md +0 -254
  140. package/template-starter/docs/guides/netlify-deployment.md +0 -159
  141. package/template-starter/docs/guides/vercel-deployment.md +0 -131
  142. package/template-starter/docs/index.md +0 -49
  143. package/template-starter/docs/setup.md +0 -149
  144. package/template-starter/package.json +0 -31
  145. package/template-starter/pagefind.toml +0 -3
  146. package/template-starter/postcss.config.js +0 -5
  147. package/template-starter/src/app.css +0 -34
  148. package/template-starter/src/app.d.ts +0 -13
  149. package/template-starter/src/app.html +0 -11
  150. package/template-starter/src/lib/components/APITable.svelte +0 -120
  151. package/template-starter/src/lib/components/APITable.test.ts +0 -96
  152. package/template-starter/src/lib/components/Breadcrumbs.svelte +0 -85
  153. package/template-starter/src/lib/components/Breadcrumbs.test.ts +0 -82
  154. package/template-starter/src/lib/components/Callout.svelte +0 -60
  155. package/template-starter/src/lib/components/Callout.test.ts +0 -91
  156. package/template-starter/src/lib/components/CodeBlock.svelte +0 -68
  157. package/template-starter/src/lib/components/CodeBlock.test.ts +0 -62
  158. package/template-starter/src/lib/components/DocLayout.svelte +0 -84
  159. package/template-starter/src/lib/components/Footer.svelte +0 -78
  160. package/template-starter/src/lib/components/Image.svelte +0 -100
  161. package/template-starter/src/lib/components/Image.test.ts +0 -81
  162. package/template-starter/src/lib/components/Navbar.svelte +0 -141
  163. package/template-starter/src/lib/components/Search.svelte +0 -248
  164. package/template-starter/src/lib/components/Tabs.svelte +0 -48
  165. package/template-starter/src/lib/components/Tabs.test.ts +0 -89
  166. package/template-starter/src/routes/+layout.svelte +0 -28
  167. package/template-starter/src/routes/+page.svelte +0 -92
  168. package/template-starter/svelte.config.js +0 -17
  169. package/template-starter/tailwind.config.ts +0 -17
  170. package/template-starter/tsconfig.json +0 -13
  171. package/template-starter/vite.config.ts +0 -6
  172. package/tests/e2e/example.spec.ts +0 -345
  173. package/tsconfig.json +0 -20
  174. package/vite.config.ts +0 -6
  175. package/vitest.config.ts +0 -33
  176. package/vitest.setup.ts +0 -21
  177. /package/{src/lib → dist}/assets/favicon.svg +0 -0
  178. /package/{src/lib → dist}/components/APITable.svelte +0 -0
  179. /package/{src/lib → dist}/components/Breadcrumbs.svelte +0 -0
  180. /package/{src/lib → dist}/components/Callout.svelte +0 -0
  181. /package/{src/lib → dist}/components/CodeBlock.svelte +0 -0
  182. /package/{src/lib → dist}/components/Footer.svelte +0 -0
  183. /package/{src/lib → dist}/components/Image.svelte +0 -0
  184. /package/{src/lib → dist}/components/Tabs.svelte +0 -0
  185. /package/{src/lib → dist}/svelte-component-library.d.ts +0 -0
@@ -1,89 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
-
3
- /**
4
- * Unit tests for Tabs component
5
- * Tests component configuration and prop handling
6
- */
7
-
8
- describe('Tabs Component', () => {
9
- describe('Props', () => {
10
- it('renders all tab buttons', () => {
11
- const items = [
12
- { label: 'Tab 1', content: 'Content 1' },
13
- { label: 'Tab 2', content: 'Content 2' }
14
- ];
15
-
16
- const labels = items.map((item) => item.label);
17
- expect(labels).toContain('Tab 1');
18
- expect(labels).toContain('Tab 2');
19
- });
20
-
21
- it('should accept items array prop', () => {
22
- const items = [
23
- { label: 'Overview', content: 'Overview content' },
24
- { label: 'API', content: 'API content' }
25
- ];
26
- expect(Array.isArray(items)).toBe(true);
27
- expect(items.length).toBeGreaterThan(0);
28
- expect(items[0]).toHaveProperty('label');
29
- expect(items[0]).toHaveProperty('content');
30
- });
31
-
32
- it('should have tab labels and content', () => {
33
- const items = [
34
- { label: 'Tab 1', content: 'Content 1' },
35
- { label: 'Tab 2', content: 'Content 2' }
36
- ];
37
- items.forEach((item) => {
38
- expect(item.label).toBeTruthy();
39
- expect(item.content).toBeTruthy();
40
- });
41
- });
42
-
43
- it('should display correct tab labels', () => {
44
- const items = [
45
- { label: 'Introduction', content: 'Intro content' },
46
- { label: 'Installation', content: 'Install content' },
47
- { label: 'Usage', content: 'Usage content' }
48
- ];
49
- const labels = items.map((item) => item.label);
50
- expect(labels).toContain('Introduction');
51
- expect(labels).toContain('Installation');
52
- expect(labels).toContain('Usage');
53
- });
54
- });
55
-
56
- describe('Functionality', () => {
57
- it('should track selected tab', () => {
58
- let selectedIndex = 0;
59
- const items = [
60
- { label: 'Tab 1', content: 'Content 1' },
61
- { label: 'Tab 2', content: 'Content 2' }
62
- ];
63
- expect(selectedIndex).toBeGreaterThanOrEqual(0);
64
- expect(selectedIndex).toBeLessThan(items.length);
65
- });
66
-
67
- it('should support switching between tabs', () => {
68
- const items = [
69
- { label: 'Tab 1', content: 'Content 1' },
70
- { label: 'Tab 2', content: 'Content 2' },
71
- { label: 'Tab 3', content: 'Content 3' }
72
- ];
73
- const currentTab = 1;
74
- expect(currentTab).toBeGreaterThanOrEqual(0);
75
- expect(currentTab).toBeLessThan(items.length);
76
- expect(items[currentTab].label).toBe('Tab 2');
77
- });
78
-
79
- it('should handle single tab', () => {
80
- const items = [{ label: 'Single Tab', content: 'Content' }];
81
- expect(items.length).toBe(1);
82
- });
83
-
84
- it('should be accessible with keyboard navigation', () => {
85
- const navigableKeys = ['Enter', 'Space', 'ArrowLeft', 'ArrowRight'];
86
- expect(navigableKeys.length).toBeGreaterThan(0);
87
- });
88
- });
89
- });
@@ -1,28 +0,0 @@
1
- <script lang="ts">
2
- import '../app.css';
3
-
4
- let { children } = $props();
5
- </script>
6
-
7
- <svelte:window
8
- on:resize={() => {
9
- // Handle window resize if needed
10
- }}
11
- />
12
-
13
- <div class="app">
14
- {@render children?.()}
15
- </div>
16
-
17
- <style>
18
- :global(body) {
19
- margin: 0;
20
- padding: 0;
21
- }
22
-
23
- .app {
24
- display: flex;
25
- flex-direction: column;
26
- min-height: 100vh;
27
- }
28
- </style>
@@ -1,92 +0,0 @@
1
- <script>
2
- // Home page for documentation starter
3
- </script>
4
-
5
- <main class="mx-auto max-w-4xl px-6 py-12">
6
- <div class="mb-12">
7
- <h1 class="mb-4 text-5xl font-bold">Documentation Starter</h1>
8
- <p class="mb-6 text-xl text-gray-600">
9
- Welcome to your documentation site built with Svelte Docs System.
10
- </p>
11
- <p class="text-lg text-gray-500">
12
- Edit the <code class="rounded bg-gray-100 px-2 py-1 font-mono">docs/</code> folder to add your documentation content.
13
- </p>
14
- </div>
15
-
16
- <section class="mb-12">
17
- <h2 class="mb-4 text-3xl font-bold">Getting Started</h2>
18
- <div class="space-y-4">
19
- <div class="rounded-lg border border-gray-200 p-6">
20
- <h3 class="mb-2 font-semibold">📝 Add Documentation</h3>
21
- <p class="text-gray-600">Create markdown files in the <code class="font-mono">docs/</code> folder and they'll automatically be added to your site.</p>
22
- </div>
23
- <div class="rounded-lg border border-gray-200 p-6">
24
- <h3 class="mb-2 font-semibold">⚙️ Configure Navigation</h3>
25
- <p class="text-gray-600">Edit <code class="font-mono">docs/_config.json</code> to customize the sidebar navigation structure.</p>
26
- </div>
27
- <div class="rounded-lg border border-gray-200 p-6">
28
- <h3 class="mb-2 font-semibold">🎨 Customize Styling</h3>
29
- <p class="text-gray-600">Update <code class="font-mono">tailwind.config.ts</code> and CSS files to match your brand.</p>
30
- </div>
31
- </div>
32
- </section>
33
-
34
- <section class="mb-12">
35
- <h2 class="mb-4 text-3xl font-bold">Available Scripts</h2>
36
- <ul class="space-y-2 text-gray-700">
37
- <li><code class="font-mono">npm run dev</code> - Start development server</li>
38
- <li><code class="font-mono">npm run build</code> - Build for production</li>
39
- <li><code class="font-mono">npm run preview</code> - Preview production build</li>
40
- <li><code class="font-mono">npm run check</code> - Type check and lint</li>
41
- </ul>
42
- </section>
43
-
44
- <section>
45
- <h2 class="mb-4 text-3xl font-bold">Learn More</h2>
46
- <p class="text-gray-700">
47
- Check the documentation in the <code class="font-mono">docs/</code> folder to learn how to use all available features.
48
- </p>
49
- </section>
50
- </main>
51
-
52
- <style>
53
- :global(body) {
54
- background-color: white;
55
- color: #333;
56
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
57
- }
58
-
59
- :global(.dark) :global(body) {
60
- background-color: #030712;
61
- color: #f3f4f6;
62
- }
63
-
64
- main {
65
- max-width: 56rem;
66
- margin: 0 auto;
67
- }
68
-
69
- h1 {
70
- color: #111827;
71
- }
72
-
73
- :global(.dark) h1 {
74
- color: white;
75
- }
76
-
77
- h2 {
78
- color: #111827;
79
- }
80
-
81
- :global(.dark) h2 {
82
- color: white;
83
- }
84
-
85
- code {
86
- color: #dc2626;
87
- }
88
-
89
- :global(.dark) code {
90
- color: #fca5a5;
91
- }
92
- </style>
@@ -1,17 +0,0 @@
1
- import adapter from '@sveltejs/adapter-static';
2
-
3
- /** @type {import('@sveltejs/kit').Config} */
4
- const config = {
5
- kit: {
6
- adapter: adapter({
7
- pages: 'build',
8
- assets: 'build',
9
- fallback: 'index.html'
10
- }),
11
- prerender: {
12
- entries: ['*']
13
- }
14
- }
15
- };
16
-
17
- export default config;
@@ -1,17 +0,0 @@
1
- export default {
2
- content: ['./src/**/*.{html,js,svelte,ts}'],
3
- theme: {
4
- extend: {
5
- colors: {
6
- 'docs': {
7
- 'primary': '#3b82f6',
8
- 'dark': '#1f2937',
9
- 'light': '#f9fafb',
10
- 'border': '#e5e7eb'
11
- }
12
- }
13
- }
14
- },
15
- plugins: [],
16
- darkMode: 'class'
17
- };
@@ -1,13 +0,0 @@
1
- {
2
- "extends": "./.svelte-kit/tsconfig.json",
3
- "compilerOptions": {
4
- "allowJs": true,
5
- "checkJs": true,
6
- "esModuleInterop": true,
7
- "forceConsistentCasingInFileNames": true,
8
- "resolveJsonModule": true,
9
- "skipLibCheck": true,
10
- "sourceMap": true,
11
- "strict": true
12
- }
13
- }
@@ -1,6 +0,0 @@
1
- import { sveltekit } from '@sveltejs/kit/vite';
2
- import { defineConfig } from 'vite';
3
-
4
- export default defineConfig({
5
- plugins: [sveltekit()]
6
- });
@@ -1,345 +0,0 @@
1
- import { test, expect } from '@playwright/test';
2
-
3
- /**
4
- * Example E2E Tests
5
- * Demonstrates the structure of E2E tests for Svelte Docs System
6
- *
7
- * Note: These tests require Playwright to be installed
8
- * Run with: npm run test:e2e
9
- */
10
-
11
- test.describe('Documentation System E2E', () => {
12
- test.beforeEach(async ({ page }) => {
13
- // Navigate to the documentation homepage before each test
14
- await page.goto('/');
15
- });
16
-
17
- test.describe('Navigation', () => {
18
- test('should navigate between pages', async ({ page }) => {
19
- // Find and click a navigation link
20
- await page.click('a[href="/docs/guides"]');
21
-
22
- // Wait for navigation and verify page content
23
- await page.waitForURL('/docs/guides');
24
- expect(page.url()).toContain('/docs/guides');
25
-
26
- // Verify content loaded
27
- const heading = await page.locator('h1');
28
- await expect(heading).toBeVisible();
29
- });
30
-
31
- test('should display breadcrumbs', async ({ page }) => {
32
- await page.goto('/docs/guides/getting-started');
33
-
34
- // Check breadcrumb structure
35
- const breadcrumbs = page.locator('[role="navigation"] a');
36
- const count = await breadcrumbs.count();
37
-
38
- expect(count).toBeGreaterThan(0);
39
-
40
- // Verify breadcrumb content
41
- const lastBreadcrumb = breadcrumbs.nth(count - 1);
42
- await expect(lastBreadcrumb).toContainText(/Getting Started|getting-started/i);
43
- });
44
-
45
- test('should update active navigation item', async ({ page }) => {
46
- const navItem = page.locator('nav a').first();
47
-
48
- await navItem.click();
49
- await page.waitForLoadState('networkidle');
50
-
51
- // Check if active class is applied
52
- const activeItem = page.locator('nav a.active, nav a[aria-current]').first();
53
- await expect(activeItem).toBeVisible();
54
- });
55
- });
56
-
57
- test.describe('Search', () => {
58
- test('should search and display results', async ({ page }) => {
59
- // Click search input
60
- const searchInput = page.locator('input[placeholder*="Search"]');
61
- await searchInput.click();
62
-
63
- // Type search query
64
- await searchInput.fill('getting started');
65
-
66
- // Wait for results to appear
67
- const searchResults = page.locator('[role="listbox"], .search-results');
68
- await expect(searchResults).toBeVisible();
69
-
70
- // Verify results contain the query
71
- const resultItems = page.locator('[role="option"], .search-result-item');
72
- expect(await resultItems.count()).toBeGreaterThan(0);
73
- });
74
-
75
- test('should navigate to search result', async ({ page }) => {
76
- const searchInput = page.locator('input[placeholder*="Search"]');
77
- await searchInput.fill('API');
78
-
79
- // Wait for results and click first one
80
- const firstResult = page.locator('[role="option"], .search-result-item').first();
81
- await firstResult.click();
82
-
83
- // Verify navigation happened
84
- await page.waitForLoadState('networkidle');
85
- expect(page.url()).toContain('/');
86
- });
87
-
88
- test('should show no results message', async ({ page }) => {
89
- const searchInput = page.locator('input[placeholder*="Search"]');
90
- await searchInput.fill('xyzabc123notarealterm');
91
-
92
- // Wait a bit for search to complete
93
- await page.waitForTimeout(500);
94
-
95
- // Check for no results message
96
- const noResultsMsg = page.locator('text=/No results|nothing found/i');
97
- await expect(noResultsMsg).toBeVisible();
98
- });
99
- });
100
-
101
- test.describe('Dark Mode', () => {
102
- test('should toggle dark mode', async ({ page }) => {
103
- // Find and click dark mode toggle
104
- const darkModeToggle = page.locator('[aria-label*="Dark"], [aria-label*="Theme"]');
105
-
106
- // Get initial state
107
- const htmlElement = page.locator('html');
108
- const initialClass = await htmlElement.getAttribute('class');
109
-
110
- // Click toggle
111
- await darkModeToggle.click();
112
-
113
- // Verify class changed
114
- const newClass = await htmlElement.getAttribute('class');
115
- expect(newClass).not.toBe(initialClass);
116
- });
117
-
118
- test('should persist dark mode preference', async ({ page, context }) => {
119
- // Enable dark mode
120
- const toggle = page.locator('[aria-label*="Dark"], [aria-label*="Theme"]');
121
- await toggle.click();
122
-
123
- // Verify it's enabled
124
- const htmlElement = page.locator('html');
125
- const isDarkMode = (await htmlElement.getAttribute('class'))?.includes('dark');
126
- expect(isDarkMode).toBeTruthy();
127
-
128
- // Reload page
129
- await page.reload();
130
-
131
- // Verify dark mode still active
132
- const isDarkModeAfterReload = (
133
- await htmlElement.getAttribute('class')
134
- )?.includes('dark');
135
- expect(isDarkModeAfterReload).toBeTruthy();
136
- });
137
-
138
- test('should have readable text in dark mode', async ({ page }) => {
139
- // Enable dark mode
140
- const toggle = page.locator('[aria-label*="Dark"], [aria-label*="Theme"]');
141
- await toggle.click();
142
-
143
- // Get text color and background color
144
- const mainContent = page.locator('main').first();
145
-
146
- const styles = await mainContent.evaluate((el) => {
147
- const computed = window.getComputedStyle(el);
148
- return {
149
- color: computed.color,
150
- backgroundColor: computed.backgroundColor
151
- };
152
- });
153
-
154
- // Verify colors are defined
155
- expect(styles.color).toBeTruthy();
156
- expect(styles.backgroundColor).toBeTruthy();
157
- });
158
- });
159
-
160
- test.describe('Responsive Design', () => {
161
- test('should show mobile menu on small screens', async ({ page }) => {
162
- // Set mobile viewport
163
- await page.setViewportSize({ width: 375, height: 667 });
164
-
165
- // Look for hamburger menu
166
- const hamburgerMenu = page.locator('[aria-label*="Menu"], [aria-label*="Navigation"]');
167
- await expect(hamburgerMenu).toBeVisible();
168
-
169
- // Click hamburger
170
- await hamburgerMenu.click();
171
-
172
- // Verify menu opens
173
- const mobileNav = page.locator('nav').first();
174
- await expect(mobileNav).toBeVisible();
175
- });
176
-
177
- test('should show sidebar on desktop', async ({ page }) => {
178
- // Set desktop viewport
179
- await page.setViewportSize({ width: 1440, height: 900 });
180
-
181
- // Sidebar should be visible
182
- const sidebar = page.locator('aside, nav');
183
- await expect(sidebar.first()).toBeVisible();
184
- });
185
- });
186
-
187
- test.describe('Accessibility', () => {
188
- test('should be keyboard navigable', async ({ page }) => {
189
- // Tab through page elements
190
- const firstButton = page.locator('button').first();
191
-
192
- // Initially should not have focus
193
- let hasFocus = await firstButton.evaluate((el) => el === document.activeElement);
194
- expect(hasFocus).toBeFalsy();
195
-
196
- // Press Tab and verify focus appears
197
- await page.keyboard.press('Tab');
198
-
199
- // Check if any element has focus
200
- const focusedElement = await page.evaluate(() => {
201
- return document.activeElement?.tagName;
202
- });
203
-
204
- expect(focusedElement).toBeTruthy();
205
- });
206
-
207
- test('should have alt text for images', async ({ page }) => {
208
- const images = page.locator('img');
209
-
210
- const count = await images.count();
211
- if (count > 0) {
212
- // Get alt text of first image
213
- const altText = await images.first().getAttribute('alt');
214
-
215
- // Should have alt text (if decorative, should be empty intentionally)
216
- expect(altText).not.toBeNull();
217
- }
218
- });
219
-
220
- test('should have proper heading hierarchy', async ({ page }) => {
221
- const h1Count = await page.locator('h1').count();
222
- const h2s = await page.locator('h2').count();
223
-
224
- // Page should have exactly one h1
225
- expect(h1Count).toBe(1);
226
-
227
- // h2s should exist (if multiple sections)
228
- // This is flexible as some pages might not have subsections
229
- expect(h2s).toBeGreaterThanOrEqual(0);
230
- });
231
- });
232
-
233
- test.describe('Content Display', () => {
234
- test('should render markdown content', async ({ page }) => {
235
- // Navigate to a content page
236
- await page.goto('/docs');
237
-
238
- // Wait for main content to load
239
- const mainContent = page.locator('main, article').first();
240
- await expect(mainContent).toBeVisible();
241
-
242
- // Verify content exists
243
- const text = await mainContent.textContent();
244
- expect(text).toBeTruthy();
245
- expect(text?.length).toBeGreaterThan(0);
246
- });
247
-
248
- test('should display code blocks with syntax highlighting', async ({ page }) => {
249
- const codeBlocks = page.locator('pre, code');
250
-
251
- if (await codeBlocks.count() > 0) {
252
- const firstCode = codeBlocks.first();
253
- await expect(firstCode).toBeVisible();
254
-
255
- // Verify code content
256
- const content = await firstCode.textContent();
257
- expect(content).toBeTruthy();
258
- }
259
- });
260
-
261
- test('should have functional copy button on code blocks', async ({ page }) => {
262
- const codeBlock = page.locator('pre').first();
263
-
264
- if (await codeBlock.isVisible()) {
265
- const copyButton = page
266
- .locator('button')
267
- .filter({ hasText: /Copy|copy/ })
268
- .first();
269
-
270
- if (await copyButton.isVisible()) {
271
- // Click copy button
272
- await copyButton.click();
273
-
274
- // Verify some feedback (success message, button state change, etc.)
275
- const successMsg = page.locator('text=/copied|success/i').first();
276
- await expect(successMsg).toBeVisible({ timeout: 2000 });
277
- }
278
- }
279
- });
280
- });
281
-
282
- test.describe('Performance', () => {
283
- test('should load page within acceptable time', async ({ page }) => {
284
- const startTime = Date.now();
285
-
286
- await page.goto('/');
287
- await page.waitForLoadState('networkidle');
288
-
289
- const loadTime = Date.now() - startTime;
290
-
291
- // Page should load within 3 seconds
292
- expect(loadTime).toBeLessThan(3000);
293
- });
294
-
295
- test('should have good Core Web Vitals', async ({ page }) => {
296
- await page.goto('/');
297
-
298
- const vitals = await page.evaluate(() => {
299
- return new Promise<any>((resolve) => {
300
- let lcp = 0;
301
- let cls = 0;
302
-
303
- const observer = new PerformanceObserver((list) => {
304
- for (const entry of list.getEntries()) {
305
- if ((entry as any).name === 'largest-contentful-paint') {
306
- lcp = (entry as any).renderTime || (entry as any).loadTime;
307
- } else if ((entry as any).hadRecentInput === false) {
308
- cls += (entry as any).value;
309
- }
310
- }
311
- });
312
-
313
- observer.observe({ entryTypes: ['largest-contentful-paint', 'layout-shift'] });
314
-
315
- setTimeout(() => {
316
- observer.disconnect();
317
- resolve({ lcp, cls });
318
- }, 3000);
319
- });
320
- });
321
-
322
- // LCP should be less than 2.5 seconds
323
- expect(vitals.lcp).toBeLessThan(2500);
324
-
325
- // CLS should be less than 0.1
326
- expect(vitals.cls).toBeLessThan(0.1);
327
- });
328
- });
329
- });
330
-
331
- test.describe('Error Handling', () => {
332
- test('should show 404 page for non-existent routes', async ({ page }) => {
333
- await page.goto('/docs/this-page-does-not-exist-123');
334
-
335
- // Should see 404 message or not found page
336
- const notFoundMsg = page.locator('text=/404|not found|does not exist/i');
337
-
338
- // Try to find error message
339
- const hasError =
340
- (await notFoundMsg.count()) > 0 ||
341
- page.url().includes('404');
342
-
343
- expect(hasError).toBeTruthy();
344
- });
345
- });
package/tsconfig.json DELETED
@@ -1,20 +0,0 @@
1
- {
2
- "extends": "./.svelte-kit/tsconfig.json",
3
- "compilerOptions": {
4
- "rewriteRelativeImportExtensions": true,
5
- "allowJs": true,
6
- "checkJs": true,
7
- "esModuleInterop": true,
8
- "forceConsistentCasingInFileNames": true,
9
- "resolveJsonModule": true,
10
- "skipLibCheck": true,
11
- "sourceMap": true,
12
- "strict": true,
13
- "moduleResolution": "bundler"
14
- }
15
- // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
16
- // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
17
- //
18
- // To make changes to top-level options such as include and exclude, we recommend extending
19
- // the generated config; see https://svelte.dev/docs/kit/configuration#typescript
20
- }
package/vite.config.ts DELETED
@@ -1,6 +0,0 @@
1
- import { sveltekit } from '@sveltejs/kit/vite';
2
- import { defineConfig } from 'vite';
3
-
4
- export default defineConfig({
5
- plugins: [sveltekit()]
6
- });
package/vitest.config.ts DELETED
@@ -1,33 +0,0 @@
1
- import { defineConfig } from 'vitest/config';
2
- import { sveltekit } from '@sveltejs/kit/vite';
3
-
4
- export default defineConfig({
5
- plugins: [sveltekit()],
6
- test: {
7
- globals: true,
8
- environment: 'happy-dom',
9
- setupFiles: ['./vitest.setup.ts'],
10
- // Ensure we use browser build of Svelte - force conditions for client-side rendering
11
- conditions: ['browser', 'import', 'module'],
12
- singleThread: true,
13
- coverage: {
14
- provider: 'v8',
15
- reporter: ['text', 'json', 'html', 'lcov'],
16
- exclude: [
17
- 'node_modules/',
18
- 'dist/',
19
- 'build/',
20
- 'coverage/',
21
- '**/*.test.ts',
22
- '**/*.spec.ts',
23
- 'tests/',
24
- 'template-starter/'
25
- ],
26
- include: ['src/lib/**/*.ts', 'src/lib/**/*.svelte'],
27
- lines: 85,
28
- functions: 85,
29
- branches: 80,
30
- statements: 85
31
- }
32
- }
33
- });