From b993adb468385e46bebe57ac0127bc20796a96f7 Mon Sep 17 00:00:00 2001 From: Jack Franklin Date: Thu, 25 Jun 2020 10:19:10 +0100 Subject: [PATCH] chore(agnostic): Migrate DOMWorld (#6054) DOMWorld only needs to use Node's `fs` module if you're adding a filepath as a script/style tag. We can detect this case and run the `require` inline such that in a browser this code won't execute. --- src/common/DOMWorld.ts | 42 +++++++++++++++++++++++++++++++++++++----- src/common/Debug.ts | 4 ++-- src/environment.ts | 17 +++++++++++++++++ 3 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 src/environment.ts diff --git a/src/common/DOMWorld.ts b/src/common/DOMWorld.ts index 678ddc4300dd1..867eaf7b840fa 100644 --- a/src/common/DOMWorld.ts +++ b/src/common/DOMWorld.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import * as fs from 'fs'; import { assert } from './assert'; import { helper } from './helper'; import { LifecycleWatcher, PuppeteerLifeCycleEvent } from './LifecycleWatcher'; @@ -25,13 +24,12 @@ import { TimeoutSettings } from './TimeoutSettings'; import { MouseButtonInput } from './Input'; import { FrameManager, Frame } from './FrameManager'; import { getQueryHandlerAndSelector, QueryHandler } from './QueryHandler'; +import { isNode } from '../environment'; // This predicateQueryHandler is declared here so that TypeScript knows about it // when it is used in the predicate function below. declare const predicateQueryHandler: QueryHandler; -const readFileAsync = helper.promisify(fs.readFile); - export interface WaitForSelectorOptions { visible?: boolean; hidden?: boolean; @@ -232,8 +230,15 @@ export class DOMWorld { } /** - * @param {!{url?: string, path?: string, content?: string, type?: string}} options - * @returns {!Promise} + * Adds a script tag into the current context. + * + * @remarks + * + * You can pass a URL, filepath or string of contents. Note that when running Puppeteer + * in a browser environment you cannot pass a filepath and should use either + * `url` or `content`. + * + * @param options */ async addScriptTag(options: { url?: string; @@ -254,6 +259,14 @@ export class DOMWorld { } if (path !== null) { + if (!isNode) { + throw new Error( + 'Cannot pass a filepath to addScriptTag in the browser environment.' + ); + } + // eslint-disable-next-line @typescript-eslint/no-var-requires + const fs = require('fs'); + const readFileAsync = helper.promisify(fs.readFile); let contents = await readFileAsync(path, 'utf8'); contents += '//# sourceURL=' + path.replace(/\n/g, ''); const context = await this.executionContext(); @@ -304,6 +317,17 @@ export class DOMWorld { } } + /** + * Adds a style tag into the current context. + * + * @remarks + * + * You can pass a URL, filepath or string of contents. Note that when running Puppeteer + * in a browser environment you cannot pass a filepath and should use either + * `url` or `content`. + * + * @param options + */ async addStyleTag(options: { url?: string; path?: string; @@ -320,6 +344,14 @@ export class DOMWorld { } if (path !== null) { + if (!isNode) { + throw new Error( + 'Cannot pass a filepath to addStyleTag in the browser environment.' + ); + } + // eslint-disable-next-line @typescript-eslint/no-var-requires + const fs = require('fs'); + const readFileAsync = helper.promisify(fs.readFile); let contents = await readFileAsync(path, 'utf8'); contents += '/*# sourceURL=' + path.replace(/\n/g, '') + '*/'; const context = await this.executionContext(); diff --git a/src/common/Debug.ts b/src/common/Debug.ts index 24f0434bf868f..236be96d5b458 100644 --- a/src/common/Debug.ts +++ b/src/common/Debug.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -const isNodeEnv = typeof document === 'undefined'; +import { isNode } from '../environment'; /** * A debug function that can be used in any environment. @@ -35,7 +35,7 @@ const isNodeEnv = typeof document === 'undefined'; * ``` */ export const debug = (prefix: string): ((...args: unknown[]) => void) => { - if (isNodeEnv) { + if (isNode) { // eslint-disable-next-line @typescript-eslint/no-var-requires return require('debug')(prefix); } diff --git a/src/environment.ts b/src/environment.ts new file mode 100644 index 0000000000000..0d2a7a1f125cb --- /dev/null +++ b/src/environment.ts @@ -0,0 +1,17 @@ +/** + * Copyright 2020 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const isNode = typeof document === 'undefined';