105 lines
4.0 KiB
TypeScript
105 lines
4.0 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('Plan Editor Drag & Drop Vibration', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
// Mock navigator.vibrate
|
|
await page.addInitScript(() => {
|
|
try {
|
|
Object.defineProperty(navigator, 'vibrate', {
|
|
value: (pattern) => {
|
|
console.log(`Vibration triggered: ${pattern}`);
|
|
window.dispatchEvent(new CustomEvent('vibration-triggered', { detail: pattern }));
|
|
return true;
|
|
},
|
|
writable: true,
|
|
configurable: true,
|
|
});
|
|
} catch (e) {
|
|
console.error('Failed to mock vibrate', e);
|
|
}
|
|
});
|
|
|
|
await page.goto('/');
|
|
|
|
// Create a new user
|
|
const uniqueId = Date.now().toString();
|
|
const email = `dragvibetest${uniqueId}@example.com`;
|
|
|
|
await page.fill('input[type="email"]', email);
|
|
await page.fill('input[type="password"]', 'password123');
|
|
await page.click('button:has-text("Sign Up")');
|
|
await page.waitForURL('**/dashboard');
|
|
|
|
if (await page.getByPlaceholder('Enter your name').isVisible()) {
|
|
await page.getByPlaceholder('Enter your name').fill('Vibe Tester');
|
|
await page.getByRole('button', { name: 'Complete Profile' }).click();
|
|
}
|
|
});
|
|
|
|
test('should trigger vibration on drag start', async ({ page }) => {
|
|
// Navigate to Plans
|
|
await page.getByRole('button', { name: 'Plans' }).click();
|
|
|
|
// Create Plan
|
|
await page.getByLabel('Create Plan').click();
|
|
await page.getByLabel('Plan Name').fill('Vibration Plan');
|
|
|
|
// Add Exercises
|
|
await page.getByRole('button', { name: 'Add Exercise' }).click();
|
|
await page.getByRole('button', { name: 'Create New Exercise' }).click();
|
|
await page.getByLabel('Exercise Name').fill('Exercise 1');
|
|
await page.getByRole('button', { name: 'Save Exercise' }).click();
|
|
|
|
await page.getByRole('button', { name: 'Add Exercise' }).click();
|
|
await page.getByRole('button', { name: 'Create New Exercise' }).click();
|
|
await page.getByLabel('Exercise Name').fill('Exercise 2');
|
|
await page.getByRole('button', { name: 'Save Exercise' }).click();
|
|
|
|
// Listen for vibration event with timeout
|
|
let vibrationDetected = false;
|
|
page.on('console', msg => {
|
|
if (msg.text().includes('Vibration triggered') || msg.text().includes('handlePointerDown')) {
|
|
console.log('Browser Console:', msg.text());
|
|
}
|
|
if (msg.text().includes('Vibration triggered')) vibrationDetected = true;
|
|
});
|
|
|
|
// Drag
|
|
const dragHandle = page.locator('.cursor-grab').first();
|
|
const dragDest = page.locator('.cursor-grab').nth(1);
|
|
|
|
// Drag using manual pointer control simulating TOUCH via evaluate
|
|
const box = await dragHandle.boundingBox();
|
|
if (box) {
|
|
// Dispatch directly in browser to ensure React synthetic event system picks it up
|
|
await dragHandle.evaluate((el) => {
|
|
const event = new PointerEvent('pointerdown', {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
pointerType: 'touch',
|
|
clientX: 0,
|
|
clientY: 0,
|
|
isPrimary: true
|
|
});
|
|
el.dispatchEvent(event);
|
|
});
|
|
|
|
// Wait for usage
|
|
await page.waitForTimeout(500);
|
|
|
|
// Dispatch pointerup
|
|
await dragHandle.evaluate((el) => {
|
|
const event = new PointerEvent('pointerup', {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
pointerType: 'touch',
|
|
isPrimary: true
|
|
});
|
|
el.dispatchEvent(event);
|
|
});
|
|
}
|
|
|
|
// Check flag
|
|
expect(vibrationDetected).toBeTruthy();
|
|
});
|
|
}); |