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 */
16import expect from 'expect';
17import {
18  getTestState,
19  setupTestBrowserHooks,
20  setupTestPageAndContextHooks,
21  describeChromeOnly,
22} from './mocha-utils'; // eslint-disable-line import/extensions
23
24describeChromeOnly('Chromium-Specific Launcher tests', function () {
25  describe('Puppeteer.launch |browserURL| option', function () {
26    it('should be able to connect using browserUrl, with and without trailing slash', async () => {
27      const { defaultBrowserOptions, puppeteer } = getTestState();
28
29      const originalBrowser = await puppeteer.launch(
30        Object.assign({}, defaultBrowserOptions, {
31          args: ['--remote-debugging-port=21222'],
32        })
33      );
34      const browserURL = 'http://127.0.0.1:21222';
35
36      const browser1 = await puppeteer.connect({ browserURL });
37      const page1 = await browser1.newPage();
38      expect(await page1.evaluate(() => 7 * 8)).toBe(56);
39      browser1.disconnect();
40
41      const browser2 = await puppeteer.connect({
42        browserURL: browserURL + '/',
43      });
44      const page2 = await browser2.newPage();
45      expect(await page2.evaluate(() => 8 * 7)).toBe(56);
46      browser2.disconnect();
47      originalBrowser.close();
48    });
49    it('should throw when using both browserWSEndpoint and browserURL', async () => {
50      const { defaultBrowserOptions, puppeteer } = getTestState();
51
52      const originalBrowser = await puppeteer.launch(
53        Object.assign({}, defaultBrowserOptions, {
54          args: ['--remote-debugging-port=21222'],
55        })
56      );
57      const browserURL = 'http://127.0.0.1:21222';
58
59      let error = null;
60      await puppeteer
61        .connect({
62          browserURL,
63          browserWSEndpoint: originalBrowser.wsEndpoint(),
64        })
65        .catch((error_) => (error = error_));
66      expect(error.message).toContain(
67        'Exactly one of browserWSEndpoint, browserURL or transport'
68      );
69
70      originalBrowser.close();
71    });
72    it('should throw when trying to connect to non-existing browser', async () => {
73      const { defaultBrowserOptions, puppeteer } = getTestState();
74
75      const originalBrowser = await puppeteer.launch(
76        Object.assign({}, defaultBrowserOptions, {
77          args: ['--remote-debugging-port=21222'],
78        })
79      );
80      const browserURL = 'http://127.0.0.1:32333';
81
82      let error = null;
83      await puppeteer
84        .connect({ browserURL })
85        .catch((error_) => (error = error_));
86      expect(error.message).toContain(
87        'Failed to fetch browser webSocket URL from'
88      );
89      originalBrowser.close();
90    });
91  });
92
93  describe('Puppeteer.launch |pipe| option', function () {
94    it('should support the pipe option', async () => {
95      const { defaultBrowserOptions, puppeteer } = getTestState();
96      const options = Object.assign({ pipe: true }, defaultBrowserOptions);
97      const browser = await puppeteer.launch(options);
98      expect((await browser.pages()).length).toBe(1);
99      expect(browser.wsEndpoint()).toBe('');
100      const page = await browser.newPage();
101      expect(await page.evaluate('11 * 11')).toBe(121);
102      await page.close();
103      await browser.close();
104    });
105    it('should support the pipe argument', async () => {
106      const { defaultBrowserOptions, puppeteer } = getTestState();
107      const options = Object.assign({}, defaultBrowserOptions);
108      options.args = ['--remote-debugging-pipe'].concat(options.args || []);
109      const browser = await puppeteer.launch(options);
110      expect(browser.wsEndpoint()).toBe('');
111      const page = await browser.newPage();
112      expect(await page.evaluate('11 * 11')).toBe(121);
113      await page.close();
114      await browser.close();
115    });
116    it('should fire "disconnected" when closing with pipe', async () => {
117      const { defaultBrowserOptions, puppeteer } = getTestState();
118      const options = Object.assign({ pipe: true }, defaultBrowserOptions);
119      const browser = await puppeteer.launch(options);
120      const disconnectedEventPromise = new Promise((resolve) =>
121        browser.once('disconnected', resolve)
122      );
123      // Emulate user exiting browser.
124      browser.process().kill();
125      await disconnectedEventPromise;
126    });
127  });
128});
129
130describeChromeOnly('Chromium-Specific Page Tests', function () {
131  setupTestBrowserHooks();
132  setupTestPageAndContextHooks();
133  it('Page.setRequestInterception should work with intervention headers', async () => {
134    const { server, page } = getTestState();
135
136    server.setRoute('/intervention', (req, res) =>
137      res.end(`
138        <script>
139          document.write('<script src="${server.CROSS_PROCESS_PREFIX}/intervention.js">' + '</scr' + 'ipt>');
140        </script>
141      `)
142    );
143    server.setRedirect('/intervention.js', '/redirect.js');
144    let serverRequest = null;
145    server.setRoute('/redirect.js', (req, res) => {
146      serverRequest = req;
147      res.end('console.log(1);');
148    });
149
150    await page.setRequestInterception(true);
151    page.on('request', (request) => request.continue());
152    await page.goto(server.PREFIX + '/intervention');
153    // Check for feature URL substring rather than https://www.chromestatus.com to
154    // make it work with Edgium.
155    expect(serverRequest.headers.intervention).toContain(
156      'feature/5718547946799104'
157    );
158  });
159});
160