Files
site-builder/tests/youtube-embed.spec.js
Josh Knapp b511a6684d Add templates, tests, and miscellaneous project files
Includes new page templates (fitness-gym, nonprofit, online-course,
photography-studio, real-estate, startup-company, travel-blog,
wedding-invitation) with thumbnail SVGs, test specs, documentation
files, and minor updates to index.html, router.php, and playwright config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:15:58 -08:00

131 lines
5.3 KiB
JavaScript

const { test, expect } = require('@playwright/test');
const { waitForEditor, addBlockById, clearCanvas } = require('./helpers');
test.describe('YouTube Embed Fix (Error 153)', () => {
test.beforeEach(async ({ page }) => {
await waitForEditor(page);
await clearCanvas(page);
});
test('should use youtube-nocookie.com domain for YouTube embeds', async ({ page }) => {
// Add Video block via API
const result = await addBlockById(page, 'video-block');
expect(result.success).toBe(true);
await page.waitForTimeout(500);
// Select the video wrapper via API
await page.evaluate(() => {
const editor = window.editor;
const wrapper = editor.getWrapper();
const videoWrapper = wrapper.find('[data-video-wrapper]')[0];
if (videoWrapper) editor.select(videoWrapper);
});
await page.waitForTimeout(500);
// Open Settings tab
await page.locator('button[data-panel="traits"]').click();
await page.waitForTimeout(500);
// Find Video URL input in traits container
const videoUrlInput = page.locator('#traits-container input[placeholder*="YouTube"]');
await expect(videoUrlInput).toBeVisible({ timeout: 5000 });
const testYouTubeUrl = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
await videoUrlInput.fill(testYouTubeUrl);
await videoUrlInput.press('Enter');
await page.waitForTimeout(1000);
// Click "Apply Video" button if present
const applyBtn = page.locator('#traits-container button:has-text("Apply Video")');
if (await applyBtn.isVisible({ timeout: 1000 }).catch(() => false)) {
await applyBtn.click();
await page.waitForTimeout(1000);
}
// Verify via editor HTML output (canvas renders iframes as divs)
const html = await page.evaluate(() => window.editor.getHtml());
expect(html).toContain('youtube-nocookie.com');
expect(html).toContain('embed/dQw4w9WgXcQ');
expect(html).not.toContain('www.youtube.com/embed');
});
test('should have correct referrerpolicy attribute', async ({ page }) => {
// Add Video block and check via editor HTML
const result = await addBlockById(page, 'video-block');
expect(result.success).toBe(true);
await page.waitForTimeout(500);
const html = await page.evaluate(() => window.editor.getHtml());
expect(html).toContain('referrerpolicy="strict-origin-when-cross-origin"');
});
test('should have required allow attributes', async ({ page }) => {
// Add Video block and check via editor HTML
const result = await addBlockById(page, 'video-block');
expect(result.success).toBe(true);
await page.waitForTimeout(500);
const html = await page.evaluate(() => window.editor.getHtml());
expect(html).toContain('accelerometer');
expect(html).toContain('encrypted-media');
expect(html).toContain('gyroscope');
expect(html).toContain('picture-in-picture');
});
test('should work with youtu.be short URLs', async ({ page }) => {
// Add Video block
const result = await addBlockById(page, 'video-block');
expect(result.success).toBe(true);
await page.waitForTimeout(500);
// Select the wrapper
await page.evaluate(() => {
const editor = window.editor;
const wrapper = editor.getWrapper();
const videoWrapper = wrapper.find('[data-video-wrapper]')[0];
if (videoWrapper) editor.select(videoWrapper);
});
await page.waitForTimeout(500);
// Open Settings
await page.locator('button[data-panel="traits"]').click();
await page.waitForTimeout(500);
// Fill URL
const videoUrlInput = page.locator('#traits-container input[placeholder*="YouTube"]');
await expect(videoUrlInput).toBeVisible({ timeout: 5000 });
await videoUrlInput.fill('https://youtu.be/dQw4w9WgXcQ');
await videoUrlInput.press('Enter');
await page.waitForTimeout(1000);
// Click Apply if present
const applyBtn = page.locator('#traits-container button:has-text("Apply Video")');
if (await applyBtn.isVisible({ timeout: 1000 }).catch(() => false)) {
await applyBtn.click();
await page.waitForTimeout(1000);
}
// Verify via editor HTML
const html = await page.evaluate(() => window.editor.getHtml());
expect(html).toContain('youtube-nocookie.com');
expect(html).toContain('embed/dQw4w9WgXcQ');
});
test('video block uses unified Video element with iframe and video tags', async ({ page }) => {
// Add Video block and verify structure via editor HTML
const result = await addBlockById(page, 'video-block');
expect(result.success).toBe(true);
await page.waitForTimeout(500);
const html = await page.evaluate(() => window.editor.getHtml());
// The block should contain both iframe and video elements
expect(html).toContain('<iframe');
expect(html).toContain('class="video-frame"');
expect(html).toContain('<video');
expect(html).toContain('class="video-player"');
expect(html).toContain('class="video-wrapper"');
});
});