@@ -3,12 +3,19 @@ import { TestRunnerCoreConfig } from '@web/test-runner-core';
3
3
import { v8ToIstanbul } from '@web/test-runner-coverage-v8' ;
4
4
import { SessionResult } from '@web/test-runner-core' ;
5
5
6
+ declare global {
7
+ interface Window {
8
+ __bringTabToFront : ( ) => void ;
9
+ }
10
+ }
11
+
6
12
export class ChromeLauncherPage {
7
13
private config : TestRunnerCoreConfig ;
8
14
private testFiles : string [ ] ;
9
15
private product : string ;
10
16
public puppeteerPage : Page ;
11
17
private nativeInstrumentationEnabledOnPage = false ;
18
+ private patchAdded = false ;
12
19
13
20
constructor (
14
21
config : TestRunnerCoreConfig ,
@@ -37,6 +44,29 @@ export class ChromeLauncherPage {
37
44
} ) ;
38
45
}
39
46
47
+ // Patching the browser page to workaround an issue in the new headless mode of Chrome where some functions
48
+ // with callbacks (requestAnimationFrame and requestIdleCallback) are not executing their callbacks.
49
+ // https://github.com/puppeteer/puppeteer/issues/10350
50
+ if ( ! this . patchAdded ) {
51
+ await this . puppeteerPage . exposeFunction ( '__bringTabToFront' , ( ) =>
52
+ this . puppeteerPage . bringToFront ( ) ,
53
+ ) ;
54
+ await this . puppeteerPage . evaluateOnNewDocument ( ( ) => {
55
+ // eslint-disable-next-line @typescript-eslint/ban-types
56
+ function patchFunction ( name : string , fn : Function ) {
57
+ ( window as any ) [ name ] = ( ...args : unknown [ ] ) => {
58
+ fn . call ( window , ...args ) ;
59
+ // Make sure that the tab running the test code is brought back to the front.
60
+ window . __bringTabToFront ( ) ;
61
+ } ;
62
+ }
63
+
64
+ patchFunction ( 'requestAnimationFrame' , window . requestAnimationFrame ) ;
65
+ patchFunction ( 'requestIdleCallback' , window . requestIdleCallback ) ;
66
+ } ) ;
67
+ this . patchAdded = true ;
68
+ }
69
+
40
70
await this . puppeteerPage . setViewport ( { height : 600 , width : 800 } ) ;
41
71
await this . puppeteerPage . goto ( url ) ;
42
72
}
0 commit comments