Repository: dotnet/runtime
File: src/mono/wasm/Wasm.Build.Tests/Blazor/EventPipeDiagnosticsTests.cs (C#)

Code before:
                    }
                    """
                }
            });
    }

    private async Task SetupCounterPage(IPage page)
    {
        await Task.Delay(500);
        // Navigate to the Counter page
        await page.Locator("text=Counter").ClickAsync();

        // Verify we're on the Counter page
        var txt = await page.Locator("p[role='status']").InnerHTMLAsync();
        Assert.Equal("Current count: 0", txt);

        var up = """
        globalThis.uploadTrace = async (filename, tracesPromise) => {
            console.log(`${filename} typeof  ${typeof tracesPromise} ${new Date().toISOString()}`);

            const traces = await tracesPromise;

            console.log(`${filename} typeof  ${typeof traces} ${new Date().toISOString()}`);
                    
            // concatenate the buffers into a single Uint8Array
            const concatenated = new Uint8Array(traces.reduce((acc, curr) => acc + curr.byteLength, 0));
            let offset = 0;
            for (const trace of traces) {
                concatenated.set(new Uint8Array(trace), offset);
                offset += trace.byteLength;
            }

            console.log(`File ${filename} size to upload: ${concatenated.byteLength} bytes ${new Date().toISOString()}`);
            await fetch(`/upload/${filename}`, {
                headers: {
                    'Content-Type': 'application/octet-stream'
                },
                method: 'POST',
                body: concatenated
            });
            console.log(`File uploaded successfully`);
        };
        console.log(`globalThis.uploadTrace defined ${new Date().toISOString()}`);
        """;
        await page.EvaluateAsync(up);
    }

    private async Task ClickAndCollect(IPage page)
    {
        // Click the button a few times
        for (int i = 0; i < 5; i++)

Review comment (bug):
The JS snippet uses template literals with `${filename}` / `/upload/${filename}`, but `filename` is never defined in the script. The subsequent C# `Replace("${filename}", fileName)` will splice in a raw value like `cpuprofile.nettrace` (without quotes), which makes the template literal expression invalid JS and will fail at runtime. Define `filename` as a quoted JS string (or keep the previous helper that takes `filename` as a parameter) rather than string-replacing into a template literal expression.

Code after:
                    
            // concatenate the buffers into a single Uint8Array
            const concatenated = new Uint8Array(traces.reduce((acc, curr) => acc + curr.byteLength, 0));
            let offset = 0;
            for (const trace of traces) {
                concatenated.set(new Uint8Array(trace), offset);
                offset += trace.byteLength;
            }

            console.log(`File ${filename} size to upload: ${concatenated.byteLength} bytes ${new Date().toISOString()}`);
            await fetch(`/upload/${filename}`, {
                headers: {
                    'Content-Type': 'application/octet-stream'
                },
                method: 'POST',
                body: concatenated
            });
            console.log(`File uploaded successfully: ${new Date().toISOString()}`);
            await new Promise(resolve => setTimeout(resolve, 1000));
            console.log(`Shutting down: ${new Date().toISOString()}`);
            console.log(`WASM EXIT 0`);
        };
        console.log(`globalThis.collectAndUpload method created ${new Date().toISOString()}`);
        """;
        up = up.Replace("${traceCommand}", traceCommand).Replace("${filename}", fileName);
        await page.EvaluateAsync(up);
    }

    private async Task ClickAndCollect(IPage page)
    {
        // Use void to prevent Playwright from awaiting the returned Promise,
        // so tracing runs in parallel with button clicks below.
        await page.EvaluateAsync(@"void (globalThis.donePromise = globalThis.collectAndUpload())");
        _testOutput.WriteLine($"Installed script: {DateTime.Now.ToString("O")}");

        // Click the button a few times while tracing is running
        for (int i = 0; i < 5; i++)
        {
            await page.Locator("text=\"Click me\"").ClickAsync();
            await Task.Delay(10);
        }
        _testOutput.WriteLine($"Done clicking: {DateTime.Now.ToString("O")}");

        var txt2 = await page.Locator("p[role='status']").InnerHTMLAsync();
        Assert.NotEqual("Current count: 0", txt2);

        // Wait for trace collection and upload to complete
        await page.EvaluateAsync(@"globalThis.donePromise");
    }
}