Open sachin6757 opened 2 years ago
We would need exact steps to follow in order to address this.
@pavelfeldman , We are using robotframework browser library. Please find steps below:
Here testcase is failing at step 4. The file is not getting download. However this testcase pass when testcase is not run on grid.
Below is the error log:
Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Browser/playwright.py", line 149, in grpc_channel yield playwright_pb2_grpc.PlaywrightStub(self._channel) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Browser/keywords/promises.py", line 143, in _wait_for_download response = stub.WaitForDownload(Request().FilePath(path=str(file_path))) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/grpc/_channel.py", line 946, in __call__ return _end_unary_response_blocking(state, call, False, None) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/grpc/_channel.py", line 849, in _end_unary_response_blocking raise _InactiveRpcError(state) grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with: status = StatusCode.RESOURCE_EXHAUSTED details = "Error: download.saveAs: canceled" debug_error_string = "{"created":"@1659031595.482469000","description":"Error received from peer ipv6:[::1]:59436","file":"src/core/lib/surface/call.cc","file_line":967,"grpc_message":"Error: download.saveAs: canceled","grpc_statu... [ Message content over the limit has been removed. ] return promises[0].result() File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/_base.py", line 428, in result return self.__get_result() File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/_base.py", line 384, in __get_result raise self._exception File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/thread.py", line 57, in run result = self.fn(*self.args, **self.kwargs) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Browser/keywords/promises.py", line 143, in _wait_for_download response = stub.WaitForDownload(Request().FilePath(path=str(file_path))) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/contextlib.py", line 130, in __exit__ self.gen.throw(type, value, traceback) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Browser/playwright.py", line 153, in grpc_channel raise AssertionError(error.details()) AssertionError: Error: download.saveAs: canceled
I'm not entirely sure this is a bug, likely a missing feature. Your browser is running in a docker container, whilst the test runner is likely running on a different container/host/virtual machine. Your assertion is by default looking at the file path on the host that is executing the tests.
I guess if Playwright wants to support this they'll have to somehow interface with Selenium to fetch the document. Suggestion: Could you create a volume mount that is accessible from both the host as well as the docker container? You could try downloading to that asserting it.
In the past I did this with an samba share. To avoid complexity we just run use the docker container supplied by Playwright to execute the tests in.
I am facing same issue while trying to download file in docker container through grid. I was trying to see the behaviour by simply clicking download button, observed that file downloading is failing with 'Failed - Download Error' in chrome taskbar. Although while running same container in selenium, working as expected.
Can someone look into the issue.
I'm not entirely sure this is a bug, likely a missing feature. Your browser is running in a docker container, whilst the test runner is likely running on a different container/host/virtual machine. Your assertion is by default looking at the file path on the host that is executing the tests.
I guess if Playwright wants to support this they'll have to somehow interface with Selenium to fetch the document. Suggestion: Could you create a volume mount that is accessible from both the host as well as the docker container? You could try downloading to that asserting it.
In the past I did this with an samba share. To avoid complexity we just run use the docker container supplied by Playwright to execute the tests in.
I tried with same directory volumes mapping b/w host and container. But still same behaviour is being observed.
volumes:
Playwright code snippet's await _page.GotoAsync("https://www.browserstack.com/test-on-the-right-mobile-devices"); var waitForDownloadTask = _page.WaitForDownloadAsync(); await _page.Locator(".icon-csv").ClickAsync(); var download = await waitForDownloadTask; await download.SaveAsAsync("/tmp/file.csv");
We would need exact steps to follow in order to address this.
I have provided more details on this issue in below. Can you check please now.
Any progress on this? I'm facing the same issue. I have to run tests remotely (on grid), because I need the same environment for development (my local machine is on windows) and on CI/CD with linux, because I also test graphs via screenshots. So I have to run tests on grid and download is not working. I'm using .NET playwright
@pavelfeldman @Ghislain89 is there any plan for priotization on this issue?
same issue with running in jenkins (playwright v1.32.3, typescript v4.9.5, node v18.15.0)
We are also facing same issue while running testcase via Jenkins on VM... Please help in resolving this issue
Any update on this issue. I'm also facing same issue. Not able to download files when running the Playwright test in Selenium Grid. Getting as 'Failed - Download error'. But, the same is passing in local. I'm using latest Playwright version 1.37.1 version. We have mounted the download location as well which is reachable.
Any update on this?
Facing this same issue. On the chrome browser instance started by Playwright in my selenium grid, file downloads fail. I tried opening a new chrome instance manually through the grid UI and tried downloading the same file. There it works
Plus. Facing the same issue.
Yeah, facing similar issues. Tried to play around and it looks like something gets messed up after PW connection.
Playwright playwright = Playwright.create();
Browser browser = playwright.chromium().connectOverCDP(endpointUrl);
Tried to directly create a grid session - the results are the same.
Map<String, String> env = new HashMap<>();
env.put("SELENIUM_REMOTE_URL", GRID_URL);
Playwright playwright = Playwright.create(new Playwright.CreateOptions().setEnv(env));
Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));`
BrowserContext context = browser.newContext(new Browser.NewContextOptions().setAcceptDownloads(true));
context.newPage().navigate("https://www.google.nl/intl/nl/chrome/");
I can confirm the behavior seen by @anandhu-co-in . The browser launched via Playwright shows Failed - download error on selenium grid.
I looked at the playwright DEBUG logs and this can be interesting . Seems like while setting setDownloadBehavior Playwright is setting downloadPath to a location on test runner windows machine on my laptop.
pw:protocol SEND ► {"id":19,"method":"Browser.setDownloadBehavior","params":{"behavior":"allowAndName","browserContextId":"3DA1D9479BE90414B862A89619609496","downloadPath":"C:\Users\AMAR-D~1\AppData\Local\Temp\playwright-artifacts-XXXXXX99prej","eventsEnabled":true}}
Is there a way we can override setDownloadBehavior , specially downloadPath via config for SELENIUM GRID?
Did some more hit and trial and seems Playwright does not override downloadsPath config if we run sessions on selenium grid. Anyway even if download would have worked, Playwright still will require a way to download file from remote machine to local.
Did some more hit and trial and seems Playwright does not override downloadsPath config if we run sessions on selenium grid. Anyway even if download would have worked, Playwright still will require a way to download file from remote machine to local.
It's not an issue if you use docker selenium grid - just mount volume to the downloads path
Did some more hit and trial and seems Playwright does not override downloadsPath config if we run sessions on selenium grid. Anyway even if download would have worked, Playwright still will require a way to download file from remote machine to local.
It's not an issue if you use docker selenium grid - just mount volume to the downloads path
Thanks @rkrenovsky for workaround suggestion but in my case mounting volume will not work. We are running centralized selenium grid inside Kubernetes . Since Kubernetes Nodes are remote Linux machines and not accessible to developers.
Did some more hit and trial and seems Playwright does not override downloadsPath config if we run sessions on selenium grid. Anyway even if download would have worked, Playwright still will require a way to download file from remote machine to local.
It's not an issue if you use docker selenium grid - just mount volume to the downloads path
Thanks @rkrenovsky for workaround suggestion but in my case mounting volume will not work. We are running centralized selenium grid inside Kubernetes . Since Kubernetes Nodes are remote Linux machines and not accessible to developers.
Another workaround, that I'm using in my docker MacOS selenium grid, is that I'm copying downloaded files via ssh in my tests
@rkrenovsky That's not an option in an enterprise environments where Kubernetes Nodes are mostly ephemeral in nature, secured from direct access and containers are prevented from accessing host Nodes. Let's hope this will get addressed as BiDi support matures in Playwright .
@amardeep2006 While this is out of scope for playwright and not exactly what you are looking for I have had luck intercepting downloads while using playwright and a remote chromium browser (not selenium grid).
If you grab a CDP session you can use the Fetch domain to intercept the download and read it to your local playwright client. I don't have the code readily handy but in case it helps anyway the gist of the approach is:
Use CDP Fetch.enable to setup request interception for your download.
On the Fetch.requestPaused event for your download you can issue a Fetch.takeResponseBodyAsStream to get a virtual handle to the download stream and
use IO.read CDP method to read it a chunk at a time down to your playwright client.
It's not ideal but is the best I've been able to do with this problem. YMMV with Selenium grid.
Thanks a ton for the idea @jwroberts . I was able to get initial success by your idea. Early code I have aded on my repo is very very raw . It needs some polishing. It's not production ready but can be a reference if someone wants to improve it. Please share the code if you already have better version with you. I have added a sample code at my github repo. https://github.com/amardeep2006/selenium-grid-experiments/blob/main/playwright/tests
I will keep adding examples there as I polish this functionality. PS : File upload was positive anticlimax and worked out of box with Playwright.
Context:
Bug Description
We have testcases to test the download functionality from the application. We have used promise to wait for the download to verify if the file is getting downloaded.
When we run testcase locally it works fine. However when we try to run testcase on selenium grid its failing with following error:
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Browser/playwright.py", line 149, in grpc_channel yield playwright_pb2_grpc.PlaywrightStub(self._channel) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Browser/keywords/promises.py", line 143, in _wait_for_download response = stub.WaitForDownload(Request().FilePath(path=str(file_path))) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/grpc/_channel.py", line 946, in __call__ return _end_unary_response_blocking(state, call, False, None) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/grpc/_channel.py", line 849, in _end_unary_response_blocking raise _InactiveRpcError(state) grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with: status = StatusCode.RESOURCE_EXHAUSTED details = "Error: download.saveAs: canceled" debug_error_string = "{"created":"@1658769026.465787000","description":"Error received from peer ipv6:[::1]:54106","file":"src/core/lib/surface/call.cc","file_line":967,"grpc_message":"Error: download.saveAs: canceled","grpc_statu... [ Message content over the limit has been removed. ] return promises[0].result() File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/_base.py", line 428, in result return self.__get_result() File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/_base.py", line 384, in __get_result raise self._exception File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/thread.py", line 57, in run result = self.fn(*self.args, **self.kwargs) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Browser/keywords/promises.py", line 143, in _wait_for_download response = stub.WaitForDownload(Request().FilePath(path=str(file_path))) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/contextlib.py", line 130, in __exit__ self.gen.throw(type, value, traceback) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Browser/playwright.py", line 153, in grpc_channel raise AssertionError(error.details()) AssertionError: Error: download.saveAs: canceled