Fix server launch on Playwright 1.60

Playwright 1.60 bundled its internals and removed the private
lib/browserServerImpl.js that launchServer.js required, so
`python -m camoufox server` died with MODULE_NOT_FOUND. Load the
driver's package entrypoint instead, which is a bundled playwright-core
and exposes launchServer as public API.

The driver path is now passed explicitly rather than inferred from
process.cwd().

Fixes #656
This commit is contained in:
Pratyush Sharma
2026-07-15 18:31:36 +05:30
parent 8253a167ad
commit 5bf8081aec
2 changed files with 23 additions and 8 deletions
+18 -7
View File
@@ -1,7 +1,21 @@
// Workaround that accesses Playwright's undocumented `launchServer` method in Python
// Without having to use the Node.js Playwright library.
// Workaround that accesses Playwright's `launchServer` method in Python
// Without having to install the Node.js Playwright library.
const { BrowserServerLauncherImpl } = require(`${process.cwd()}/lib/browserServerImpl.js`)
const path = require('path')
// The driver shipped with playwright-python is a copy of playwright-core, so its
// entrypoint exposes `launchServer`. Resolve through the entrypoint rather than lib/
// internals, whose layout is private and changes between releases: 1.60 bundled
// lib/browserServerImpl.js away, which broke this script.
const driverPackage = process.argv[2]
let playwright
try {
playwright = require(path.join(driverPackage, 'index.js'))
} catch (error) {
console.error(`Error loading the Playwright driver from ${driverPackage}:`, error.message)
process.exit(1)
}
function collectData() {
return new Promise((resolve) => {
@@ -22,10 +36,7 @@ collectData().then((options) => {
console.time('Server launched');
console.info('Launching server...');
const server = new BrowserServerLauncherImpl('firefox')
// Call Playwright's `launchServer` method
server.launchServer(options).then(browserServer => {
playwright.firefox.launchServer(options).then(browserServer => {
console.timeEnd('Server launched');
console.log('Websocket endpoint:\x1b[93m', browserServer.wsEndpoint(), '\x1b[0m');
// Continue forever
+5 -1
View File
@@ -50,12 +50,16 @@ def launch_server(**kwargs) -> NoReturn:
data = orjson.dumps(to_camel_case_dict(config))
# The Playwright driver's package directory, which bundles playwright-core.
driver_package = Path(nodejs).parent / "package"
process = subprocess.Popen( # nosec
[
nodejs,
str(LAUNCH_SCRIPT),
str(driver_package),
],
cwd=Path(nodejs).parent / "package",
cwd=driver_package,
stdin=subprocess.PIPE,
text=True,
)