1/**
2 * Copyright 2019 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 */
16
17/* eslint-disable @typescript-eslint/no-var-requires */
18
19import expect from 'expect';
20import { getTestState, itChromeOnly } from './mocha-utils'; // eslint-disable-line import/extensions
21
22import path from 'path';
23
24describe('Fixtures', function () {
25  itChromeOnly('dumpio option should work with pipe option ', async () => {
26    const { defaultBrowserOptions, puppeteerPath } = getTestState();
27
28    let dumpioData = '';
29    const { spawn } = require('child_process');
30    const options = Object.assign({}, defaultBrowserOptions, {
31      pipe: true,
32      dumpio: true,
33    });
34    const res = spawn('node', [
35      path.join(__dirname, 'fixtures', 'dumpio.js'),
36      puppeteerPath,
37      JSON.stringify(options),
38    ]);
39    res.stderr.on('data', (data) => (dumpioData += data.toString('utf8')));
40    await new Promise((resolve) => res.on('close', resolve));
41    expect(dumpioData).toContain('message from dumpio');
42  });
43  it('should dump browser process stderr', async () => {
44    const { defaultBrowserOptions, puppeteerPath } = getTestState();
45
46    let dumpioData = '';
47    const { spawn } = require('child_process');
48    const options = Object.assign({}, defaultBrowserOptions, { dumpio: true });
49    const res = spawn('node', [
50      path.join(__dirname, 'fixtures', 'dumpio.js'),
51      puppeteerPath,
52      JSON.stringify(options),
53    ]);
54    res.stderr.on('data', (data) => (dumpioData += data.toString('utf8')));
55    await new Promise((resolve) => res.on('close', resolve));
56    expect(dumpioData).toContain('DevTools listening on ws://');
57  });
58  it('should close the browser when the node process closes', async () => {
59    const { defaultBrowserOptions, puppeteerPath, puppeteer } = getTestState();
60
61    const { spawn, execSync } = require('child_process');
62    const options = Object.assign({}, defaultBrowserOptions, {
63      // Disable DUMPIO to cleanly read stdout.
64      dumpio: false,
65    });
66    const res = spawn('node', [
67      path.join(__dirname, 'fixtures', 'closeme.js'),
68      puppeteerPath,
69      JSON.stringify(options),
70    ]);
71    let wsEndPointCallback;
72    const wsEndPointPromise = new Promise<string>(
73      (x) => (wsEndPointCallback = x)
74    );
75    let output = '';
76    res.stdout.on('data', (data) => {
77      output += data;
78      if (output.indexOf('\n'))
79        wsEndPointCallback(output.substring(0, output.indexOf('\n')));
80    });
81    const browser = await puppeteer.connect({
82      browserWSEndpoint: await wsEndPointPromise,
83    });
84    const promises = [
85      new Promise((resolve) => browser.once('disconnected', resolve)),
86      new Promise((resolve) => res.on('close', resolve)),
87    ];
88    if (process.platform === 'win32')
89      execSync(`taskkill /pid ${res.pid} /T /F`);
90    else process.kill(res.pid);
91    await Promise.all(promises);
92  });
93});
94