How to use killFirefox method in Puppeteer

Best JavaScript code snippet using puppeteer

Run Puppeteer automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Launcher.js

Source: Launcher.js Github

copy
1/**
2 * Copyright 2017 Google Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16const os = require('os');
17const path = require('path');
18const removeFolder = require('rimraf');
19const childProcess = require('child_process');
20const {Connection} = require('./Connection');
21const {Browser} = require('./Browser');
22const readline = require('readline');
23const fs = require('fs');
24const util = require('util');
25const {helper} = require('./helper');
26const {TimeoutError} = require('../Errors')
27const FirefoxTransport = require('./FirefoxTransport');
28
29const mkdtempAsync = util.promisify(fs.mkdtemp);
30const removeFolderAsync = util.promisify(removeFolder);
31
32const FIREFOX_PROFILE_PATH = path.join(os.tmpdir(), 'puppeteer_firefox_profile-');
33
34/**
35 * @internal
36 */
37class Launcher {
38  /**
39   * @param {Object} options
40   * @return {!Promise<!Browser>}
41   */
42  async launch(options = {}) {
43    const {
44      args = [],
45      dumpio = false,
46      executablePath = null,
47      handleSIGHUP = true,
48      handleSIGINT = true,
49      handleSIGTERM = true,
50      ignoreHTTPSErrors = false,
51      headless = true,
52      defaultViewport = {width: 800, height: 600},
53      slowMo = 0,
54    } = options;
55
56    if (!executablePath)
57      throw new Error('Firefox launching is only supported with local version of firefox!');
58
59    const firefoxArguments = args.slice();
60    firefoxArguments.push('-no-remote');
61    firefoxArguments.push('-juggler', '0');
62    firefoxArguments.push('-foreground');
63    if (headless)
64      firefoxArguments.push('-headless');
65    let temporaryProfileDir = null;
66    if (!firefoxArguments.some(arg => arg.startsWith('-profile') || arg.startsWith('--profile'))) {
67      temporaryProfileDir = await mkdtempAsync(FIREFOX_PROFILE_PATH);
68      firefoxArguments.push(`-profile`, temporaryProfileDir);
69    }
70    if (firefoxArguments.every(arg => arg.startsWith('--') || arg.startsWith('-')))
71      firefoxArguments.push('about:blank');
72
73    const stdio = ['pipe', 'pipe', 'pipe'];
74    const firefoxProcess = childProcess.spawn(
75        executablePath,
76        firefoxArguments,
77        {
78          // On non-windows platforms, `detached: false` makes child process a leader of a new
79          // process group, making it possible to kill child process tree with `.kill(-pid)` command.
80          // @see https://nodejs.org/api/child_process.html#child_process_options_detached
81          detached: process.platform !== 'win32',
82          stdio
83        }
84    );
85
86    if (dumpio) {
87      firefoxProcess.stderr.pipe(process.stderr);
88      firefoxProcess.stdout.pipe(process.stdout);
89    }
90
91    let firefoxClosed = false;
92    const waitForFirefoxToClose = new Promise((fulfill, reject) => {
93      firefoxProcess.once('exit', () => {
94        firefoxClosed = true;
95        // Cleanup as processes exit.
96        if (temporaryProfileDir) {
97          removeFolderAsync(temporaryProfileDir)
98              .then(() => fulfill())
99              .catch(err => console.error(err));
100        } else {
101          fulfill();
102        }
103      });
104    });
105
106    const listeners = [ helper.addEventListener(process, 'exit', killFirefox) ];
107    if (handleSIGINT)
108      listeners.push(helper.addEventListener(process, 'SIGINT', () => { killFirefox(); process.exit(130); }));
109    if (handleSIGTERM)
110      listeners.push(helper.addEventListener(process, 'SIGTERM', killFirefox));
111    if (handleSIGHUP)
112      listeners.push(helper.addEventListener(process, 'SIGHUP', killFirefox));
113    /** @type {?Connection} */
114    let connection = null;
115    try {
116      const port = await waitForWSEndpoint(firefoxProcess, 30000);
117      const transport = await FirefoxTransport.create(parseInt(port, 10));
118      connection = new Connection(transport, slowMo);
119      const browser = new Browser(connection, defaultViewport, firefoxProcess, killFirefox);
120      if (ignoreHTTPSErrors)
121        await connection.send('Browser.setIgnoreHTTPSErrors', {enabled: true});
122      if (!browser.targets().length)
123        await new Promise(x => browser.once('targetcreated', x));
124      return browser;
125    } catch (e) {
126      killFirefox();
127      throw e;
128    }
129
130    // This method has to be sync to be used as 'exit' event handler.
131    function killFirefox() {
132      helper.removeEventListeners(listeners);
133      if (firefoxProcess.pid && !firefoxProcess.killed && !firefoxClosed) {
134        // Force kill chrome.
135        try {
136          if (process.platform === 'win32')
137            childProcess.execSync(`taskkill /pid ${firefoxProcess.pid} /T /F`);
138          else
139            process.kill(-firefoxProcess.pid, 'SIGKILL');
140        } catch (e) {
141          // the process might have already stopped
142        }
143      }
144      // Attempt to remove temporary profile directory to avoid littering.
145      try {
146        removeFolder.sync(temporaryProfileDir);
147      } catch (e) { }
148    }
149  }
150}
151
152/**
153 * @param {!Puppeteer.ChildProcess} firefoxProcess
154 * @param {number} timeout
155 * @return {!Promise<string>}
156 */
157function waitForWSEndpoint(firefoxProcess, timeout) {
158  return new Promise((resolve, reject) => {
159    const rl = readline.createInterface({ input: firefoxProcess.stdout });
160    let stderr = '';
161    const listeners = [
162      helper.addEventListener(rl, 'line', onLine),
163      helper.addEventListener(rl, 'close', () => onClose()),
164      helper.addEventListener(firefoxProcess, 'exit', () => onClose()),
165      helper.addEventListener(firefoxProcess, 'error', error => onClose(error))
166    ];
167    const timeoutId = timeout ? setTimeout(onTimeout, timeout) : 0;
168
169    /**
170     * @param {!Error=} error
171     */
172    function onClose(error) {
173      cleanup();
174      reject(new Error([
175        'Failed to launch Firefox!' + (error ? ' ' + error.message : ''),
176        stderr,
177        '',
178      ].join('\n')));
179    }
180
181    function onTimeout() {
182      cleanup();
183      reject(new TimeoutError(`Timed out after ${timeout} ms while trying to connect to Firefox!`));
184    }
185
186    /**
187     * @param {string} line
188     */
189    function onLine(line) {
190      stderr += line + '\n';
191      const match = line.match(/^Juggler listening on (\d+)$/);
192      if (!match)
193        return;
194      cleanup();
195      resolve(match[1]);
196    }
197
198    function cleanup() {
199      if (timeoutId)
200        clearTimeout(timeoutId);
201      helper.removeEventListeners(listeners);
202    }
203  });
204}
205
206module.exports = {Launcher};
207
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Puppeteer on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)