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.
This commit is contained in:
Jack Franklin 2020-06-25 10:19:10 +01:00 committed by Mathias Bynens
parent c1490349bc
commit b993adb468
3 changed files with 56 additions and 7 deletions

View File

@ -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<!ElementHandle>}
* 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();

View File

@ -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);
}

17
src/environment.ts Normal file
View File

@ -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';