All files index.ts

100% Statements 12/12
100% Branches 1/1
100% Functions 10/10
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103                                                                                                18x     18x       26x       18x           1x       1x       4x                             7x       7x 8x   7x         18x    
import {
  type PluginData,
  type PluginDependencies,
  type PluginRequirements,
  PuppeteerExtraPlugin,
} from '@zorilla/puppeteer-extra-plugin';
import merge from 'deepmerge';
 
/**
 * Represents a deeply nested preference value structure.
 * Chrome preferences can be primitives or nested objects.
 */
type PreferenceValue =
  | string
  | number
  | boolean
  | null
  | { [key: string]: PreferenceValue };
 
interface PluginOptions {
  userPrefs?: Record<string, PreferenceValue>;
}
 
/**
 * Launch puppeteer with arbitrary user preferences.
 *
 * The user defined preferences will be merged with preferences set by other plugins.
 * Plugins can add user preferences by exposing a data entry with the name `userPreferences`.
 *
 * Overview:
 * https://chromium.googlesource.com/chromium/src/+/master/chrome/common/pref_names.cc
 *
 * @param {Object} opts - Options
 * @param {Object} [opts.userPrefs={}] - An object containing the preferences.
 *
 * @example
 * import puppeteer from '@zorilla/puppeteer-extra'
 * import userPreferencesPlugin from '@zorilla/puppeteer-extra-plugin-user-preferences'
 * puppeteer.use(userPreferencesPlugin({userPrefs: {
 *   webkit: {
 *     webprefs: {
 *       default_font_size: 22
 *     }
 *   }
 * }}))
 * const browser = await puppeteer.launch()
 */
class Plugin extends PuppeteerExtraPlugin {
  private _userPrefsFromPlugins: Record<string, PreferenceValue> = {};
 
  constructor(opts: PluginOptions = {}) {
    super(opts);
  }
 
  override get name(): string {
    return 'user-preferences';
  }
 
  override get defaults(): Required<PluginOptions> {
    return {
      userPrefs: {},
    };
  }
 
  override get requirements(): PluginRequirements {
    return new Set(['runLast', 'dataFromPlugins']);
  }
 
  override get dependencies(): PluginDependencies {
    return new Set(['user-data-dir']);
  }
 
  override get data(): PluginData[] {
    return [
      {
        name: {
          userDataDirFile: true,
        },
        value: {
          target: 'Profile',
          file: 'Preferences',
          contents: JSON.stringify(this.combinedPrefs, null, 2),
        },
      },
    ];
  }
 
  get combinedPrefs(): Record<string, PreferenceValue> {
    return merge(this.opts.userPrefs, this._userPrefsFromPlugins);
  }
 
  override async beforeLaunch(_options: unknown): Promise<void> {
    this._userPrefsFromPlugins = merge.all(
      this.getDataFromPlugins('userPreferences').map(d => d.value)
    ) as Record<string, PreferenceValue>;
    this.debug('_userPrefsFromPlugins', this._userPrefsFromPlugins);
  }
}
 
export default function (pluginConfig?: PluginOptions): Plugin {
  return new Plugin(pluginConfig);
}