diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f15c876f0a3be..a9e7e70bb6852 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -204,8 +204,11 @@ jobs: - name: Install dependencies run: | sudo apt-get install xvfb + # Ensure both a Chromium and a Firefox binary are available. + PUPPETEER_PRODUCT=firefox npm install npm install - ls .local-chromium + ls .local-chromium .local-firefox + - name: Build run: | npm run build diff --git a/src/node/Launcher.ts b/src/node/Launcher.ts index 17301d0e07b7e..6ebe144d0cf6a 100644 --- a/src/node/Launcher.ts +++ b/src/node/Launcher.ts @@ -203,6 +203,7 @@ class ChromeLauncher implements ProductLauncher { defaultArgs(options: BrowserLaunchArgumentOptions = {}): string[] { const chromeArguments = [ + '--allow-pre-commit-input', // TODO(crbug.com/1320996): neither headful nor headless should rely on this flag. '--disable-background-networking', '--enable-features=NetworkService,NetworkServiceInProcess', '--disable-background-timer-throttling', diff --git a/test/launcher.spec.ts b/test/launcher.spec.ts index fe6d67d7192ea..33cb1ff71fbd4 100644 --- a/test/launcher.spec.ts +++ b/test/launcher.spec.ts @@ -548,12 +548,12 @@ describe('Launcher specs', function () { async () => { const { defaultBrowserOptions, puppeteer } = getTestState(); const options = { - args: ['--no-startup-window'], waitForInitialPage: false, // This is needed to prevent Puppeteer from adding an initial blank page. // See also https://github.com/puppeteer/puppeteer/blob/ad6b736039436fcc5c0a262e5b575aa041427be3/src/node/Launcher.ts#L200 ignoreDefaultArgs: true, ...defaultBrowserOptions, + args: ['--no-startup-window'], }; const browser = await puppeteer.launch(options); const pages = await browser.pages(); diff --git a/test/network.spec.ts b/test/network.spec.ts index f776e0589815c..f4d4b5069cfc5 100644 --- a/test/network.spec.ts +++ b/test/network.spec.ts @@ -227,7 +227,10 @@ describe('network', function () { const { page, server } = getTestState(); const responses = new Map(); - page.on('response', (r) => responses.set(r.url().split('/').pop(), r)); + page.on( + 'response', + (r) => !utils.isFavicon(r) && responses.set(r.url().split('/').pop(), r) + ); // Load and re-load to make sure serviceworker is installed and running. await page.goto(server.PREFIX + '/serviceworkers/fetch/sw.html', { @@ -251,7 +254,9 @@ describe('network', function () { await page.goto(server.EMPTY_PAGE); server.setRoute('/post', (req, res) => res.end()); let request = null; - page.on('request', (r) => (request = r)); + page.on('request', (r) => { + if (!utils.isFavicon(r)) request = r; + }); await page.evaluate(() => fetch('./post', { method: 'POST', @@ -652,8 +657,16 @@ describe('network', function () { const { page, server } = getTestState(); server.setAuth('/empty.html', 'user', 'pass'); - let response = await page.goto(server.EMPTY_PAGE); - expect(response.status()).toBe(401); + let response; + try { + response = await page.goto(server.EMPTY_PAGE); + expect(response.status()).toBe(401); + } catch (error) { + // In headful, an error is thrown instead of 401. + if (!error.message.startsWith('net::ERR_INVALID_AUTH_CREDENTIALS')) { + throw error; + } + } await page.authenticate({ username: 'user', password: 'pass', @@ -686,8 +699,15 @@ describe('network', function () { expect(response.status()).toBe(200); await page.authenticate(null); // Navigate to a different origin to bust Chrome's credential caching. - response = await page.goto(server.CROSS_PROCESS_PREFIX + '/empty.html'); - expect(response.status()).toBe(401); + try { + response = await page.goto(server.CROSS_PROCESS_PREFIX + '/empty.html'); + expect(response.status()).toBe(401); + } catch (error) { + // In headful, an error is thrown instead of 401. + if (!error.message.startsWith('net::ERR_INVALID_AUTH_CREDENTIALS')) { + throw error; + } + } }); it('should not disable caching', async () => { const { page, server } = getTestState(); diff --git a/test/proxy.spec.ts b/test/proxy.spec.ts index 34655d27c104d..d26d64e69afe6 100644 --- a/test/proxy.spec.ts +++ b/test/proxy.spec.ts @@ -43,6 +43,9 @@ describeFailsFirefox('request proxy', () => { let proxiedRequestUrls: string[]; let proxyServer: Server; let proxyServerUrl: string; + const defaultArgs = [ + '--disable-features=NetworkTimeServiceQuerying', // We disable this in tests so that proxy-related tests don't intercept queries from this service in headful. + ]; beforeEach(() => { proxiedRequestUrls = []; @@ -100,7 +103,7 @@ describeFailsFirefox('request proxy', () => { browser = await puppeteer.launch({ ...defaultBrowserOptions, - args: [`--proxy-server=${proxyServerUrl}`], + args: [...defaultArgs, `--proxy-server=${proxyServerUrl}`], }); const page = await browser.newPage(); @@ -118,6 +121,7 @@ describeFailsFirefox('request proxy', () => { browser = await puppeteer.launch({ ...defaultBrowserOptions, args: [ + ...defaultArgs, `--proxy-server=${proxyServerUrl}`, `--proxy-bypass-list=${new URL(emptyPageUrl).host}`, ], @@ -138,7 +142,7 @@ describeFailsFirefox('request proxy', () => { browser = await puppeteer.launch({ ...defaultBrowserOptions, - args: [`--proxy-server=${proxyServerUrl}`], + args: [...defaultArgs, `--proxy-server=${proxyServerUrl}`], }); const context = await browser.createIncognitoBrowserContext(); @@ -157,6 +161,7 @@ describeFailsFirefox('request proxy', () => { browser = await puppeteer.launch({ ...defaultBrowserOptions, args: [ + ...defaultArgs, `--proxy-server=${proxyServerUrl}`, `--proxy-bypass-list=${new URL(emptyPageUrl).host}`, ], @@ -180,7 +185,10 @@ describeFailsFirefox('request proxy', () => { const { puppeteer, defaultBrowserOptions, server } = getTestState(); const emptyPageUrl = getEmptyPageUrl(server); - browser = await puppeteer.launch(defaultBrowserOptions); + browser = await puppeteer.launch({ + ...defaultBrowserOptions, + args: defaultArgs, + }); const context = await browser.createIncognitoBrowserContext({ proxyServer: proxyServerUrl, @@ -198,7 +206,10 @@ describeFailsFirefox('request proxy', () => { const { puppeteer, defaultBrowserOptions, server } = getTestState(); const emptyPageUrl = getEmptyPageUrl(server); - browser = await puppeteer.launch(defaultBrowserOptions); + browser = await puppeteer.launch({ + ...defaultBrowserOptions, + args: defaultArgs, + }); const context = await browser.createIncognitoBrowserContext({ proxyServer: proxyServerUrl, diff --git a/test/requestinterception-experimental.spec.ts b/test/requestinterception-experimental.spec.ts index e16a715c0ea52..70f87b3604b57 100644 --- a/test/requestinterception-experimental.spec.ts +++ b/test/requestinterception-experimental.spec.ts @@ -458,7 +458,7 @@ describe('request interception', function () { await page.setRequestInterception(true); const requests = []; page.on('request', (request) => { - requests.push(request); + !utils.isFavicon(request) && requests.push(request); request.continue({}, 0); }); const dataURL = 'data:text/html,
yo
'; diff --git a/test/requestinterception.spec.ts b/test/requestinterception.spec.ts index c0bd5d2010ab2..0602e2f915c94 100644 --- a/test/requestinterception.spec.ts +++ b/test/requestinterception.spec.ts @@ -381,7 +381,7 @@ describe('request interception', function () { await page.setRequestInterception(true); const requests = []; page.on('request', (request) => { - requests.push(request); + !utils.isFavicon(request) && requests.push(request); request.continue(); }); const dataURL = 'data:text/html,
yo
';