chore: use fs.promises API instead of promisify (#6871)

This commit is contained in:
Max Schmitt 2021-06-03 09:55:33 -07:00 committed by GitHub
parent d16afef75a
commit 064150f8dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 63 additions and 135 deletions

View File

@ -15,7 +15,6 @@
*/
import * as fs from 'fs';
import * as util from 'util';
import * as folio from 'folio';
import type { LaunchOptions, BrowserContextOptions, Page } from '../../types/types';
import type { PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions } from '../../types/test';
@ -139,7 +138,7 @@ export const test = folio.test.extend<PlaywrightTestArgs & PlaywrightTestOptions
if (!video)
return;
const videoPath = await video.path();
await util.promisify(fs.unlink)(videoPath).catch(e => {});
await fs.promises.unlink(videoPath).catch(e => {});
}));
}
},

View File

@ -15,7 +15,6 @@
*/
import fs from 'fs';
import * as util from 'util';
import { isString } from '../utils/utils';
import * as channels from '../protocol/channels';
import { Events } from './events';
@ -190,7 +189,7 @@ export class AndroidDevice extends ChannelOwner<channels.AndroidDeviceChannel, c
const { binary } = await channel.screenshot();
const buffer = Buffer.from(binary, 'base64');
if (options.path)
await util.promisify(fs.writeFile)(options.path, buffer);
await fs.promises.writeFile(options.path, buffer);
return buffer;
});
}
@ -274,7 +273,7 @@ export class AndroidSocket extends ChannelOwner<channels.AndroidSocketChannel, c
async function loadFile(file: string | Buffer): Promise<string> {
if (isString(file))
return (await util.promisify(fs.readFile)(file)).toString('base64');
return fs.promises.readFile(file, { encoding: 'base64' }).toString();
return file.toString('base64');
}

View File

@ -18,7 +18,6 @@
import { Page, BindingCall } from './page';
import * as network from './network';
import * as channels from '../protocol/channels';
import * as util from 'util';
import fs from 'fs';
import { ChannelOwner } from './channelOwner';
import { deprecate, evaluationScript, urlMatches } from './clientHelper';
@ -35,9 +34,6 @@ import * as structs from '../../types/structs';
import { CDPSession } from './cdpSession';
import { Tracing } from './tracing';
const fsWriteFileAsync = util.promisify(fs.writeFile.bind(fs));
const fsReadFileAsync = util.promisify(fs.readFile.bind(fs));
export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel, channels.BrowserContextInitializer> implements api.BrowserContext {
_pages = new Set<Page>();
private _routes: { url: URLMatch, handler: network.RouteHandler }[] = [];
@ -289,7 +285,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
const state = await channel.storageState();
if (options.path) {
await mkdirIfNeeded(options.path);
await fsWriteFileAsync(options.path, JSON.stringify(state, undefined, 2), 'utf8');
await fs.promises.writeFile(options.path, JSON.stringify(state, undefined, 2), 'utf8');
}
return state;
});
@ -353,7 +349,7 @@ export async function prepareBrowserContextParams(options: BrowserContextOptions
viewport: options.viewport === null ? undefined : options.viewport,
noDefaultViewport: options.viewport === null,
extraHTTPHeaders: options.extraHTTPHeaders ? headersObjectToArray(options.extraHTTPHeaders) : undefined,
storageState: typeof options.storageState === 'string' ? JSON.parse(await fsReadFileAsync(options.storageState, 'utf8')) : options.storageState,
storageState: typeof options.storageState === 'string' ? JSON.parse(await fs.promises.readFile(options.storageState, 'utf8')) : options.storageState,
};
if (!contextParams.recordVideo && options.videosPath) {
contextParams.recordVideo = {

View File

@ -17,7 +17,6 @@
import * as types from './types';
import fs from 'fs';
import * as util from 'util';
import { isString, isRegExp } from '../utils/utils';
const deprecatedHits = new Set();
@ -50,7 +49,7 @@ export async function evaluationScript(fun: Function | string | { path?: string,
if (fun.content !== undefined)
return fun.content;
if (fun.path !== undefined) {
let source = await util.promisify(fs.readFile)(fun.path, 'utf8');
let source = await fs.promises.readFile(fun.path, 'utf8');
if (addSourceUrl)
source += '//# sourceURL=' + fun.path.replace(/\n/g, '');
return source;

View File

@ -22,13 +22,10 @@ import { SelectOption, FilePayload, Rect, SelectOptionOptions } from './types';
import fs from 'fs';
import * as mime from 'mime';
import path from 'path';
import * as util from 'util';
import { assert, isString, mkdirIfNeeded } from '../utils/utils';
import * as api from '../../types/types';
import * as structs from '../../types/structs';
const fsWriteFileAsync = util.promisify(fs.writeFile.bind(fs));
export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements api.ElementHandle {
readonly _elementChannel: channels.ElementHandleChannel;
@ -230,7 +227,7 @@ export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements
const buffer = Buffer.from(result.binary, 'base64');
if (options.path) {
await mkdirIfNeeded(options.path);
await fsWriteFileAsync(options.path, buffer);
await fs.promises.writeFile(options.path, buffer);
}
return buffer;
});
@ -302,7 +299,7 @@ export async function convertInputFiles(files: string | FilePayload | string[] |
if (typeof item === 'string') {
return {
name: path.basename(item),
buffer: (await util.promisify(fs.readFile)(item)).toString('base64')
buffer: (await fs.promises.readFile(item)).toString('base64')
};
} else {
return {

View File

@ -22,7 +22,6 @@ import { ElementHandle, convertSelectOptionValues, convertInputFiles } from './e
import { assertMaxArguments, JSHandle, serializeArgument, parseResult } from './jsHandle';
import fs from 'fs';
import * as network from './network';
import * as util from 'util';
import { Page } from './page';
import { EventEmitter } from 'events';
import { Waiter } from './waiter';
@ -32,8 +31,6 @@ import { urlMatches } from './clientHelper';
import * as api from '../../types/types';
import * as structs from '../../types/structs';
const fsReadFileAsync = util.promisify(fs.readFile.bind(fs));
export type WaitForNavigationOptions = {
timeout?: number,
waitUntil?: LifecycleEvent,
@ -275,7 +272,7 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
return this._wrapApiCall(this._apiName('addScriptTag'), async (channel: channels.FrameChannel) => {
const copy = { ...options };
if (copy.path) {
copy.content = (await fsReadFileAsync(copy.path)).toString();
copy.content = (await fs.promises.readFile(copy.path)).toString();
copy.content += '//# sourceURL=' + copy.path.replace(/\n/g, '');
}
return ElementHandle.from((await channel.addScriptTag({ ...copy })).element);
@ -286,7 +283,7 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
return this._wrapApiCall(this._apiName('addStyleTag'), async (channel: channels.FrameChannel) => {
const copy = { ...options };
if (copy.path) {
copy.content = (await fsReadFileAsync(copy.path)).toString();
copy.content = (await fs.promises.readFile(copy.path)).toString();
copy.content += '/*# sourceURL=' + copy.path.replace(/\n/g, '') + '*/';
}
return ElementHandle.from((await channel.addStyleTag({ ...copy })).element);

View File

@ -21,7 +21,6 @@ import { Frame } from './frame';
import { Headers, WaitForEventOptions } from './types';
import fs from 'fs';
import * as mime from 'mime';
import * as util from 'util';
import { isString, headersObjectToArray, headersArrayToObject } from '../utils/utils';
import { Events } from './events';
import { Page } from './page';
@ -196,7 +195,7 @@ export class Route extends ChannelOwner<channels.RouteChannel, channels.RouteIni
let isBase64 = false;
let length = 0;
if (options.path) {
const buffer = await util.promisify(fs.readFile)(options.path);
const buffer = await fs.promises.readFile(options.path);
body = buffer.toString('base64');
isBase64 = true;
length = buffer.length;

View File

@ -40,7 +40,6 @@ import * as api from '../../types/types';
import * as structs from '../../types/structs';
import fs from 'fs';
import path from 'path';
import * as util from 'util';
import { Size, URLMatch, Headers, LifecycleEvent, WaitForEventOptions, SelectOption, SelectOptionOptions, FilePayload, WaitForFunctionOptions } from './types';
import { evaluationScript, urlMatches } from './clientHelper';
import { isString, isRegExp, isObject, mkdirIfNeeded, headersObjectToArray } from '../utils/utils';
@ -48,9 +47,6 @@ import { isSafeCloseError } from '../utils/errors';
import { Video } from './video';
import { Artifact } from './artifact';
const fsWriteFileAsync = util.promisify(fs.writeFile.bind(fs));
const mkdirAsync = util.promisify(fs.mkdir);
type PDFOptions = Omit<channels.PagePdfParams, 'width' | 'height' | 'margin'> & {
width?: string | number,
height?: string | number,
@ -481,7 +477,7 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
const buffer = Buffer.from(result.binary, 'base64');
if (options.path) {
await mkdirIfNeeded(options.path);
await fsWriteFileAsync(options.path, buffer);
await fs.promises.writeFile(options.path, buffer);
}
return buffer;
});
@ -666,8 +662,8 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
const result = await channel.pdf(transportOptions);
const buffer = Buffer.from(result.pdf, 'base64');
if (options.path) {
await mkdirAsync(path.dirname(options.path), { recursive: true });
await fsWriteFileAsync(options.path, buffer);
await fs.promises.mkdir(path.dirname(options.path), { recursive: true });
await fs.promises.writeFile(options.path, buffer);
}
return buffer;
});

View File

@ -18,7 +18,6 @@ import * as channels from '../protocol/channels';
import { Dispatcher, DispatcherScope } from './dispatcher';
import { StreamDispatcher } from './streamDispatcher';
import fs from 'fs';
import * as util from 'util';
import { mkdirIfNeeded } from '../utils/utils';
import { Artifact } from '../server/artifact';
@ -43,7 +42,7 @@ export class ArtifactDispatcher extends Dispatcher<Artifact, channels.ArtifactIn
}
try {
await mkdirIfNeeded(params.path);
await util.promisify(fs.copyFile)(localPath, params.path);
await fs.promises.copyFile(localPath, params.path);
resolve();
} catch (e) {
reject(e);

View File

@ -22,7 +22,6 @@ import path from 'path';
import ProgressBar from 'progress';
import { getProxyForUrl } from 'proxy-from-env';
import * as URL from 'url';
import * as util from 'util';
import { BrowserName, Registry, hostPlatform } from '../utils/registry';
import { debugLogger } from '../utils/debugLogger';
@ -35,8 +34,6 @@ import { debugLogger } from '../utils/debugLogger';
// without types.
const ProxyAgent = require('https-proxy-agent');
const unlinkAsync = util.promisify(fs.unlink.bind(fs));
const chmodAsync = util.promisify(fs.chmod.bind(fs));
const existsAsync = (path: string): Promise<boolean> => new Promise(resolve => fs.stat(path, err => resolve(!err)));
export type OnProgressCallback = (downloadedBytes: number, totalBytes: number) => void;
@ -96,14 +93,14 @@ export async function downloadBrowserWithProgressBar(registry: Registry, browser
await extract(zipPath, { dir: browserDirectory});
const executablePath = registry.executablePath(browserName)!;
debugLogger.log('install', `fixing permissions at ${executablePath}`);
await chmodAsync(executablePath, 0o755);
await fs.promises.chmod(executablePath, 0o755);
} catch (e) {
debugLogger.log('install', `FAILED installation ${progressBarName} with error: ${e}`);
process.exitCode = 1;
throw e;
} finally {
if (await existsAsync(zipPath))
await unlinkAsync(zipPath);
await fs.promises.unlink(zipPath);
}
logPolitely(`${progressBarName} downloaded to ${browserDirectory}`);
return true;

View File

@ -16,18 +16,12 @@
import fs from 'fs';
import path from 'path';
import util from 'util';
import lockfile from 'proper-lockfile';
import {Registry, allBrowserNames, isBrowserDirectory, BrowserName, registryDirectory} from '../utils/registry';
import * as browserFetcher from './browserFetcher';
import { getAsBooleanFromENV, calculateSha1, removeFolders } from '../utils/utils';
const fsMkdirAsync = util.promisify(fs.mkdir.bind(fs));
const fsReaddirAsync = util.promisify(fs.readdir.bind(fs));
const fsReadFileAsync = util.promisify(fs.readFile.bind(fs));
const fsExistsAsync = (filePath: string) => fsReadFileAsync(filePath).then(() => true).catch(e => false);
const fsUnlinkAsync = util.promisify(fs.unlink.bind(fs));
const fsWriteFileAsync = util.promisify(fs.writeFile.bind(fs));
const fsExistsAsync = (filePath: string) => fs.promises.readFile(filePath).then(() => true).catch(e => false);
const PACKAGE_PATH = path.join(__dirname, '..', '..');
@ -38,7 +32,7 @@ export async function installBrowsersWithProgressBar(browserNames: BrowserName[]
return false;
}
await fsMkdirAsync(registryDirectory, { recursive: true });
await fs.promises.mkdir(registryDirectory, { recursive: true });
const lockfilePath = path.join(registryDirectory, '__dirlock');
const releaseLock = await lockfile.lock(registryDirectory, {
retries: {
@ -56,8 +50,8 @@ export async function installBrowsersWithProgressBar(browserNames: BrowserName[]
const linksDir = path.join(registryDirectory, '.links');
try {
await fsMkdirAsync(linksDir, { recursive: true });
await fsWriteFileAsync(path.join(linksDir, calculateSha1(PACKAGE_PATH)), PACKAGE_PATH);
await fs.promises.mkdir(linksDir, { recursive: true });
await fs.promises.writeFile(path.join(linksDir, calculateSha1(PACKAGE_PATH)), PACKAGE_PATH);
await validateCache(linksDir, browserNames);
} finally {
await releaseLock();
@ -67,11 +61,11 @@ export async function installBrowsersWithProgressBar(browserNames: BrowserName[]
async function validateCache(linksDir: string, browserNames: BrowserName[]) {
// 1. Collect used downloads and package descriptors.
const usedBrowserPaths: Set<string> = new Set();
for (const fileName of await fsReaddirAsync(linksDir)) {
for (const fileName of await fs.promises.readdir(linksDir)) {
const linkPath = path.join(linksDir, fileName);
let linkTarget = '';
try {
linkTarget = (await fsReadFileAsync(linkPath)).toString();
linkTarget = (await fs.promises.readFile(linkPath)).toString();
const linkRegistry = new Registry(linkTarget);
for (const browserName of allBrowserNames) {
if (!linkRegistry.isSupportedBrowser(browserName))
@ -88,13 +82,13 @@ async function validateCache(linksDir: string, browserNames: BrowserName[]) {
usedBrowserPaths.add(usedBrowserPath);
}
} catch (e) {
await fsUnlinkAsync(linkPath).catch(e => {});
await fs.promises.unlink(linkPath).catch(e => {});
}
}
// 2. Delete all unused browsers.
if (!getAsBooleanFromENV('PLAYWRIGHT_SKIP_BROWSER_GC')) {
let downloadedBrowsers = (await fsReaddirAsync(registryDirectory)).map(file => path.join(registryDirectory, file));
let downloadedBrowsers = (await fs.promises.readdir(registryDirectory)).map(file => path.join(registryDirectory, file));
downloadedBrowsers = downloadedBrowsers.filter(file => isBrowserDirectory(file));
const directories = new Set<string>(downloadedBrowsers);
for (const browserDirectory of usedBrowserPaths)
@ -110,7 +104,7 @@ async function validateCache(linksDir: string, browserNames: BrowserName[]) {
await browserFetcher.downloadBrowserWithProgressBar(myRegistry, browserName).catch(e => {
throw new Error(`Failed to download ${browserName}, caused by\n${e.stack}`);
});
await fsWriteFileAsync(markerFilePath(myRegistry.browserDirectory(browserName)), '');
await fs.promises.writeFile(markerFilePath(myRegistry.browserDirectory(browserName)), '');
}
}

View File

@ -19,7 +19,6 @@ import * as types from '../types';
import { EventEmitter } from 'events';
import fs from 'fs';
import * as stream from 'stream';
import * as util from 'util';
import * as ws from 'ws';
import { createGuid, makeWaitForNextTask } from '../../utils/utils';
import { BrowserOptions, BrowserProcess, PlaywrightOptions } from '../browser';
@ -34,8 +33,6 @@ import { AndroidWebView } from '../../protocol/channels';
import { CRPage } from '../chromium/crPage';
import { SdkObject, internalCallMetadata } from '../instrumentation';
const readFileAsync = util.promisify(fs.readFile);
export interface Backend {
devices(): Promise<DeviceBackend[]>;
}
@ -174,7 +171,7 @@ export class AndroidDevice extends SdkObject {
debug('pw:android')('Installing the new driver');
for (const file of ['android-driver.apk', 'android-driver-target.apk'])
await this.installApk(await readFileAsync(require.resolve(`../../../bin/${file}`)));
await this.installApk(await fs.promises.readFile(require.resolve(`../../../bin/${file}`)));
debug('pw:android')('Starting the new driver');
this.shell('am instrument -w com.microsoft.playwright.androiddriver.test/androidx.test.runner.AndroidJUnitRunner').catch(e => debug('pw:android')(e));

View File

@ -15,7 +15,6 @@
*/
import fs from 'fs';
import * as util from 'util';
import { SdkObject } from './instrumentation';
type SaveCallback = (localPath: string, error?: string) => Promise<void>;
@ -85,7 +84,7 @@ export class Artifact extends SdkObject {
return;
this._deleted = true;
if (fileName)
await util.promisify(fs.unlink)(fileName).catch(e => {});
await fs.promises.unlink(fileName).catch(e => {});
}
async deleteOnContextClose(): Promise<void> {
@ -95,7 +94,7 @@ export class Artifact extends SdkObject {
return;
this._deleted = true;
if (!this._unaccessibleErrorMessage)
await util.promisify(fs.unlink)(this._localPath).catch(e => {});
await fs.promises.unlink(this._localPath).catch(e => {});
await this.reportFinished('File deleted upon browser context closure.');
}

View File

@ -17,7 +17,6 @@
import fs from 'fs';
import * as os from 'os';
import path from 'path';
import * as util from 'util';
import { BrowserContext, normalizeProxySettings, validateBrowserContextOptions } from './browserContext';
import * as registry from '../utils/registry';
import { ConnectionTransport, WebSocketTransport } from './transport';
@ -33,8 +32,6 @@ import { helper } from './helper';
import { RecentLogsCollector } from '../utils/debugLogger';
import { CallMetadata, SdkObject } from './instrumentation';
const mkdirAsync = util.promisify(fs.mkdir);
const mkdtempAsync = util.promisify(fs.mkdtemp);
const existsAsync = (path: string): Promise<boolean> => new Promise(resolve => fs.stat(path, err => resolve(!err)));
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
@ -143,15 +140,15 @@ export abstract class BrowserType extends SdkObject {
const tempDirectories = [];
if (options.downloadsPath)
await mkdirAsync(options.downloadsPath, { recursive: true });
await fs.promises.mkdir(options.downloadsPath, { recursive: true });
if (options.tracesDir)
await mkdirAsync(options.tracesDir, { recursive: true });
await fs.promises.mkdir(options.tracesDir, { recursive: true });
const artifactsDir = await mkdtempAsync(ARTIFACTS_FOLDER);
const artifactsDir = await fs.promises.mkdtemp(ARTIFACTS_FOLDER);
tempDirectories.push(artifactsDir);
if (!userDataDir) {
userDataDir = await mkdtempAsync(path.join(os.tmpdir(), `playwright_${this._name}dev_profile-`));
userDataDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), `playwright_${this._name}dev_profile-`));
tempDirectories.push(userDataDir);
}

View File

@ -18,7 +18,6 @@
import fs from 'fs';
import os from 'os';
import path from 'path';
import util from 'util';
import { CRBrowser } from './crBrowser';
import { Env } from '../processLauncher';
import { kBrowserCloseMessageId } from './crConnection';
@ -37,7 +36,6 @@ import { CallMetadata } from '../instrumentation';
import { findChromiumChannel } from './findChromiumChannel';
import http from 'http';
const mkdtempAsync = util.promisify(fs.mkdtemp);
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
export class Chromium extends BrowserType {
@ -65,7 +63,7 @@ export class Chromium extends BrowserType {
if (options.headers)
headersMap = headersArrayToObject(options.headers, false);
const artifactsDir = await mkdtempAsync(ARTIFACTS_FOLDER);
const artifactsDir = await fs.promises.mkdtemp(ARTIFACTS_FOLDER);
const chromeTransport = await WebSocketTransport.connect(progress, await urlToWSEndpoint(endpointURL), headersMap);
const browserProcess: BrowserProcess = {

View File

@ -15,7 +15,6 @@
*/
import fs from 'fs';
import * as util from 'util';
import { CRSession } from './crConnection';
const kBindingName = '__pw_devtools__';
@ -44,7 +43,7 @@ export class CRDevTools {
if (parsed.method === 'getPreferences') {
if (this._prefs === undefined) {
try {
const json = await util.promisify(fs.readFile)(this._preferencesPath, 'utf8');
const json = await fs.promises.readFile(this._preferencesPath, 'utf8');
this._prefs = JSON.parse(json);
} catch (e) {
this._prefs = {};
@ -100,7 +99,7 @@ export class CRDevTools {
_save() {
// Serialize saves to avoid corruption.
this._savePromise = this._savePromise.then(async () => {
await util.promisify(fs.writeFile)(this._preferencesPath, JSON.stringify(this._prefs)).catch(e => null);
await fs.promises.writeFile(this._preferencesPath, JSON.stringify(this._prefs)).catch(e => null);
});
}
}

View File

@ -18,7 +18,6 @@
import { CRSession } from './crConnection';
import { Protocol } from './protocol';
import fs from 'fs';
import * as util from 'util';
import * as types from '../types';
import { mkdirIfNeeded } from '../../utils/utils';
import { splitErrorMessage } from '../../utils/stackTrace';
@ -43,10 +42,10 @@ export async function releaseObject(client: CRSession, objectId: string) {
export async function readProtocolStream(client: CRSession, handle: string, path: string | null): Promise<Buffer> {
let eof = false;
let fd: number | undefined;
let fd: fs.promises.FileHandle | undefined;
if (path) {
await mkdirIfNeeded(path);
fd = await util.promisify(fs.open)(path, 'w');
fd = await fs.promises.open(path, 'w');
}
const bufs = [];
while (!eof) {
@ -54,11 +53,11 @@ export async function readProtocolStream(client: CRSession, handle: string, path
eof = response.eof;
const buf = Buffer.from(response.data, response.base64Encoded ? 'base64' : undefined);
bufs.push(buf);
if (path)
await util.promisify(fs.write)(fd!, buf);
if (fd)
await fd.write(buf);
}
if (path)
await util.promisify(fs.close)(fd!);
if (fd)
await fd.close();
await client.send('IO.close', {handle});
return Buffer.concat(bufs);
}

View File

@ -17,7 +17,6 @@
import fs from 'fs';
import os from 'os';
import path from 'path';
import util from 'util';
import { CRBrowser, CRBrowserContext } from '../chromium/crBrowser';
import { CRConnection, CRSession } from '../chromium/crConnection';
import { CRExecutionContext } from '../chromium/crExecutionContext';
@ -37,7 +36,6 @@ import { RecentLogsCollector } from '../../utils/debugLogger';
import { internalCallMetadata, SdkObject } from '../instrumentation';
import * as channels from '../../protocol/channels';
const mkdtempAsync = util.promisify(fs.mkdtemp);
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
export class ElectronApplication extends SdkObject {
@ -125,7 +123,7 @@ export class Electron extends SdkObject {
electronArguments.push('--no-sandbox');
}
const artifactsDir = await mkdtempAsync(ARTIFACTS_FOLDER);
const artifactsDir = await fs.promises.mkdtemp(ARTIFACTS_FOLDER);
const browserLogsCollector = new RecentLogsCollector();
const { launchedProcess, gracefullyClose, kill } = await launchProcess({

View File

@ -15,15 +15,12 @@
*/
import fs from 'fs';
import * as util from 'util';
import { BrowserContext } from '../../browserContext';
import { helper } from '../../helper';
import * as network from '../../network';
import { Page } from '../../page';
import * as har from './har';
const fsWriteFileAsync = util.promisify(fs.writeFile.bind(fs));
type HarOptions = {
path: string;
omitContent?: boolean;
@ -233,7 +230,7 @@ export class HarTracer {
else
pageEntry.pageTimings.onLoad = -1;
}
await fsWriteFileAsync(this._options.path, JSON.stringify({ log: this._log }, undefined, 2));
await fs.promises.writeFile(this._options.path, JSON.stringify({ log: this._log }, undefined, 2));
}
}

View File

@ -16,7 +16,6 @@
import fs from 'fs';
import path from 'path';
import * as util from 'util';
import { CRPage } from '../../chromium/crPage';
import { Page } from '../../page';
import { ProgressController } from '../../progress';
@ -26,7 +25,6 @@ import type { CallLog, EventData, Mode, Source } from './recorderTypes';
import { BrowserContext } from '../../browserContext';
import { isUnderTest } from '../../../utils/utils';
const readFileAsync = util.promisify(fs.readFile);
const existsAsync = (path: string): Promise<boolean> => new Promise(resolve => fs.stat(path, err => resolve(!err)));
declare global {
@ -57,7 +55,7 @@ export class RecorderApp extends EventEmitter {
}
private async _init() {
const icon = await readFileAsync(require.resolve('../../../web/recorder/app_icon.png'));
const icon = await fs.promises.readFile(require.resolve('../../../web/recorder/app_icon.png'));
const crPopup = this._page._delegate as CRPage;
await crPopup._mainFrameSession._client.send('Browser.setDockTile', {
image: icon.toString('base64')
@ -67,7 +65,7 @@ export class RecorderApp extends EventEmitter {
if (route.request().url().startsWith('https://playwright/')) {
const uri = route.request().url().substring('https://playwright/'.length);
const file = require.resolve('../../../web/recorder/' + uri);
const buffer = await readFileAsync(file);
const buffer = await fs.promises.readFile(file);
await route.fulfill({
status: 200,
headers: [

View File

@ -17,7 +17,6 @@
import { EventEmitter } from 'events';
import fs from 'fs';
import path from 'path';
import util from 'util';
import { BrowserContext } from '../../browserContext';
import { Page } from '../../page';
import { FrameSnapshot, ResourceSnapshot } from '../../snapshot/snapshotTypes';
@ -25,8 +24,6 @@ import { Snapshotter, SnapshotterBlob, SnapshotterDelegate } from '../../snapsho
import { ElementHandle } from '../../dom';
import { TraceEvent } from '../common/traceEvents';
const fsWriteFileAsync = util.promisify(fs.writeFile.bind(fs));
export class TraceSnapshotter extends EventEmitter implements SnapshotterDelegate {
private _snapshotter: Snapshotter;
private _resourcesDir: string;
@ -64,7 +61,7 @@ export class TraceSnapshotter extends EventEmitter implements SnapshotterDelegat
onBlob(blob: SnapshotterBlob): void {
this._writeArtifactChain = this._writeArtifactChain.then(async () => {
await fsWriteFileAsync(path.join(this._resourcesDir, blob.sha1), blob.buffer).catch(() => {});
await fs.promises.writeFile(path.join(this._resourcesDir, blob.sha1), blob.buffer).catch(() => {});
});
}

View File

@ -16,7 +16,6 @@
import fs from 'fs';
import path from 'path';
import util from 'util';
import yazl from 'yazl';
import { calculateSha1, createGuid, mkdirIfNeeded, monotonicTime } from '../../../utils/utils';
import { Artifact } from '../../artifact';
@ -28,10 +27,6 @@ import { Page } from '../../page';
import * as trace from '../common/traceEvents';
import { TraceSnapshotter } from './traceSnapshotter';
const fsAppendFileAsync = util.promisify(fs.appendFile.bind(fs));
const fsWriteFileAsync = util.promisify(fs.writeFile.bind(fs));
const fsMkdirAsync = util.promisify(fs.mkdir.bind(fs));
export type TracerOptions = {
name?: string;
snapshots?: boolean;
@ -80,7 +75,7 @@ export class Tracing implements InstrumentationListener {
);
// context + page must be the first events added, no awaits above this line.
await fsMkdirAsync(this._resourcesDir, { recursive: true });
await fs.promises.mkdir(this._resourcesDir, { recursive: true });
this._context.instrumentation.addListener(this);
if (options.snapshots)
@ -179,7 +174,7 @@ export class Tracing implements InstrumentationListener {
};
this._appendTraceEvent(event);
this._appendEventChain = this._appendEventChain.then(async () => {
await fsWriteFileAsync(path.join(this._resourcesDir!, sha1), params.buffer).catch(() => {});
await fs.promises.writeFile(path.join(this._resourcesDir!, sha1), params.buffer).catch(() => {});
});
}),
);
@ -207,7 +202,7 @@ export class Tracing implements InstrumentationListener {
// Serialize all writes to the trace file.
this._appendEventChain = this._appendEventChain.then(async () => {
await fsAppendFileAsync(this._traceFile!, JSON.stringify(event) + '\n');
await fs.promises.appendFile(this._traceFile!, JSON.stringify(event) + '\n');
});
}
}

View File

@ -17,7 +17,6 @@
import fs from 'fs';
import path from 'path';
import { createPlaywright } from '../../playwright';
import * as util from 'util';
import { PersistentSnapshotStorage, TraceModel } from './traceModel';
import { TraceEvent } from '../common/traceEvents';
import { ServerRouteHandler, HttpServer } from '../../../utils/httpServer';
@ -27,8 +26,6 @@ import { isUnderTest } from '../../../utils/utils';
import { internalCallMetadata } from '../../instrumentation';
import { ProgressController } from '../../progress';
const fsReadFileAsync = util.promisify(fs.readFile.bind(fs));
export class TraceViewer {
private _server: HttpServer;
private _browserName: string;
@ -76,7 +73,7 @@ export class TraceViewer {
response.statusCode = 200;
response.setHeader('Content-Type', 'application/json');
(async () => {
const traceContent = await fsReadFileAsync(tracePrefix + '.trace', 'utf8');
const traceContent = await fs.promises.readFile(tracePrefix + '.trace', 'utf8');
const events = traceContent.split('\n').map(line => line.trim()).filter(line => !!line).map(line => JSON.parse(line)) as TraceEvent[];
const model = new TraceModel(snapshotStorage);
model.appendEvents(events, snapshotStorage);

View File

@ -14,7 +14,6 @@
* limitations under the License.
*/
import fs from 'fs';
import * as util from 'util';
import path from 'path';
import * as os from 'os';
import { getUbuntuVersion } from '../utils/ubuntuVersion';
@ -22,10 +21,7 @@ import * as registry from '../utils/registry';
import * as utils from '../utils/utils';
import { printDepsWindowsExecutable } from '../utils/binaryPaths';
const accessAsync = util.promisify(fs.access.bind(fs));
const checkExecutable = (filePath: string) => accessAsync(filePath, fs.constants.X_OK).then(() => true).catch(e => false);
const statAsync = util.promisify(fs.stat.bind(fs));
const readdirAsync = util.promisify(fs.readdir.bind(fs));
const checkExecutable = (filePath: string) => fs.promises.access(filePath, fs.constants.X_OK).then(() => true).catch(e => false);
export async function validateHostRequirements(registry: registry.Registry, browserName: registry.BrowserName) {
if (utils.getAsBooleanFromENV('PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS')) {
@ -195,8 +191,8 @@ function isSharedLib(basename: string) {
}
async function executablesOrSharedLibraries(directoryPath: string): Promise<string[]> {
const allPaths = (await readdirAsync(directoryPath)).map(file => path.resolve(directoryPath, file));
const allStats = await Promise.all(allPaths.map(aPath => statAsync(aPath)));
const allPaths = (await fs.promises.readdir(directoryPath)).map(file => path.resolve(directoryPath, file));
const allStats = await Promise.all(allPaths.map(aPath => fs.promises.stat(aPath)));
const filePaths = allPaths.filter((aPath, index) => (allStats[index] as any).isFile());
const executablersOrLibraries = (await Promise.all(filePaths.map(async filePath => {

View File

@ -17,16 +17,13 @@
import fs from 'fs';
import * as os from 'os';
import * as util from 'util';
const readFileAsync = util.promisify(fs.readFile.bind(fs));
export async function getUbuntuVersion(): Promise<string> {
if (os.platform() !== 'linux')
return '';
let osReleaseText = await readFileAsync('/etc/upstream-release/lsb-release', 'utf8').catch(e => '');
let osReleaseText = await fs.promises.readFile('/etc/upstream-release/lsb-release', 'utf8').catch(e => '');
if (!osReleaseText)
osReleaseText = await readFileAsync('/etc/os-release', 'utf8').catch(e => '');
osReleaseText = await fs.promises.readFile('/etc/os-release', 'utf8').catch(e => '');
if (!osReleaseText)
return '';
return getUbuntuVersionInternal(osReleaseText);

View File

@ -17,13 +17,10 @@
import path from 'path';
import fs from 'fs';
import removeFolder from 'rimraf';
import * as util from 'util';
import * as crypto from 'crypto';
import os from 'os';
import { spawn } from 'child_process';
const mkdirAsync = util.promisify(fs.mkdir.bind(fs));
export function spawnAsync(cmd: string, args: string[], options: any): Promise<{stdout: string, stderr: string, code: number, error?: Error}> {
const process = spawn(cmd, args, options);
@ -134,7 +131,7 @@ export function getAsBooleanFromENV(name: string): boolean {
export async function mkdirIfNeeded(filePath: string) {
// This will harmlessly throw on windows if the dirname is the root directory.
await mkdirAsync(path.dirname(filePath), {recursive: true}).catch(() => {});
await fs.promises.mkdir(path.dirname(filePath), {recursive: true}).catch(() => {});
}
type HeadersArray = { name: string, value: string }[];

View File

@ -20,12 +20,9 @@ import { removeFolders } from '../../lib/utils/utils';
import * as path from 'path';
import * as fs from 'fs';
import * as os from 'os';
import * as util from 'util';
import { RemoteServer, RemoteServerOptions } from './remoteServer';
import { baseTest, CommonWorkerFixtures } from './baseTest';
const mkdtempAsync = util.promisify(fs.mkdtemp);
type PlaywrightWorkerOptions = {
tracesDir: LaunchOptions['tracesDir'];
executablePath: LaunchOptions['executablePath'];
@ -94,7 +91,7 @@ export const playwrightFixtures: folio.Fixtures<PlaywrightTestOptions & Playwrig
// - Firefox removes lock file later, presumably from another watchdog process?
// - WebKit has circular symlinks that makes CI go crazy.
await run(async () => {
const dir = await mkdtempAsync(path.join(os.tmpdir(), 'playwright-test-'));
const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'playwright-test-'));
dirs.push(dir);
return dir;
});

View File

@ -17,7 +17,6 @@
import { browserTest as it, expect } from './config/browserTest';
import fs from 'fs';
import path from 'path';
import util from 'util';
import crypto from 'crypto';
import { chromiumVersionLessThan } from './config/utils';
@ -152,9 +151,9 @@ it.describe('download event', () => {
const dir = testInfo.outputPath('downloads');
const userPath = path.join(dir, 'download.txt');
await download.saveAs(userPath);
expect((await util.promisify(fs.readdir)(dir)).length).toBe(1);
expect((await fs.promises.readdir(dir)).length).toBe(1);
await download.saveAs(userPath);
expect((await util.promisify(fs.readdir)(dir)).length).toBe(1);
expect((await fs.promises.readdir(dir)).length).toBe(1);
expect(fs.existsSync(userPath)).toBeTruthy();
expect(fs.readFileSync(userPath).toString()).toBe('Hello world');
await page.close();

View File

@ -26,7 +26,6 @@ const WebSocketServer = require('ws').Server;
const fulfillSymbol = Symbol('fullfil callback');
const rejectSymbol = Symbol('reject callback');
const readFileAsync = util.promisify(fs.readFile.bind(fs));
const gzipAsync = util.promisify(zlib.gzip.bind(zlib));
class TestServer {
@ -50,8 +49,8 @@ class TestServer {
*/
static async createHTTPS(dirPath, port, loopback) {
const server = new TestServer(dirPath, port, loopback, {
key: fs.readFileSync(path.join(__dirname, 'key.pem')),
cert: fs.readFileSync(path.join(__dirname, 'cert.pem')),
key: await fs.promises.readFile(path.join(__dirname, 'key.pem')),
cert: await fs.promises.readFile(path.join(__dirname, 'cert.pem')),
passphrase: 'aaaa',
});
await new Promise(x => server._server.once('listening', x));
@ -273,7 +272,7 @@ class TestServer {
if (this._csp.has(pathName))
response.setHeader('Content-Security-Policy', this._csp.get(pathName));
const {err, data} = await readFileAsync(filePath).then(data => ({data})).catch(err => ({err}));
const {err, data} = await fs.promises.readFile(filePath).then(data => ({data})).catch(err => ({err}));
// The HTTP transaction might be already terminated after async hop here - do nothing in this case.
if (response.writableEnded)
return;