diff --git a/tests/assets/example.mp3 b/tests/assets/audio/example.mp3 similarity index 100% rename from tests/assets/example.mp3 rename to tests/assets/audio/example.mp3 diff --git a/tests/assets/movie.ogv b/tests/assets/audio/movie.ogv similarity index 100% rename from tests/assets/movie.ogv rename to tests/assets/audio/movie.ogv diff --git a/tests/assets/video.html b/tests/assets/video.html deleted file mode 100644 index c193f924cbfa0..0000000000000 --- a/tests/assets/video.html +++ /dev/null @@ -1,16 +0,0 @@ - -
- - - --Video courtesy of -Big Buck Bunny. -
- - - \ No newline at end of file diff --git a/tests/assets/video/big-buck-bunny-av1.mp4 b/tests/assets/video/big-buck-bunny-av1.mp4 new file mode 100644 index 0000000000000..ca92a8c2cfdcd Binary files /dev/null and b/tests/assets/video/big-buck-bunny-av1.mp4 differ diff --git a/tests/assets/video/big-buck-bunny-h264.mkv b/tests/assets/video/big-buck-bunny-h264.mkv new file mode 100644 index 0000000000000..e59cb40abdda4 Binary files /dev/null and b/tests/assets/video/big-buck-bunny-h264.mkv differ diff --git a/tests/assets/video/big-buck-bunny-h264.mp4 b/tests/assets/video/big-buck-bunny-h264.mp4 new file mode 100644 index 0000000000000..9b6d89da00a2d Binary files /dev/null and b/tests/assets/video/big-buck-bunny-h264.mp4 differ diff --git a/tests/assets/video/big-buck-bunny-hevc.mp4 b/tests/assets/video/big-buck-bunny-hevc.mp4 new file mode 100644 index 0000000000000..c2b2f4792150f Binary files /dev/null and b/tests/assets/video/big-buck-bunny-hevc.mp4 differ diff --git a/tests/assets/video/big-buck-bunny-vp9.webm b/tests/assets/video/big-buck-bunny-vp9.webm new file mode 100644 index 0000000000000..76f6275d693de Binary files /dev/null and b/tests/assets/video/big-buck-bunny-vp9.webm differ diff --git a/tests/assets/movie.webm b/tests/assets/video/movie-vp8.webm similarity index 100% rename from tests/assets/movie.webm rename to tests/assets/video/movie-vp8.webm diff --git a/tests/assets/movie.mp4 b/tests/assets/video/movie.mp4 similarity index 100% rename from tests/assets/movie.mp4 rename to tests/assets/video/movie.mp4 diff --git a/tests/assets/video_mp4.html b/tests/assets/video_mp4.html deleted file mode 100644 index dada285d76add..0000000000000 --- a/tests/assets/video_mp4.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - --Video courtesy of -Big Buck Bunny. -
- - - \ No newline at end of file diff --git a/tests/assets/video_webm.html b/tests/assets/video_webm.html deleted file mode 100644 index 7d86354419713..0000000000000 --- a/tests/assets/video_webm.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - --Video courtesy of -Big Buck Bunny. -
- - - \ No newline at end of file diff --git a/tests/library/capabilities.spec.ts b/tests/library/capabilities.spec.ts index 8b065834ab2b0..7bf0df8323b56 100644 --- a/tests/library/capabilities.spec.ts +++ b/tests/library/capabilities.spec.ts @@ -15,9 +15,11 @@ */ import os from 'os'; -import url from 'url'; +import path from 'path'; import { contextTest as it, expect } from '../config/browserTest'; import { hostPlatform } from '../../packages/playwright-core/src/server/utils/hostPlatform'; +import { Page } from 'packages/playwright/test'; +import { TestServer } from 'tests/config/testserver'; it('SharedArrayBuffer should work @smoke', async function({ contextFactory, httpsServer }) { const context = await contextFactory({ ignoreHTTPSErrors: true }); @@ -64,43 +66,6 @@ it('should respect CSP @smoke', async ({ page, server }) => { expect(await page.evaluate(() => window['testStatus'])).toBe('SUCCESS'); }); -it('should play video @smoke', async ({ page, asset, browserName, isWindows, isLinux, mode }) => { - it.skip(browserName === 'webkit' && isWindows, 'passes locally but fails on GitHub Action bot, apparently due to a Media Pack issue in the Windows Server'); - it.fixme(browserName === 'firefox' && isLinux, 'https://github.com/microsoft/playwright/issues/5721'); - it.skip(mode.startsWith('service')); - - // Safari only plays mp4 so we test WebKit with an .mp4 clip. - const fileName = browserName === 'webkit' ? 'video_mp4.html' : 'video.html'; - const absolutePath = asset(fileName); - // Our test server doesn't support range requests required to play on Mac, - // so we load the page using a file url. - await page.goto(url.pathToFileURL(absolutePath).href); - await page.$eval('video', v => v.play()); - await page.$eval('video', v => v.pause()); -}); - -it('should play webm video @smoke', async ({ page, asset, browserName, platform, macVersion, mode }) => { - it.skip(browserName === 'webkit' && platform === 'win32', 'not supported'); - it.skip(mode.startsWith('service')); - - const absolutePath = asset('video_webm.html'); - // Our test server doesn't support range requests required to play on Mac, - // so we load the page using a file url. - await page.goto(url.pathToFileURL(absolutePath).href); - await page.$eval('video', v => v.play()); - await page.$eval('video', v => v.pause()); -}); - -it('should play audio @smoke', async ({ page, server, browserName, platform }) => { - it.fixme(browserName === 'webkit' && platform === 'win32', 'https://github.com/microsoft/playwright/issues/10892'); - await page.goto(server.EMPTY_PAGE); - await page.setContent(``); - await page.$eval('audio', e => e.play()); - await page.waitForTimeout(1000); - await page.$eval('audio', e => e.pause()); - expect(await page.$eval('audio', e => e.currentTime)).toBeGreaterThan(0.2); -}); - it('should support webgl @smoke', async ({ page, browserName, platform }) => { it.fixme(browserName === 'chromium' && platform === 'darwin' && os.arch() === 'arm64', 'SwiftShader is not available on macOS-arm64 - https://github.com/microsoft/playwright/issues/28216'); const hasWebGL = await page.evaluate(() => { @@ -125,7 +90,7 @@ it('should support webgl 2 @smoke', async ({ page, browserName, headless, isWind it('should not crash on page with mp4 @smoke', async ({ page, server, platform, browserName }) => { it.fixme(browserName === 'webkit' && platform === 'win32', 'https://github.com/microsoft/playwright/issues/11009, times out in setContent'); - await page.setContent(``); + await page.setContent(``); await page.waitForTimeout(1000); }); @@ -480,3 +445,110 @@ it('should not auto play audio', { await page.goto('http://127.0.0.1/audio.html'); await expect(page.locator('#log')).toHaveText('State: suspended'); }); + +async function testVideo(page: Page, server: TestServer, file: string, type?: string) { + server.setRoute('/video.html', (req, res) => { + res.writeHead(200, { 'content-type': 'text/html' }); + res.end(` + + `); + }); + await page.goto(server.PREFIX + '/video.html'); + const video = page.locator('#test-video'); + await video.evaluate(async (v: HTMLVideoElement) => { + await v.play(); + await new Promise((resolve, reject) => { + v.addEventListener('ended', resolve); + v.addEventListener('error', reject); + }); + }); + const currentTime = await video.evaluate((v: HTMLVideoElement) => v.currentTime); + expect(currentTime).toBeGreaterThan(0); +} + +async function testAudio(page: Page, server: TestServer, file: string, type?: string) { + server.setRoute('/audio.html', (req, res) => { + res.writeHead(200, { 'content-type': 'text/html' }); + res.end(` + + `); + }); + await page.goto(server.PREFIX + '/audio.html'); + const audio = page.locator('#test-audio'); + await audio.evaluate(async (a: HTMLAudioElement) => { + await a.play(); + await new Promise((resolve, reject) => { + a.addEventListener('ended', resolve); + a.addEventListener('error', reject); + }); + }); + const currentTime = await audio.evaluate((a: HTMLAudioElement) => a.currentTime); + expect(currentTime).toBeGreaterThan(0); +} + +function skipDueToNoProprietaryCodecs(browserName: string, channel: string | undefined) { + return browserName === 'chromium' && ![ + 'chrome', + 'chrome-beta', + 'chrome-dev', + 'chrome-canary', + 'msedge', + 'msedge-dev', + 'msedge-beta', + ].includes(channel); +} + +it.describe('Audio & Video codec playback', () => { + it('H.264 (MKV container)', async ({ page, server, browserName, channel, headless, platform }) => { + it.skip(skipDueToNoProprietaryCodecs(browserName, channel), 'Proprietary codec'); + it.fixme(browserName === 'webkit' && platform === 'win32'); + it.fixme(browserName === 'webkit' && platform === 'linux' && headless); + await testVideo(page, server, '/video/big-buck-bunny-h264.mkv', 'video/mp4'); + }); + + it('H.264 (MP4 container)', async ({ page, server, browserName, channel, headless, platform }) => { + it.skip(skipDueToNoProprietaryCodecs(browserName, channel), 'Proprietary codec'); + it.fixme(browserName === 'webkit' && platform === 'linux' && headless); + await testVideo(page, server, '/video/big-buck-bunny-h264.mp4', 'video/mp4'); + }); + + it('HEVC (MP4 container)', async ({ page, server, browserName, channel, platform }) => { + it.skip(skipDueToNoProprietaryCodecs(browserName, channel), 'Proprietary codec'); + it.skip(browserName === 'webkit', 'Does not work in Safari either'); + it.skip(browserName === 'firefox' && platform === 'win32', 'Does not work in Mozilla Firefox either'); + await testVideo(page, server, '/video/big-buck-bunny-hevc.mp4', 'video/mp4'); + }); + + it('VP9 (WebM container)', async ({ page, server, browserName, platform }) => { + it.fixme(browserName === 'webkit' && platform === 'linux'); + it.fixme(browserName === 'webkit' && platform === 'win32'); + await testVideo(page, server, '/video/big-buck-bunny-vp9.webm', 'video/webm'); + }); + + it('AV1 (MP4 container)', async ({ page, server, browserName, platform }) => { + it.skip(browserName === 'webkit' && platform === 'darwin', 'Does not work in Safari either'); + it.skip(browserName === 'webkit' && platform === 'win32', 'Does not work in Safari either'); + await testVideo(page, server, '/video/big-buck-bunny-av1.mp4', 'video/mp4'); + }); + + it('VP8 (WebM container)', async ({ page, server, browserName, platform }) => { + it.fixme(browserName === 'webkit' && platform === 'win32'); + await testVideo(page, server, '/video/movie-vp8.webm', 'video/webm'); + }); + + it('Theora (OGV container)', async ({ page, server, browserName, platform }) => { + it.fixme(browserName === 'webkit' && platform === 'win32'); + it.fixme(browserName === 'webkit' && platform === 'linux' && hostPlatform.startsWith('ubuntu22.04')); + it.fixme(browserName === 'firefox' && platform === 'linux'); + await testAudio(page, server, '/audio/movie.ogv', 'audio/ogg'); + }); + + it('MP3 (MP3 container)', async ({ page, server, browserName, platform }) => { + it.fixme(browserName === 'firefox' && platform === 'linux'); + await testAudio(page, server, '/audio/example.mp3', 'audio/mpeg'); + }); +});