@priscilla-ai/vue 1.0.6 → 1.0.7
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.
- package/CHANGELOG.md +10 -0
- package/FIXES_AND_RECOMMENDATIONS.md +604 -0
- package/package.json +11 -2
- package/src/__tests__/Navbar.spec.ts +284 -0
- package/src/__tests__/PriscillaAI.behavior.spec.ts +500 -0
- package/src/__tests__/PriscillaAI.plugin.spec.ts +125 -0
- package/vitest.config.ts +21 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import { defineComponent, h } from 'vue'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Navbar Component Tests (17 tests)
|
|
7
|
+
*
|
|
8
|
+
* These tests verify that a Navbar component correctly integrates with
|
|
9
|
+
* the PriscillaAI component, passing props correctly and maintaining
|
|
10
|
+
* proper layout and styling.
|
|
11
|
+
*
|
|
12
|
+
* Note: This test suite uses a mock Navbar component to demonstrate
|
|
13
|
+
* expected behavior with PriscillaAI integration.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// Mock Navbar component for testing
|
|
17
|
+
const Navbar = defineComponent({
|
|
18
|
+
name: 'Navbar',
|
|
19
|
+
components: {
|
|
20
|
+
// Note: In real app, this would be the actual PriscillaAI component
|
|
21
|
+
PriscillaAI: defineComponent({
|
|
22
|
+
name: 'PriscillaAI',
|
|
23
|
+
props: ['xpath', 'chapterId', 'programId'],
|
|
24
|
+
template: '<div class="priscilla-ai-mock" />',
|
|
25
|
+
}),
|
|
26
|
+
},
|
|
27
|
+
template: `
|
|
28
|
+
<nav class="navbar" style="background-color: #16a34a; border-bottom: 1px solid #15803d;">
|
|
29
|
+
<div class="navbar-container" style="margin: 0 auto; max-width: 1280px; padding: 0 8px;">
|
|
30
|
+
<div class="navbar-content" style="display: flex; height: 80px; align-items: center; justify-content: space-between;">
|
|
31
|
+
<div class="navbar-start" style="display: flex; flex: 1; align-items: center;">
|
|
32
|
+
<a class="navbar-logo" href="/" style="display: flex; align-items: center; margin-right: 16px; flex-shrink: 0;">
|
|
33
|
+
<img class="logo-image" src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text>VJ</text></svg>" alt="Vue Jobs" style="height: 40px; width: auto;" />
|
|
34
|
+
<span class="brand-text" style="color: white; font-size: 24px; font-weight: bold; margin-left: 8px; display: none;">
|
|
35
|
+
Vue Jobs
|
|
36
|
+
</span>
|
|
37
|
+
</a>
|
|
38
|
+
<div class="navbar-end" style="margin-left: auto;">
|
|
39
|
+
<div class="navbar-actions" style="display: flex; gap: 8px;">
|
|
40
|
+
<PriscillaAI
|
|
41
|
+
:xpath="xpathSelector"
|
|
42
|
+
:chapterId="currentChapterId"
|
|
43
|
+
:programId="currentProgramId"
|
|
44
|
+
/>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</nav>
|
|
51
|
+
`,
|
|
52
|
+
data() {
|
|
53
|
+
return {
|
|
54
|
+
xpathSelector: "//textarea[@id='code-block']",
|
|
55
|
+
currentChapterId: 12,
|
|
56
|
+
currentProgramId: 589,
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
describe('Navbar Component Integration', () => {
|
|
62
|
+
let wrapper: ReturnType<typeof mount>
|
|
63
|
+
|
|
64
|
+
beforeEach(() => {
|
|
65
|
+
wrapper = mount(Navbar, {
|
|
66
|
+
global: {
|
|
67
|
+
stubs: {
|
|
68
|
+
img: true,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Test 1: Navbar component rendering
|
|
76
|
+
*
|
|
77
|
+
* Verifies that the Navbar component mounts and renders without errors.
|
|
78
|
+
* This is a basic smoke test ensuring the component structure is valid.
|
|
79
|
+
*/
|
|
80
|
+
it('should render Navbar component', () => {
|
|
81
|
+
expect(wrapper.exists()).toBe(true)
|
|
82
|
+
expect(wrapper.find('nav').exists()).toBe(true)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Test 2: Green styling application (background-color, border)
|
|
87
|
+
*
|
|
88
|
+
* Validates that the Navbar applies the correct CSS styling
|
|
89
|
+
* for green background and border.
|
|
90
|
+
*/
|
|
91
|
+
it('should apply green styling to navBar', () => {
|
|
92
|
+
const nav = wrapper.find('nav')
|
|
93
|
+
expect(nav.exists()).toBe(true)
|
|
94
|
+
// Check style attribute or class
|
|
95
|
+
const style = nav.attributes('style') || ''
|
|
96
|
+
expect(style).toContain('background-color')
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Test 3: Logo image rendering with proper alt text
|
|
101
|
+
*
|
|
102
|
+
* Ensures the logo image is properly displayed with descriptive alt text.
|
|
103
|
+
* This is important for accessibility and SEO.
|
|
104
|
+
*/
|
|
105
|
+
it('should render logo image with alt text', () => {
|
|
106
|
+
const logo = wrapper.find('img')
|
|
107
|
+
expect(logo.exists()).toBe(true)
|
|
108
|
+
expect(logo.attributes('alt')).toBe('Vue Jobs')
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Test 4: Brand text "Vue Jobs" display
|
|
113
|
+
*
|
|
114
|
+
* Verifies that the brand name "Vue Jobs" is displayed in the Navbar.
|
|
115
|
+
* On mobile screens, this text is hidden and shown only on medium screens.
|
|
116
|
+
*/
|
|
117
|
+
it('should display brand text "Vue Jobs"', () => {
|
|
118
|
+
expect(wrapper.text()).toContain('Vue Jobs')
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Test 5: PriscillaAI component mounting
|
|
123
|
+
*
|
|
124
|
+
* Checks that the PriscillaAI component is properly mounted as a child
|
|
125
|
+
* of the Navbar component.
|
|
126
|
+
*/
|
|
127
|
+
it('should mount PriscillaAI component inside Navbar', () => {
|
|
128
|
+
const priscilla = wrapper.findComponent({ name: 'PriscillaAI' })
|
|
129
|
+
expect(priscilla.exists()).toBe(true)
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Test 6: XPath prop passing
|
|
134
|
+
*
|
|
135
|
+
* Validates that the correct XPath selector is passed to the PriscillaAI component.
|
|
136
|
+
* This XPath targets a textarea element with id="code-block".
|
|
137
|
+
*/
|
|
138
|
+
it('should pass correct xpath prop to PriscillaAI', () => {
|
|
139
|
+
const priscilla = wrapper.findComponent({ name: 'PriscillaAI' })
|
|
140
|
+
expect(priscilla.props('xpath')).toBe("//textarea[@id='code-block']")
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Test 7: ChapterId prop passing
|
|
145
|
+
*
|
|
146
|
+
* Ensures the chapterId prop (12) is correctly passed to PriscillaAI.
|
|
147
|
+
* This ID is used to fetch chapter-specific hints from the API.
|
|
148
|
+
*/
|
|
149
|
+
it('should pass correct chapterId prop to PriscillaAI', () => {
|
|
150
|
+
const priscilla = wrapper.findComponent({ name: 'PriscillaAI' })
|
|
151
|
+
expect(priscilla.props('chapterId')).toBe(12)
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Test 8: ProgramId prop passing
|
|
156
|
+
*
|
|
157
|
+
* Verifies the programId prop (589) is correctly passed to PriscillaAI.
|
|
158
|
+
* This ID identifies which program/module the student is working on.
|
|
159
|
+
*/
|
|
160
|
+
it('should pass correct programId prop to PriscillaAI', () => {
|
|
161
|
+
const priscilla = wrapper.findComponent({ name: 'PriscillaAI' })
|
|
162
|
+
expect(priscilla.props('programId')).toBe(589)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Test 9: All required props present
|
|
167
|
+
*
|
|
168
|
+
* Comprehensive check that all three required props are passed to PriscillaAI:
|
|
169
|
+
* xpath, chapterId, and programId.
|
|
170
|
+
*/
|
|
171
|
+
it('should pass all required props to PriscillaAI', () => {
|
|
172
|
+
const priscilla = wrapper.findComponent({ name: 'PriscillaAI' })
|
|
173
|
+
expect(priscilla.props()).toHaveProperty('xpath')
|
|
174
|
+
expect(priscilla.props()).toHaveProperty('chapterId')
|
|
175
|
+
expect(priscilla.props()).toHaveProperty('programId')
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Test 10: Max-width container structure
|
|
180
|
+
*
|
|
181
|
+
* Ensures the Navbar uses a max-width container for responsive design.
|
|
182
|
+
* The container limits content width on large screens.
|
|
183
|
+
*/
|
|
184
|
+
it('should use max-width container structure', () => {
|
|
185
|
+
const container = wrapper.find('.navbar-container')
|
|
186
|
+
expect(container.exists()).toBe(true)
|
|
187
|
+
const style = container.attributes('style') || ''
|
|
188
|
+
expect(style).toContain('max-width')
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Test 11: Flexbox layout implementation
|
|
193
|
+
*
|
|
194
|
+
* Validates that the Navbar uses Flexbox for proper layout:
|
|
195
|
+
* - Main container uses flex layout
|
|
196
|
+
* - Items are properly aligned (justify-between, items-center)
|
|
197
|
+
*/
|
|
198
|
+
it('should use flexbox layout', () => {
|
|
199
|
+
const mainDiv = wrapper.find('.navbar-content')
|
|
200
|
+
expect(mainDiv.exists()).toBe(true)
|
|
201
|
+
const style = mainDiv.attributes('style') || ''
|
|
202
|
+
expect(style).toContain('display: flex')
|
|
203
|
+
expect(style).toContain('align-items')
|
|
204
|
+
expect(style).toContain('justify-content')
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Test 12: Logo alignment and centering
|
|
209
|
+
*
|
|
210
|
+
* Ensures the logo and brand text are properly aligned on the left side
|
|
211
|
+
* of the Navbar using flex display and proper spacing.
|
|
212
|
+
*/
|
|
213
|
+
it('should align logo and brand text properly', () => {
|
|
214
|
+
const logoContainer = wrapper.find('.navbar-logo')
|
|
215
|
+
expect(logoContainer.exists()).toBe(true)
|
|
216
|
+
const style = logoContainer.attributes('style') || ''
|
|
217
|
+
expect(style).toContain('display: flex')
|
|
218
|
+
expect(style).toContain('flex-shrink: 0')
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Test 13: Right-side positioning of PriscillaAI
|
|
223
|
+
*
|
|
224
|
+
* Validates that PriscillaAI is positioned on the right side of the Navbar
|
|
225
|
+
* using margin-left: auto for right alignment.
|
|
226
|
+
*/
|
|
227
|
+
it('should position PriscillaAI on the right side', () => {
|
|
228
|
+
const rightContainer = wrapper.find('.navbar-end')
|
|
229
|
+
expect(rightContainer.exists()).toBe(true)
|
|
230
|
+
const style = rightContainer.attributes('style') || ''
|
|
231
|
+
expect(style).toContain('margin-left: auto')
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Test 14: Mobile text hiding on small screens
|
|
236
|
+
*
|
|
237
|
+
* Ensures the brand text "Vue Jobs" is hidden on small mobile screens
|
|
238
|
+
* using display: none, improving mobile UX.
|
|
239
|
+
*/
|
|
240
|
+
it('should hide brand text on small screens', () => {
|
|
241
|
+
const brandText = wrapper.find('.brand-text')
|
|
242
|
+
expect(brandText.exists()).toBe(true)
|
|
243
|
+
expect(brandText.text()).toContain('Vue Jobs')
|
|
244
|
+
const style = brandText.attributes('style') || ''
|
|
245
|
+
expect(style).toContain('display: none')
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Test 15: Responsive padding
|
|
250
|
+
*
|
|
251
|
+
* Validates that the Navbar uses responsive padding
|
|
252
|
+
* to ensure good spacing across all device sizes.
|
|
253
|
+
*/
|
|
254
|
+
it('should apply responsive padding', () => {
|
|
255
|
+
const container = wrapper.find('.navbar-container')
|
|
256
|
+
expect(container.exists()).toBe(true)
|
|
257
|
+
const style = container.attributes('style') || ''
|
|
258
|
+
expect(style).toContain('padding')
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Test 16: Logo alt text presence and validity
|
|
263
|
+
*
|
|
264
|
+
* Double-checks that the logo image has alt text for accessibility.
|
|
265
|
+
* Screen readers and search engines rely on this for understanding content.
|
|
266
|
+
*/
|
|
267
|
+
it('should have valid alt text for logo', () => {
|
|
268
|
+
const logo = wrapper.find('img')
|
|
269
|
+
const altText = logo.attributes('alt')
|
|
270
|
+
expect(altText).toBeTruthy()
|
|
271
|
+
expect(altText?.length).toBeGreaterThan(0)
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Test 17: Semantic nav element usage
|
|
276
|
+
*
|
|
277
|
+
* Ensures the Navbar uses the semantic HTML <nav> element instead of
|
|
278
|
+
* a generic <div>. This is important for accessibility and SEO.
|
|
279
|
+
*/
|
|
280
|
+
it('should use semantic nav element', () => {
|
|
281
|
+
expect(wrapper.find('nav').exists()).toBe(true)
|
|
282
|
+
expect(wrapper.element.tagName).toBe('NAV')
|
|
283
|
+
})
|
|
284
|
+
})
|