UNPKG

@copperjs/copper

Version:
182 lines 9.64 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const sinon = require("sinon"); const path = require("path"); const fs = require("fs-extra"); const mkdirp = require("mkdirp"); const readDir = require("recursive-readdir"); const os = require("os"); const proxyquire = require("proxyquire"); const puppeteer = require("puppeteer-core"); const chai_1 = require("chai"); const errors_1 = require("../common/errors"); const config_1 = require("./config"); const fetchStub = sinon.stub(); const mkdirpStub = sinon.stub(); const chromeLaunch = sinon.stub(); const chromeKill = sinon.stub(); const { SessionManager } = proxyquire.noCallThru()('./sessionManager', { 'node-fetch': { default: fetchStub }, 'chrome-launcher': { launch: chromeLaunch }, mkdirp: mkdirpStub, }); describe('sessionManger', () => { let sessionManager; let tmpdir; beforeEach(async () => { sessionManager = new SessionManager(); tmpdir = path.join(os.tmpdir(), 'unittests'); await mkdirp(tmpdir); fetchStub.resolves({ json: () => ({ webSocketDebuggerUrl: 'webSocketDebuggerUrl' }) }); mkdirpStub.resolves(); chromeLaunch.resolves({ port: 1, pid: 2, kill: chromeKill }); config_1.copperConfig.value.enableW3CProtocol = false; }); afterEach(async () => { sinon.restore(); fetchStub.reset(); mkdirpStub.reset(); chromeLaunch.reset(); chromeKill.reset(); config_1.copperConfig.reset(); await fs.remove(tmpdir); }); describe('parse configuration', () => { it("should parse chromeOptions from desiredCapabilities['goog:chromeOptions']", () => { const opts = {}; chai_1.expect(sessionManager.getChromeOptions({ 'goog:chromeOptions': opts })).to.equal(opts); }); it('should parse chromeOptions from desiredCapabilities.chromeOptions', () => { const opts = {}; chai_1.expect(sessionManager.getChromeOptions({ chromeOptions: opts })).to.equal(opts); }); it('should parse capabilities from desiredCapabilities.capabilities.firstMatch', () => { const caps = {}; chai_1.expect(sessionManager.parseSessionRequest({ capabilities: { firstMatch: [caps] } }).capabilities).to.equal(caps); }); it('should parse capabilities from desiredCapabilities.desiredCapabilities', () => { const caps = {}; chai_1.expect(sessionManager.parseSessionRequest({ desiredCapabilities: caps }).capabilities).to.equal(caps); }); it('should have default desiredCapabilities', () => { chai_1.expect(sessionManager.parseSessionRequest().capabilities).to.eql({ browserName: 'chrome' }); }); }); describe('webdriver specific args', () => { it('should handle chrome profile', async () => { sinon.stub(os, 'tmpdir').returns(tmpdir); await sessionManager.handleChromeProfile(); chai_1.expect(mkdirpStub).to.have.been.calledWith(`${tmpdir}/puppeteer_dev_chrome_profile-`); }); it('should unzip an extension and save it locally', async () => { const EMPTY_ZIP = 'UEsDBBQACAAIAIBT5FIAAAAAAAAAAAEAAAANACAAZW1wdHlmaWxlLnR4dFVUDQAHAGPhYLRm4WCyZuFgdXgLAAEE9QEAAAQUAAAAMwQAUEsHCLfv3IMDAAAAAQAAAFBLAQIUAxQACAAIAIBT5FK379yDAwAAAAEAAAANACAAAAAAAAAAAACkgQAAAABlbXB0eWZpbGUudHh0VVQNAAcAY+FgtGbhYLJm4WB1eAsAAQT1AQAABBQAAABQSwUGAAAAAAEAAQBbAAAAXgAAAAAA'; await sessionManager.saveExtensionLocally(EMPTY_ZIP, tmpdir); const files = await readDir(tmpdir); chai_1.expect(files).to.have.lengthOf(1); chai_1.expect(files[0]).to.contain('emptyfile.txt'); }); it('should cache extensions that are already uploaded', async () => { const EMPTY_ZIP = 'UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA=='; const upload1 = await sessionManager.saveExtensionLocally(EMPTY_ZIP, tmpdir); const upload2 = await sessionManager.saveExtensionLocally(EMPTY_ZIP, tmpdir); chai_1.expect(upload1).to.equal(upload2); }); it('should throw on invalid zip files', async () => { const INVALID_ZIP = 'abcd'; await chai_1.expect(sessionManager.saveExtensionLocally(INVALID_ZIP, '/path/does/not/exist')).to.be .rejected; }); it('should handle multiple extensions', async () => { const EMPTY_ZIP = 'UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA=='; sinon.stub(os, 'tmpdir').returns(tmpdir); await sessionManager.handleExtensions({ chromeOptions: { extensions: [EMPTY_ZIP] } }, 'extensions'); chai_1.expect(mkdirpStub).to.have.been.calledWith(`${tmpdir}/extensions`); }); it('should ignore a session with no extensions passed', async () => { sinon.stub(os, 'tmpdir').returns(tmpdir); await sessionManager.handleExtensions({}, 'extensions'); chai_1.expect(mkdirpStub).to.not.have.been.called; }); }); describe('createSession', () => { it('should create a session', async () => { const session = await sessionManager.createSession(); chai_1.expect(session).to.shallowDeepEqual({ pid: 2, port: 1 }); chai_1.expect(chromeLaunch).to.have.been.calledWith({}); }); it('should accept args from chromeOptions', async () => { await sessionManager.createSession({ chromeOptions: { chromeFlags: ['--foo'] }, }); chai_1.expect(chromeLaunch).to.have.been.calledWith({ chromeFlags: ['--foo'] }); }); it('should accept args from desiredCapabilities', async () => { await sessionManager.createSession({ desiredCapabilities: { chromeOptions: { args: ['--foo'] }, browserName: 'chrome' }, }); chai_1.expect(chromeLaunch).to.have.been.calledWith({ chromeFlags: ['--foo'], ignoreDefaultFlags: true }); }); it('should throw error when failed to create a browser', async () => { chromeLaunch.rejects(); await chai_1.expect(sessionManager.createSession()).to.be.rejectedWith(errors_1.CreateSessionError); }); it('should create a puppeteer instance when enableW3CProtocol is enabled', async () => { config_1.copperConfig.value.enableW3CProtocol = true; const stub = sinon.stub(puppeteer, 'connect').resolves({ pages: () => Promise.resolve([]) }); const session = await sessionManager.createSession(); chai_1.expect(session).to.shallowDeepEqual({ pid: 2, port: 1 }); chai_1.expect(stub).to.have.been.calledWith({ browserWSEndpoint: 'webSocketDebuggerUrl' }); }); }); describe('removeSession', () => { it('should remove a session', async () => { const session = await sessionManager.createSession(); await sessionManager.removeSession(session.id); chai_1.expect(chromeKill).to.have.been.called; }); it('should catch when failed to remove a session', async () => { chromeKill.rejects(); const session = await sessionManager.createSession(); await chai_1.expect(sessionManager.removeSession(session.id)).not.to.be.rejected; }); it('should disconnect puppeteer instance when exists', async () => { config_1.copperConfig.value.enableW3CProtocol = true; const stub = sinon.stub().resolves(); sinon.stub(puppeteer, 'connect').resolves({ pages: () => Promise.resolve([]), disconnect: stub }); const session = await sessionManager.createSession(); await sessionManager.removeSession(session.id); chai_1.expect(stub).to.have.been.called; }); }); it('should return session websocket url', async () => { const session = await sessionManager.createSession(); chai_1.expect(sessionManager.getWebSocketUrl(session.id)).to.equal('webSocketDebuggerUrl'); }); it('should return session puppeteer instance', async () => { config_1.copperConfig.value.enableW3CProtocol = true; const pages = [{}]; const puppeteerInstance = { pages: () => Promise.resolve(pages) }; sinon.stub(puppeteer, 'connect').resolves(puppeteerInstance); const session = await sessionManager.createSession(); chai_1.expect(sessionManager.getPuppeteer(session.id)).to.eql({ browser: puppeteerInstance, page: pages[0] }); }); it('should not have a puppeteer instance when enableW3CProtocol is disabled', async () => { config_1.copperConfig.value.enableW3CProtocol = false; const session = await sessionManager.createSession(); chai_1.expect(sessionManager.getPuppeteer(session.id)).to.be.undefined; }); it('should get a session by id', async () => { const session = await sessionManager.createSession(); chai_1.expect(sessionManager.getSession(session.id)).to.eql(session); }); it('should throw when no matching session', () => { chai_1.expect(() => sessionManager.getSession('foo')).to.throw(errors_1.SessionNotFound); }); it('should list all sessions', async () => { const session = await sessionManager.createSession(); const sessions = await sessionManager.listSessions(); chai_1.expect(sessions).to.have.lengthOf(1); chai_1.expect(sessions[0]).to.shallowDeepEqual(session); }); }); //# sourceMappingURL=sessionManager.test.js.map