From fd55b2f00271a6e6aac5c0d236c8e8384b70940c Mon Sep 17 00:00:00 2001 From: Ariel Sandor <39200214+arielsandor@users.noreply.github.com> Date: Tue, 31 Mar 2026 09:46:29 -0300 Subject: [PATCH] fix: replace fs.promises.mkdtemp with mkdir for Workers compatibility Cloudflare Workers' nodejs_compat (via unenv) does not implement fs.mkdtemp or fs.promises.mkdtemp. This causes a runtime crash when using @cloudflare/playwright in a Worker environment. Replace mkdtemp(prefix) with mkdir(prefix + randomSuffix, { recursive: true }) in the three call sites within browserType.ts and chromium.ts. The random suffix uses Math.random().toString(36).slice(2), providing sufficient uniqueness for temporary directory names. --- packages/playwright-core/src/server/browserType.ts | 6 ++++-- packages/playwright-core/src/server/chromium/chromium.ts | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/playwright-core/src/server/browserType.ts b/packages/playwright-core/src/server/browserType.ts index 98a2adec3..b0966041c 100644 --- a/packages/playwright-core/src/server/browserType.ts +++ b/packages/playwright-core/src/server/browserType.ts @@ -155,7 +155,8 @@ export abstract class BrowserType extends SdkObject { await this._createArtifactDirs(options); const tempDirectories: string[] = []; - const artifactsDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'playwright-artifacts-')); + const artifactsDir = path.join(os.tmpdir(), 'playwright-artifacts-' + Math.random().toString(36).slice(2)); + await fs.promises.mkdir(artifactsDir, { recursive: true }); tempDirectories.push(artifactsDir); if (userDataDir) { @@ -164,7 +165,8 @@ export abstract class BrowserType extends SdkObject { if (!await existsAsync(userDataDir)) await fs.promises.mkdir(userDataDir, { recursive: true, mode: 0o700 }); } else { - userDataDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), `playwright_${this._name}dev_profile-`)); + userDataDir = path.join(os.tmpdir(), `playwright_${this._name}dev_profile-` + Math.random().toString(36).slice(2)); + await fs.promises.mkdir(userDataDir, { recursive: true }); tempDirectories.push(userDataDir); } await this.prepareUserDataDir(options, userDataDir); diff --git a/packages/playwright-core/src/server/chromium/chromium.ts b/packages/playwright-core/src/server/chromium/chromium.ts index ec9f63d44..8aef15bc8 100644 --- a/packages/playwright-core/src/server/chromium/chromium.ts +++ b/packages/playwright-core/src/server/chromium/chromium.ts @@ -89,7 +89,8 @@ export class Chromium extends BrowserType { else if (headersMap && !Object.keys(headersMap).some(key => key.toLowerCase() === 'user-agent')) headersMap['User-Agent'] = getUserAgent(); - const artifactsDir = await progress.race(fs.promises.mkdtemp(ARTIFACTS_FOLDER)); + const artifactsDir = ARTIFACTS_FOLDER + Math.random().toString(36).slice(2); + await progress.race(fs.promises.mkdir(artifactsDir, { recursive: true })); const doCleanup = async () => { await removeFolders([artifactsDir]); const cb = onClose;