2020-08-03 13:41:48 -07:00
/ * *
* Copyright Microsoft Corporation . All rights reserved .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
2020-10-21 01:48:00 +02:00
import os from 'os' ;
2020-08-06 14:12:14 -07:00
import url from 'url' ;
2022-03-25 15:05:50 -08:00
import { contextTest as it , expect } from '../config/browserTest' ;
2025-02-12 19:27:24 -08:00
import { hostPlatform } from '../../packages/playwright-core/src/server/utils/hostPlatform' ;
2020-08-03 13:41:48 -07:00
2024-11-13 17:21:21 -08:00
it ( 'SharedArrayBuffer should work @smoke' , async function ( { contextFactory , httpsServer } ) {
2021-09-01 13:27:37 +03:00
const context = await contextFactory ( { ignoreHTTPSErrors : true } ) ;
const page = await context . newPage ( ) ;
httpsServer . setRoute ( '/sharedarraybuffer' , ( req , res ) = > {
res . setHeader ( 'Cross-Origin-Opener-Policy' , 'same-origin' ) ;
res . setHeader ( 'Cross-Origin-Embedder-Policy' , 'require-corp' ) ;
res . end ( ) ;
} ) ;
await page . goto ( httpsServer . PREFIX + '/sharedarraybuffer' ) ;
expect ( await page . evaluate ( ( ) = > typeof SharedArrayBuffer ) ) . toBe ( 'function' ) ;
} ) ;
2024-05-15 02:34:39 -07:00
it ( 'Web Assembly should work @smoke' , async ( { page , server , browserName , platform } ) = > {
it . fixme ( browserName === 'webkit' && platform === 'win32' , 'Windows JIT is disabled: https://bugs.webkit.org/show_bug.cgi?id=273854' ) ;
2020-08-03 13:41:48 -07:00
await page . goto ( server . PREFIX + '/wasm/table2.html' ) ;
2020-08-06 14:12:14 -07:00
expect ( await page . evaluate ( 'loadTable()' ) ) . toBe ( '42, 83' ) ;
2020-08-03 13:41:48 -07:00
} ) ;
2022-03-10 19:42:52 +01:00
it ( 'WebSocket should work @smoke' , async ( { page , server } ) = > {
2021-05-26 15:18:52 -07:00
server . sendOnWebSocketConnection ( 'incoming' ) ;
2020-08-28 04:20:29 -07:00
const value = await page . evaluate ( port = > {
2020-08-03 13:41:48 -07:00
let cb ;
const result = new Promise ( f = > cb = f ) ;
const ws = new WebSocket ( 'ws://localhost:' + port + '/ws' ) ;
ws . addEventListener ( 'message' , data = > { ws . close ( ) ; cb ( data . data ) ; } ) ;
ws . addEventListener ( 'error' , error = > cb ( 'Error' ) ) ;
return result ;
} , server . PORT ) ;
expect ( value ) . toBe ( 'incoming' ) ;
} ) ;
2022-03-10 19:42:52 +01:00
it ( 'should respect CSP @smoke' , async ( { page , server } ) = > {
2020-08-03 13:41:48 -07:00
server . setRoute ( '/empty.html' , async ( req , res ) = > {
res . setHeader ( 'Content-Security-Policy' , ` script-src 'unsafe-inline'; ` ) ;
res . end ( `
< script >
window . testStatus = 'SUCCESS' ;
window . testStatus = eval ( "'FAILED'" ) ;
< / script > ` );
} ) ;
await page . goto ( server . EMPTY_PAGE ) ;
2020-08-06 14:12:14 -07:00
expect ( await page . evaluate ( ( ) = > window [ 'testStatus' ] ) ) . toBe ( 'SUCCESS' ) ;
2020-08-03 13:41:48 -07:00
} ) ;
2024-10-04 08:22:27 -07:00
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' ) ;
2023-07-25 16:47:04 -07:00
it . skip ( mode . startsWith ( 'service' ) ) ;
2021-04-02 21:07:45 -07:00
2020-08-03 16:06:57 -07:00
// Safari only plays mp4 so we test WebKit with an .mp4 clip.
2021-05-13 10:22:23 -07:00
const fileName = browserName === 'webkit' ? 'video_mp4.html' : 'video.html' ;
2020-08-13 17:32:27 -07:00
const absolutePath = asset ( fileName ) ;
2020-08-03 13:41:48 -07:00
// Our test server doesn't support range requests required to play on Mac,
// so we load the page using a file url.
2020-08-04 17:26:42 -07:00
await page . goto ( url . pathToFileURL ( absolutePath ) . href ) ;
2020-08-03 13:41:48 -07:00
await page . $eval ( 'video' , v = > v . play ( ) ) ;
2023-01-27 09:48:47 -08:00
await page . $eval ( 'video' , v = > v . pause ( ) ) ;
} ) ;
2024-09-27 07:06:37 -07:00
it ( 'should play webm video @smoke' , async ( { page , asset , browserName , platform , macVersion , mode } ) = > {
2024-10-04 08:22:27 -07:00
it . skip ( browserName === 'webkit' && platform === 'win32' , 'not supported' ) ;
2023-07-25 16:47:04 -07:00
it . skip ( mode . startsWith ( 'service' ) ) ;
2023-01-27 09:48:47 -08:00
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 ( ) ) ;
2020-08-03 13:41:48 -07:00
await page . $eval ( 'video' , v = > v . pause ( ) ) ;
} ) ;
2020-11-04 13:24:30 -08:00
2022-03-10 19:42:52 +01:00
it ( 'should play audio @smoke' , async ( { page , server , browserName , platform } ) = > {
2021-12-13 15:02:06 -08:00
it . fixme ( browserName === 'webkit' && platform === 'win32' , 'https://github.com/microsoft/playwright/issues/10892' ) ;
await page . goto ( server . EMPTY_PAGE ) ;
await page . setContent ( ` <audio src=" ${ server . PREFIX } /example.mp3"></audio> ` ) ;
await page . $eval ( 'audio' , e = > e . play ( ) ) ;
await page . waitForTimeout ( 1000 ) ;
await page . $eval ( 'audio' , e = > e . pause ( ) ) ;
2022-02-04 16:14:48 -08:00
expect ( await page . $eval ( 'audio' , e = > e . currentTime ) ) . toBeGreaterThan ( 0.2 ) ;
2021-12-13 15:02:06 -08:00
} ) ;
2023-12-06 13:52:49 -08:00
it ( 'should support webgl @smoke' , async ( { page , browserName , platform } ) = > {
2024-07-12 20:12:56 +02:00
it . fixme ( browserName === 'chromium' && platform === 'darwin' && os . arch ( ) === 'arm64' , 'SwiftShader is not available on macOS-arm64 - https://github.com/microsoft/playwright/issues/28216' ) ;
2020-11-16 16:18:50 -08:00
const hasWebGL = await page . evaluate ( ( ) = > {
2020-11-04 13:24:30 -08:00
const canvas = document . createElement ( 'canvas' ) ;
return ! ! canvas . getContext ( 'webgl' ) ;
} ) ;
2020-11-16 16:18:50 -08:00
expect ( hasWebGL ) . toBe ( true ) ;
2020-11-04 13:24:30 -08:00
} ) ;
2023-12-06 13:52:49 -08:00
it ( 'should support webgl 2 @smoke' , async ( { page , browserName , headless , isWindows , platform } ) = > {
2024-07-12 20:12:56 +02:00
it . skip ( browserName === 'webkit' , 'WebKit doesn\'t have webgl2 enabled yet upstream.' ) ;
2023-01-27 21:52:34 -08:00
it . fixme ( browserName === 'firefox' && isWindows ) ;
2024-07-12 20:12:56 +02:00
it . fixme ( browserName === 'chromium' && ! headless , 'chromium doesn\'t like webgl2 when running under xvfb' ) ;
it . fixme ( browserName === 'chromium' && platform === 'darwin' && os . arch ( ) === 'arm64' , 'SwiftShader is not available on macOS-arm64 - https://github.com/microsoft/playwright/issues/28216' ) ;
2021-04-02 21:07:45 -07:00
2020-11-04 13:24:30 -08:00
const hasWebGL2 = await page . evaluate ( ( ) = > {
const canvas = document . createElement ( 'canvas' ) ;
return ! ! canvas . getContext ( 'webgl2' ) ;
} ) ;
expect ( hasWebGL2 ) . toBe ( true ) ;
} ) ;
2021-12-20 12:44:06 -08:00
2022-03-10 19:42:52 +01:00
it ( 'should not crash on page with mp4 @smoke' , async ( { page , server , platform , browserName } ) = > {
2021-12-20 12:44:06 -08:00
it . fixme ( browserName === 'webkit' && platform === 'win32' , 'https://github.com/microsoft/playwright/issues/11009, times out in setContent' ) ;
await page . setContent ( ` <video><source src=" ${ server . PREFIX } /movie.mp4"/></video> ` ) ;
await page . waitForTimeout ( 1000 ) ;
2021-12-29 19:51:28 -07:00
} ) ;
2022-01-06 09:08:13 -08:00
2022-01-27 11:40:06 -08:00
it ( 'should not crash on showDirectoryPicker' , async ( { page , server , browserName , browserMajorVersion } ) = > {
2022-01-06 09:08:13 -08:00
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/7339' } ) ;
2022-01-27 11:40:06 -08:00
it . skip ( browserName === 'chromium' && browserMajorVersion < 99 , 'Fixed in Chromium r956769' ) ;
2022-01-06 09:08:13 -08:00
it . skip ( browserName !== 'chromium' , 'showDirectoryPicker is only available in Chromium' ) ;
await page . goto ( server . EMPTY_PAGE ) ;
2024-09-27 07:06:37 -07:00
// "User activation is required to show a file picker." - so we click first.
await page . locator ( 'body' ) . click ( ) ;
2024-06-26 07:51:57 -07:00
page . evaluate ( async ( ) = > {
const dir = await ( window as any ) . showDirectoryPicker ( ) ;
return dir . name ;
// In headless it throws (aborted), in headed it stalls (Test ended) and waits for the picker to be accepted.
2024-08-01 06:13:15 -07:00
} ) . catch ( e = > expect ( e . message ) . toMatch ( /((DOMException|AbortError): .*The user aborted a request|Test ended)/ ) ) ;
2024-06-26 07:51:57 -07:00
// The dialog will not be accepted, so we just wait for some time to
// to give the browser a chance to crash.
await page . waitForTimeout ( 3 _000 ) ;
2022-01-06 09:08:13 -08:00
} ) ;
2022-10-26 15:41:36 -07:00
it ( 'should not crash on storage.getDirectory()' , async ( { page , server , browserName , isMac } ) = > {
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/18235' } ) ;
it . skip ( browserName === 'firefox' , 'navigator.storage.getDirectory is not a function' ) ;
await page . goto ( server . EMPTY_PAGE ) ;
const error = await page . evaluate ( async ( ) = > {
const dir = await navigator . storage . getDirectory ( ) ;
return dir . name ;
} ) . catch ( e = > e ) ;
if ( browserName === 'webkit' ) {
if ( isMac )
expect ( error . message ) . toContain ( 'UnknownError: The operation failed for an unknown transient reason' ) ;
else
expect ( error . message ) . toContain ( 'TypeError: undefined is not an object' ) ;
} else {
expect ( error ) . toBeFalsy ( ) ;
}
} ) ;
2023-01-26 10:15:19 -08:00
2023-02-21 23:49:14 +01:00
it ( 'navigator.clipboard should be present' , async ( { page , server } ) = > {
2023-01-26 10:15:19 -08:00
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/18901' } ) ;
await page . goto ( server . EMPTY_PAGE ) ;
expect ( await page . evaluate ( ( ) = > navigator . clipboard ) ) . toBeTruthy ( ) ;
} ) ;
2023-02-02 19:04:26 +01:00
2023-02-21 23:49:14 +01:00
it ( 'should set CloseEvent.wasClean to false when the server terminates a WebSocket connection' , async ( { page , server } ) = > {
2023-02-02 19:04:26 +01:00
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/12353' } ) ;
server . onceWebSocketConnection ( socket = > {
socket . terminate ( ) ;
} ) ;
const wasClean = await page . evaluate ( port = > new Promise < boolean > ( resolve = > {
const ws = new WebSocket ( 'ws://localhost:' + port + '/ws' ) ;
ws . addEventListener ( 'close' , error = > resolve ( error . wasClean ) ) ;
} ) , server . PORT ) ;
expect ( wasClean ) . toBe ( false ) ;
} ) ;
2023-02-21 19:36:19 +01:00
2023-03-16 19:24:13 +01:00
it ( 'serviceWorker should intercept document request' , async ( { page , server } ) = > {
2023-02-21 19:36:19 +01:00
server . setRoute ( '/sw.js' , ( req , res ) = > {
res . setHeader ( 'Content-Type' , 'application/javascript' ) ;
res . end ( `
self . addEventListener ( 'fetch' , event = > {
event . respondWith ( new Response ( 'intercepted' ) ) ;
} ) ;
2023-03-16 19:24:13 +01:00
self . addEventListener ( 'activate' , event = > {
event . waitUntil ( clients . claim ( ) ) ;
} ) ;
2023-02-21 19:36:19 +01:00
` );
} ) ;
await page . goto ( server . EMPTY_PAGE ) ;
2023-03-16 19:24:13 +01:00
await page . evaluate ( async ( ) = > {
await navigator . serviceWorker . register ( '/sw.js' ) ;
await new Promise ( resolve = > navigator . serviceWorker . oncontrollerchange = resolve ) ;
} ) ;
2023-02-21 19:36:19 +01:00
await page . reload ( ) ;
expect ( await page . textContent ( 'body' ) ) . toBe ( 'intercepted' ) ;
} ) ;
2023-03-03 13:38:13 -08:00
it ( 'webkit should define window.safari' , async ( { page , server , browserName } ) = > {
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/21037' } ) ;
2024-01-22 15:44:13 -08:00
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/29032' } ) ;
2023-03-03 13:38:13 -08:00
it . skip ( browserName !== 'webkit' ) ;
await page . goto ( server . EMPTY_PAGE ) ;
const defined = await page . evaluate ( ( ) = > ! ! ( window as any ) . safari ) ;
expect ( defined ) . toBeTruthy ( ) ;
2024-01-22 15:44:13 -08:00
expect ( await page . evaluate ( ( ) = > typeof ( window as any ) . safari . pushNotification ) ) . toBe ( 'object' ) ;
expect ( await page . evaluate ( ( ) = > ( window as any ) . safari . pushNotification . toString ( ) ) ) . toBe ( '[object SafariRemoteNotification]' ) ;
2023-03-03 13:38:13 -08:00
} ) ;
2023-03-09 16:21:01 +01:00
2023-03-17 12:32:55 +01:00
it ( 'make sure that XMLHttpRequest upload events are emitted correctly' , async ( { page , server } ) = > {
2023-03-09 16:21:01 +01:00
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/21489' } ) ;
await page . goto ( server . EMPTY_PAGE ) ;
const events = await page . evaluate ( async ( ) = > {
const events : string [ ] = [ ] ;
const xhr = new XMLHttpRequest ( ) ;
xhr . upload . addEventListener ( 'loadstart' , ( ) = > events . push ( 'loadstart' ) ) ;
xhr . upload . addEventListener ( 'progress' , ( ) = > events . push ( 'progress' ) ) ;
xhr . upload . addEventListener ( 'load' , ( ) = > events . push ( 'load' ) ) ;
xhr . upload . addEventListener ( 'loadend' , ( ) = > events . push ( 'loadend' ) ) ;
xhr . open ( 'POST' , '/simple.json' ) ;
xhr . send ( 'hello' ) ;
await new Promise ( f = > xhr . onload = f ) ;
return events ;
} ) ;
expect ( events ) . toEqual ( [ 'loadstart' , 'progress' , 'load' , 'loadend' ] ) ;
} ) ;
2023-05-01 14:55:20 -07:00
2024-11-13 17:21:21 -08:00
it ( 'loading in HTMLImageElement.prototype' , async ( { page , server } ) = > {
2023-05-01 14:55:20 -07:00
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/22738' } ) ;
await page . goto ( server . EMPTY_PAGE ) ;
const defined = await page . evaluate ( ( ) = > 'loading' in HTMLImageElement . prototype ) ;
expect ( defined ) . toBeTruthy ( ) ;
} ) ;
2023-05-05 11:37:28 -07:00
it ( 'window.GestureEvent in WebKit' , async ( { page , server , browserName } ) = > {
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/22735' } ) ;
await page . goto ( server . EMPTY_PAGE ) ;
const defined = await page . evaluate ( ( ) = > 'GestureEvent' in window ) ;
expect ( defined ) . toBe ( browserName === 'webkit' ) ;
const type = await page . evaluate ( ( ) = > typeof ( window as any ) . GestureEvent ) ;
expect ( type ) . toBe ( browserName === 'webkit' ? 'function' : 'undefined' ) ;
} ) ;
2023-05-10 09:31:20 -07:00
2024-11-13 17:21:21 -08:00
it ( 'requestFullscreen' , async ( { page , server } ) = > {
2023-05-10 09:31:20 -07:00
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/22832' } ) ;
await page . goto ( server . EMPTY_PAGE ) ;
await page . evaluate ( ( ) = > {
const result = new Promise ( resolve = > document . addEventListener ( 'fullscreenchange' , resolve ) ) ;
2023-06-02 21:59:12 +02:00
void document . documentElement . requestFullscreen ( ) ;
2023-05-10 09:31:20 -07:00
return result ;
} ) ;
expect ( await page . evaluate ( ( ) = > document . fullscreenElement === document . documentElement ) ) . toBeTruthy ( ) ;
await page . evaluate ( ( ) = > {
const result = new Promise ( resolve = > document . addEventListener ( 'fullscreenchange' , resolve ) ) ;
2023-06-02 21:59:12 +02:00
void document . exitFullscreen ( ) ;
2023-05-10 09:31:20 -07:00
return result ;
} ) ;
expect ( await page . evaluate ( ( ) = > ! ! document . fullscreenElement ) ) . toBeFalsy ( ) ;
} ) ;
2023-08-21 22:12:12 +02:00
2024-11-13 17:21:21 -08:00
it ( 'should send no Content-Length header for GET requests with a Content-Type' , async ( { page , server } ) = > {
2023-08-21 22:12:12 +02:00
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/22569' } ) ;
await page . goto ( server . EMPTY_PAGE ) ;
const [ request ] = await Promise . all ( [
server . waitForRequest ( '/empty.html' ) ,
page . evaluate ( ( ) = > fetch ( '/empty.html' , {
'headers' : { 'Content-Type' : 'application/json' } ,
'method' : 'GET'
} ) )
] ) ;
expect ( request . headers [ 'content-length' ] ) . toBe ( undefined ) ;
} ) ;
2023-11-15 18:47:42 -08:00
2023-11-16 20:39:32 +01:00
it ( 'Intl.ListFormat should work' , async ( { page , server , browserName } ) = > {
2023-11-15 18:47:42 -08:00
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/23978' } ) ;
2023-11-16 20:39:32 +01:00
it . skip ( browserName === 'webkit' && hostPlatform . startsWith ( 'ubuntu20.04' ) , 'libicu is too old and WebKit disables Intl.ListFormat by default then' ) ;
2023-11-15 18:47:42 -08:00
await page . goto ( server . EMPTY_PAGE ) ;
const formatted = await page . evaluate ( ( ) = > {
const data = [ 'first' , 'second' , 'third' ] ;
const listFormat = new Intl . ListFormat ( 'en' , {
type : 'disjunction' ,
style : 'short' ,
} ) ;
return listFormat . format ( data ) ;
} ) ;
expect ( formatted ) . toBe ( 'first, second, or third' ) ;
} ) ;
2024-03-21 11:27:27 -07:00
it ( 'service worker should cover the iframe' , async ( { page , server } ) = > {
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/29267' } ) ;
server . setRoute ( '/sw.html' , ( req , res ) = > {
res . writeHead ( 200 , { 'content-type' : 'text/html' } ) . end ( `
< script >
window . registrationPromise = navigator . serviceWorker . register ( 'sw.js' ) ;
window . activationPromise = new Promise ( resolve = > navigator . serviceWorker . oncontrollerchange = resolve ) ;
< / script >
` );
} ) ;
server . setRoute ( '/iframe.html' , ( req , res ) = > {
res . writeHead ( 200 , { 'content-type' : 'text/html' } ) . end ( ` <div>from the server</div> ` ) ;
} ) ;
server . setRoute ( '/sw.js' , ( req , res ) = > {
res . writeHead ( 200 , { 'content-type' : 'application/javascript' } ) . end ( `
const kIframeHtml = "<div>from the service worker</div>" ;
self . addEventListener ( 'fetch' , event = > {
if ( event . request . url . endsWith ( 'iframe.html' ) ) {
const blob = new Blob ( [ kIframeHtml ] , { type : 'text/html' } ) ;
const response = new Response ( blob , { status : 200 , statusText : 'OK' } ) ;
event . respondWith ( response ) ;
return ;
}
event . respondWith ( fetch ( event . request ) ) ;
} ) ;
self . addEventListener ( 'activate' , event = > {
event . waitUntil ( clients . claim ( ) ) ;
} ) ;
` );
} ) ;
await page . goto ( server . PREFIX + '/sw.html' ) ;
await page . evaluate ( ( ) = > window [ 'activationPromise' ] ) ;
await page . evaluate ( ( ) = > {
const iframe = document . createElement ( 'iframe' ) ;
iframe . src = '/iframe.html' ;
document . body . appendChild ( iframe ) ;
} ) ;
await expect ( page . frameLocator ( 'iframe' ) . locator ( 'div' ) ) . toHaveText ( 'from the service worker' ) ;
} ) ;
2024-03-21 15:34:23 -07:00
it ( 'service worker should register in an iframe' , async ( { page , server } ) = > {
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/29267' } ) ;
server . setRoute ( '/main.html' , ( req , res ) = > {
res . writeHead ( 200 , { 'content-type' : 'text/html' } ) . end ( `
< iframe src = '/dir/iframe.html' > < / iframe >
` );
} ) ;
server . setRoute ( '/dir/iframe.html' , ( req , res ) = > {
res . writeHead ( 200 , { 'content-type' : 'text/html' } ) . end ( `
< script >
window . registrationPromise = navigator . serviceWorker . register ( 'sw.js' ) ;
window . activationPromise = new Promise ( resolve = > navigator . serviceWorker . oncontrollerchange = resolve ) ;
< / script >
` );
} ) ;
server . setRoute ( '/dir/sw.js' , ( req , res ) = > {
res . writeHead ( 200 , { 'content-type' : 'application/javascript' } ) . end ( `
const kIframeHtml = "<div>from the service worker</div>" ;
self . addEventListener ( 'fetch' , event = > {
if ( event . request . url . endsWith ( 'html' ) ) {
event . respondWith ( fetch ( event . request ) ) ;
return ;
}
const blob = new Blob ( [ 'responseFromServiceWorker' ] , { type : 'text/plain' } ) ;
const response = new Response ( blob , { status : 200 , statusText : 'OK' } ) ;
event . respondWith ( response ) ;
} ) ;
self . addEventListener ( 'activate' , event = > {
event . waitUntil ( clients . claim ( ) ) ;
} ) ;
` );
} ) ;
await page . goto ( server . PREFIX + '/main.html' ) ;
const iframe = page . frames ( ) [ 1 ] ;
await iframe . evaluate ( ( ) = > window [ 'activationPromise' ] ) ;
const response = await iframe . evaluate ( async ( ) = > {
const response = await fetch ( 'foo.txt' ) ;
return response . text ( ) ;
} ) ;
expect ( response ) . toBe ( 'responseFromServiceWorker' ) ;
} ) ;
2024-09-27 19:02:54 +02:00
2024-09-30 10:30:45 +02:00
it ( 'should be able to render avif images' , {
annotation : {
type : 'issue' ,
description : 'https://github.com/microsoft/playwright/issues/32673' ,
}
} , async ( { page , server , browserName , platform } ) = > {
2024-09-27 19:02:54 +02:00
it . fixme ( browserName === 'webkit' && platform === 'win32' ) ;
2024-10-22 22:30:54 +02:00
it . skip ( browserName === 'webkit' && hostPlatform . startsWith ( 'ubuntu20.04' ) , 'Ubuntu 20.04 is frozen' ) ;
2024-10-24 16:49:35 +02:00
it . skip ( browserName === 'webkit' && hostPlatform . startsWith ( 'debian11' ) , 'Debian 11 is too old' ) ;
2024-09-27 19:02:54 +02:00
await page . goto ( server . EMPTY_PAGE ) ;
await page . setContent ( ` <img src=" ${ server . PREFIX } /rgb.avif" onerror="window.error = true"> ` ) ;
await expect . poll ( ( ) = > page . locator ( 'img' ) . boundingBox ( ) ) . toEqual ( expect . objectContaining ( {
width : 128 ,
height : 128 ,
} ) ) ;
expect ( await page . evaluate ( ( ) = > ( window as any ) . error ) ) . toBe ( undefined ) ;
} ) ;
2024-11-18 16:56:59 +01:00
it ( 'should not crash when clicking a label with a <input type="file"/>' , {
annotation : {
type : 'issue' ,
description : 'https://github.com/microsoft/playwright/issues/33257'
}
} , async ( { page } ) = > {
await page . setContent ( `
< form >
< label >
A second file
< input type = "file" / >
< / label >
< / form >
` );
const fileChooserPromise = page . waitForEvent ( 'filechooser' ) ;
await page . getByText ( 'A second file' ) . click ( ) ;
const fileChooser = await fileChooserPromise ;
expect ( fileChooser . page ( ) ) . toBe ( page ) ;
} ) ;
2024-11-22 14:53:29 -08:00
2025-02-03 13:30:54 +01:00
it ( 'should not crash when clicking a color input' , {
annotation : {
type : 'issue' ,
description : 'https://github.com/microsoft/playwright/issues/33864'
}
} , async ( { page , browserMajorVersion , browserName } ) = > {
it . skip ( browserName === 'firefox' && browserMajorVersion < 135 ) ;
await page . setContent ( '<input type="color">' ) ;
const input = page . locator ( 'input' ) ;
await expect ( input ) . toBeVisible ( ) ;
await input . click ( ) ;
await expect ( input ) . toBeVisible ( ) ;
} ) ;
2024-11-22 14:53:29 -08:00
it ( 'should not auto play audio' , {
annotation : {
type : 'issue' ,
description : 'https://github.com/microsoft/playwright/issues/33590'
}
} , async ( { page , browserName , isWindows } ) = > {
it . fixme ( browserName === 'webkit' && isWindows ) ;
2024-11-28 14:36:49 +00:00
it . skip ( process . env . PW_CLOCK === 'frozen' , 'no way to inject real setTimeout' ) ;
2024-11-22 14:53:29 -08:00
await page . route ( '**/*' , async route = > {
await route . fulfill ( {
status : 200 ,
contentType : 'text/html' ,
body : `
< script >
async function onLoad() {
const log = document . getElementById ( 'log' ) ;
const audioContext = new AudioContext ( ) ;
const gainNode = new GainNode ( audioContext ) ;
gainNode . connect ( audioContext . destination ) ;
gainNode . gain . value = 0.025 ;
const sineNode = new OscillatorNode ( audioContext ) ;
sineNode . connect ( gainNode ) ;
sineNode . start ( ) ;
await new Promise ( ( resolve ) = > setTimeout ( resolve , 1000 ) ) ;
log . innerHTML = 'State: ' + audioContext . state ;
}
< / script >
< body onload = "onLoad()" >
< div id = "log" > < / div >
< / body > ` ,
} ) ;
} ) ;
await page . goto ( 'http://127.0.0.1/audio.html' ) ;
await expect ( page . locator ( '#log' ) ) . toHaveText ( 'State: suspended' ) ;
} ) ;
2025-05-02 14:56:57 +02:00
it ( 'should not crash on feature detection for PublicKeyCredential' , {
annotation : {
type : 'issue' ,
description : 'https://github.com/microsoft/playwright/issues/35433'
}
} , async ( { page , server } ) = > {
await page . goto ( server . EMPTY_PAGE ) ;
await page . evaluate ( async ( ) = > {
await PublicKeyCredential . getClientCapabilities ( ) ;
await PublicKeyCredential . isConditionalMediationAvailable ( ) ;
await PublicKeyCredential . isUserVerifyingPlatformAuthenticatorAvailable ( ) ;
} ) ;
} ) ;