Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Playwright.connect() for remote connection #4687

Closed
yury-s opened this issue Dec 11, 2020 · 13 comments
Closed

[Feature] Playwright.connect() for remote connection #4687

yury-s opened this issue Dec 11, 2020 · 13 comments

Comments

@yury-s
Copy link
Member

yury-s commented Dec 11, 2020

Current API allows to connect to Playwright server remotely by means of browserType.launchServer() and browserType.connect(). This requires launching local instance of playwright first and then establishing connections to each of the browsers individually. This can be replaced with a single client->server connection when creating Playwright client (e.g. new Playwright(<websocket address>). Among other things this approach doesn't require launching Playwright driver on the client side, so language bindings wouldn't need to bundle it in such cases.

@pavelfeldman
Copy link
Member

I don't think we have enough data to move further with this one, punting for now.

@vania-pooh
Copy link
Contributor

@pavelfeldman at least there should be some way to connect to remote web socket. Otherwise you limit Playwright to local test execution only.

@pavelfeldman pavelfeldman reopened this Jan 17, 2021
@pavelfeldman
Copy link
Member

Let me clarify why I closed it. This request was not about ability to connect remotely, this will still be our goal. This bug was about internal design, not requiring the driver internally when connecting remotely from the language ports (Python, Java, etc). Original bug claims:

This requires launching local instance of playwright first and then establishing connections to each of the browsers individually.

I think this is Ok since during the inner loop, developers run full Playwright anyways

This can be replaced with a single client->server connection when creating Playwright client (e.g. new Playwright().

And while it can be done, I think it is a wrong direction from the layering standpoint. We can optimize the language ports significantly if we don't mix those aspects and keep driver and rpc aspects separate.

@fehmer
Copy link

fehmer commented Jan 18, 2021

hi @pavelfeldman ,

This request was not about ability to connect remotely, this will still be our goal.

That's good news. Some bugs/feature request got linked to this issue, I guess that's why the closing caused confusion. Is there a issue/feature request we can use instead to keep track of this in the linked issues?

@kumaraditya303
Copy link
Contributor

Another use case would be to run Playwright browser instances on a remote server and run the clients as light weight docker container e.g. alpine linux to run the tests without using driver locally.

@pavelfeldman
Copy link
Member

It looks like the industry has settled on the browserType.connect. Please file a new issue if you are still interested in this functionality.

@sridharreddysuram123
Copy link

@pavelfeldman at least there should be some way to connect to remote web socket. Otherwise you limit Playwright to local test execution only.

Any solution for this?

@dskochubey
Copy link

@pavelfeldman I’m currently evaluating 1.27 with LambdaTest. I’m following LambdaTest example of using browserType.connect() or browserType.launch() to connect to a remote browser. Playwright returns error browserType.launch: Playwright version 1.27.0 not supported. Supported versions are 1.19.0 to 1.24.2. I didn’t find any announcements that that feature doesn’t supported any more and what use instead. Can anybody clarify on this?

P.S. with 1.24.2 everything works just fine.

@pavelfeldman
Copy link
Member

Looks like Lambdateat is only supporting old versions of Playwright?

@dskochubey
Copy link

@pavelfeldman It seems that issue is on Playwright's side. I use the Playwright method browserType.connect(wsEndpoint[, options]) with wsEndpoing provided by LambdaTest. When running a test, Playwright throws the error: browserType.connect: Playwright version 1.27.0 not supported. Supported versions are 1.19.0 to 1.24.2.

@gointoit
Copy link

gointoit commented Dec 8, 2023

@pavelfeldman at least there should be some way to connect to remote web socket. Otherwise you limit Playwright to local test execution only.

Any solution for this? 😄

@jfrantzius
Copy link

jfrantzius commented Feb 22, 2024

In my case I want to run my Java test on a non-supported platform in Jenkins, while connecting to a Playwright server (which runs using the official docker image). Because my Jenkins is air-gapped, I need to disable the browsers download.

The problem now is that Playwright.create() (in PlaywrightImpl.createImpl() always creates a process for a local driver, which then fails for me like this:

/tmp/playwright-java-7549223223667235521/node: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by /tmp/playwright-java-7549223223667235521/node)
/tmp/playwright-java-7549223223667235521/node: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by /tmp/playwright-java-7549223223667235521/node)
/tmp/playwright-java-7549223223667235521/node: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by /tmp/playwright-java-7549223223667235521/node)
/tmp/playwright-java-7549223223667235521/node: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by /tmp/playwright-java-7549223223667235521/node)
/tmp/playwright-java-7549223223667235521/node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /tmp/playwright-java-7549223223667235521/node)
/tmp/playwright-java-7549223223667235521/node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /tmp/playwright-java-7549223223667235521/node)
Skipping browsers download because `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` env variable is set
java.io.IOException: Stream closed
	at java.base/java.lang.ProcessBuilder$NullOutputStream.write(ProcessBuilder.java:442)
	at java.base/java.io.OutputStream.write(OutputStream.java:157)
	at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81)
	at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:142)
	at com.microsoft.playwright.impl.WriterThread.run(PipeTransport.java:167)
java.io.IOException: Stream closed
	at java.base/java.lang.ProcessBuilder$NullOutputStream.write(ProcessBuilder.java:442)
	at java.base/java.io.OutputStream.write(OutputStream.java:157)
	at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81)
	at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:142)
	at java.base/java.io.FilterOutputStream.close(FilterOutputStream.java:182)
	at com.microsoft.playwright.impl.PipeTransport.close(PipeTransport.java:93)
	at com.microsoft.playwright.impl.PipeTransport.poll(PipeTransport.java:71)
	at com.microsoft.playwright.impl.Connection.processOneMessage(Connection.java:200)
	at com.microsoft.playwright.impl.ChannelOwner.runUntil(ChannelOwner.java:118)
	at com.microsoft.playwright.impl.Connection.sendMessage(Connection.java:126)
	at com.microsoft.playwright.impl.ChannelOwner.sendMessage(ChannelOwner.java:106)
	at com.microsoft.playwright.impl.Connection$Root.initialize(Connection.java:82)
	at com.microsoft.playwright.impl.Connection.initializePlaywright(Connection.java:177)
	at com.microsoft.playwright.impl.PlaywrightImpl.createImpl(PlaywrightImpl.java:52)
	at com.microsoft.playwright.impl.PlaywrightImpl.create(PlaywrightImpl.java:35)
	at com.microsoft.playwright.Playwright.create(Playwright.java:110)
	at com.microsoft.playwright.Playwright.create(Playwright.java:114)

Currently I see no way to work around this problem, does anybody perhaps know a solution? Or would this require the feature this issue is asking for?

Also asking in https://stackoverflow.com/questions/78041616/how-to-connect-to-remote-playwright-server-without-creating-local-driver

@jfrantzius
Copy link

jfrantzius commented Feb 26, 2024

I tried to workaround by initializing a Java PlaywrightImpl on a redirected stdin+stdout of the driver running in a separate container, instead of it starting a local process and using that process' stdin+stdout (as the implementation in com.microsoft.playwright.impl.PlaywrightImpl.createImpl(CreateOptions, boolean) currently does):

	    try {
	    	Socket socket = new Socket(LOCALHOST_IP, 2020);
			receiveFromServerInputStream = socket.getInputStream();
			writeToServerOutputStream = socket.getOutputStream();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		Connection connection = new Connection(new PipeTransport(receiveFromServerInputStream, writeToServerOutputStream), env);
		PlaywrightImpl result = connection.initializePlaywright();

That separate container (mcr.microsoft.com/playwright/java:v1.39.0-jammy) has this start script:

# extract the driver npm 
unzip /root/.m2/repository/com/microsoft/playwright/driver-bundle/1.39.0/driver-bundle-1.39.0.jar -d /root/driver-bundle

# install netcat
apt-get update && apt-get install -y netcat
# create a TCP socket to make server i/o accessible from outside container
nc -l -p 2020 &  

# start the driver and redirect i/o to TCP socket  
cd /root/driver-bundle/driver/linux-arm64
echo Starting Playwright driver  
PW_LANG_NAME=java DEBUG=pw:api ./playwright.sh run-driver 2>&1 | nc localhost 2020 

I thought that this should work in theory, but in practice I haven't found out why it is stuck here:

"main" #1 prio=5 os_prio=31 cpu=11837.15ms elapsed=5470.87s tid=0x0000000128810800 nid=0x2803 waiting on condition  [0x000000016beff000]
   java.lang.Thread.State: TIMED_WAITING (parking)
	at jdk.internal.misc.Unsafe.park(java.base@11.0.18/Native Method)
	- parking to wait for  <0x00000006c66166b0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.parkNanos(java.base@11.0.18/LockSupport.java:234)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(java.base@11.0.18/AbstractQueuedSynchronizer.java:2123)
	at java.util.concurrent.ArrayBlockingQueue.poll(java.base@11.0.18/ArrayBlockingQueue.java:432)
	at com.microsoft.playwright.impl.PipeTransport.poll(PipeTransport.java:68)
	at com.microsoft.playwright.impl.Connection.processOneMessage(Connection.java:200)
	at com.microsoft.playwright.impl.ChannelOwner.runUntil(ChannelOwner.java:118)
	at com.microsoft.playwright.impl.Connection.sendMessage(Connection.java:126)
	at com.microsoft.playwright.impl.ChannelOwner.sendMessage(ChannelOwner.java:106)
	at com.microsoft.playwright.impl.Connection$Root.initialize(Connection.java:82)
	at com.microsoft.playwright.impl.Connection.initializePlaywright(Connection.java:177)

I have not clue how to debug the connection unfortunately ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants