/
index.js
121 lines (103 loc) · 2.99 KB
/
index.js
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
'use strict'
const util = require('util')
const fs = require('fs')
const fse = require('fs-extra')
const os = require('os')
const path = require('path')
const debug = require('debug')('puppeteer-extra-plugin:user-data-dir')
const mkdtempAsync = util.promisify(fs.mkdtemp)
const { PuppeteerExtraPlugin } = require('puppeteer-extra-plugin')
/**
*
* Further reading:
* https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md
*/
class Plugin extends PuppeteerExtraPlugin {
constructor(opts = {}) {
super(opts)
this._userDataDir = null
this._isTemporary = false
const defaults = {
deleteTemporary: true,
deleteExisting: false,
files: []
}
// Follow Puppeteers temporary user data dir naming convention by default
defaults.folderPath = os.tmpdir()
defaults.folderPrefix = 'puppeteer_dev_profile-'
this._opts = Object.assign(defaults, opts)
debug('initialized', this._opts)
}
get name() {
return 'user-data-dir'
}
get requirements() {
return new Set(['runLast', 'dataFromPlugins'])
}
get shouldDeleteDirectory() {
if (this._isTemporary && this._opts.deleteTemporary) {
return true
}
return this._opts.deleteExisting
}
get temporaryDirectoryPath() {
return path.join(this._opts.folderPath, this._opts.folderPrefix)
}
get defaultProfilePath() {
return path.join(this._userDataDir, 'Default')
}
async makeTemporaryDirectory() {
this._userDataDir = await mkdtempAsync(this.temporaryDirectoryPath)
this._isTemporary = true
}
deleteUserDataDir() {
debug('removeUserDataDir')
try {
// We're doing it sync to improve chances to cleanup
// correctly in the event of ultimate disaster.
fse.rmdirSync(this._userDataDir, { recursive: true })
} catch (e) {
debug(e)
}
}
async writeFilesToProfile() {
const filesFromPlugins = this.getDataFromPlugins('userDataDirFile').map(
d => d.value
)
const files = [].concat(filesFromPlugins, this._opts.files)
if (!files.length) {
return
}
for (const file of files) {
if (file.target !== 'Profile') {
console.warn(`Warning: Ignoring file with invalid target`, file)
continue
}
const filePath = path.join(this.defaultProfilePath, file.file)
try {
await fse.outputFile(filePath, file.contents)
debug(`Wrote file`, filePath)
} catch (err) {
console.warn('Warning: Failure writing file', filePath, file, err)
}
}
}
async beforeLaunch(options) {
this._userDataDir = options.userDataDir
if (!this._userDataDir) {
await this.makeTemporaryDirectory()
options.userDataDir = this._userDataDir
debug('created custom dir', options.userDataDir)
}
await this.writeFilesToProfile()
}
async onClose() {
debug('onClose')
if (this.shouldDeleteDirectory) {
this.deleteUserDataDir()
}
}
}
module.exports = function(pluginConfig) {
return new Plugin(pluginConfig)
}