UNPKG

@revoloo/cypress6

Version:

Cypress.io end to end testing tool

188 lines (142 loc) 5.54 kB
import '../../spec_helper' import _ from 'lodash' import Bluebird from 'bluebird' import 'chai-as-promised' // for the types! import chalk from 'chalk' import { connect } from '@packages/network' import CRI from 'chrome-remote-interface' import { expect } from 'chai' import humanInterval from 'human-interval' import * as protocol from '../../../lib/browsers/protocol' import sinon from 'sinon' import snapshot from 'snap-shot-it' import stripAnsi from 'strip-ansi' import { stripIndents } from 'common-tags' describe('lib/browsers/protocol', () => { // protocol connects explicitly to this host const host = '127.0.0.1' context('._getDelayMsForRetry', () => { it('retries as expected for up to 50 seconds', () => { const log = sinon.spy(console, 'log') let delays = [] let delay: number let i = 0 while ((delay = protocol._getDelayMsForRetry(i))) { delays.push(delay) i++ } expect(_.sum(delays)).to.eq(humanInterval('50 seconds')) log.getCalls().forEach((log, i) => { const line = stripAnsi(log.args[0]) expect(line).to.include(`Failed to connect to Chrome, retrying in 1 second (attempt ${i + 18}/62)`) }) snapshot(delays) }) }) context('.getWsTargetFor', () => { const expectedCdpFailedError = stripIndents` Cypress failed to make a connection to the Chrome DevTools Protocol after retrying for 50 seconds. This usually indicates there was a problem opening the Chrome browser. The CDP port requested was ${chalk.yellow('12345')}. Error details: ` it('rejects if CDP connection fails', () => { const innerErr = new Error('cdp connection failure') sinon.stub(connect, 'createRetryingSocket').callsArgWith(1, innerErr) const p = protocol.getWsTargetFor(12345) return expect(p).to.eventually.be.rejected .and.property('message').include(expectedCdpFailedError) .and.include(innerErr.message) }) it('rejects if CRI.List fails', () => { const innerErr = new Error('cdp connection failure') sinon.stub(Bluebird, 'delay').resolves() sinon.stub(CRI, 'List') .withArgs({ host, port: 12345, getDelayMsForRetry: sinon.match.func }) .rejects(innerErr) const end = sinon.stub() sinon.stub(connect, 'createRetryingSocket').callsArgWith(1, null, { end }) const p = protocol.getWsTargetFor(12345) return expect(p).to.eventually.be.rejected .and.property('message').include(expectedCdpFailedError) .and.include(innerErr.message) }) it('returns the debugger URL of the first about:blank tab', async () => { const targets = [ { type: 'page', url: 'chrome://newtab', webSocketDebuggerUrl: 'foo', }, { type: 'page', url: 'about:blank', webSocketDebuggerUrl: 'bar', }, ] const end = sinon.stub() sinon.stub(CRI, 'List') .withArgs({ host, port: 12345, getDelayMsForRetry: sinon.match.func }) .resolves(targets) sinon.stub(connect, 'createRetryingSocket').callsArgWith(1, null, { end }) const p = protocol.getWsTargetFor(12345) await expect(p).to.eventually.equal('bar') expect(end).to.be.calledOnce }) }) context('CRI.List', () => { const port = 1234 const targets = [ { type: 'page', url: 'chrome://newtab', webSocketDebuggerUrl: 'foo', }, { type: 'page', url: 'about:blank', webSocketDebuggerUrl: 'ws://debug-url', }, ] it('retries several times if starting page cannot be found', async () => { const end = sinon.stub() sinon.stub(connect, 'createRetryingSocket').callsArgWith(1, null, { end }) const criList = sinon.stub(CRI, 'List') .withArgs({ host, port, getDelayMsForRetry: sinon.match.func }).resolves(targets) .onFirstCall().resolves([]) .onSecondCall().resolves([]) .onThirdCall().resolves(targets) const targetUrl = await protocol.getWsTargetFor(port) expect(criList).to.have.been.calledThrice expect(targetUrl).to.equal('ws://debug-url') }) it('logs correctly if retries occur while connecting to CDP and while listing CRI targets', async () => { const log = sinon.spy(console, 'log') const end = sinon.stub() // fail 20 times to get 2 log lines from connect failures sinon.stub(connect, 'createRetryingSocket').callsFake((opts, cb) => { _.times(20, (i) => { opts.getDelayMsForRetry(i, new Error) }) // @ts-ignore return cb(null, { end }) }) sinon.stub(Bluebird, 'delay').resolves() // fail an additional 2 times on CRI.List const criList = sinon.stub(CRI, 'List') .withArgs({ host, port, getDelayMsForRetry: sinon.match.func }).resolves(targets) .onFirstCall().resolves([]) .onSecondCall().resolves([]) .onThirdCall().resolves(targets) const targetUrl = await protocol.getWsTargetFor(port) expect(criList).to.have.been.calledThrice expect(targetUrl).to.equal('ws://debug-url') // 2 from connect failing, 2 from CRI.List failing expect(log).to.have.callCount(4) log.getCalls().forEach((log, i) => { const line = stripAnsi(log.args[0]) expect(line).to.include(`Failed to connect to Chrome, retrying in 1 second (attempt ${i + 18}/62)`) }) }) }) })