start-vibing 4.4.0 → 4.4.2

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 (58) hide show
  1. package/package.json +2 -2
  2. package/template/.claude/commands/e2e-audit.md +16 -0
  3. package/template/.claude/hooks/e2e-audit-session-start.sh +4 -0
  4. package/template/.claude/hooks/mcp-usage-session-start.sh +4 -0
  5. package/template/.claude/settings.json +8 -0
  6. package/template/.claude/skills/e2e-audit/SKILL.md +216 -660
  7. package/template/.claude/skills/e2e-audit/findings.schema.json +98 -0
  8. package/template/.claude/skills/e2e-audit/references/api-contract-playbook.md +66 -0
  9. package/template/.claude/skills/e2e-audit/references/auth-setup-playbook.md +78 -0
  10. package/template/.claude/skills/e2e-audit/references/coverage-gap-playbook.md +95 -0
  11. package/template/.claude/skills/e2e-audit/references/post-run-feedback-playbook.md +80 -0
  12. package/template/.claude/skills/e2e-audit/scripts/detect-stack.sh +205 -0
  13. package/template/.claude/skills/e2e-audit/scripts/detect-uncovered.sh +137 -0
  14. package/template/.claude/skills/e2e-audit/scripts/discover-api-surface.sh +242 -0
  15. package/template/.claude/skills/e2e-audit/scripts/discover-routes.sh +163 -0
  16. package/template/.claude/skills/e2e-audit/scripts/inventory-existing-tests.sh +161 -0
  17. package/template/.claude/skills/e2e-audit/scripts/verify-audit.sh +88 -0
  18. package/template/.claude/skills/e2e-audit/templates/auth-setup.ts.tpl +24 -0
  19. package/template/.claude/skills/e2e-audit/templates/base-fixture.ts.tpl +75 -0
  20. package/template/.claude/skills/e2e-audit/templates/findings-report.md.tpl +54 -0
  21. package/template/.claude/skills/e2e-audit/templates/post-run-feedback.md.tpl +36 -0
  22. package/template/.claude/skills/e2e-audit/DESIGN.md +0 -294
  23. package/template/.claude/skills/e2e-audit/e2e/fixtures/auth.setup.ts +0 -70
  24. package/template/.claude/skills/e2e-audit/e2e/fixtures/auth.ts +0 -21
  25. package/template/.claude/skills/e2e-audit/e2e/fixtures/base.ts +0 -90
  26. package/template/.claude/skills/e2e-audit/e2e/fixtures/storage/.gitkeep +0 -0
  27. package/template/.claude/skills/e2e-audit/e2e/fixtures/storage/admin.json +0 -50
  28. package/template/.claude/skills/e2e-audit/e2e/fixtures/storage/manager.json +0 -50
  29. package/template/.claude/skills/e2e-audit/e2e/fixtures/storage/member.json +0 -50
  30. package/template/.claude/skills/e2e-audit/e2e/fixtures/storage/owner.json +0 -50
  31. package/template/.claude/skills/e2e-audit/e2e/pages/dashboard-admin.page.ts +0 -141
  32. package/template/.claude/skills/e2e-audit/e2e/pages/dashboard-billing.page.ts +0 -47
  33. package/template/.claude/skills/e2e-audit/e2e/pages/dashboard-chat.page.ts +0 -35
  34. package/template/.claude/skills/e2e-audit/e2e/pages/dashboard-home.page.ts +0 -134
  35. package/template/.claude/skills/e2e-audit/e2e/pages/dashboard-integrations.page.ts +0 -334
  36. package/template/.claude/skills/e2e-audit/e2e/pages/dashboard-knowledge.page.ts +0 -30
  37. package/template/.claude/skills/e2e-audit/e2e/pages/dashboard-ontology.page.ts +0 -71
  38. package/template/.claude/skills/e2e-audit/e2e/pages/dashboard-profile.page.ts +0 -38
  39. package/template/.claude/skills/e2e-audit/e2e/pages/dashboard-teams.page.ts +0 -123
  40. package/template/.claude/skills/e2e-audit/e2e/pages/dashboard-transcripts.page.ts +0 -109
  41. package/template/.claude/skills/e2e-audit/e2e/specs/auth/login.spec.ts +0 -59
  42. package/template/.claude/skills/e2e-audit/e2e/specs/dashboard-admin.spec.ts +0 -233
  43. package/template/.claude/skills/e2e-audit/e2e/specs/dashboard-billing.spec.ts +0 -44
  44. package/template/.claude/skills/e2e-audit/e2e/specs/dashboard-chat.spec.ts +0 -50
  45. package/template/.claude/skills/e2e-audit/e2e/specs/dashboard-home.spec.ts +0 -243
  46. package/template/.claude/skills/e2e-audit/e2e/specs/dashboard-integrations.spec.ts +0 -472
  47. package/template/.claude/skills/e2e-audit/e2e/specs/dashboard-knowledge.spec.ts +0 -57
  48. package/template/.claude/skills/e2e-audit/e2e/specs/dashboard-ontology.spec.ts +0 -72
  49. package/template/.claude/skills/e2e-audit/e2e/specs/dashboard-profile.spec.ts +0 -48
  50. package/template/.claude/skills/e2e-audit/e2e/specs/dashboard-teams.spec.ts +0 -247
  51. package/template/.claude/skills/e2e-audit/e2e/specs/dashboard-transcripts.spec.ts +0 -122
  52. package/template/.claude/skills/e2e-audit/e2e/specs/security/headers.spec.ts +0 -39
  53. package/template/.claude/skills/e2e-audit/e2e/specs/security/rbac.spec.ts +0 -92
  54. package/template/.claude/skills/e2e-audit/e2e/specs/security/xss.spec.ts +0 -74
  55. package/template/.claude/skills/e2e-audit/e2e/utils/console-collector.ts +0 -89
  56. package/template/.claude/skills/e2e-audit/e2e/utils/security-helpers.ts +0 -114
  57. package/template/.claude/skills/e2e-audit/e2e/utils/test-data.ts +0 -64
  58. package/template/.claude/skills/e2e-audit/runbook.md +0 -115
@@ -1,44 +0,0 @@
1
- import { test, expect } from '../fixtures/base'
2
- import { DashboardBillingPage } from '../pages/dashboard-billing.page'
3
- import { createConsoleCollector } from '../utils/console-collector'
4
-
5
- test.describe('Dashboard Billing @smoke', () => {
6
- let billing: DashboardBillingPage
7
-
8
- test.beforeEach(async ({ authenticatedPage, apiErrors: _apiErrors }) => {
9
- billing = new DashboardBillingPage(authenticatedPage)
10
- await billing.goto()
11
- await billing.waitForLoad()
12
- })
13
-
14
- test('page loads with heading and description', async ({ authenticatedPage }) => {
15
- await expect(authenticatedPage, 'Should navigate to billing page').toHaveURL(/dashboard\/billing/)
16
- await expect(billing.heading, 'Billing heading should be visible').toBeVisible()
17
- await expect(billing.description).toBeVisible()
18
- })
19
-
20
- test('shows subscription card with plan info', async () => {
21
- await expect(billing.planName).toBeVisible()
22
- await expect(billing.planLabel).toBeVisible()
23
- await expect(billing.activeUsersLabel).toBeVisible()
24
- await expect(billing.statusLabel).toBeVisible()
25
- })
26
-
27
- test('shows subscribe button', async () => {
28
- await expect(billing.subscribeButton).toBeVisible()
29
- })
30
-
31
- test('shows Stripe security text', async () => {
32
- await expect(billing.stripeSecurityText).toBeVisible()
33
- })
34
- })
35
-
36
- test.describe('Dashboard Billing - Security @security', () => {
37
- test('no sensitive data in console', async ({ authenticatedPage, apiErrors: _apiErrors }) => {
38
- const collector = createConsoleCollector(authenticatedPage)
39
- const billing = new DashboardBillingPage(authenticatedPage)
40
- await billing.goto()
41
- await billing.waitForLoad()
42
- collector.assertNoSensitiveLeaks()
43
- })
44
- })
@@ -1,50 +0,0 @@
1
- import { test, expect } from '../fixtures/base'
2
- import { DashboardChatPage } from '../pages/dashboard-chat.page'
3
- import { createConsoleCollector } from '../utils/console-collector'
4
- import { testXssOnInput } from '../utils/security-helpers'
5
-
6
- test.describe('Dashboard Chat @smoke', () => {
7
- let chat: DashboardChatPage
8
-
9
- test.beforeEach(async ({ authenticatedPage, apiErrors: _apiErrors }) => {
10
- chat = new DashboardChatPage(authenticatedPage)
11
- await chat.goto()
12
- await chat.waitForLoad()
13
- })
14
-
15
- test('page loads successfully', async ({ authenticatedPage }) => {
16
- await expect(authenticatedPage, 'Should navigate to chat page').toHaveURL(/dashboard\/chat/)
17
- })
18
-
19
- test('displays page heading', async () => {
20
- await expect(chat.heading).toBeVisible()
21
- })
22
-
23
- test('message input is visible and enabled', async () => {
24
- const inputVisible = await chat.messageInput.isVisible().catch(() => false)
25
- if (inputVisible) {
26
- await expect(chat.messageInput).toBeEnabled()
27
- }
28
- })
29
- })
30
-
31
- test.describe('Dashboard Chat - Security @security', () => {
32
- test('no sensitive data in console', async ({ authenticatedPage, apiErrors: _apiErrors }) => {
33
- const collector = createConsoleCollector(authenticatedPage)
34
- const chat = new DashboardChatPage(authenticatedPage)
35
- await chat.goto()
36
- await chat.waitForLoad()
37
- collector.assertNoSensitiveLeaks()
38
- })
39
-
40
- test('message input resists XSS', async ({ authenticatedPage, apiErrors: _apiErrors }) => {
41
- const chat = new DashboardChatPage(authenticatedPage)
42
- await chat.goto()
43
- await chat.waitForLoad()
44
-
45
- const inputVisible = await chat.messageInput.isVisible().catch(() => false)
46
- if (inputVisible) {
47
- await testXssOnInput(authenticatedPage, chat.messageInput)
48
- }
49
- })
50
- })
@@ -1,243 +0,0 @@
1
- import { test, expect } from '../fixtures/base'
2
- import { DashboardHomePage } from '../pages/dashboard-home.page'
3
- import { createConsoleCollector } from '../utils/console-collector'
4
- import { testXssOnInput } from '../utils/security-helpers'
5
-
6
- test.describe('Dashboard Home @smoke', () => {
7
- let home: DashboardHomePage
8
-
9
- test.beforeEach(async ({ authenticatedPage, apiErrors: _apiErrors }) => {
10
- home = new DashboardHomePage(authenticatedPage)
11
- await home.goto()
12
- await home.waitForLoad()
13
- })
14
-
15
- test('page loads with correct URL and heading', async ({ authenticatedPage }) => {
16
- await expect(authenticatedPage, 'Should navigate to home page').toHaveURL(/dashboard\/home/)
17
- await expect(home.heading, 'Home heading should be visible').toBeVisible()
18
- })
19
-
20
- test('displays hero section elements', async () => {
21
- await expect(home.logo).toBeVisible()
22
- await expect(home.subtitle).toBeVisible()
23
- await expect(home.aiAvatar).toBeVisible()
24
- })
25
-
26
- test('search input has placeholder and aria-label', async () => {
27
- await expect(home.searchInput).toBeVisible()
28
- await expect(home.searchInput).toBeEnabled()
29
- const placeholder = await home.searchInput.getAttribute('placeholder')
30
- expect(placeholder).toBeTruthy()
31
- })
32
-
33
- test('ask button is disabled when search is empty', async () => {
34
- await expect(home.askButton).toBeDisabled()
35
- })
36
-
37
- test('ask button enables when text is entered', async () => {
38
- await home.typeSearch('test query')
39
- await expect(home.askButton).toBeEnabled()
40
- })
41
-
42
- test('organization overview section is visible', async () => {
43
- await expect(home.orgOverviewTitle).toBeVisible()
44
- })
45
- })
46
-
47
- test.describe('Dashboard Home - Ice Breakers @smoke', () => {
48
- let home: DashboardHomePage
49
-
50
- test.beforeEach(async ({ authenticatedPage, apiErrors: _apiErrors }) => {
51
- home = new DashboardHomePage(authenticatedPage)
52
- await home.goto()
53
- await home.waitForLoad()
54
- })
55
-
56
- test('displays 3 ice breaker suggestion buttons', async () => {
57
- const suggestions = await home.suggestionButtons.all()
58
- expect(suggestions.length).toBe(3)
59
- })
60
-
61
- test('clicking suggestion populates search input', async () => {
62
- await home.clickSuggestion(0)
63
- const value = await home.searchInput.inputValue()
64
- expect(value.length).toBeGreaterThan(0)
65
- })
66
-
67
- test('suggestion buttons have aria-labels', async () => {
68
- const suggestions = await home.suggestionButtons.all()
69
- for (const btn of suggestions) {
70
- const label = await btn.getAttribute('aria-label')
71
- expect(label).toBeTruthy()
72
- }
73
- })
74
- })
75
-
76
- test.describe('Dashboard Home - Search Submit Flow @critical', () => {
77
- let home: DashboardHomePage
78
-
79
- test.beforeEach(async ({ authenticatedPage, apiErrors: _apiErrors }) => {
80
- home = new DashboardHomePage(authenticatedPage)
81
- await home.goto()
82
- await home.waitForLoad()
83
- })
84
-
85
- test('typed search creates chat session and navigates to chat page', async ({ authenticatedPage }) => {
86
- await home.submitSearch('E2E test: typed search submit')
87
-
88
- // Verify toast appears
89
- await expect(authenticatedPage.getByText(/chat session created|sessão de chat criada/i)).toBeVisible({ timeout: 10000 })
90
-
91
- // Verify navigation to chat page with sessionId
92
- await authenticatedPage.waitForURL(/dashboard\/chat\?sessionId=/, { timeout: 10000 })
93
- expect(authenticatedPage.url()).toContain('/dashboard/chat?sessionId=')
94
-
95
- // Verify user message appears in chat
96
- await expect(authenticatedPage.getByText('E2E test: typed search submit')).toBeVisible({ timeout: 10000 })
97
- })
98
-
99
- test('ice breaker click + Enter creates chat session and navigates', async ({ authenticatedPage }) => {
100
- // Click first ice breaker to populate input
101
- await home.clickSuggestion(0)
102
- const query = await home.searchInput.inputValue()
103
- expect(query.length).toBeGreaterThan(0)
104
-
105
- // Press Enter to submit
106
- await home.searchInput.press('Enter')
107
-
108
- // Verify toast appears
109
- await expect(authenticatedPage.getByText(/chat session created|sessão de chat criada/i)).toBeVisible({ timeout: 10000 })
110
-
111
- // Verify navigation to chat page
112
- await authenticatedPage.waitForURL(/dashboard\/chat\?sessionId=/, { timeout: 10000 })
113
-
114
- // Verify the ice breaker question appears as user message
115
- await expect(authenticatedPage.getByText(query)).toBeVisible({ timeout: 10000 })
116
- })
117
- })
118
-
119
- test.describe('Dashboard Home - Profile & Feedback @smoke', () => {
120
- let home: DashboardHomePage
121
-
122
- test.beforeEach(async ({ authenticatedPage, apiErrors: _apiErrors }) => {
123
- home = new DashboardHomePage(authenticatedPage)
124
- await home.goto()
125
- await home.waitForLoad()
126
- })
127
-
128
- test('profile dropdown shows user info', async () => {
129
- await home.openProfileDropdown()
130
- await expect(home.profileMenuName).toBeVisible()
131
- await expect(home.profileMenuEmail).toBeVisible()
132
- await expect(home.feedbackMenuItem).toBeVisible()
133
- await expect(home.logoutButton).toBeVisible()
134
- })
135
-
136
- test('feedback dialog opens and has all fields', async () => {
137
- await home.openFeedbackDialog()
138
- await expect(home.feedbackDialogTitle).toBeVisible()
139
- await expect(home.feedbackTypeCombobox).toBeVisible()
140
- await expect(home.feedbackMessageTextbox).toBeVisible()
141
- await expect(home.feedbackContactSwitch).toBeVisible()
142
- await expect(home.feedbackCancelButton).toBeVisible()
143
- await expect(home.feedbackSubmitButton).toBeVisible()
144
- })
145
-
146
- test('feedback submit button is disabled until type and message are filled', async () => {
147
- await home.openFeedbackDialog()
148
-
149
- // Initially disabled
150
- await expect(home.feedbackSubmitButton).toBeDisabled()
151
-
152
- // Fill type and message
153
- await home.fillFeedback('Relatório de Bug', 'This is an E2E test feedback message')
154
-
155
- // Now enabled
156
- await expect(home.feedbackSubmitButton).toBeEnabled()
157
- })
158
-
159
- test('feedback type combobox has 4 options', async ({ authenticatedPage }) => {
160
- await home.openFeedbackDialog()
161
- await home.feedbackTypeCombobox.click()
162
-
163
- const options = await authenticatedPage.getByRole('option').all()
164
- expect(options.length).toBe(4)
165
- })
166
-
167
- test('feedback message shows character counter', async ({ authenticatedPage }) => {
168
- await home.openFeedbackDialog()
169
- await home.feedbackMessageTextbox.fill('Test message for counter')
170
- await expect(authenticatedPage.getByText(/24\/2000/)).toBeVisible()
171
- })
172
-
173
- test('feedback cancel button closes dialog', async () => {
174
- await home.openFeedbackDialog()
175
- await expect(home.feedbackDialogTitle).toBeVisible()
176
- await home.feedbackCancelButton.click()
177
- await expect(home.feedbackDialogTitle).not.toBeVisible()
178
- })
179
- })
180
-
181
- test.describe('Dashboard Home - ROI Stats @smoke', () => {
182
- let home: DashboardHomePage
183
-
184
- test.beforeEach(async ({ authenticatedPage, apiErrors: _apiErrors }) => {
185
- home = new DashboardHomePage(authenticatedPage)
186
- await home.goto()
187
- await home.waitForLoad()
188
- })
189
-
190
- test('ROI section title is visible', async () => {
191
- await expect(home.roiSectionTitle).toBeVisible()
192
- })
193
-
194
- test('my stats card shows time saved, files, and paragraphs', async () => {
195
- await expect(home.myStatsTitle).toBeVisible()
196
- await expect(home.myTimeSaved).toBeVisible()
197
- await expect(home.myFilesProcessed).toBeVisible()
198
- await expect(home.myParagraphs).toBeVisible()
199
- })
200
-
201
- test('time saved tooltip appears on hover', async ({ authenticatedPage }) => {
202
- // Hover on the first "Time Saved" stat card
203
- await home.myTimeSaved.hover()
204
- // Tooltip should appear
205
- const tooltip = authenticatedPage.getByRole('tooltip')
206
- await expect(tooltip).toBeVisible({ timeout: 3000 })
207
- })
208
- })
209
-
210
- test.describe('Dashboard Home - ROI Team Stats (OWNER/ADMIN) @rbac', () => {
211
- // Default role is 'owner', which should see team stats
212
- let home: DashboardHomePage
213
-
214
- test.beforeEach(async ({ authenticatedPage, apiErrors: _apiErrors }) => {
215
- home = new DashboardHomePage(authenticatedPage)
216
- await home.goto()
217
- await home.waitForLoad()
218
- })
219
-
220
- test('owner sees team stats card', async () => {
221
- await expect(home.teamStatsTitle).toBeVisible()
222
- await expect(home.teamTimeSaved).toBeVisible()
223
- await expect(home.teamFilesProcessed).toBeVisible()
224
- await expect(home.teamParagraphs).toBeVisible()
225
- })
226
- })
227
-
228
- test.describe('Dashboard Home - Security @security', () => {
229
- test('no sensitive data in console', async ({ authenticatedPage, apiErrors: _apiErrors }) => {
230
- const collector = createConsoleCollector(authenticatedPage)
231
- const home = new DashboardHomePage(authenticatedPage)
232
- await home.goto()
233
- await home.waitForLoad()
234
- collector.assertNoSensitiveLeaks()
235
- })
236
-
237
- test('search input resists XSS', async ({ authenticatedPage, apiErrors: _apiErrors }) => {
238
- const home = new DashboardHomePage(authenticatedPage)
239
- await home.goto()
240
- await home.waitForLoad()
241
- await testXssOnInput(authenticatedPage, home.searchInput)
242
- })
243
- })