mirror of
https://github.com/cypress-io/cypress.git
synced 2026-02-05 06:40:56 -06:00
server/desktop: remove download/install update option
This commit is contained in:
@@ -49,7 +49,6 @@ describe "App", ->
|
||||
context "on:menu:clicked", ->
|
||||
beforeEach ->
|
||||
cy.stub(@ipc, "logOut")
|
||||
cy.stub(@ipc, "windowOpen")
|
||||
|
||||
@start()
|
||||
|
||||
@@ -57,28 +56,6 @@ describe "App", ->
|
||||
@ipc.onMenuClicked.yield(null, "log:out")
|
||||
expect(@ipc.logOut).to.be.called
|
||||
|
||||
it "checks for updates", ->
|
||||
@ipc.onMenuClicked.yield(null, "check:for:updates")
|
||||
expect(@ipc.windowOpen).to.be.calledWithExactly({
|
||||
position: "center",
|
||||
width: 300,
|
||||
height: 240,
|
||||
toolbar: false,
|
||||
title: "Updates",
|
||||
type: "UPDATES",
|
||||
})
|
||||
|
||||
context "on updates being applied", ->
|
||||
beforeEach ->
|
||||
@ipc.getOptions.resolves({"updating": true})
|
||||
|
||||
@start()
|
||||
|
||||
it "shows updates being applied view", ->
|
||||
cy
|
||||
.get("#login").contains("Applying updates")
|
||||
.get("img").should("have.attr", "src", "img/cypress-inverse.png")
|
||||
|
||||
context "getting current user", ->
|
||||
beforeEach ->
|
||||
@getCurrentUser = @util.deferred()
|
||||
|
||||
@@ -18,7 +18,7 @@ describe "Update Banner", ->
|
||||
|
||||
describe "general behavior", ->
|
||||
beforeEach ->
|
||||
cy.stub(@ipc, "getOptions").resolves({})
|
||||
cy.stub(@ipc, "getOptions").resolves({version: "1.3.3"})
|
||||
@start()
|
||||
|
||||
it "does not display update banner when no update available", ->
|
||||
@@ -42,41 +42,26 @@ describe "Update Banner", ->
|
||||
@updaterCheck.reject({name: "foo", message: "Something bad happened"})
|
||||
cy.get(".footer").should("be.visible")
|
||||
|
||||
describe "in global mode", ->
|
||||
beforeEach ->
|
||||
cy.stub(@ipc, "getOptions").resolves({})
|
||||
@start()
|
||||
|
||||
it "opens updates window on click of Update link", ->
|
||||
@updaterCheck.resolve("1.3.4")
|
||||
cy.contains("Update").click().then ->
|
||||
expect(@ipc.windowOpen).to.be.calledWith({
|
||||
position: "center"
|
||||
width: 300
|
||||
height: 240
|
||||
toolbar: false
|
||||
title: "Updates"
|
||||
type: "UPDATES"
|
||||
})
|
||||
|
||||
describe "in project mode", ->
|
||||
beforeEach ->
|
||||
cy.stub(@ipc, "getOptions").resolves({projectPath: "/foo/bar"})
|
||||
@start()
|
||||
@updaterCheck.resolve("1.3.4")
|
||||
|
||||
it "opens modal with info on click of Update link", ->
|
||||
it "opens modal on click of Update link", ->
|
||||
cy.contains("Update").click()
|
||||
cy.get(".modal").should("be.visible")
|
||||
|
||||
describe "update modal", ->
|
||||
beforeEach ->
|
||||
cy.contains("Update").click()
|
||||
it "closes modal when X is clicked", ->
|
||||
cy.contains("Update").click()
|
||||
cy.get(".close").click()
|
||||
cy.get(".modal").should("not.be.visible")
|
||||
|
||||
it.only "opens changelog when Changelog is clicked", ->
|
||||
cy.get(".modal").contains("Changelog").click().then =>
|
||||
expect(@ipc.externalOpen).to.be.calledWith("https://on.cypress.io/changelog")
|
||||
describe "in project mode", ->
|
||||
beforeEach ->
|
||||
cy.stub(@ipc, "getOptions").resolves({version: "1.3.3", projectPath: "/foo/bar"})
|
||||
@start()
|
||||
@updaterCheck.resolve("1.3.4")
|
||||
cy.contains("Update").click()
|
||||
|
||||
it "closes modal when X is clicked", ->
|
||||
cy.get(".close").click()
|
||||
cy.get(".modal").should("not.be.visible")
|
||||
it.only "modal has info about updating package.json", ->
|
||||
cy.get(".modal").contains("Quit this app")
|
||||
cy.get(".modal").contains("npm install -D cypress@1.3.4")
|
||||
|
||||
it "opens changelog when Changelog is clicked", ->
|
||||
cy.get(".modal").contains("Changelog").click().then =>
|
||||
expect(@ipc.externalOpen).to.be.calledWith("https://on.cypress.io/changelog")
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
describe "Updates", ->
|
||||
beforeEach ->
|
||||
cy.viewport(300, 240)
|
||||
cy.visit("/updates.html").then (win) =>
|
||||
{ startUpdateApp, @ipc } = win.App
|
||||
|
||||
@version = "1.78"
|
||||
|
||||
cy.stub(@ipc, "getOptions").resolves({version: @version})
|
||||
cy.stub(@ipc, "updaterRun")
|
||||
cy.stub(@ipc, "externalOpen")
|
||||
cy.stub(@ipc, "windowClose")
|
||||
|
||||
startUpdateApp()
|
||||
|
||||
it "updates title", ->
|
||||
cy.title().should("include", "Updates")
|
||||
|
||||
it "displays loading spinner before updater:run is called", ->
|
||||
cy.get(".loader").should("exist")
|
||||
|
||||
it "triggers updater:run", ->
|
||||
expect(@ipc.updaterRun).to.be.called
|
||||
|
||||
it "links to Changelog", ->
|
||||
@ipc.updaterRun.yield(null, {event: "none"})
|
||||
|
||||
cy.contains("a", "View Changelog").click().then ->
|
||||
expect(@ipc.externalOpen).to.be.calledWith("https://on.cypress.io/changelog")
|
||||
|
||||
it "displays current version", ->
|
||||
@ipc.updaterRun.yield(null, {event: "none"})
|
||||
|
||||
cy.get(".version").contains(@version)
|
||||
|
||||
describe "updater:run start", ->
|
||||
it "displays check for updates msg", ->
|
||||
@ipc.updaterRun.yield(null, {event: "start"})
|
||||
cy.contains("Checking for updates...")
|
||||
|
||||
describe "updater:run apply", ->
|
||||
it "displays applying updates msg", ->
|
||||
@ipc.updaterRun.yield(null, {event: "apply"})
|
||||
cy.contains("Applying updates...")
|
||||
|
||||
describe "updater:run error", ->
|
||||
it "displays error msg", ->
|
||||
@ipc.updaterRun.yield(null, {event: "error"})
|
||||
cy.contains("An error occurred updating")
|
||||
cy.contains("You can manually update Cypress by running 'cypress install' from your terminal or by downloading it again.")
|
||||
|
||||
it "triggers window:close on click of close btn", ->
|
||||
@ipc.updaterRun.yield(null, {event: "error"})
|
||||
cy.contains(".btn", "Done").click().then ->
|
||||
expect(@ipc.windowClose).to.be.called
|
||||
|
||||
describe "updater:run none", ->
|
||||
it "displays none msg", ->
|
||||
@ipc.updaterRun.yield(null, {event: "none"})
|
||||
cy.contains("No updates available")
|
||||
|
||||
it "triggers window:close on click of close btn", ->
|
||||
@ipc.updaterRun.yield(null, {event: "none"})
|
||||
cy.contains(".btn", "Done").click().then ->
|
||||
expect(@ipc.windowClose).to.be.called
|
||||
|
||||
describe "updater:run download", ->
|
||||
it "displays download msg", ->
|
||||
@ipc.updaterRun.yield(null, {event: "download"})
|
||||
cy.contains("Downloading updates...")
|
||||
|
||||
describe "updater:run done", ->
|
||||
it "displays done msg", ->
|
||||
@ipc.updaterRun.yield(null, {event: "done"})
|
||||
cy.contains("Updates ready")
|
||||
|
||||
it "triggers window:close on click of restart btn", ->
|
||||
@ipc.updaterRun.yield(null, {event: "done"})
|
||||
cy.contains(".btn", "Restart").click().then ->
|
||||
expect(@ipc.windowClose).to.be.called
|
||||
@@ -8,8 +8,4 @@ module.exports = {
|
||||
getPathToIndex () {
|
||||
return file('index.html')
|
||||
},
|
||||
|
||||
getPathToUpdates () {
|
||||
return file('updates.html')
|
||||
},
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import appStore from '../lib/app-store'
|
||||
import authStore from '../lib/auth-store'
|
||||
import viewStore from '../lib/view-store'
|
||||
|
||||
import ApplyingUpdates from './applying-updates'
|
||||
import Intro from './intro'
|
||||
import Layout from './layout'
|
||||
import Login from '../login/login'
|
||||
@@ -27,21 +26,15 @@ class App extends Component {
|
||||
projectPath: options.projectPath,
|
||||
})
|
||||
|
||||
if (options.updating) {
|
||||
viewStore.showApplyingUpdates()
|
||||
// mobx can trigger a synchronous re-render, which executes
|
||||
// componentDidMount, etc in other components, making bluebird
|
||||
// think another promise was created but not returned
|
||||
// return null to prevent bluebird warning about it
|
||||
// same goes for other `return null`s below
|
||||
return null
|
||||
} else {
|
||||
return ipc.getCurrentUser()
|
||||
}
|
||||
return ipc.getCurrentUser()
|
||||
})
|
||||
.then((user) => {
|
||||
if (viewStore.isApplyingUpdates()) return
|
||||
authStore.setUser(user)
|
||||
// mobx can trigger a synchronous re-render, which executes
|
||||
// componentDidMount, etc in other components, making bluebird
|
||||
// think another promise was created but not returned
|
||||
// return null to prevent bluebird warning about it
|
||||
// same goes for other `return null`s below
|
||||
return null
|
||||
})
|
||||
.catch(ipc.isUnauthed, () => {
|
||||
@@ -56,8 +49,6 @@ class App extends Component {
|
||||
return <Loader color='#888' scale={0.5} />
|
||||
case C.LOGIN:
|
||||
return <Login />
|
||||
case C.APPLYING_UPDATES:
|
||||
return <ApplyingUpdates />
|
||||
case C.INTRO:
|
||||
return (
|
||||
<Layout>
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import React, { Component } from 'react'
|
||||
|
||||
export default class ApplyingUpdates extends Component {
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div id='login'>
|
||||
<div className='login-img-wrapper'>
|
||||
<img src='img/cypress-inverse.png' />
|
||||
</div>
|
||||
<div className='login-content'>
|
||||
<div className='login-spinner'>
|
||||
<i className='fa fa-spinner fa-spin'></i>{' '}
|
||||
Applying updates and restarting...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import ipc from './ipc'
|
||||
import authStore from './auth-store'
|
||||
import updater from '../update/update-model'
|
||||
|
||||
const appApi = {
|
||||
logOut () {
|
||||
@@ -16,9 +15,6 @@ const appApi = {
|
||||
case 'log:out':
|
||||
this.logOut()
|
||||
break
|
||||
case 'check:for:updates':
|
||||
updater.openUpdateWindow()
|
||||
break
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
export default {
|
||||
LOADING: 'LOADING',
|
||||
LOGIN: 'LOGIN',
|
||||
APPLYING_UPDATES: 'APPLYING_UPDATES',
|
||||
INTRO: 'INTRO',
|
||||
PROJECT_SPECS: 'PROJECT_SPECS',
|
||||
PROJECT_RUNS: 'PROJECT_RUNS',
|
||||
|
||||
@@ -9,16 +9,6 @@ class ViewStore {
|
||||
name: C.LOADING,
|
||||
}
|
||||
|
||||
@action showApplyingUpdates () {
|
||||
this.currentView = {
|
||||
name: C.APPLYING_UPDATES,
|
||||
}
|
||||
}
|
||||
|
||||
isApplyingUpdates () {
|
||||
return this._isView(C.APPLYING_UPDATES)
|
||||
}
|
||||
|
||||
@action showLoading () {
|
||||
this.currentView = {
|
||||
name: C.LOADING,
|
||||
|
||||
@@ -7,7 +7,6 @@ import handleGlobalErrors from './lib/handle-global-errors'
|
||||
import momentOverrides from './lib/configure-moment'
|
||||
|
||||
import App from './app/app'
|
||||
import Updates from './update/updates'
|
||||
|
||||
useStrict(true)
|
||||
|
||||
@@ -24,8 +23,4 @@ window.App = {
|
||||
start () {
|
||||
render(<App />, document.getElementById('app'))
|
||||
},
|
||||
|
||||
startUpdateApp () {
|
||||
render(<Updates />, document.getElementById('updates'))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import { observer } from 'mobx-react'
|
||||
import BootstrapModal from 'react-bootstrap-modal'
|
||||
|
||||
import appStore from '../lib/app-store'
|
||||
import updater from './update-model'
|
||||
import ipc from '../lib/ipc'
|
||||
|
||||
@observer
|
||||
@@ -31,7 +30,7 @@ class UpdateBanner extends Component {
|
||||
return (
|
||||
<div id='updates-available'>
|
||||
New updates are available
|
||||
<strong onClick={this._downloadUpdate}>
|
||||
<strong onClick={() => this._toggleModal(true)}>
|
||||
<i className='fa fa-download'></i>{' '}
|
||||
Update
|
||||
</strong>
|
||||
@@ -50,21 +49,15 @@ class UpdateBanner extends Component {
|
||||
<div className='update-modal modal-body os-dialog'>
|
||||
<BootstrapModal.Dismiss className='btn btn-link close'>x</BootstrapModal.Dismiss>
|
||||
<h4>Update to the latest version</h4>
|
||||
<p>Version <strong>{appStore.newVersion}</strong> is now available (<a href='#' onClick={this._openChangelog}>Changelog</a>)</p>
|
||||
<p>
|
||||
Version <strong>{appStore.newVersion}</strong> is now available (currently running <strong>{appStore.version}</strong>).{' '}
|
||||
<a href='#' onClick={this._openChangelog}>Changelog</a>
|
||||
</p>
|
||||
<ol>
|
||||
<li>
|
||||
Set <code>"cypress"</code> in your app's <code>package.json</code> to <code>"{appStore.newVersion}"</code>
|
||||
|
||||
<pre>
|
||||
{'{\n'}
|
||||
{' "devDependencies": {\n'}
|
||||
{` "cypress": "${appStore.newVersion}"\n`}
|
||||
{' }\n'}
|
||||
{'}'}
|
||||
</pre>
|
||||
<li>Quit this app</li>
|
||||
<li> Run <code>npm install -D cypress@{appStore.newVersion}</code>
|
||||
</li>
|
||||
<li>Quit this app and run <code>npm install</code></li>
|
||||
<li>Run <code>cypress open</code> to re-open the new version of the app</li>
|
||||
<li>Run <code>cypress open</code> to open the new version of the app</li>
|
||||
</ol>
|
||||
</div>
|
||||
</BootstrapModal>
|
||||
@@ -82,14 +75,6 @@ class UpdateBanner extends Component {
|
||||
})
|
||||
}
|
||||
|
||||
_downloadUpdate = () => {
|
||||
if (appStore.isGlobalMode) {
|
||||
updater.openUpdateWindow()
|
||||
} else {
|
||||
this._toggleModal(true)
|
||||
}
|
||||
}
|
||||
|
||||
@action _toggleModal = (showModal) => {
|
||||
this.showingModal = showModal
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
import { computed, observable, action } from 'mobx'
|
||||
|
||||
import ipc from '../lib/ipc'
|
||||
|
||||
class Updater {
|
||||
@observable version
|
||||
@observable state
|
||||
@observable finished = false
|
||||
|
||||
@action setVersion (version) {
|
||||
this.version = version
|
||||
}
|
||||
|
||||
@action setNewVersion (newVersion) {
|
||||
this.newVersion = newVersion
|
||||
}
|
||||
|
||||
@action setState (state) {
|
||||
switch (state) {
|
||||
case 'error':
|
||||
case 'done':
|
||||
case 'none':
|
||||
this.finished = true
|
||||
this.state = state
|
||||
break
|
||||
default:
|
||||
this.state = state
|
||||
}
|
||||
|
||||
return this.state
|
||||
}
|
||||
|
||||
@computed get stateFormatted () {
|
||||
let result
|
||||
|
||||
switch (this.state) {
|
||||
case 'checking':
|
||||
result = 'Checking for updates...'
|
||||
break
|
||||
case 'downloading':
|
||||
result = 'Downloading updates...'
|
||||
break
|
||||
case 'applying':
|
||||
result = 'Applying updates...'
|
||||
break
|
||||
case 'done':
|
||||
result = 'Updates ready'
|
||||
break
|
||||
case 'none':
|
||||
result = 'No updates available'
|
||||
break
|
||||
case 'error':
|
||||
result = 'An error occurred updating: \nYou can manually update Cypress by running \'cypress install\' from your terminal or by downloading it again.'
|
||||
break
|
||||
default:
|
||||
result = ''
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@computed get buttonFormatted () {
|
||||
|
||||
if (this.state === 'done') {
|
||||
return 'Restart'
|
||||
} else {
|
||||
return 'Done'
|
||||
}
|
||||
}
|
||||
|
||||
openUpdateWindow () {
|
||||
return ipc.windowOpen({
|
||||
position: 'center',
|
||||
width: 300,
|
||||
height: 240,
|
||||
toolbar: false,
|
||||
title: 'Updates',
|
||||
type: 'UPDATES',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default new Updater()
|
||||
@@ -1,129 +0,0 @@
|
||||
import React, { Component } from 'react'
|
||||
import { observer } from 'mobx-react'
|
||||
import Loader from 'react-loader'
|
||||
|
||||
import ipc from '../lib/ipc'
|
||||
import updater from './update-model'
|
||||
|
||||
const openChangelog = (e) => {
|
||||
e.preventDefault()
|
||||
return ipc.externalOpen('https://on.cypress.io/changelog')
|
||||
}
|
||||
|
||||
@observer
|
||||
class Updates extends Component {
|
||||
componentDidMount () {
|
||||
ipc.getOptions().then((options = {}) => {
|
||||
updater.setVersion(options.version)
|
||||
})
|
||||
|
||||
ipc.updaterRun((err, data = {}) => {
|
||||
switch (data.event) {
|
||||
case 'start':
|
||||
return updater.setState('checking')
|
||||
case 'apply':
|
||||
return updater.setState('applying')
|
||||
case 'error':
|
||||
return updater.setState('error')
|
||||
case 'done':
|
||||
return updater.setState('done')
|
||||
case 'none':
|
||||
return updater.setState('none')
|
||||
case 'download':
|
||||
updater.setNewVersion(data.version)
|
||||
return updater.setState('downloading')
|
||||
default:
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
if (!updater.state) return <Loader color='#888' scale={0.5}/>
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
<a onClick={openChangelog} href='#'>
|
||||
View Changelog
|
||||
</a>
|
||||
</p>
|
||||
{ this._currentVersion() }
|
||||
{ this._newVersion() }
|
||||
{ this._state() }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
_currentVersion = () => {
|
||||
if (updater.version) {
|
||||
return (
|
||||
<p className='version'>
|
||||
<b>Current Version:</b>{' '}
|
||||
<span>{ updater.version }</span>
|
||||
</p>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
_newVersion = () => {
|
||||
if (updater.newVersion) {
|
||||
return (
|
||||
<p className='new-version'>
|
||||
<b>New Version:</b>{' '}
|
||||
<span>{ updater.newVersion }</span>
|
||||
</p>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
_state = () => {
|
||||
let errClass
|
||||
if (updater.state === 'error') {
|
||||
errClass = 'text-danger'
|
||||
}
|
||||
|
||||
if (updater.state) {
|
||||
return (
|
||||
<div>
|
||||
<p className={`state ${errClass}`}>
|
||||
{ this._notFinished() }{' '}
|
||||
<span dangerouslySetInnerHTML={this._getHtmlState()} />
|
||||
</p>
|
||||
{ this._finished() }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
_getHtmlState = () => {
|
||||
return { __html: updater.stateFormatted.split('\n').join('<br />') }
|
||||
}
|
||||
|
||||
_notFinished = () => {
|
||||
if (!updater.finished) {
|
||||
return (
|
||||
<i className='fa fa-spinner fa-spin'></i>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
_finished = () => {
|
||||
if (updater.finished) {
|
||||
return (
|
||||
<div>
|
||||
<button onClick={this._closeWindow} className='btn btn-default'>
|
||||
{ updater.buttonFormatted }
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
_closeWindow (e) {
|
||||
e.preventDefault()
|
||||
ipc.windowClose()
|
||||
}
|
||||
}
|
||||
|
||||
export default Updates
|
||||
@@ -18,30 +18,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
#updates {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
}
|
||||
|
||||
html.updates {
|
||||
background-color: #ECECEC;
|
||||
}
|
||||
|
||||
html.has-updates {
|
||||
.helper-line {
|
||||
bottom: 90px;
|
||||
}
|
||||
}
|
||||
|
||||
#updates-applied {
|
||||
padding-top: 175px;
|
||||
text-align: center;
|
||||
|
||||
h3 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.update-modal {
|
||||
ol {
|
||||
padding-left: 20px;
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="updates">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Updates</title>
|
||||
{{#each stylesheets}}
|
||||
<link rel="stylesheet" href="{{this}}" />
|
||||
{{/each}}
|
||||
</head>
|
||||
<body>
|
||||
<div id="updates"></div>
|
||||
|
||||
<script src="vendor.js"></script>
|
||||
{{#each scripts}}
|
||||
<script src="{{this}}"></script>
|
||||
{{/each}}
|
||||
<script>
|
||||
window.env = '{{env.NODE_ENV}}'
|
||||
if (!window.Cypress) {
|
||||
App.startUpdateApp()
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -117,26 +117,6 @@ handleEvent = (options, bus, event, id, type, arg) ->
|
||||
onNoNewVersion: -> send(false)
|
||||
})
|
||||
|
||||
when "updater:run"
|
||||
echo = (event, version) ->
|
||||
send({event: event, version: version})
|
||||
|
||||
upd = Updater.run({
|
||||
onStart: -> echo("start")
|
||||
onApply: -> echo("apply")
|
||||
onError: -> echo("error")
|
||||
onDone: -> echo("done")
|
||||
onNone: -> echo("none")
|
||||
onDownload: (version) ->
|
||||
echo("download", version)
|
||||
})
|
||||
|
||||
## TODO: there is no note here, what if the window
|
||||
## is closed once the updater finishes?
|
||||
win = Windows.getByWebContents(event.sender)
|
||||
win.once "closed", ->
|
||||
upd.cancel()
|
||||
|
||||
when "get:logs"
|
||||
logs.get()
|
||||
.then(send)
|
||||
|
||||
@@ -6,7 +6,6 @@ shell = require("electron").shell
|
||||
appData = require("../util/app_data")
|
||||
open = require("../util/open")
|
||||
|
||||
onUpdatesClicked = ->
|
||||
onLogOutClicked = ->
|
||||
|
||||
module.exports = {
|
||||
@@ -15,11 +14,8 @@ module.exports = {
|
||||
withDevTools: false
|
||||
})
|
||||
|
||||
## these are set by modes/headed.coffee and need to be preserved
|
||||
## if the menu is set again by launcher.coffee when the Electron
|
||||
## browser is run
|
||||
if options.onUpdatesClicked
|
||||
onUpdatesClicked = options.onUpdatesClicked
|
||||
## this set by modes/headed.coffee and needs to be preserved if the menu
|
||||
## is set again by launcher.coffee when the Electron browser is run
|
||||
if options.onLogOutClicked
|
||||
onLogOutClicked = options.onLogOutClicked
|
||||
|
||||
@@ -32,10 +28,6 @@ module.exports = {
|
||||
click: ->
|
||||
shell.openExternal("https://on.cypress.io/changelog")
|
||||
}
|
||||
{
|
||||
label: "Check for Updates"
|
||||
click: onUpdatesClicked
|
||||
}
|
||||
{
|
||||
type: "separator"
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@ getUrl = (type) ->
|
||||
cyDesktop.getPathToAbout()
|
||||
when "DEBUG"
|
||||
cyDesktop.getPathToDebug()
|
||||
when "UPDATES"
|
||||
cyDesktop.getPathToUpdates()
|
||||
when "INDEX"
|
||||
cyDesktop.getPathToIndex()
|
||||
else
|
||||
|
||||
@@ -9,7 +9,6 @@ cyIcons = require("@cypress/icons")
|
||||
user = require("../user")
|
||||
errors = require("../errors")
|
||||
savedState = require("../saved_state")
|
||||
Updater = require("../updater")
|
||||
logs = require("../gui/logs")
|
||||
menu = require("../gui/menu")
|
||||
Events = require("../gui/events")
|
||||
@@ -78,9 +77,6 @@ module.exports = {
|
||||
## instance here instead of callback functions
|
||||
menu.set({
|
||||
withDevTools: isDev()
|
||||
onUpdatesClicked: ->
|
||||
bus.emit("menu:item:clicked", "check:for:updates")
|
||||
|
||||
onLogOutClicked: ->
|
||||
bus.emit("menu:item:clicked", "log:out")
|
||||
})
|
||||
@@ -97,9 +93,6 @@ module.exports = {
|
||||
|
||||
Events.start(options, bus)
|
||||
|
||||
if options.updating
|
||||
Updater.install(options)
|
||||
|
||||
return win
|
||||
|
||||
run: (options) ->
|
||||
|
||||
@@ -1,23 +1,11 @@
|
||||
_ = require("lodash")
|
||||
os = require("os")
|
||||
fs = require("fs-extra")
|
||||
tar = require("tar-fs")
|
||||
nmi = require("node-machine-id")
|
||||
path = require("path")
|
||||
glob = require("glob")
|
||||
home = require("home-or-tmp")
|
||||
trash = require("trash")
|
||||
chmodr = require("chmodr")
|
||||
semver = require("semver")
|
||||
request = require("request")
|
||||
Promise = require("bluebird")
|
||||
NwUpdater = require("node-webkit-updater")
|
||||
cwd = require("./cwd")
|
||||
konfig = require("./konfig")
|
||||
logger = require("./logger")
|
||||
argsUtil = require("./util/args")
|
||||
|
||||
chmodr = Promise.promisify(chmodr)
|
||||
|
||||
## backup the original cwd
|
||||
localCwd = cwd()
|
||||
@@ -68,29 +56,11 @@ class Updater
|
||||
|
||||
@client = new NwUpdater @getPackage()
|
||||
@request = null
|
||||
@cancelled = false
|
||||
@callbacks = callbacks
|
||||
|
||||
if process.env["CYPRESS_ENV"] isnt "production"
|
||||
@patchAppPath()
|
||||
|
||||
getArgs: ->
|
||||
c = @getClient()
|
||||
|
||||
## get a reference to current cwd
|
||||
currentCwd = process.cwd()
|
||||
|
||||
## change to the original local cwd
|
||||
## in case we have a project open
|
||||
process.chdir(localCwd)
|
||||
|
||||
args = _.compact ["--app-path=" + c.getAppPath(), "--exec-path=" + c.getAppExec(), "--updating"]
|
||||
|
||||
## now restore back to what it was
|
||||
process.chdir(currentCwd)
|
||||
|
||||
return args
|
||||
|
||||
patchAppPath: ->
|
||||
@getClient().getAppPath = -> cwd()
|
||||
|
||||
@@ -103,152 +73,6 @@ class Updater
|
||||
## requiring inline due to easier testability
|
||||
@client ? throw new Error("missing Updater#client")
|
||||
|
||||
trash: (appPath) ->
|
||||
## moves the current appPath to the trash
|
||||
## this is the path to the existing app
|
||||
logger.info "trashing current app", appPath: appPath
|
||||
|
||||
Promise.resolve(trash([appPath]))
|
||||
|
||||
install: (argsObj = {}) ->
|
||||
c = @getClient()
|
||||
|
||||
argsObj = @normalizeArgs(argsObj)
|
||||
|
||||
{appPath, execPath} = argsObj
|
||||
|
||||
## slice out updating, execPath, and appPath args
|
||||
argsObj = _.omit(argsObj, "updating", "execPath", "appPath")
|
||||
|
||||
args = argsUtil.toArray(argsObj)
|
||||
|
||||
## trash the 'old' app currently installed at the default
|
||||
## installation: /Applications/Cypress.app
|
||||
@trash(appPath).then =>
|
||||
logger.info "installing updated app", appPath: appPath, execPath: execPath
|
||||
|
||||
@copyTmpToAppPath(c.getAppPath(), appPath).then ->
|
||||
c.run(execPath, args)
|
||||
|
||||
## and now quit this process
|
||||
process.exit(0)
|
||||
|
||||
normalizeArgs: (args = {}) ->
|
||||
## argsObj should look like this
|
||||
##
|
||||
## OSX:
|
||||
## {
|
||||
## updating: true
|
||||
## appPath: "/Applications/Cypress.app"
|
||||
## execPath: "/Applications/Cypress.app"
|
||||
## }
|
||||
##
|
||||
## Linux:
|
||||
## {
|
||||
## updating: true
|
||||
## appPath: "/home/vagrant/.cypress/Cypress"
|
||||
## execPath: "/home/vagrant/.cypress/Cypress/Cypress"
|
||||
## }
|
||||
##
|
||||
## there was a bug in Cypress in the 0.17.x range
|
||||
## which due to changing process.cwd() we messed
|
||||
## up the app-path + exec-path and were accidentally
|
||||
## trying to trash 3 levels above the users project!
|
||||
## so let's detect that and fix it right here with
|
||||
## the defaults.
|
||||
##
|
||||
{appPath, execPath} = args
|
||||
|
||||
switch os.platform()
|
||||
when "darwin"
|
||||
if not osxAppRe.test(appPath)
|
||||
args.appPath = args.execPath = "/Applications/Cypress.app"
|
||||
|
||||
when "linux"
|
||||
if not linuxAppRe.test(appPath)
|
||||
p = path.join(@getHome(), ".cypress", "Cypress")
|
||||
|
||||
args.appPath = p
|
||||
args.execPath = path.join(p, "Cypress")
|
||||
|
||||
return args
|
||||
|
||||
getHome: -> home
|
||||
|
||||
copyTmpToAppPath: (tmp, appPath) ->
|
||||
new Promise (resolve, reject) ->
|
||||
|
||||
obj = {
|
||||
fs: require("original-fs")
|
||||
}
|
||||
|
||||
## now move the /tmp application over
|
||||
## to the 'existing / old' app path.
|
||||
## meaning from from /tmp/Cypress.app to /Applications/Cypress.app
|
||||
|
||||
## https://github.com/atom/electron/pull/3641
|
||||
## tar-fs
|
||||
tar
|
||||
.pack(tmp, obj)
|
||||
.pipe(tar.extract(appPath, obj))
|
||||
|
||||
.on "error", reject
|
||||
|
||||
.on "finish", resolve
|
||||
|
||||
runInstaller: (newAppPath) ->
|
||||
## get the --updating args
|
||||
args = @getArgs()
|
||||
|
||||
logger.info "running installer from tmp", destination: newAppPath, args: args
|
||||
|
||||
## runs the 'new' app in the /tmp directory with
|
||||
## appPath + execPath to the 'existing / old' app
|
||||
## (which is where its normally installed in /Applications)
|
||||
## it additionally passes the --updating flag
|
||||
@getClient().runInstaller(newAppPath, args, {})
|
||||
|
||||
process.exit()
|
||||
|
||||
unpack: (destinationPath, manifest) ->
|
||||
logger.info "unpacking new version", destination: destinationPath
|
||||
|
||||
@trigger("apply")
|
||||
|
||||
fn = (err, newAppPath) =>
|
||||
return @trigger("error", err) if err
|
||||
|
||||
return if @cancelled
|
||||
|
||||
@runInstaller(newAppPath)
|
||||
|
||||
@getClient().unpack(destinationPath, fn, manifest)
|
||||
|
||||
download: (manifest) ->
|
||||
logger.info "downloading new version", version: manifest.version
|
||||
|
||||
@trigger("download", manifest.version)
|
||||
|
||||
fn = (err, destinationPath) =>
|
||||
return @trigger("error", err) if err
|
||||
|
||||
## fixes issue with updater failing during unpack
|
||||
setTimeout =>
|
||||
return if @cancelled
|
||||
|
||||
@unpack(destinationPath, manifest)
|
||||
, 1000
|
||||
|
||||
@request = @getClient().download(fn, manifest)
|
||||
|
||||
cancel: ->
|
||||
@cancelled = true
|
||||
|
||||
try
|
||||
## attempt to abort the request
|
||||
## and slurp up any errors
|
||||
@request.abort()
|
||||
|
||||
trigger: (event, args...) ->
|
||||
## normalize event name
|
||||
event = "on" + event[0].toUpperCase() + event.slice(1)
|
||||
@@ -268,25 +92,7 @@ class Updater
|
||||
logger.info "new version does not exist"
|
||||
options.onNoNewVersion?()
|
||||
|
||||
run: ->
|
||||
@trigger("start")
|
||||
|
||||
@check
|
||||
onNewVersion: (manifest) =>
|
||||
@download(manifest)
|
||||
|
||||
onNoNewVersion: =>
|
||||
@trigger("none")
|
||||
|
||||
return @
|
||||
|
||||
@install = (options) ->
|
||||
Updater().install(options)
|
||||
|
||||
@check = (options = {}) ->
|
||||
Updater().check(options)
|
||||
|
||||
@run = (callbacks = {}) ->
|
||||
Updater(callbacks).run()
|
||||
|
||||
module.exports = Updater
|
||||
|
||||
@@ -85,7 +85,6 @@
|
||||
"bytes": "^2.4.0",
|
||||
"chai": "^1.9.2",
|
||||
"chalk": "1.1.1",
|
||||
"chmodr": "^0.1.0",
|
||||
"chokidar": "1.6.0",
|
||||
"cjsxify": "^0.3.0",
|
||||
"compression": "1.1.0",
|
||||
@@ -108,7 +107,6 @@
|
||||
"graceful-fs": "^4.1.11",
|
||||
"gulp-util": "^3.0.6",
|
||||
"hbs": "4.0.0",
|
||||
"home-or-tmp": "^2.0.0",
|
||||
"http-accept": "^0.1.6",
|
||||
"http-proxy": "^1.13.2",
|
||||
"http-status-codes": "^1.0.6",
|
||||
|
||||
@@ -193,35 +193,6 @@ describe "lib/gui/events", ->
|
||||
@handleEvent("updater:check")
|
||||
@expectSendCalledWith(false)
|
||||
|
||||
describe "updater:run", ->
|
||||
beforeEach ->
|
||||
@once = @sandbox.stub()
|
||||
@sandbox.stub(Windows, "getByWebContents").withArgs(@event.sender).returns({once: @once})
|
||||
|
||||
it "calls cancel when win is closed", ->
|
||||
cancel = @sandbox.spy()
|
||||
run = @sandbox.stub(Updater, "run").returns({cancel: cancel})
|
||||
@once.withArgs("closed").yields()
|
||||
@handleEvent("updater:run")
|
||||
expect(cancel).to.be.calledOnce
|
||||
|
||||
_.each {
|
||||
onStart: "start"
|
||||
onApply: "apply"
|
||||
onError: "error"
|
||||
onDone: "done"
|
||||
onNone: "none"
|
||||
}, (val, key) ->
|
||||
it "returns #{val} on #{key}", ->
|
||||
@sandbox.stub(Updater, "run").yieldsTo(key)
|
||||
@handleEvent("updater:run")
|
||||
@expectSendCalledWith({event: val, version: undefined})
|
||||
|
||||
it "returns down + version on onDownload", ->
|
||||
@sandbox.stub(Updater, "run").yieldsTo("onDownload", "0.14.0")
|
||||
@handleEvent("updater:run")
|
||||
@expectSendCalledWith({event: "download", version: "0.14.0"})
|
||||
|
||||
context "log events", ->
|
||||
describe "get:logs", ->
|
||||
it "returns array of logs", ->
|
||||
|
||||
@@ -71,13 +71,12 @@ describe "gui/menu", ->
|
||||
expect(getMenuItem("Cypress")).to.be.undefined
|
||||
|
||||
context "File", ->
|
||||
it "contains changelog, check for updates, logout, close window", ->
|
||||
it "contains changelog, logout, close window", ->
|
||||
menu.set()
|
||||
labels = getLabels(getMenuItem("File").submenu)
|
||||
|
||||
expect(labels).to.eql([
|
||||
"Changelog"
|
||||
"Check for Updates"
|
||||
"Manage Account"
|
||||
"Log Out"
|
||||
"View App Data"
|
||||
@@ -89,23 +88,6 @@ describe "gui/menu", ->
|
||||
getSubMenuItem(getMenuItem("File"), "Changelog").click()
|
||||
expect(electron.shell.openExternal).to.be.calledWith("https://on.cypress.io/changelog")
|
||||
|
||||
it "calls updates callback when Check for Updates is clicked", ->
|
||||
onUpdatesClicked = @sandbox.stub()
|
||||
menu.set({onUpdatesClicked})
|
||||
getSubMenuItem(getMenuItem("File"), "Check for Updates").click()
|
||||
expect(onUpdatesClicked).to.be.called
|
||||
|
||||
it "calls original updates callback when menu is reset without new callback", ->
|
||||
onUpdatesClicked = @sandbox.stub()
|
||||
menu.set({onUpdatesClicked})
|
||||
menu.set()
|
||||
getSubMenuItem(getMenuItem("File"), "Check for Updates").click()
|
||||
expect(onUpdatesClicked).to.be.called
|
||||
|
||||
it "is noop when Check for Updates is clicked with no callback", ->
|
||||
menu.set()
|
||||
expect(-> getSubMenuItem(getMenuItem("File"), "Check for Updates").click()).not.to.throw()
|
||||
|
||||
it "opens dashboard when Manage Account is clicked", ->
|
||||
menu.set()
|
||||
getSubMenuItem(getMenuItem("File"), "Manage Account").click()
|
||||
|
||||
@@ -92,7 +92,6 @@ describe "gui/headed", ->
|
||||
|
||||
@sandbox.stub(menu, "set")
|
||||
@sandbox.stub(Events, "start")
|
||||
@sandbox.stub(Updater, "install")
|
||||
@sandbox.stub(Windows, "open").resolves(@win)
|
||||
@sandbox.stub(Windows, "trackState")
|
||||
|
||||
@@ -105,14 +104,6 @@ describe "gui/headed", ->
|
||||
headed.ready(opts).then ->
|
||||
expect(Events.start).to.be.calledWith(opts)
|
||||
|
||||
it "calls Updater.install if options.updating", ->
|
||||
headed.ready({updating: true}).then ->
|
||||
expect(Updater.install).to.be.calledOnce
|
||||
|
||||
it "does not call Updater.install", ->
|
||||
headed.ready({}).then ->
|
||||
expect(Updater.install).not.to.be.called
|
||||
|
||||
it "calls menu.set", ->
|
||||
headed.ready({}).then ->
|
||||
expect(menu.set).to.be.calledOnce
|
||||
|
||||
@@ -2,14 +2,10 @@ require("../spec_helper")
|
||||
|
||||
delete global.fs
|
||||
|
||||
os = require("os")
|
||||
tar = require("tar-fs")
|
||||
nmi = require("node-machine-id")
|
||||
cwd = require("#{root}lib/cwd")
|
||||
home = require("home-or-tmp")
|
||||
request = require("request")
|
||||
Updater = require("#{root}lib/updater")
|
||||
Fixtures = require("#{root}/test/support/helpers/fixtures")
|
||||
|
||||
describe "lib/updater", ->
|
||||
context "interface", ->
|
||||
@@ -41,104 +37,6 @@ describe "lib/updater", ->
|
||||
client2 = u.getClient()
|
||||
expect(client).to.eq(client2)
|
||||
|
||||
context "#normalizeArgs", ->
|
||||
beforeEach ->
|
||||
@env = process.env.CYPRESS_ENV
|
||||
|
||||
process.env.CYPRESS_ENV = "production"
|
||||
|
||||
@updater = Updater({})
|
||||
@updater.getClient()
|
||||
|
||||
afterEach ->
|
||||
process.env.CYPRESS_ENV = @env
|
||||
|
||||
it "resets appPath + execPath on OSX", ->
|
||||
@sandbox.stub(os, "platform").returns("darwin")
|
||||
|
||||
expect(@updater.normalizeArgs({
|
||||
appPath: "/Users/bmann/Dev"
|
||||
execPath: "/Users/bmann/Dev"
|
||||
})).to.deep.eq({
|
||||
appPath: "/Applications/Cypress.app"
|
||||
execPath: "/Applications/Cypress.app"
|
||||
})
|
||||
|
||||
it "does not reset appPath + execPath on OSX", ->
|
||||
@sandbox.stub(os, "platform").returns("darwin")
|
||||
|
||||
expect(@updater.normalizeArgs({
|
||||
appPath: "/foo/Cypress.app"
|
||||
execPath: "/foo/Cypress.app"
|
||||
})).to.deep.eq({
|
||||
appPath: "/foo/Cypress.app"
|
||||
execPath: "/foo/Cypress.app"
|
||||
})
|
||||
|
||||
it "resets appPath + execPath on linux", ->
|
||||
@sandbox.stub(os, "platform").returns("linux")
|
||||
@sandbox.stub(@updater, "getHome").returns("/home/vagrant")
|
||||
|
||||
expect(@updater.normalizeArgs({
|
||||
appPath: "/Users/bmann/Dev"
|
||||
execPath: "/Users/bmann/Dev"
|
||||
})).to.deep.eq({
|
||||
appPath: "/home/vagrant/.cypress/Cypress"
|
||||
execPath: "/home/vagrant/.cypress/Cypress/Cypress"
|
||||
})
|
||||
|
||||
it "does not reset appPath + execPath on linux", ->
|
||||
@sandbox.stub(os, "platform").returns("linux")
|
||||
|
||||
expect(@updater.normalizeArgs({
|
||||
appPath: "/foo/Cypress"
|
||||
execPath: "/foo/Cypress/Cypress"
|
||||
})).to.deep.eq({
|
||||
appPath: "/foo/Cypress"
|
||||
execPath: "/foo/Cypress/Cypress"
|
||||
})
|
||||
|
||||
context "#getHome", ->
|
||||
beforeEach ->
|
||||
@updater = Updater({})
|
||||
|
||||
it "returns home-or-tmp", ->
|
||||
expect(@updater.getHome()).to.eq(home)
|
||||
|
||||
context "#getArgs", ->
|
||||
beforeEach ->
|
||||
@updater = Updater({})
|
||||
@updater.getClient()
|
||||
@sandbox.stub(@updater.client, "getAppExec").returns("bar")
|
||||
|
||||
it "compacts null values", ->
|
||||
@sandbox.stub(@updater.client, "getAppPath").returns("foo")
|
||||
expect(@updater.getArgs()).to.deep.eq ["--app-path=foo", "--exec-path=bar", "--updating"]
|
||||
|
||||
## TODO: this is failing in local docker but lib/updater
|
||||
## is being removed in 0.20.0, so it doesn't really matter
|
||||
it.skip "changes cwd to be the original + then restores", ->
|
||||
tmp = os.tmpDir()
|
||||
|
||||
## manually change process.cwd
|
||||
process.chdir(tmp)
|
||||
|
||||
localCwd = cwd()
|
||||
|
||||
fn = ->
|
||||
process.cwd() + "/baz"
|
||||
|
||||
@sandbox.stub(@updater.client, "getAppPath", fn)
|
||||
|
||||
args = @updater.getArgs()
|
||||
|
||||
expect(args).to.deep.eq(["--app-path=#{localCwd + "/baz"}", "--exec-path=bar", "--updating"])
|
||||
|
||||
expect(args[0]).not.to.include(tmp)
|
||||
|
||||
expect(process.cwd()).to.include(tmp)
|
||||
expect(process.cwd()).not.to.include(localCwd)
|
||||
|
||||
context "#checkNewVersion", ->
|
||||
beforeEach ->
|
||||
@get = @sandbox.spy(request, "get")
|
||||
@@ -169,299 +67,6 @@ describe "lib/updater", ->
|
||||
|
||||
done()
|
||||
|
||||
context ".run", ->
|
||||
beforeEach ->
|
||||
@updater = Updater({})
|
||||
@updater.getClient()
|
||||
@checkNewVersion = @sandbox.stub(@updater.client, "checkNewVersion")
|
||||
@sandbox.stub(process, "exit")
|
||||
|
||||
it "invokes onRun", ->
|
||||
spy = @sandbox.spy()
|
||||
Updater.run({onStart: spy})
|
||||
expect(spy).to.be.called
|
||||
|
||||
describe "client#checkNewVersion", ->
|
||||
beforeEach ->
|
||||
@download = @sandbox.stub(Updater.prototype, "download")
|
||||
|
||||
it "is called once", ->
|
||||
@updater.run()
|
||||
expect(@checkNewVersion).to.be.calledOnce
|
||||
|
||||
it "calls #download if new version exists", ->
|
||||
@checkNewVersion.yields(null, true, {})
|
||||
@updater.run()
|
||||
expect(@download).to.be.calledOnce
|
||||
|
||||
it "passes manifest to #download when new version exists", ->
|
||||
@checkNewVersion.yields(null, true, {foo: "bar"})
|
||||
@updater.run()
|
||||
expect(@download).to.be.calledWith({foo: "bar"})
|
||||
|
||||
it "does not call #download if there isnt a new version", ->
|
||||
@checkNewVersion.yields(null, false, {foo: "bar"})
|
||||
@updater.run()
|
||||
expect(@download).not.to.be.called
|
||||
|
||||
it "invokes onNone when there isnt a new version", ->
|
||||
spy = @sandbox.spy()
|
||||
@checkNewVersion.yields(null, false)
|
||||
@updater.callbacks.onNone = spy
|
||||
@updater.run()
|
||||
expect(spy).to.be.called
|
||||
|
||||
it "does not call #download if there is an error", ->
|
||||
@checkNewVersion.yields((new Error()), true, {foo: "bar"})
|
||||
@updater.run()
|
||||
expect(@download).not.to.be.called
|
||||
|
||||
it "invokes onError callbacks", ->
|
||||
err = new Error("checking onError")
|
||||
spy = @sandbox.spy()
|
||||
@checkNewVersion.yields(err)
|
||||
@updater.callbacks.onError = spy
|
||||
@updater.run()
|
||||
expect(spy).to.be.calledWith(err)
|
||||
|
||||
describe "#download", ->
|
||||
beforeEach ->
|
||||
@sandbox.stub(@updater.client, "download")
|
||||
@sandbox.stub(@updater, "unpack")
|
||||
@clock = @sandbox.useFakeTimers()
|
||||
|
||||
it "invokes onDownload", ->
|
||||
spy = @sandbox.spy()
|
||||
@updater.callbacks.onDownload = spy
|
||||
@updater.download({})
|
||||
@clock.tick(1000)
|
||||
expect(spy).to.be.called
|
||||
|
||||
it "calls unpack with destinationPath and manifest", ->
|
||||
@updater.client.download.yields(null, "/Users/bmann/app")
|
||||
@updater.download({})
|
||||
@clock.tick(1000)
|
||||
expect(@updater.unpack).to.be.calledOnce.and.to.be.calledWith("/Users/bmann/app", {})
|
||||
|
||||
it "does not call unpack on error", ->
|
||||
@updater.client.download.yields((new Error()), "/Users/bmann/app")
|
||||
@updater.download({})
|
||||
@clock.tick(1000)
|
||||
expect(@updater.unpack).not.to.be.called
|
||||
|
||||
it "invokes onError callbacks", ->
|
||||
err = new Error("checking onError")
|
||||
spy = @sandbox.spy()
|
||||
@updater.callbacks.onError = spy
|
||||
@updater.client.download.yields(err)
|
||||
@updater.download({})
|
||||
@clock.tick(1000)
|
||||
expect(spy).to.be.calledWith(err)
|
||||
|
||||
describe "#unpack", ->
|
||||
beforeEach ->
|
||||
@sandbox.stub(@updater.client, "unpack")
|
||||
@sandbox.stub(@updater, "runInstaller")
|
||||
|
||||
it "invokes onApply", ->
|
||||
spy = @sandbox.spy()
|
||||
@updater.callbacks.onApply = spy
|
||||
@updater.unpack("/some/path", {})
|
||||
expect(spy).to.be.called
|
||||
|
||||
it "calls runInstaller with newAppPath", ->
|
||||
@updater.client.unpack.yields(null, "/Users/bmann/app")
|
||||
@updater.unpack("/some/path", {})
|
||||
expect(@updater.runInstaller).to.be.calledOnce.and.to.be.calledWith("/Users/bmann/app")
|
||||
|
||||
it "does not call runInstaller on error", ->
|
||||
@updater.client.unpack.yields((new Error()), "/Users/bmann/app")
|
||||
@updater.unpack("/some/path", {})
|
||||
expect(@updater.runInstaller).not.to.be.called
|
||||
|
||||
it "invokes onError callbacks", ->
|
||||
err = new Error("checking onError")
|
||||
spy = @sandbox.spy()
|
||||
@updater.callbacks.onError = spy
|
||||
@updater.client.unpack.yields(err)
|
||||
@updater.unpack("/some/path", {})
|
||||
expect(spy).to.be.calledWith(err)
|
||||
|
||||
describe "#runInstaller", ->
|
||||
beforeEach ->
|
||||
@sandbox.stub(@updater.client, "runInstaller")
|
||||
# @sandbox.stub(@updater, "copyCyDataTo").resolves()
|
||||
|
||||
it "calls process.exit", ->
|
||||
@updater.runInstaller("/Users/bmann/newApp")
|
||||
expect(process.exit).to.be.calledOnce
|
||||
|
||||
it "calls runInstaller on the client", ->
|
||||
c = @updater.client
|
||||
@updater.runInstaller("/Users/bmann/newApp")
|
||||
|
||||
expect(@updater.client.runInstaller).to.be.calledWith("/Users/bmann/newApp", ["--app-path=#{c.getAppPath()}", "--exec-path=#{c.getAppExec()}", "--updating"], {})
|
||||
|
||||
## we no longer pass up additional App argv
|
||||
## other than from debug i'm not sure why we
|
||||
## would have ever wanted to do this. in fact
|
||||
## its caused a bug in parseArgs and its duplicated
|
||||
## every existing argument
|
||||
it "does not pass along additional App argv", ->
|
||||
c = @updater.client
|
||||
@updater.runInstaller("/Users/bmann/newApp")
|
||||
expect(@updater.client.runInstaller).to.be.calledWith("/Users/bmann/newApp", ["--app-path=#{c.getAppPath()}", "--exec-path=#{c.getAppExec()}", "--updating"], {})
|
||||
|
||||
describe "#copyCyDataTo", ->
|
||||
beforeEach ->
|
||||
fs.outputJsonAsync(".cy/cache", {foo: "bar"}).then ->
|
||||
fs.outputFileAsync(".cy/foo/bar.txt", "foo!").then ->
|
||||
fs.outputJsonAsync("new/app/path/Contents/Resources/app/package.json", {})
|
||||
|
||||
afterEach ->
|
||||
fs.removeAsync("new").then ->
|
||||
fs.removeAsync(".cy/foo")
|
||||
|
||||
describe "#copyTmpToAppPath", ->
|
||||
beforeEach ->
|
||||
@onStub = @sandbox.stub()
|
||||
@onStub.withArgs("error").returnsThis()
|
||||
|
||||
@onPipe = @sandbox.stub().returnsThis()
|
||||
|
||||
@sandbox.stub(tar, "pack").returns({
|
||||
on: @onStub
|
||||
pipe: @onPipe
|
||||
})
|
||||
|
||||
@sandbox.stub(tar, "extract").returns("extractFoo")
|
||||
|
||||
it "calls tar.pack", ->
|
||||
@onStub.withArgs("finish").yieldsAsync()
|
||||
|
||||
@updater.copyTmpToAppPath("a", "b").then ->
|
||||
expect(tar.pack).to.be.calledWith("a", {
|
||||
fs: require("original-fs")
|
||||
})
|
||||
|
||||
it "calls tar.extract", ->
|
||||
@onStub.withArgs("finish").yieldsAsync()
|
||||
|
||||
@updater.copyTmpToAppPath("a", "b").then ->
|
||||
expect(tar.extract).to.be.calledWith("b", {
|
||||
fs: require("original-fs")
|
||||
})
|
||||
|
||||
it "pipes return value of tar.extract", ->
|
||||
@onStub.withArgs("finish").yieldsAsync()
|
||||
|
||||
@updater.copyTmpToAppPath("a", "b").then =>
|
||||
expect(@onPipe).to.be.calledWith("extractFoo")
|
||||
|
||||
it "throws on error", ->
|
||||
err = new Error("foo")
|
||||
@onStub.withArgs("error").yieldsAsync(err)
|
||||
|
||||
@updater.copyTmpToAppPath("a", "b")
|
||||
.then ->
|
||||
throw new Error("should have failed but did not")
|
||||
.catch (e) ->
|
||||
expect(e).to.eq(err)
|
||||
|
||||
describe "#trash", ->
|
||||
beforeEach ->
|
||||
fs.outputFileAsync("random/dirs/and/file.txt", "foobarbaz!")
|
||||
|
||||
it "moves directory to trash", (done) ->
|
||||
@updater.trash("random").then ->
|
||||
fs.statAsync("random")
|
||||
.then -> done("random should not exist!")
|
||||
.catch -> done()
|
||||
|
||||
describe "#install", ->
|
||||
beforeEach ->
|
||||
@argsObj = {
|
||||
appPath: "/Users/bmann/app_path"
|
||||
execPath: "/Users/bmann/app_exec_path"
|
||||
}
|
||||
|
||||
@normalizedArgs = @updater.normalizeArgs(@argsObj)
|
||||
|
||||
@sandbox.stub(@updater.client, "getAppPath").returns("foo")
|
||||
@sandbox.stub(@updater, "copyTmpToAppPath").resolves()
|
||||
|
||||
@run = @sandbox.stub(@updater.client, "run")
|
||||
@trash = @sandbox.stub(@updater, "trash").resolves()
|
||||
|
||||
it "trashes current appPath", ->
|
||||
@updater.install(@argsObj).then =>
|
||||
expect(@trash).to.be.calledWith(@normalizedArgs.appPath)
|
||||
|
||||
it "calls #copyTmpToAppPath with tmp + appPath", ->
|
||||
@updater.install(@argsObj).then =>
|
||||
expect(@updater.copyTmpToAppPath).to.be.calledWith "foo", @normalizedArgs.appPath
|
||||
|
||||
it "calls process.exit", ->
|
||||
@updater.install(@argsObj).then =>
|
||||
expect(process.exit).to.be.calledOnce
|
||||
|
||||
it "calls client.run with execPath + args", ->
|
||||
@updater.install(@argsObj).then =>
|
||||
expect(@run).to.be.calledWith(@argsObj.execPath, [])
|
||||
|
||||
context "args", ->
|
||||
beforeEach ->
|
||||
@argsObj = {
|
||||
updating: true
|
||||
appPath: "app"
|
||||
execPath: "exec"
|
||||
"getKey": true
|
||||
}
|
||||
|
||||
@normalizedArgs = @updater.normalizeArgs(@argsObj)
|
||||
|
||||
it "uses args object", ->
|
||||
@updater.install(@argsObj).then =>
|
||||
expect(@run).to.be.calledWith(@normalizedArgs.execPath, ["--getKey=true"])
|
||||
|
||||
context "integration", ->
|
||||
before ->
|
||||
## 10 min timeout
|
||||
@timeout(10 * 60 * 1000)
|
||||
|
||||
## ensure we have the cypress.zip fixture
|
||||
Fixtures.ensureNwZip()
|
||||
|
||||
beforeEach ->
|
||||
## force a lower package.json version
|
||||
@sandbox.stub(fs, "readJsonSync").returns({version: "0.0.1"})
|
||||
|
||||
## force a manifest.json response here to be a slightly higher version
|
||||
nock("http://download.cypress.io")
|
||||
.get("/desktop.json")
|
||||
.reply 200, {
|
||||
name: "cypress"
|
||||
version: "0.0.2"
|
||||
packages: {
|
||||
mac: {
|
||||
url: "http://cdn.cypress.io/desktop/0.0.2/cypress.zip"
|
||||
}
|
||||
win: {
|
||||
url: "http://cdn.cypress.io/desktop/0.0.2/cypress.zip"
|
||||
}
|
||||
linux: {
|
||||
url: "http://cdn.cypress.io/desktop/0.0.2/cypress.zip"
|
||||
}
|
||||
}
|
||||
}
|
||||
.get("/dist.cypress.io/0.0.2/cypress.zip")
|
||||
.reply 200, ->
|
||||
fs.createReadStream Fixtures.path("nw/cypress.zip")
|
||||
|
||||
# it "runs", ->
|
||||
# @updater = Updater({quit: @sandbox.spy()})
|
||||
# @updater.run()
|
||||
|
||||
context "#check", ->
|
||||
beforeEach ->
|
||||
@updater = Updater({quit: @sandbox.spy()})
|
||||
|
||||
Reference in New Issue
Block a user