feat(deps): electron@9.0.5 (#7791)

* chore(deps): electron@9.0.5

BREAKING CHANGE: libgbm is a requirement

* update node, xcode, docker images

* lockfile

* chore(types): tsify lib/gui/windows and spec

* fix Electron extension loading

global extension loading was deprecated in 9, now has to be per-session

* make windows fns stubbable

* update electron_spec

* tsify issue_173_spec

* use upstream foxdriver to fix FF >= 75

see https://github.com/benmalka/foxdriver/issues/7

* update test

* for now, install libgbm-dev at ci time

see https://github.com/cypress-io/cypress-docker-images/pull/332

* fix open mode

* remove devtools-ext dir
This commit is contained in:
Zach Bloomquist
2020-06-29 14:29:51 -04:00
committed by GitHub
parent 8c998f105d
commit ffcb036b40
23 changed files with 419 additions and 452 deletions

View File

@@ -1 +1 @@
12.8.1
12.14.1

View File

@@ -7,7 +7,7 @@ branches:
# https://www.appveyor.com/docs/lang/nodejs-iojs/
environment:
# use matching version of Node.js
nodejs_version: "12.8.1"
nodejs_version: "12.14.1"
# encode secure variables which will NOT be used
# in pull requests
# https://www.appveyor.com/docs/build-configuration/#secure-variables

View File

@@ -43,14 +43,14 @@ executors:
# the Docker image with Cypress dependencies and Chrome browser
cy-doc:
docker:
- image: cypress/browsers:node12.13.0-chrome80-ff74
- image: cypress/browsers:node12.14.1-chrome83-ff77
environment:
PLATFORM: linux
# Docker image with non-root "node" user
non-root-docker-user:
docker:
- image: cypress/browsers:node12.13.0-chrome80-ff74
- image: cypress/browsers:node12.14.1-chrome83-ff77
user: node
environment:
PLATFORM: linux
@@ -60,8 +60,8 @@ executors:
# https://circleci.com/docs/2.0/testing-ios/#supported-xcode-versions
mac:
macos:
## Node 12.10.0 (yarn 1.17.3)
xcode: "11.0.0"
## Node 12.12.0 (yarn 1.19.1)
xcode: "11.2.1"
environment:
PLATFORM: mac
@@ -1144,6 +1144,9 @@ jobs:
- run: mkdir test-binary
- run: node --version
- run: npm --version
# TODO: this can be removed as soon as the minimum Node version is bumped to 10
# see https://github.com/cypress-io/cypress-docker-images/pull/332
- run: apt-get update && apt-get install -y libgbm-dev
- run:
name: Create new NPM package
working_directory: test-binary

View File

@@ -187,7 +187,7 @@
"typescript": "3.7.4"
},
"engines": {
"node": ">=12.8.1",
"node": ">=12.14.1",
"yarn": ">=1.17.3"
},
"productName": "Cypress",

View File

@@ -24,7 +24,7 @@
"minimist": "1.2.5"
},
"devDependencies": {
"electron": "8.3.1",
"electron": "9.0.5",
"mocha": "3.5.3"
},
"files": [

View File

@@ -66,12 +66,12 @@ const _getAutomation = function (win, options) {
return automation
}
const _installExtensions = function (extensionPaths = [], options) {
Windows.removeAllExtensions()
const _installExtensions = function (win, extensionPaths = [], options) {
Windows.removeAllExtensions(win)
return extensionPaths.forEach((path) => {
return Bluebird.map(extensionPaths, (path) => {
try {
return Windows.installExtension(path)
return Windows.installExtension(win, path)
} catch (error) {
return options.onWarning(errors.get('EXTENSION_NOT_LOADED', 'Electron', path))
}
@@ -349,10 +349,10 @@ module.exports = {
debug('launching browser window to url: %s', url)
_installExtensions(launchOptions.extensions, options)
return this._render(url, projectRoot, automation, preferences)
.then((win) => {
.then(async (win) => {
await _installExtensions(win, launchOptions.extensions, options)
// cause the webview to receive focus so that
// native browser focus + blur events fire correctly
// https://github.com/cypress-io/cypress/issues/1939
@@ -363,7 +363,7 @@ module.exports = {
win.once('closed', () => {
debug('closed event fired')
Windows.removeAllExtensions()
Windows.removeAllExtensions(win)
return events.emit('exit')
})

View File

@@ -4,7 +4,7 @@ import _ from 'lodash'
import Marionette from 'marionette-client'
import { Command } from 'marionette-client/lib/marionette/message.js'
import util from 'util'
import Foxdriver from '@benmalka/foxdriver'
import Foxdriver from 'foxdriver'
import * as protocol from './protocol'
const errors = require('../errors')

View File

@@ -36,6 +36,11 @@ const nullifyUnserializableValues = (obj) => {
const handleEvent = function (options, bus, event, id, type, arg) {
debug('got request for event: %s, %o', type, arg)
_.defaults(options, {
windowOpenFn: Windows.open,
getWindowByWebContentsFn: Windows.getByWebContents,
})
const sendResponse = function (originalData = {}) {
try {
const data = nullifyUnserializableValues(originalData)
@@ -161,12 +166,12 @@ const handleEvent = function (options, bus, event, id, type, arg) {
.catch(sendErr)
case 'window:open':
return Windows.open(options.projectRoot, arg)
return options.windowOpenFn(options.projectRoot, arg)
.then(send)
.catch(sendErr)
case 'window:close':
return Windows.getByWebContents(event.sender).destroy()
return options.getWindowByWebContentsFn(event.sender).destroy()
case 'open:file':
return fileOpener.openFile(arg)

View File

@@ -1,327 +0,0 @@
const _ = require('lodash')
const Promise = require('bluebird')
const cyDesktop = require('@packages/desktop-gui')
const contextMenu = require('electron-context-menu')
const { BrowserWindow } = require('electron')
const debug = require('debug')('cypress:server:windows')
const cwd = require('../cwd')
const savedState = require('../saved_state')
let windows = {}
let recentlyCreatedWindow = false
const getUrl = function (type) {
switch (type) {
case 'INDEX':
return cyDesktop.getPathToIndex()
default:
throw new Error(`No acceptable window type found for: '${type}'`)
}
}
const getByType = (type) => {
return windows[type]
}
const setWindowProxy = function (win) {
if (!process.env.HTTP_PROXY) {
return
}
return win.webContents.session.setProxy({
proxyRules: process.env.HTTP_PROXY,
proxyBypassRules: process.env.NO_PROXY,
})
}
module.exports = {
installExtension (path) {
// extensions can only be installed for all BrowserWindows
const name = BrowserWindow.addExtension(path)
debug('electron extension installed %o', { success: !!name, name, path })
if (!name) {
throw new Error('Extension could not be installed.')
}
},
removeAllExtensions () {
const extensions = _.keys(BrowserWindow.getExtensions())
debug('removing all electron extensions %o', extensions)
return extensions.forEach(BrowserWindow.removeExtension)
},
reset () {
windows = {}
},
destroy (type) {
let win
if (type && (win = getByType(type))) {
return win.destroy()
}
},
get (type) {
return getByType(type) || (() => {
throw new Error(`No window exists for: '${type}'`)
})()
},
showAll () {
return _.invoke(windows, 'showInactive')
},
hideAllUnlessAnotherWindowIsFocused () {
// bail if we have another focused window
// or we are in the middle of creating a new one
if (BrowserWindow.getFocusedWindow() || recentlyCreatedWindow) {
return
}
// else hide all windows
return _.invoke(windows, 'hide')
},
focusMainWindow () {
return getByType('INDEX').show()
},
getByWebContents (webContents) {
return BrowserWindow.fromWebContents(webContents)
},
_newBrowserWindow (options) {
return new BrowserWindow(options)
},
defaults (options = {}) {
return _.defaultsDeep(options, {
x: null,
y: null,
show: true,
frame: true,
width: null,
height: null,
minWidth: null,
minHeight: null,
devTools: false,
trackState: false,
contextMenu: false,
recordFrameRate: null,
// extension: null ## TODO add these once we update electron
// devToolsExtension: null ## since these API's were added in 1.7.6
onFocus () {},
onBlur () {},
onClose () {},
onCrashed () {},
onNewWindow () {},
webPreferences: {
partition: null,
webSecurity: true,
nodeIntegration: false,
backgroundThrottling: false,
},
})
},
create (projectRoot, options = {}) {
let ts
options = this.defaults(options)
if (options.show === false) {
options.frame = false
options.webPreferences.offscreen = true
}
options.webPreferences.webSecurity = !!options.chromeWebSecurity
if (options.partition) {
options.webPreferences.partition = options.partition
}
const win = this._newBrowserWindow(options)
win.on('blur', function (...args) {
return options.onBlur.apply(win, args)
})
win.on('focus', function (...args) {
return options.onFocus.apply(win, args)
})
win.once('closed', function (...args) {
win.removeAllListeners()
return options.onClose.apply(win, args)
})
// the webview loses focus on navigation, so we
// have to refocus it everytime top navigates in headless mode
// https://github.com/cypress-io/cypress/issues/2190
if (options.show === false) {
win.webContents.on('did-start-loading', () => {
if (!win.isDestroyed()) {
return win.focusOnWebView()
}
})
}
win.webContents.on('crashed', function (...args) {
return options.onCrashed.apply(win, args)
})
win.webContents.on('new-window', function (...args) {
return options.onNewWindow.apply(win, args)
})
ts = options.trackState
if (ts) {
this.trackState(projectRoot, options.isTextTerminal, win, ts)
}
// open dev tools if they're true
if (options.devTools) {
// and possibly detach dev tools if true
win.webContents.openDevTools()
}
if (options.contextMenu) {
// adds context menu with copy, paste, inspect element, etc
contextMenu({
showInspectElement: true,
window: win,
})
}
return win
},
open (projectRoot, options = {}) {
// if we already have a window open based
// on that type then just show + focus it!
let win
win = getByType(options.type)
if (win) {
win.show()
return Promise.resolve(win)
}
recentlyCreatedWindow = true
_.defaults(options, {
width: 600,
height: 500,
show: true,
webPreferences: {
preload: cwd('lib', 'ipc', 'ipc.js'),
},
})
if (!options.url) {
options.url = getUrl(options.type)
}
win = this.create(projectRoot, options)
debug('creating electron window with options %o', options)
windows[options.type] = win
win.webContents.id = _.uniqueId('webContents')
win.once('closed', () => {
delete windows[options.type]
})
// enable our url to be a promise
// and wait for this to be resolved
return Promise.join(
options.url,
setWindowProxy(win),
)
.spread((url) => {
// navigate the window here!
win.loadURL(url)
recentlyCreatedWindow = false
}).thenReturn(win)
},
trackState (projectRoot, isTextTerminal, win, keys) {
const isDestroyed = () => {
return win.isDestroyed()
}
win.on('resize', _.debounce(() => {
if (isDestroyed()) {
return
}
const [width, height] = win.getSize()
const [x, y] = win.getPosition()
const newState = {}
newState[keys.width] = width
newState[keys.height] = height
newState[keys.x] = x
newState[keys.y] = y
return savedState.create(projectRoot, isTextTerminal)
.then((state) => {
return state.set(newState)
})
}
, 500))
win.on('moved', _.debounce(() => {
if (isDestroyed()) {
return
}
const [x, y] = win.getPosition()
const newState = {}
newState[keys.x] = x
newState[keys.y] = y
return savedState.create(projectRoot, isTextTerminal)
.then((state) => {
return state.set(newState)
})
}
, 500))
win.webContents.on('devtools-opened', () => {
const newState = {}
newState[keys.devTools] = true
return savedState.create(projectRoot, isTextTerminal)
.then((state) => {
return state.set(newState)
})
})
return win.webContents.on('devtools-closed', () => {
const newState = {}
newState[keys.devTools] = false
return savedState.create(projectRoot, isTextTerminal)
.then((state) => {
return state.set(newState)
})
})
},
}

View File

@@ -0,0 +1,332 @@
import _ from 'lodash'
import Bluebird from 'bluebird'
import contextMenu from 'electron-context-menu'
import { BrowserWindow } from 'electron'
import Debug from 'debug'
import cwd from '../cwd'
import savedState from '../saved_state'
const cyDesktop = require('@packages/desktop-gui')
const debug = Debug('cypress:server:windows')
export type WindowOptions = Electron.BrowserWindowConstructorOptions & {
type?: 'INDEX'
url?: string
devTools?: boolean
}
let windows = {}
let recentlyCreatedWindow = false
const getUrl = function (type) {
switch (type) {
case 'INDEX':
return cyDesktop.getPathToIndex()
default:
throw new Error(`No acceptable window type found for: '${type}'`)
}
}
const getByType = (type) => {
return windows[type]
}
const setWindowProxy = function (win) {
if (!process.env.HTTP_PROXY) {
return
}
return win.webContents.session.setProxy({
proxyRules: process.env.HTTP_PROXY,
proxyBypassRules: process.env.NO_PROXY,
})
}
export function installExtension (win: BrowserWindow, path) {
return win.webContents.session.loadExtension(path)
.then((data) => {
debug('electron extension installed %o', { data, path })
})
.catch((err) => {
debug('error installing electron extension %o', { err, path })
throw err
})
}
export function removeAllExtensions (win: BrowserWindow) {
let extensions
try {
extensions = win.webContents.session.getAllExtensions()
extensions.forEach(({ id }) => {
win.webContents.session.removeExtension(id)
})
} catch (err) {
debug('error removing all extensions %o', { err, extensions })
}
}
export function reset () {
windows = {}
}
export function destroy (type) {
let win
if (type && (win = getByType(type))) {
return win.destroy()
}
}
export function get (type) {
return getByType(type) || (() => {
throw new Error(`No window exists for: '${type}'`)
})()
}
export function showAll () {
return _.invoke(windows, 'showInactive')
}
export function hideAllUnlessAnotherWindowIsFocused () {
// bail if we have another focused window
// or we are in the middle of creating a new one
if (BrowserWindow.getFocusedWindow() || recentlyCreatedWindow) {
return
}
// else hide all windows
return _.invoke(windows, 'hide')
}
export function focusMainWindow () {
return getByType('INDEX').show()
}
export function getByWebContents (webContents) {
return BrowserWindow.fromWebContents(webContents)
}
export function _newBrowserWindow (options) {
return new BrowserWindow(options)
}
export function defaults (options = {}) {
return _.defaultsDeep(options, {
x: null,
y: null,
show: true,
frame: true,
width: null,
height: null,
minWidth: null,
minHeight: null,
devTools: false,
trackState: false,
contextMenu: false,
recordFrameRate: null,
onFocus () {},
onBlur () {},
onClose () {},
onCrashed () {},
onNewWindow () {},
webPreferences: {
partition: null,
webSecurity: true,
nodeIntegration: false,
backgroundThrottling: false,
},
})
}
export function create (projectRoot, _options: WindowOptions = {}, newBrowserWindow = _newBrowserWindow) {
const options = defaults(_options)
if (options.show === false) {
options.frame = false
options.webPreferences.offscreen = true
}
options.webPreferences.webSecurity = !!options.chromeWebSecurity
if (options.partition) {
options.webPreferences.partition = options.partition
}
const win = newBrowserWindow(options)
win.on('blur', function (...args) {
return options.onBlur.apply(win, args)
})
win.on('focus', function (...args) {
return options.onFocus.apply(win, args)
})
win.once('closed', function (...args) {
win.removeAllListeners()
return options.onClose.apply(win, args)
})
// the webview loses focus on navigation, so we
// have to refocus it everytime top navigates in headless mode
// https://github.com/cypress-io/cypress/issues/2190
if (options.show === false) {
win.webContents.on('did-start-loading', () => {
if (!win.isDestroyed()) {
return win.focusOnWebView()
}
})
}
win.webContents.on('crashed', function (...args) {
return options.onCrashed.apply(win, args)
})
win.webContents.on('new-window', function (...args) {
return options.onNewWindow.apply(win, args)
})
if (options.trackState) {
trackState(projectRoot, options.isTextTerminal, win, options.trackState)
}
// open dev tools if they're true
if (options.devTools) {
// and possibly detach dev tools if true
win.webContents.openDevTools()
}
if (options.contextMenu) {
// adds context menu with copy, paste, inspect element, etc
contextMenu({
showInspectElement: true,
window: win,
})
}
return win
}
export function open (projectRoot, options: WindowOptions = {}, newBrowserWindow = _newBrowserWindow) {
// if we already have a window open based
// on that type then just show + focus it!
let win
win = getByType(options.type)
if (win) {
win.show()
return Bluebird.resolve(win)
}
recentlyCreatedWindow = true
_.defaults(options, {
width: 600,
height: 500,
show: true,
webPreferences: {
preload: cwd('lib', 'ipc', 'ipc.js'),
},
})
if (!options.url) {
options.url = getUrl(options.type)
}
win = create(projectRoot, options, newBrowserWindow)
debug('creating electron window with options %o', options)
if (options.type) {
windows[options.type] = win
win.once('closed', () => {
delete windows[options.type!]
})
}
// enable our url to be a promise
// and wait for this to be resolved
return Bluebird.join(
options.url,
setWindowProxy(win),
)
.spread((url) => {
// navigate the window here!
win.loadURL(url)
recentlyCreatedWindow = false
}).thenReturn(win)
}
export function trackState (projectRoot, isTextTerminal, win, keys) {
const isDestroyed = () => {
return win.isDestroyed()
}
win.on('resize', _.debounce(() => {
if (isDestroyed()) {
return
}
const [width, height] = win.getSize()
const [x, y] = win.getPosition()
const newState = {}
newState[keys.width] = width
newState[keys.height] = height
newState[keys.x] = x
newState[keys.y] = y
return savedState.create(projectRoot, isTextTerminal)
.then((state) => {
return state.set(newState)
})
}
, 500))
win.on('moved', _.debounce(() => {
if (isDestroyed()) {
return
}
const [x, y] = win.getPosition()
const newState = {}
newState[keys.x] = x
newState[keys.y] = y
return savedState.create(projectRoot, isTextTerminal)
.then((state) => {
return state.set(newState)
})
}
, 500))
win.webContents.on('devtools-opened', () => {
const newState = {}
newState[keys.devTools] = true
return savedState.create(projectRoot, isTextTerminal)
.then((state) => {
return state.set(newState)
})
})
return win.webContents.on('devtools-closed', () => {
const newState = {}
newState[keys.devTools] = false
return savedState.create(projectRoot, isTextTerminal)
.then((state) => {
return state.set(newState)
})
})
}

View File

@@ -20,7 +20,6 @@
"test-watch": "./test/support/watch test"
},
"dependencies": {
"@benmalka/foxdriver": "0.4.0",
"@cypress/browserify-preprocessor": "2.2.4",
"@cypress/commit-info": "2.2.0",
"@cypress/get-windows-proxy": "1.6.1",
@@ -59,6 +58,7 @@
"firefox-profile": "1.3.1",
"fix-path": "2.1.0",
"fluent-ffmpeg": "2.1.2",
"foxdriver": "0.1.1",
"fs-extra": "8.1.0",
"get-port": "5.1.1",
"getos": "3.2.1",

View File

@@ -1,4 +1,4 @@
const e2e = require('../support/helpers/e2e').default
import e2e from '../support/helpers/e2e'
describe('e2e issue 173', () => {
e2e.setup()

View File

@@ -1,11 +1,5 @@
context('before:browser:launch extension e2e', () => {
it('has the expected extension', () => {
if (Cypress.browser.name === 'electron') {
cy.wrap(window.top).its('theExtensionLoaded').should('be.true')
return
}
cy.visit('/index.html')
.get('#extension')
.should('contain', 'inserted from extension!')

View File

@@ -2,16 +2,7 @@ const path = require('path')
module.exports = (on) => {
on('before:browser:launch', (browser, options) => {
const { extensions } = options
if (browser.name === 'electron') {
// electron doesn't support background pages yet, so load a devtools extension
// instead which will work
extensions.push(path.join(__dirname, '../../devtools-ext'))
} else {
extensions.push(path.join(__dirname, '../../../plugin-extension/ext'))
}
options.extensions.push(path.join(__dirname, '../../../plugin-extension/ext'))
options.preferences.devTools = true
return options

View File

@@ -1,15 +0,0 @@
<script>
function addProperty () {
chrome.devtools.inspectedWindow.onResourceAdded.addListener(() => {
chrome.devtools.inspectedWindow.eval('window.theExtensionLoaded = true')
})
}
// sometimes chrome.devtools is undefined, most likely bug in chromium :|
// this was causing flake in our e2e tests
if (chrome.devtools) {
addProperty()
} else {
setTimeout(addProperty, 1000)
}
</script>

View File

@@ -1,13 +0,0 @@
{
"name": "e2e devtools ext",
"version": "0",
"description": "tests adding devtools extension into Cypress",
"permissions": [
"tabs",
"webNavigation",
"<all_urls>"
],
"content_scripts": [],
"devtools_page": "devtools.html",
"manifest_version": 2
}

View File

@@ -135,15 +135,15 @@ describe('lib/browsers/electron', () => {
plugins.has.returns(true)
plugins.execute.resolves({ extensions: ['foo', 'bar'] })
Windows.installExtension.withArgs('bar').throws()
Windows.installExtension.withArgs(sinon.match.any, 'bar').throws()
return electron.open('electron', this.url, this.options, this.automation)
.then(() => {
expect(Windows.removeAllExtensions).to.be.calledOnce
expect(Windows.installExtension).to.be.calledTwice
expect(Windows.installExtension).to.be.calledWith('foo')
expect(Windows.installExtension).to.be.calledWith('bar')
expect(Windows.installExtension).to.be.calledWith(sinon.match.any, 'foo')
expect(Windows.installExtension).to.be.calledWith(sinon.match.any, 'bar')
expect(this.options.onWarning).to.be.calledOnce

View File

@@ -7,7 +7,7 @@ import firefoxUtil from '../../../lib/browsers/firefox-util'
import * as firefox from '../../../lib/browsers/firefox'
import { EventEmitter } from 'events'
import Marionette from 'marionette-client'
import Foxdriver from '@benmalka/foxdriver'
import Foxdriver from 'foxdriver'
const mockfs = require('mock-fs')
const FirefoxProfile = require('firefox-profile')
const utils = require('../../../lib/browsers/utils')

View File

@@ -17,9 +17,8 @@ const openProject = require(`${root}../lib/open_project`)
const open = require(`${root}../lib/util/open`)
const auth = require(`${root}../lib/gui/auth`)
const logs = require(`${root}../lib/gui/logs`)
const events = require(`${root}../lib/gui/events`)
const events = require(`../../../lib/gui/events`)
const dialog = require(`${root}../lib/gui/dialog`)
const Windows = require(`${root}../lib/gui/windows`)
const ensureUrl = require(`${root}../lib/util/ensure-url`)
const konfig = require(`${root}../lib/konfig`)
@@ -206,11 +205,11 @@ describe('lib/gui/events', () => {
loadURL () {},
webContents: {},
})
return sinon.stub(Windows, 'create').withArgs(this.options.projectRoot).returns(this.win)
})
it('calls Windows#open with args and resolves with return of Windows.open', function () {
it('calls windowOpenFn with args and resolves with return', function () {
this.options.windowOpenFn = sinon.stub().rejects().withArgs({ type: 'INDEX ' }).resolves(this.win)
return this.handleEvent('window:open', { type: 'INDEX' })
.then((assert) => {
return assert.sendCalledWith(events.nullifyUnserializableValues(this.win))
@@ -220,7 +219,7 @@ describe('lib/gui/events', () => {
it('catches errors', function () {
const err = new Error('foo')
sinon.stub(Windows, 'open').withArgs(this.options.projectRoot, { foo: 'bar' }).rejects(err)
this.options.windowOpenFn = sinon.stub().withArgs(this.options.projectRoot, { foo: 'bar' }).rejects(err)
return this.handleEvent('window:open', { foo: 'bar' }).then((assert) => {
return assert.sendErrCalledWith(err)
@@ -230,11 +229,14 @@ describe('lib/gui/events', () => {
describe('window:close', () => {
it('calls destroy on Windows#getByWebContents', function () {
this.destroy = sinon.stub()
sinon.stub(Windows, 'getByWebContents').withArgs(this.event.sender).returns({ destroy: this.destroy })
const win = {
destroy: sinon.stub(),
}
this.options.getWindowByWebContentsFn = sinon.stub().withArgs(this.event.sender).returns(win)
this.handleEvent('window:close')
expect(this.destroy).to.be.calledOnce
expect(win.destroy).to.be.calledOnce
})
})
})

View File

@@ -1,13 +1,17 @@
require('../../spec_helper')
import '../../spec_helper'
import { expect } from 'chai'
import 'sinon-chai'
import _ from 'lodash'
import path from 'path'
import Promise from 'bluebird'
import { EventEmitter } from 'events'
import { BrowserWindow } from 'electron'
import * as Windows from '../../../lib/gui/windows'
import savedState from '../../../lib/saved_state'
const _ = require('lodash')
const path = require('path')
const Promise = require('bluebird')
const EE = require('events').EventEmitter
const { BrowserWindow } = require('electron')
const cyDesktop = require('@packages/desktop-gui')
const Windows = require(`${root}../lib/gui/windows`)
const savedState = require(`${root}../lib/saved_state`)
const DEFAULT_USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/0.0.0 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36'
@@ -15,17 +19,15 @@ describe('lib/gui/windows', () => {
beforeEach(function () {
Windows.reset()
this.win = new EE()
this.win = new EventEmitter()
this.win.loadURL = sinon.stub()
this.win.destroy = sinon.stub()
this.win.getSize = sinon.stub().returns([1, 2])
this.win.getPosition = sinon.stub().returns([3, 4])
this.win.webContents = new EE()
this.win.webContents = new EventEmitter()
this.win.webContents.openDevTools = sinon.stub()
this.win.webContents.userAgent = DEFAULT_USER_AGENT
this.win.isDestroyed = sinon.stub().returns(false)
return sinon.stub(Windows, '_newBrowserWindow').returns(this.win)
})
afterEach(() => {
@@ -33,38 +35,31 @@ describe('lib/gui/windows', () => {
})
context('.getByWebContents', () => {
beforeEach(() => {
return sinon.stub(BrowserWindow, 'fromWebContents')
})
it('calls BrowserWindow.fromWebContents', () => {
BrowserWindow.fromWebContents.withArgs('foo').returns('bar')
sinon.stub(BrowserWindow, 'fromWebContents').withArgs('foo' as any).returns('bar' as any)
expect(Windows.getByWebContents('foo')).to.eq('bar')
})
})
context('.open', () => {
beforeEach(function () {
return sinon.stub(Windows, 'create').returns(this.win)
})
it('sets default options', () => {
const options = {
it('sets default options', function () {
const options: Windows.WindowOptions = {
type: 'INDEX',
}
return Windows.open('/path/to/project', options)
return Windows.open('/path/to/project', options, () => this.win)
.then((win) => {
expect(options).to.deep.eq({
expect(options).to.include({
height: 500,
width: 600,
type: 'INDEX',
show: true,
url: cyDesktop.getPathToIndex(),
webPreferences: {
preload: path.resolve('lib', 'ipc', 'ipc.js'),
},
})
expect(options.webPreferences).to.include({
preload: path.resolve('lib', 'ipc', 'ipc.js'),
})
expect(win.loadURL).to.be.calledWith(cyDesktop.getPathToIndex())
@@ -74,10 +69,10 @@ describe('lib/gui/windows', () => {
context('.create', () => {
it('opens dev tools if saved state is open', function () {
Windows.create('/foo/', { devTools: true })
Windows.create('/foo/', { devTools: true }, () => this.win)
expect(this.win.webContents.openDevTools).to.be.called
Windows.create('/foo/', {})
Windows.create('/foo/', {}, () => this.win)
expect(this.win.webContents.openDevTools).not.to.be.calledTwice
})

View File

@@ -3,7 +3,7 @@ set e+x
echo "This script should be run from cypress's root"
name=cypress/browsers:node12.13.0-chrome80-ff74
name=cypress/browsers:node12.14.1-chrome83-ff77
echo "Pulling CI container $name"
docker pull $name

View File

@@ -1427,18 +1427,6 @@
jsonpointer "^4.0.0"
xtend "^4.0.0"
"@benmalka/foxdriver@0.4.0":
version "0.4.0"
resolved "https://registry.yarnpkg.com/@benmalka/foxdriver/-/foxdriver-0.4.0.tgz#aecd158a785a09e104da036efe7611a13af4ed11"
integrity sha512-Uc9n5TTRV2AhfYaqkaDc5k72pfKxyd6LDVrQJyNLZ7uY4ThgEcQMjpVRkB8C7v16gKhubH4gmD0lad5pGvDUBg==
dependencies:
fs-extra "^4.0.1"
get-port "^3.2.0"
npmlog "^4.1.2"
safe-buffer "^5.1.1"
tcp-port-used "^1.0.1"
tmp "0.0.33"
"@chromaui/localtunnel@1.10.1":
version "1.10.1"
resolved "https://registry.yarnpkg.com/@chromaui/localtunnel/-/localtunnel-1.10.1.tgz#34da7dab7055a16b1b9034a9eb7e3054ebec4b98"
@@ -10597,10 +10585,10 @@ electron-to-chromium@^1.3.413:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.441.tgz#094f71b992dca5bc96b798cfbaf37dc76302015a"
integrity sha512-leBfJwLuyGs1jEei2QioI+PjVMavmUIvPYidE8dCCYWLAq0uefhN3NYgDNb8WxD3uiUNnJ3ScMXg0upSlwySzQ==
electron@8.3.1:
version "8.3.1"
resolved "https://registry.yarnpkg.com/electron/-/electron-8.3.1.tgz#79e98c4d5b8e7c09a8a811f1aa78903f0c692721"
integrity sha512-VZpgLVFyD2SwFDkO9rwUcNgrAMah+g38FEtALGxli8bRVTbcHl8bt21szfa0YUWpc6hWcaf6JdZjqDS5q73Bsg==
electron@9.0.5:
version "9.0.5"
resolved "https://registry.yarnpkg.com/electron/-/electron-9.0.5.tgz#189ee117cc2a2777cccf40fae0766acec5faae57"
integrity sha512-bnL9H48LuQ250DML8xUscsKiuSu+xv5umXbpBXYJ0BfvYVmFfNbG3jCfhrsH7aP6UcQKVxOG1R/oQExd0EFneQ==
dependencies:
"@electron/get" "^1.0.1"
"@types/node" "^12.0.12"
@@ -12426,6 +12414,18 @@ forwarded@~0.1.2:
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
foxdriver@0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/foxdriver/-/foxdriver-0.1.1.tgz#b66e0fb1f495b0139c7a0a5a5f31541b2adf0b23"
integrity sha512-ZJ6u9kzCkmDo7OVIzqF+KlMRLc+W53GCzglaLhFG1ixMliEC7o6TeucYd1XpSacpmZnPRVQE+byyR7LXC84htA==
dependencies:
fs-extra "^4.0.1"
get-port "^3.2.0"
npmlog "^4.1.2"
safe-buffer "^5.1.1"
tcp-port-used "^1.0.1"
tmp "0.0.33"
fragment-cache@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"