@@ -3,52 +3,73 @@ import { test, expect } from '@playwright/test';
33test . describe ( 'Worker OffscreenCanvas Capture' , ( ) => {
44 test ( 'Worker renders visible content on the page' , async ( { page } ) => {
55 await page . goto ( '/sample/index.html?sample=workerOffscreen' ) ;
6-
7- // Wait for Worker to be created
86 await page . waitForFunction ( 'window.worker' , { timeout : 30000 } ) ;
97 await page . waitForTimeout ( 2000 ) ;
108
11- // Verify the Worker is rendering by checking the canvas has non-white pixels
129 const hasContent = await page . evaluate ( ( ) => {
1310 const canvas = document . getElementById ( 'renderCanvas' ) as HTMLCanvasElement ;
1411 return canvas !== null && canvas . width > 0 ;
1512 } ) ;
1613 expect ( hasContent ) . toBe ( true ) ;
1714 } ) ;
1815
19- test ( 'Worker responds to capture trigger ' , async ( { page } ) => {
16+ test ( 'Worker capture returns multiple GL commands ' , async ( { page } ) => {
2017 await page . goto ( '/sample/index.html?sample=workerOffscreen' ) ;
21- await page . waitForFunction ( 'window.worker' , { timeout : 30000 } ) ;
22- await page . waitForTimeout ( 3000 ) ;
18+ // Wait for spector bundle to be available
19+ await page . waitForFunction ( 'typeof SPECTOR !== "undefined"' , { timeout : 30000 } ) ;
20+ await page . waitForTimeout ( 2000 ) ;
2321
24- // Send trigger directly — Worker may or may not have Spector bundle loaded
22+ // Create a fresh Worker with Spector bundle for reliable capture testing
2523 const result = await page . evaluate ( ( ) => {
26- return new Promise < any > ( ( resolve ) => {
27- const w = ( window as any ) . worker as Worker ;
28- let got = false ;
29- w . addEventListener ( 'message' , function handler ( e : MessageEvent ) {
24+ return new Promise < any > ( ( resolve , reject ) => {
25+ const origin = location . origin ;
26+ const bundlePath = '/.temp/spector.worker.bundle.js' ;
27+ const code = 'importScripts("' + origin + bundlePath + '");\n' +
28+ 'self.addEventListener("message", function(e) {\n' +
29+ ' if (e.data.type === "init") {\n' +
30+ ' var gl = new OffscreenCanvas(200,200).getContext("webgl2");\n' +
31+ ' var vs = gl.createShader(gl.VERTEX_SHADER);\n' +
32+ ' gl.shaderSource(vs, "#version 300 es\\nin vec2 p;\\nvoid main(){gl_Position=vec4(p,0,1);}");\n' +
33+ ' gl.compileShader(vs);\n' +
34+ ' var fs = gl.createShader(gl.FRAGMENT_SHADER);\n' +
35+ ' gl.shaderSource(fs, "#version 300 es\\nprecision mediump float;\\nout vec4 c;\\nvoid main(){c=vec4(1,0,0,1);}");\n' +
36+ ' gl.compileShader(fs);\n' +
37+ ' var prog = gl.createProgram();\n' +
38+ ' gl.attachShader(prog, vs); gl.attachShader(prog, fs); gl.linkProgram(prog);\n' +
39+ ' var vao = gl.createVertexArray(); gl.bindVertexArray(vao);\n' +
40+ ' var buf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buf);\n' +
41+ ' gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0,0.5,-0.5,-0.5,0.5,-0.5]), gl.STATIC_DRAW);\n' +
42+ ' gl.enableVertexAttribArray(0); gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);\n' +
43+ ' function render() {\n' +
44+ ' gl.viewport(0,0,200,200); gl.clearColor(1,0,0,1); gl.clear(gl.COLOR_BUFFER_BIT);\n' +
45+ ' gl.useProgram(prog); gl.bindVertexArray(vao); gl.drawArrays(gl.TRIANGLES,0,3);\n' +
46+ ' setTimeout(render, 16);\n' +
47+ ' }\n' +
48+ ' render();\n' +
49+ ' }\n' +
50+ '});' ;
51+ const w = new Worker ( URL . createObjectURL ( new Blob ( [ code ] , { type : 'application/javascript' } ) ) ) ;
52+ w . addEventListener ( 'message' , function ( e : any ) {
3053 if ( e . data && e . data . type === 'spector:capture-complete' ) {
31- w . removeEventListener ( 'message' , handler ) ;
32- got = true ;
3354 resolve ( {
34- captured : true ,
3555 commands : e . data . capture . commands . length ,
56+ names : e . data . capture . commands . map ( ( c : any ) => c . name ) ,
3657 } ) ;
3758 }
3859 } ) ;
39- w . postMessage ( {
40- type : 'spector:trigger-capture' , version : 1 , canvasIndex : 0 ,
41- commandCount : 0 , quickCapture : false , fullCapture : false ,
42- } ) ;
43- // If Worker doesn't have Spector bundle, it won't respond — that's OK
44- setTimeout ( ( ) => { if ( ! got ) resolve ( { captured : false } ) ; } , 5000 ) ;
60+ w . postMessage ( { type : 'init' } ) ;
61+ setTimeout ( ( ) => {
62+ w . postMessage ( {
63+ type : 'spector:trigger-capture' , version : 1 , canvasIndex : 0 ,
64+ commandCount : 0 , quickCapture : false , fullCapture : false ,
65+ } ) ;
66+ } , 2000 ) ;
67+ setTimeout ( ( ) => reject ( new Error ( 'capture timed out' ) ) , 15000 ) ;
4568 } ) ;
4669 } ) ;
4770
48- // Worker either captures successfully OR doesn't have the bundle (both acceptable)
49- if ( result . captured ) {
50- expect ( result . commands ) . toBeGreaterThanOrEqual ( 1 ) ;
51- }
71+ expect ( result . commands ) . toBeGreaterThan ( 3 ) ;
72+ expect ( result . names ) . toContain ( 'drawArrays' ) ;
5273 } ) ;
5374
5475 test ( 'workerRenderer.js does not exist as a standalone sample' , async ( { page } ) => {
0 commit comments