diff --git a/frontend/src/test/views/HomeView.test.ts b/frontend/src/test/views/HomeView.test.ts
index 7033f29..1c63572 100644
--- a/frontend/src/test/views/HomeView.test.ts
+++ b/frontend/src/test/views/HomeView.test.ts
@@ -106,8 +106,8 @@ describe('HomeView', () => {
})
}
- // HV-01: N devices renders a carousel of N large FrameCard stubs + N dots
- it('renders one FrameCard per device in a carousel when multiple devices present', async () => {
+ // HV-01: N devices renders a vertical stack of N large FrameCard stubs
+ it('renders one FrameCard per device in a vertical stack when multiple devices present', async () => {
const devicesStore = useDevicesStore()
devicesStore.devices = [
makeDevice({ id: 1, name: 'Frame A' }),
@@ -119,58 +119,27 @@ describe('HomeView', () => {
const wrapper = mountView()
await wrapper.vm.$nextTick()
- expect(wrapper.find('.home-view__carousel').exists()).toBe(true)
+ expect(wrapper.find('.home-view__stack').exists()).toBe(true)
+ expect(wrapper.findAll('.home-view__slide')).toHaveLength(3)
expect(wrapper.findAll('.frame-card-stub')).toHaveLength(3)
- // All cards should be the large variant (no more compact stack)
+ // All cards should be the large variant (no compact / no carousel)
const cards = wrapper.findAllComponents({ name: 'FrameCard' })
for (const c of cards) expect(c.props('size')).toBe('large')
- // One navigation dot per device
- expect(wrapper.findAll('.home-view__dot')).toHaveLength(3)
})
- it('marks the first dot active by default and updates active dot on scroll', async () => {
+ it('labels each slide with the device name for accessibility', async () => {
const devicesStore = useDevicesStore()
devicesStore.devices = [
- makeDevice({ id: 1, name: 'A' }),
- makeDevice({ id: 2, name: 'B' }),
+ makeDevice({ id: 1, name: 'Living Room' }),
+ makeDevice({ id: 2, name: 'Bedroom' }),
]
vi.spyOn(devicesStore, 'fetchDevices').mockResolvedValue()
const wrapper = mountView()
await wrapper.vm.$nextTick()
- let dots = wrapper.findAll('.home-view__dot')
- expect(dots[0].classes()).toContain('home-view__dot--active')
- expect(dots[1].classes()).not.toContain('home-view__dot--active')
-
- // Simulate the carousel having scrolled to the second slide
- const carousel = wrapper.find('.home-view__carousel').element as HTMLElement
- Object.defineProperty(carousel, 'clientWidth', { configurable: true, value: 360 })
- Object.defineProperty(carousel, 'scrollLeft', { configurable: true, value: 360 })
- await wrapper.find('.home-view__carousel').trigger('scroll')
- await wrapper.vm.$nextTick()
-
- dots = wrapper.findAll('.home-view__dot')
- expect(dots[1].classes()).toContain('home-view__dot--active')
- expect(dots[0].classes()).not.toContain('home-view__dot--active')
- })
-
- it('clicking a dot scrolls the carousel to that slide', async () => {
- const devicesStore = useDevicesStore()
- devicesStore.devices = [makeDevice({ id: 1 }), makeDevice({ id: 2 }), makeDevice({ id: 3 })]
- vi.spyOn(devicesStore, 'fetchDevices').mockResolvedValue()
-
- const wrapper = mountView()
- await wrapper.vm.$nextTick()
-
- const carousel = wrapper.find('.home-view__carousel').element as HTMLElement
- Object.defineProperty(carousel, 'clientWidth', { configurable: true, value: 360 })
- const scrollToSpy = vi.fn()
- ;(carousel as any).scrollTo = scrollToSpy
-
- await wrapper.findAll('.home-view__dot')[2].trigger('click')
- await wrapper.vm.$nextTick()
-
- expect(scrollToSpy).toHaveBeenCalledWith(expect.objectContaining({ left: 720, behavior: 'smooth' }))
+ const slides = wrapper.findAll('.home-view__slide')
+ expect(slides[0].attributes('aria-label')).toBe('Living Room')
+ expect(slides[1].attributes('aria-label')).toBe('Bedroom')
})
// HV-01b: single device still renders one FrameCard (large variant branch)
diff --git a/frontend/src/views/HomeView.vue b/frontend/src/views/HomeView.vue
index b8c4f98..44a0c81 100644
--- a/frontend/src/views/HomeView.vue
+++ b/frontend/src/views/HomeView.vue
@@ -37,51 +37,34 @@
/>
-
-
+
+
@@ -131,7 +114,7 @@
+