or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

browser-lifecycle.mdindex.mdplugin-management.md

browser-lifecycle.mddocs/

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

```