Version
1.61.0
Steps to reproduce
src/main/java/org/example/TraceSources.java:
package org.example;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
import com.microsoft.playwright.Tracing;
import java.nio.file.Paths;
public class TraceSources {
public static void main(String[] args) {
String wsEndpoint = args.length > 0 ? args[0] : null;
try (Playwright playwright = Playwright.create()) {
Browser browser = wsEndpoint == null
? playwright.chromium().launch()
: playwright.chromium().connect(wsEndpoint);
BrowserContext context = browser.newContext();
context.tracing().start(new Tracing.StartOptions()
.setScreenshots(true)
.setSnapshots(true)
.setSources(true));
Page page = context.newPage();
page.navigate("https://playwright.dev");
page.getByText("Get started").click();
context.tracing().stop(new Tracing.StopOptions()
.setPath(Paths.get(wsEndpoint == null ? "trace-launch.zip" : "trace-connect.zip")));
browser.close();
}
}
}
- Point PLAYWRIGHT_JAVA_SRC at the source root, then run once with a locally
launched browser and once against a Playwright server, e.g. if Maven project:
export PLAYWRIGHT_JAVA_SRC=src/main/java
# A: locally launched browser
mvn -q compile exec:java -Dexec.mainClass=org.example.TraceSources
# B: connected browser. Start the server in another shell first:
# npx playwright@1.61.0 run-server --port 3000
mvn -q compile exec:java -Dexec.mainClass=org.example.TraceSources \
-Dexec.args="ws://localhost:3000/"
- Open both in the trace viewer:
mvn exec:java -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="show-trace trace-launch.zip"
mvn exec:java -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="show-trace trace-connect.zip"
Expected behavior
The Source tab in the trace viewer shows TraceSources.java with the selected action's line highlighted, for both traces.
Actual behavior
A (launch)
Source tab: shows TraceSources.java, current action highlighted.
B (connect)
Source tab: empty. Actions still show a file name and line number, but the file
content is not in the archive, so no code is displayed.
No exception is thrown and nothing is logged. The trace is written successfully and
is otherwise complete — screenshots, snapshots and network are all there. Only the
sources are missing.
Additional context
Possible cause:
We have not confirmed this, but source collection looks like it happens purely
client-side: the per-call Java stacks are pushed to the local driver's LocalUtils via
addStackToTracingNoReply, and stop() writes trace.stacks and the
resources/src@*.txt blobs from that stack session. Connection.internalSendMessage
appears to send that message over the same transport as the API call it belongs to,
which for a connected browser is the remote connection rather than the local driver.
If so, the local stack session stays empty and both entries are skipped.
Environment
- Operating System: Ubuntu 22.04
- CPU: x64
- Browser: Chromium (maybe the others as well)
- Java Version: 21
Version
1.61.0
Steps to reproduce
src/main/java/org/example/TraceSources.java:launched browser and once against a Playwright server, e.g. if Maven project:
Expected behavior
The Source tab in the trace viewer shows TraceSources.java with the selected action's line highlighted, for both traces.
Actual behavior
A (launch)
Source tab: shows TraceSources.java, current action highlighted.
B (connect)
Source tab: empty. Actions still show a file name and line number, but the file
content is not in the archive, so no code is displayed.
No exception is thrown and nothing is logged. The trace is written successfully and
is otherwise complete — screenshots, snapshots and network are all there. Only the
sources are missing.
Additional context
Possible cause:
We have not confirmed this, but source collection looks like it happens purely
client-side: the per-call Java stacks are pushed to the local driver's LocalUtils via
addStackToTracingNoReply, andstop()writestrace.stacksand theresources/src@*.txtblobs from that stack session.Connection.internalSendMessageappears to send that message over the same transport as the API call it belongs to,
which for a connected browser is the remote connection rather than the local driver.
If so, the local stack session stays empty and both entries are skipped.
Environment