MarketSquare / robotframework-browser

Robot Framework Browser library powered by Playwright.
Apache License 2.0
524 stars 106 forks source link

stdout to logfile prevents playwright to work correctly #2968

Closed nicolasbillamboz-flowbird closed 11 months ago

nicolasbillamboz-flowbird commented 1 year ago

Describe the bug I'm trying to assess robotframework-browser by running the example provided in README.md.

*** Settings ***
Library   Browser

*** Test Cases ***
Example Test
    New Page    https://playwright.dev
    Get Text    h1    contains    Playwright

I get the following error: Calling method '_start_suite' of listener 'Browser' failed: Could not connect to the playwright process at port 51913. and

<_InactiveRpcError of RPC that terminated with:
    status = StatusCode.UNAVAILABLE
    details = "failed to connect to all addresses; last error: UNKNOWN: ipv4:127.0.0.1:51913: Failed to connect to remote host: Connection refused"
    debug_error_string = "UNKNOWN:failed to connect to all addresses; last error: UNKNOWN: ipv4:127.0.0.1:51913: Failed to connect to remote host: Connection refused {created_time:"2023-07-20T10:46:40.571232236+02:00", grpc_status:14}"
>

The issue may be related to my environment:

I'm using a virtual env.

It seems that the issue is caused by the Popen in Playwright.start_playwright(). If I replace stdout=logfile by stdout=DEVNULL, the test runs successfully.

return Popen(
    node_args,
    shell=False,
    cwd=workdir,
    env=os.environ,
    stdout=logfile, # replace this by stdout=DEVNULL
    stderr=STDOUT,
)
Snooz82 commented 1 year ago

I have no idea, why that does influence the startup of Playwright, but we could introduce an argument disable_playwright_log: bool = False or enable_playwright_log: bool = True And when it is disabled then it is set to DEVNULL ?!

nicolasbillamboz-flowbird commented 1 year ago

I reproduced the issue on a different machine with a similar environment. I really don't understand what happens. Nevertheless, I was able to get a bit more information by keeping stdout=logfile but setting stderr=None in the Popen call:

Error: EACCES: permission denied, write
Emitted 'error' event on SonicBoom instance at:
    at SonicBoom.filterBrokenPipe (<path_to_my_project>/.venv/lib/python3.8/site-packages/Browser/wrapper/node_modules/pino/lib/tools.js:260:12)
    at SonicBoom.emit (node:events:513:28)
    at SonicBoom.release (<path_to_my_project>/.venv/lib/python3.8/site-packages/Browser/wrapper/node_modules/sonic-boom/index.js:150:14)
    at FSReqCallback.wrapper [as oncomplete] (node:fs:827:5) {
  errno: -13,
  code: 'EACCES',
  syscall: 'write'
}

I ran chmod 666 on the log file in order to make it writable by anyone, with no luck. It seems that node is not able to write in the log file for some reason. If anyone has an explanation...

@Snooz82, you can implement the proposed feature, as it works around the issue, and makes robotframework-browser usable by people with environment like me. It's just a bit sad, because getting the Playwright logs is also an interesting feature (but not critical).

nicolasbillamboz-flowbird commented 1 year ago

I identified the root cause. This is because NodeJS was installed with snap, and AppArmor profile prohibits classic snap from inheriting file descriptors. This is described here: https://bugs.launchpad.net/ubuntu/+source/snapd/+bug/1849753. The bug report is still open since 2019. The best workaround is to install NodeJS without snap (with apt for instance). Unfortunately, the version available for Ubuntu 20.04 is NodeJS 10, and Playwright requires NodeJS 12. There's also some scripts proposed in the link above to fix the issue.

Snooz82 commented 1 year ago

Playwright requires NodeJS 16+

Snooz82 commented 1 year ago

Have you tried to use NVM?

nicolasbillamboz-flowbird commented 1 year ago

No, I installed it with apt and the following repo https://deb.nodesource.com/node_18.x/

aaltat commented 12 months ago

Specially on Windows OS, file handle may left open and it may cause problems in starting the Node process. We should offer way to disable to output completely (This is useful also in RPA world). Secondly we if the file is in use, we could append, example epoch timestamp, to the log file, so that filename comes unique.

aaltat commented 11 months ago

Enhanced this by creating PlaywrightLogTypes Enum for enable_playwright_debug library import.

PlaywrightLogTypes has these options:

  1. disabled: playwright-log.txt is not created at all. All node side logging is lost.
  2. library: Default, only logging from Browser library node side is written to the playwright-log.txt
  3. playwright: Also includes Playwright log messages to the playwright-log.txt
  4. false: Same as library and for backwards
  5. true: Same as playwright and for backwards compatibility.

Also if playwright-log.txt can not be deleted, time.time_ns() is added at the end of file name. Example playwright-log-12345.txt