-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
From f9d07973790e28084e7d01b0d4f1b677042181d5 Mon Sep 17 00:00:00 2001
From: Persephone Flores <34418758+hp0844182@users.noreply.github.com>
Date: Sat, 27 Sep 2025 23:59:41 +0800
Subject: [PATCH 2/2] test: add hover tests
---
packages/motion/README.md | 107 +--------
playground/vite/src/views/gestures/hover.vue | 234 +++++++++++++++++++
tests/variant.spec.ts | 89 ++++++-
3 files changed, 323 insertions(+), 107 deletions(-)
mode change 100644 => 120000 packages/motion/README.md
create mode 100644 playground/vite/src/views/gestures/hover.vue
diff --git a/packages/motion/README.md b/packages/motion/README.md
deleted file mode 100644
index ac39e3cf..00000000
--- a/packages/motion/README.md
+++ /dev/null
@@ -1,106 +0,0 @@
-
-
-
-
Motion for Vue
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Motion for Vue is an open source, production-ready library thatβs designed for all creative developers.
-
-It's the only animation library with a hybrid engine, combining the power of JavaScript animations with the performance of native browser APIs.
-
-It looks like this:
-
-```jsx
-
-```
-
-It does all this:
-
-- Springs
-- Keyframes
-- Layout animations
-- Shared layout animations
-- Gestures (drag/tap/hover)
-- Scroll animations
-- SVG paths
-- Exit animations
-- Server-side rendering
-- Independent transforms
-- Orchestrate animations across components
-- CSS variables
-
-...and a whole lot more.
-
-## Get started
-
-### π Quick start
-
-Install `motion-v` via your package manager:
-
-```
-npm install motion-v
-```
-
-Then import the `motion` component:
-
-```vue
-
-
-
-
-
-```
-
-### π Contribute
-
-- Want to contribute to Motion? Our [contributing guide](https://github.com/motiondivision/motion-vue/blob/master/CONTRIBUTING.md) has you covered.
-- [Join our discord ](https://discord.com/invite/dCBuRgdNDG)
-
-### π©π»ββοΈ License
-
-- Motion for Vue is MIT licensed.
-
-## β¨ Sponsors
-
-Motion is sustainable thanks to the kind support of its sponsors.
-
-### Partners
-
-#### Framer
-
-Motion powers Framer animations, the web builder for creative pros. Design and ship your dream site. Zero code, maximum speed.
-
-
-
-
-
-### Platinum
-
-

-
-### Gold
-
-

-
-### Silver
-
-

diff --git a/packages/motion/README.md b/packages/motion/README.md
new file mode 120000
index 00000000..fe840054
--- /dev/null
+++ b/packages/motion/README.md
@@ -0,0 +1 @@
+../../README.md
\ No newline at end of file
diff --git a/playground/vite/src/views/gestures/hover.vue b/playground/vite/src/views/gestures/hover.vue
new file mode 100644
index 00000000..41f49e17
--- /dev/null
+++ b/playground/vite/src/views/gestures/hover.vue
@@ -0,0 +1,234 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/variant.spec.ts b/tests/variant.spec.ts
index 13061666..8ebf83fc 100644
--- a/tests/variant.spec.ts
+++ b/tests/variant.spec.ts
@@ -1,7 +1,10 @@
import { expect, test } from '@playwright/test'
// This test assumes the Vite dev server is running and the route is /dynamic-variant
-
+const pointerOptions = {
+ isPrimary: true,
+ pointerId: 1,
+}
test.describe('Variant', () => {
test('should animate opacity when variant changes', async ({ page }) => {
await page.goto('/dynamic-variant')
@@ -18,4 +21,88 @@ test.describe('Variant', () => {
await page.waitForTimeout(250)
await expect(motionBtn).toHaveCSS('opacity', '1')
})
+
+ test('should animate scale correctly on hover and press with variants', async ({ page }) => {
+ await page.goto('/gestures/hover')
+
+ // Wait for initial animation to complete
+ await page.waitForTimeout(500)
+
+ // Open the navigation menu first
+ await page.click('.toggle-container')
+ await page.waitForTimeout(300)
+
+ // Get the first list item
+ const firstItem = page.locator('.list-item').first()
+
+ // Check initial scale (should be 1 or close to 1)
+ const initialTransform = await firstItem.evaluate(el =>
+ window.getComputedStyle(el).transform,
+ )
+
+ // Hover over the item - should scale to 1.1
+ await firstItem.hover()
+ await page.waitForTimeout(200)
+
+ const hoverTransform = await firstItem.evaluate(el =>
+ window.getComputedStyle(el).transform,
+ )
+
+ // Extract scale value from transform matrix
+ const getScaleFromTransform = (transform: string) => {
+ if (transform === 'none')
+ return 1
+ const matrix = transform.match(/matrix\(([^)]+)\)/)
+ if (matrix) {
+ const values = matrix[1].split(',').map(n => parseFloat(n.trim()))
+ return Math.round(values[0] * 100) / 100 // scaleX value, rounded to 2 decimals
+ }
+ return 1
+ }
+
+ const initialScale = getScaleFromTransform(initialTransform)
+ const hoverScale = getScaleFromTransform(hoverTransform)
+
+ // Verify hover scale is approximately 1.1
+ expect(hoverScale).toBeCloseTo(1.1, 1)
+ expect(hoverScale).toBeGreaterThan(initialScale)
+
+ // Press the item while hovering - should scale to 0.95
+ // Start press
+ await firstItem.dispatchEvent('pointerdown', pointerOptions)
+ await page.waitForTimeout(300)
+
+ const pressTransform = await firstItem.evaluate(el =>
+ window.getComputedStyle(el).transform,
+ )
+ const pressScale = getScaleFromTransform(pressTransform)
+
+ // Verify press scale is approximately 0.95
+ expect(pressScale).toBeCloseTo(0.95, 1)
+ expect(pressScale).toBeLessThan(initialScale)
+
+ // // Release press - should return to hover scale
+ await firstItem.dispatchEvent('pointerup', pointerOptions)
+ await page.waitForTimeout(300)
+
+ const afterPressTransform = await firstItem.evaluate(el =>
+ window.getComputedStyle(el).transform,
+ )
+ const afterPressScale = getScaleFromTransform(afterPressTransform)
+
+ // // Should return to hover scale (1.1)
+ expect(afterPressScale).toBeCloseTo(1.1, 1)
+
+ // // Move mouse away - should return to initial scale
+ await page.mouse.move(0, 0)
+ await page.waitForTimeout(300)
+
+ const finalTransform = await firstItem.evaluate(el =>
+ window.getComputedStyle(el).transform,
+ )
+ const finalScale = getScaleFromTransform(finalTransform)
+
+ // // Should return to initial scale (1.0)
+ expect(finalScale).toBeCloseTo(1.0, 1)
+ })
})