diff --git a/packages/playwright-core/src/utils/fileUtils.ts b/packages/playwright-core/src/utils/fileUtils.ts index 77ce1bf042..7725f77ea3 100644 --- a/packages/playwright-core/src/utils/fileUtils.ts +++ b/packages/playwright-core/src/utils/fileUtils.ts @@ -46,3 +46,8 @@ export function canAccessFile(file: string) { return false; } } + +export async function copyFileAndMakeWritable(from: string, to: string) { + await fs.promises.copyFile(from, to); + await fs.promises.chmod(to, 0o664); +} diff --git a/packages/playwright-test/src/reporters/html.ts b/packages/playwright-test/src/reporters/html.ts index 79dd937fe9..adbee0334f 100644 --- a/packages/playwright-test/src/reporters/html.ts +++ b/packages/playwright-test/src/reporters/html.ts @@ -23,7 +23,7 @@ import { Transform } from 'stream'; import type { FullConfig, Suite } from '../../types/testReporter'; import { HttpServer } from 'playwright-core/lib/utils/httpServer'; import { assert, calculateSha1 } from 'playwright-core/lib/utils'; -import { removeFolders } from 'playwright-core/lib/utils/fileUtils'; +import { copyFileAndMakeWritable, removeFolders } from 'playwright-core/lib/utils/fileUtils'; import type { JsonAttachment, JsonReport, JsonSuite, JsonTestCase, JsonTestResult, JsonTestStep } from './raw'; import RawReporter from './raw'; import { stripAnsiEscapes } from './base'; @@ -272,7 +272,7 @@ class HtmlBuilder { // Copy app. const appFolder = path.join(require.resolve('playwright-core'), '..', 'lib', 'webpack', 'htmlReport'); - fs.copyFileSync(path.join(appFolder, 'index.html'), path.join(this._reportFolder, 'index.html')); + await copyFileAndMakeWritable(path.join(appFolder, 'index.html'), path.join(this._reportFolder, 'index.html')); // Copy trace viewer. if (this._hasTraces) { @@ -282,7 +282,7 @@ class HtmlBuilder { for (const file of fs.readdirSync(traceViewerFolder)) { if (file.endsWith('.map')) continue; - fs.copyFileSync(path.join(traceViewerFolder, file), path.join(traceViewerTargetFolder, file)); + await copyFileAndMakeWritable(path.join(traceViewerFolder, file), path.join(traceViewerTargetFolder, file)); } }