116 lines
3.7 KiB
TypeScript
116 lines
3.7 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import { setupPreviewState } from './utils';
|
|
|
|
test.describe('Mobile Preview Visual Tests', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/tool');
|
|
await page.waitForLoadState('networkidle');
|
|
});
|
|
|
|
test('mobile preview - light mode', async ({ page }) => {
|
|
await setupPreviewState(page, { mode: 'mobile', theme: 'light' });
|
|
|
|
const ytCard = page.locator('.yt-card').first();
|
|
|
|
// Take screenshot for visual comparison
|
|
await expect(ytCard).toHaveScreenshot('mobile-light-card.png', {
|
|
threshold: 0.02,
|
|
maxDiffPixels: 100,
|
|
});
|
|
});
|
|
|
|
test('mobile preview - dark mode', async ({ page }) => {
|
|
await setupPreviewState(page, { mode: 'mobile', theme: 'dark' });
|
|
|
|
// Verify dark mode
|
|
const isDark = await page.evaluate(() =>
|
|
document.documentElement.classList.contains('dark')
|
|
);
|
|
expect(isDark).toBe(true);
|
|
|
|
const ytCard = page.locator('.yt-card').first();
|
|
|
|
await expect(ytCard).toHaveScreenshot('mobile-dark-card.png', {
|
|
threshold: 0.02,
|
|
maxDiffPixels: 100,
|
|
});
|
|
});
|
|
|
|
test('mobile preview - full-width thumbnail', async ({ page }) => {
|
|
await setupPreviewState(page, { mode: 'mobile', theme: 'light' });
|
|
|
|
const ytCard = page.locator('.yt-card').first();
|
|
const thumbnail = ytCard.locator('[style*="aspect-ratio"]').first();
|
|
|
|
const thumbnailStyles = await thumbnail.evaluate((el) => {
|
|
const computed = window.getComputedStyle(el);
|
|
return {
|
|
width: computed.width,
|
|
borderRadius: computed.borderRadius,
|
|
aspectRatio: computed.aspectRatio,
|
|
};
|
|
});
|
|
|
|
// Mobile thumbnail should be full width with 0px radius
|
|
expect(thumbnailStyles.borderRadius).toBe('0px');
|
|
expect(thumbnailStyles.aspectRatio).toContain('16');
|
|
});
|
|
|
|
test('mobile preview - avatar 36x36', async ({ page }) => {
|
|
await setupPreviewState(page, { mode: 'mobile', theme: 'light' });
|
|
|
|
const ytCard = page.locator('.yt-card').first();
|
|
const avatar = ytCard.locator('[style*="36px"]').first();
|
|
|
|
const avatarStyles = await avatar.evaluate((el) => {
|
|
const computed = window.getComputedStyle(el);
|
|
return {
|
|
width: computed.width,
|
|
height: computed.height,
|
|
borderRadius: computed.borderRadius,
|
|
};
|
|
});
|
|
|
|
expect(avatarStyles.width).toBe('36px');
|
|
expect(avatarStyles.height).toBe('36px');
|
|
expect(avatarStyles.borderRadius).toBe('50%');
|
|
});
|
|
|
|
test('mobile preview - metadata below thumbnail', async ({ page }) => {
|
|
await setupPreviewState(page, { mode: 'mobile', theme: 'light' });
|
|
|
|
const ytCard = page.locator('.yt-card').first();
|
|
|
|
// Verify layout structure: thumbnail first, then metadata
|
|
const children = await ytCard.locator('> div').all();
|
|
expect(children.length).toBeGreaterThanOrEqual(2);
|
|
|
|
// First child should be the thumbnail container (has aspect-ratio)
|
|
const firstChild = children[0];
|
|
const hasAspectRatio = await firstChild.evaluate((el) =>
|
|
el.getAttribute('style')?.includes('aspect-ratio')
|
|
);
|
|
expect(hasAspectRatio).toBe(true);
|
|
});
|
|
|
|
test('mobile preview - typography sizes', async ({ page }) => {
|
|
await setupPreviewState(page, { mode: 'mobile', theme: 'light' });
|
|
|
|
const ytCard = page.locator('.yt-card').first();
|
|
const title = ytCard.locator('h3').first();
|
|
|
|
const titleStyles = await title.evaluate((el) => {
|
|
const computed = window.getComputedStyle(el);
|
|
return {
|
|
fontSize: computed.fontSize,
|
|
fontWeight: computed.fontWeight,
|
|
lineHeight: computed.lineHeight,
|
|
};
|
|
});
|
|
|
|
expect(titleStyles.fontSize).toBe('14px');
|
|
expect(titleStyles.fontWeight).toBe('500');
|
|
expect(titleStyles.lineHeight).toBe('20px');
|
|
});
|
|
});
|