0
# Browser Lifecycle
1
2
Enhanced browser launch and connection methods with integrated plugin lifecycle support, maintaining full compatibility with standard Puppeteer while adding plugin functionality.
3
4
## Capabilities
5
6
### Browser Launch
7
8
Launch a new browser instance with automatic plugin lifecycle integration.
9
10
```javascript { .api }
11
/**
12
* Launch a new browser instance with plugin lifecycle support
13
* All registered plugins with beforeLaunch methods are called in sequence
14
* @param options - Regular Puppeteer launch options (optional)
15
* @returns Promise resolving to Browser instance
16
*/
17
launch(options?: {
18
/** Whether to run browser in headless mode (default: true) */
19
headless?: boolean;
20
/** Path to a Chromium or Chrome executable */
21
executablePath?: string;
22
/** Additional arguments to pass to the browser instance */
23
args?: Array<string>;
24
/** Whether to ignore HTTPS errors during navigation */
25
ignoreHTTPSErrors?: boolean;
26
/** Slows down Puppeteer operations by specified milliseconds */
27
slowMo?: number;
28
/** Maximum time in milliseconds to wait for browser to start */
29
timeout?: number;
30
/** Whether to pipe browser process stdout and stderr */
31
dumpio?: boolean;
32
/** Path to a user data directory */
33
userDataDir?: string;
34
/** Close browser process on Ctrl-C (default: true) */
35
handleSIGINT?: boolean;
36
/** Close browser process on SIGTERM (default: true) */
37
handleSIGTERM?: boolean;
38
/** Close browser process on SIGHUP (default: true) */
39
handleSIGHUP?: boolean;
40
/** Additional environment variables to pass to browser */
41
env?: Object;
42
/** Connect to browser over a pipe instead of WebSocket */
43
pipe?: boolean;
44
/** Specify default viewport for each page */
45
defaultViewport?: {
46
width: number;
47
height: number;
48
deviceScaleFactor?: number;
49
isMobile?: boolean;
50
hasTouch?: boolean;
51
isLandscape?: boolean;
52
} | null;
53
}): Promise<Puppeteer.Browser>;
54
```
55
56
**Usage Examples:**
57
58
```javascript
59
const puppeteer = require('puppeteer-extra');
60
61
// Basic launch with plugins
62
const browser = await puppeteer.launch();
63
64
// Launch with custom options
65
const browser = await puppeteer.launch({
66
headless: false,
67
args: ['--no-sandbox', '--disable-setuid-sandbox'],
68
defaultViewport: { width: 1280, height: 720 }
69
});
70
71
// Plugins can modify these options before launch
72
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
73
puppeteer.use(StealthPlugin());
74
const browser = await puppeteer.launch({ headless: true }); // Stealth plugin adds its arguments
75
```
76
77
### Browser Connection
78
79
Connect to an existing Chromium instance with plugin lifecycle support.
80
81
```javascript { .api }
82
/**
83
* Connect to existing Chromium instance with plugin lifecycle support
84
* All registered plugins with beforeConnect methods are called in sequence
85
* @param options - Connection configuration options
86
* @returns Promise resolving to Browser instance
87
*/
88
connect(options?: {
89
/** WebSocket endpoint to connect to */
90
browserWSEndpoint: string;
91
/** Whether to ignore HTTPS errors during navigation (default: false) */
92
ignoreHTTPSErrors?: boolean;
93
/** Specify default viewport for each page */
94
defaultViewport?: {
95
width: number;
96
height: number;
97
deviceScaleFactor?: number;
98
isMobile?: boolean;
99
hasTouch?: boolean;
100
isLandscape?: boolean;
101
} | null;
102
/** Slows down Puppeteer operations by specified milliseconds */
103
slowMo?: number;
104
}): Promise<Puppeteer.Browser>;
105
```
106
107
**Usage Examples:**
108
109
```javascript
110
// Connect to existing browser instance
111
const browser = await puppeteer.connect({
112
browserWSEndpoint: 'ws://localhost:9222/devtools/browser/...'
113
});
114
115
// Connect with custom options
116
const browser = await puppeteer.connect({
117
browserWSEndpoint: 'ws://localhost:9222/devtools/browser/...',
118
ignoreHTTPSErrors: true,
119
defaultViewport: null // Use browser's default viewport
120
});
121
```
122
123
### Plugin Lifecycle Integration
124
125
The framework automatically manages plugin lifecycle during browser operations.
126
127
```javascript { .api }
128
/**
129
* Plugin lifecycle methods called during browser operations
130
*/
131
interface BrowserLifecycle {
132
/** Called before launch with options that can be modified */
133
beforeLaunch?(options: Object): Object | Promise<Object>;
134
135
/** Called before connect with options that can be modified */
136
beforeConnect?(options: Object): Object | Promise<Object>;
137
138
/** Called after browser creation to bind event listeners */
139
_bindBrowserEvents?(browser: Puppeteer.Browser, opts: {
140
context: 'launch' | 'connect';
141
options: Object;
142
defaultArgs?: Array<string>;
143
}): void | Promise<void>;
144
}
145
```
146
147
**Plugin Integration Flow:**
148
149
1. **Option Modification**: Plugins with `beforeLaunch`/`beforeConnect` modify options
150
2. **Requirement Checking**: Framework validates plugin requirements against options
151
3. **Browser Creation**: Standard Puppeteer launch/connect with modified options
152
4. **Page Patching**: Framework patches page creation methods for plugin compatibility
153
5. **Event Binding**: Plugins with `_bindBrowserEvents` set up event listeners
154
155
**Usage Examples:**
156
157
```javascript
158
// Example plugin that modifies launch options
159
class CustomArgsPlugin extends PuppeteerExtraPlugin {
160
constructor(customArgs = []) {
161
super();
162
this.name = 'custom-args';
163
this.customArgs = customArgs;
164
}
165
166
async beforeLaunch(options) {
167
options.args = options.args || [];
168
options.args.push(...this.customArgs);
169
return options;
170
}
171
}
172
173
// Plugin automatically integrates with launch
174
puppeteer.use(new CustomArgsPlugin(['--disable-dev-shm-usage']));
175
const browser = await puppeteer.launch(); // Custom args are automatically added
176
```
177
178
### Page Creation Patching
179
180
The framework includes built-in workarounds for Puppeteer timing issues with page creation.
181
182
```javascript { .api }
183
/**
184
* Internal page creation method patching
185
* Fixes timing issues where plugins can't modify page before first request
186
* Automatically navigates to about:blank after page creation
187
*/
188
_patchPageCreationMethods(browser: Puppeteer.Browser): void;
189
```
190
191
**Automatic Fixes:**
192
193
- **Timing Issue**: Ensures plugins can modify pages before the first navigation
194
- **Event Race Conditions**: Prevents missed `targetcreated` events
195
- **Plugin Initialization**: Allows plugins to set up page-level modifications
196
197
**Usage Examples:**
198
199
```javascript
200
// This patching happens automatically - no user code needed
201
const browser = await puppeteer.launch();
202
const page = await browser.newPage(); // Automatically patched for plugin compatibility
203
204
// Pages created through browser.newPage() work correctly with plugins
205
// Pages created implicitly (e.g., window.open) may still have timing issues
206
```
207
208
### Requirement Validation
209
210
The framework validates plugin requirements against launch/connect options.
211
212
```javascript { .api }
213
/**
214
* Check plugin requirements against current options
215
* Warns user when plugins won't work as expected
216
*/
217
checkPluginRequirements(opts: {
218
context: 'launch' | 'connect';
219
options: Object;
220
defaultArgs?: Array<string>;
221
}): void;
222
```
223
224
**Validation Rules:**
225
226
- **Headful Requirement**: Warns if plugin needs headful mode but `headless: true`
227
- **Launch Requirement**: Warns if plugin doesn't support `connect()` method
228
- **Custom Requirements**: Plugins can define additional requirement checks
229
230
**Usage Examples:**
231
232
```javascript
233
// Plugin with headful requirement
234
class HeadfulPlugin extends PuppeteerExtraPlugin {
235
constructor() {
236
super();
237
this.name = 'headful-only';
238
this.requirements = new Set(['headful']);
239
}
240
}
241
242
puppeteer.use(new HeadfulPlugin());
243
const browser = await puppeteer.launch({ headless: true });
244
// Warning: Plugin 'headful-only' is not supported in headless mode.
245
```
246
247
### Internal Framework Methods
248
249
These methods are used internally by the framework for plugin management and lifecycle coordination.
250
251
```javascript { .api }
252
/**
253
* Call plugins sequentially with the same values
254
* Plugins that expose the supplied property will be called
255
* @param prop - The plugin property/method to call
256
* @param values - Any number of values to pass to plugins
257
*/
258
callPlugins(prop: string, ...values: any[]): Promise<void>;
259
260
/**
261
* Call plugins sequentially and pass on a value (waterfall style)
262
* Plugins can modify the value or return an updated one
263
* @param prop - The plugin property/method to call
264
* @param value - Initial value to pass through plugins
265
* @returns Updated value after passing through all plugins
266
*/
267
callPluginsWithValue(prop: string, value: any): Promise<any>;
268
269
/**
270
* Get all plugins that feature a given property/method
271
* @param prop - Property name to search for
272
* @returns Array of plugins that have the specified property
273
*/
274
getPluginsByProp(prop: string): Array<PuppeteerExtraPlugin>;
275
276
/**
277
* Get the names of all registered plugins
278
* @returns Array of plugin names
279
*/
280
get pluginNames(): Array<string>;
281
```
282
283
**Plugin Call Flow Examples:**
284
285
```javascript
286
// Internal usage during launch
287
await this.callPluginsWithValue('beforeLaunch', options);
288
await this.callPlugins('_bindBrowserEvents', browser, opts);
289
290
// How plugins modify options in sequence
291
let modifiedOptions = options;
292
for (const plugin of this.getPluginsByProp('beforeLaunch')) {
293
const newValue = await plugin.beforeLaunch(modifiedOptions);
294
if (newValue) {
295
modifiedOptions = newValue;
296
}
297
}
298
```