diff --git a/packages/desktop-gui/cypress/integration/global_mode_spec.coffee b/packages/desktop-gui/cypress/integration/global_mode_spec.coffee index cd8d2e99dae6..fa4f84f53c87 100644 --- a/packages/desktop-gui/cypress/integration/global_mode_spec.coffee +++ b/packages/desktop-gui/cypress/integration/global_mode_spec.coffee @@ -133,13 +133,10 @@ describe "Global Mode", -> describe "going back", -> beforeEach -> - cy.contains("Back").click() - - it "returns to intro on click of back button", -> - cy.shouldBeOnIntro() + @closeProject = @util.deferred() + @ipc.closeProject.returns(@closeProject.promise) - it "removes project name from title", -> - cy.title().should("equal", "Cypress") + cy.contains("Back").click() it "removes ipc listeners", -> expect(@ipc.offOpenProject).to.be.called @@ -148,3 +145,17 @@ describe "Global Mode", -> it "closes project", -> expect(@ipc.closeProject).to.be.called + + it "shows loader", -> + cy.get(".loader") + cy.contains("Closing project...") + + describe "when finished closing", -> + beforeEach -> + @closeProject.resolve() + + it "goes to intro", -> + cy.shouldBeOnIntro() + + it "removes project name from title", -> + cy.title().should("equal", "Cypress") diff --git a/packages/desktop-gui/cypress/integration/project_nav_spec.coffee b/packages/desktop-gui/cypress/integration/project_nav_spec.coffee index 2bf803f87bdc..9be75d4e60f8 100644 --- a/packages/desktop-gui/cypress/integration/project_nav_spec.coffee +++ b/packages/desktop-gui/cypress/integration/project_nav_spec.coffee @@ -14,8 +14,8 @@ describe "Project Nav", -> cy.stub(@ipc, "getRuns").resolves(@runs) cy.stub(@ipc, "getSpecs").yields(null, @specs) cy.stub(@ipc, "getRecordKeys").resolves([]) - cy.stub(@ipc, "launchBrowser") cy.stub(@ipc, "closeBrowser").resolves(null) + cy.stub(@ipc, "onBrowserClose") cy.stub(@ipc, "pingApiServer").resolves() cy.stub(@ipc, "closeProject") cy.stub(@ipc, "externalOpen") @@ -26,6 +26,9 @@ describe "Project Nav", -> @openProject = @util.deferred() cy.stub(@ipc, "openProject").returns(@openProject.promise) + @launchBrowser = @util.deferred() + cy.stub(@ipc, "launchBrowser").returns(@launchBrowser.promise) + start() context "project nav", -> @@ -134,8 +137,8 @@ describe "Project Nav", -> context "browser opened after choosing spec", -> beforeEach -> - @ipc.launchBrowser.yields(null, {browserOpened: true}) cy.contains(".file", "app_spec").click() + @launchBrowser.resolve() it "displays browser icon as opened", -> cy.get(".browsers-list>a").first().find("i") @@ -150,25 +153,41 @@ describe "Project Nav", -> describe "stop browser", -> beforeEach -> + @closeBrowser = @util.deferred() + @ipc.closeBrowser.returns(@closeBrowser.promise) + cy.get(".close-browser").click() - it "calls close:browser on click of stop button", -> + it "calls ipc close:browser", -> expect(@ipc.closeBrowser).to.be.called - it "hides close button on click of stop", -> + it "hides close button", -> cy.get(".close-browser").should("not.exist") - it "re-enables browser dropdown", -> - cy.get(".browsers-list>a").first() - .should("not.have.class", "disabled") + it "blocks the UI and shows closing loader while browser is closing", -> + cy.get(".ui-blocker") + cy.get(".browsers-list").find(".fa-refresh.fa-spin") + cy.contains("Closing Chrome 50") - it "displays default browser icon", -> - cy.get(".browsers-list>a").first() - .find(".fa-chrome") + describe "when browser is finished closing", -> + beforeEach -> + @closeBrowser.resolve() + + it "re-enables browser dropdown", -> + cy.get(".browsers-list>a").first() + .should("not.have.class", "disabled") + + it "displays default browser icon", -> + cy.get(".browsers-list>a").first() + .find(".fa-chrome") + + it "unblocks the UI", -> + cy.get(".ui-blocker").should("not.exist") describe "browser is closed manually", -> beforeEach -> - @ipc.launchBrowser.yield(null, {browserClosed: true}) + cy.stub(@ipc, "awaitBrowserClose").resolves() + @ipc.onBrowserClose.yield() it "hides close browser button", -> cy.get(".close-browser").should("not.be.visible") diff --git a/packages/desktop-gui/cypress/integration/project_spec.coffee b/packages/desktop-gui/cypress/integration/project_spec.coffee index 7aec8d18f9ba..5fa84a778513 100644 --- a/packages/desktop-gui/cypress/integration/project_spec.coffee +++ b/packages/desktop-gui/cypress/integration/project_spec.coffee @@ -45,10 +45,20 @@ describe "Project", -> it "re-opens project if config changes", -> cy.shouldBeOnProjectSpecs().then => @ipc.onConfigChanged.yield() - expect(@ipc.closeProject).to.be.called - expect(@ipc.openProject).to.be.called + cy.wrap(@ipc.closeProject).should("be.called") + cy.wrap(@ipc.openProject).should("be.called") cy.shouldBeOnProjectSpecs() + describe "opening", -> + beforeEach -> + @openProject = @util.deferred() + @ipc.openProject.returns(@openProject.promise) + @start() + + it "shows loader", -> + cy.get(".loader") + cy.contains("Opening project...") + describe "warnings", -> beforeEach -> @start() diff --git a/packages/desktop-gui/cypress/integration/projects_list_spec.coffee b/packages/desktop-gui/cypress/integration/projects_list_spec.coffee index 66831ef0554c..4168209a6dbb 100644 --- a/packages/desktop-gui/cypress/integration/projects_list_spec.coffee +++ b/packages/desktop-gui/cypress/integration/projects_list_spec.coffee @@ -41,7 +41,9 @@ describe "Projects List", -> @start() it "loads projects and shows loader", -> - cy.get(".projects-list .loader").then => + cy.get(".projects-list .loader") + .should("have.text", "Loading projects...") + .then => expect(@ipc.getProjects).to.be.called describe "when loaded", -> diff --git a/packages/desktop-gui/cypress/integration/runs_list_spec.coffee b/packages/desktop-gui/cypress/integration/runs_list_spec.coffee index f586bbcc12ca..45814fd506cd 100644 --- a/packages/desktop-gui/cypress/integration/runs_list_spec.coffee +++ b/packages/desktop-gui/cypress/integration/runs_list_spec.coffee @@ -72,6 +72,7 @@ describe "Runs List", -> it "pings api server", -> expect(@ipc.pingApiServer).to.be.called cy.get(".loader") + cy.contains("Loading runs...") describe "success", -> beforeEach -> @@ -425,6 +426,7 @@ describe "Runs List", -> it "shows loading spinner", -> cy.get(".loader") + cy.contains("Loading runs...") it "shows runs when getting runs succeeds", -> @getRuns.resolve(@runs) diff --git a/packages/desktop-gui/cypress/integration/settings_spec.coffee b/packages/desktop-gui/cypress/integration/settings_spec.coffee index b6ceb975a130..020cd8c93863 100644 --- a/packages/desktop-gui/cypress/integration/settings_spec.coffee +++ b/packages/desktop-gui/cypress/integration/settings_spec.coffee @@ -197,16 +197,23 @@ describe "Settings", -> newConfig.browsers = @browsers @openProject.resolve(newConfig) - @goToSettings() - cy.contains("Configuration").click() + @goToSettings().then => + @openProject2ndCall = @util.deferred() + @ipc.openProject.onCall(1).returns(@openProject2ndCall.promise) + @ipc.onConfigChanged.yield() - it "displays updated config", -> - newConfig = @util.deepClone(@config) - newConfig.resolved.baseUrl.value = "http://localhost:7777" - @ipc.openProject.onCall(1).resolves(newConfig) - @ipc.onConfigChanged.yield() + it "re-opens the project", -> + cy.wrap(@ipc.openProject).should("be.calledTwice") - cy.contains("http://localhost:7777") + describe "when project re-opens", -> + beforeEach -> + newConfig = @util.deepClone(@config) + newConfig.resolved.baseUrl.value = "http://localhost:7777" + @openProject2ndCall.resolve(newConfig) + + it "displays updated config", -> + cy.contains("Configuration").click() + cy.contains("http://localhost:7777") describe "errors", -> beforeEach -> diff --git a/packages/desktop-gui/cypress/integration/setup_project_modal_spec.coffee b/packages/desktop-gui/cypress/integration/setup_project_modal_spec.coffee index 3a1cb4a0cded..15c0657d264d 100644 --- a/packages/desktop-gui/cypress/integration/setup_project_modal_spec.coffee +++ b/packages/desktop-gui/cypress/integration/setup_project_modal_spec.coffee @@ -48,6 +48,10 @@ describe "Set Up Project", -> beforeEach -> @getCurrentUser.resolve(@user) + it "shows loader while orgs load", -> + cy.get(".btn").contains("Set up project").click() + cy.get(".loader") + describe "general behavior", -> beforeEach -> @getOrgs.resolve(@orgs) @@ -343,6 +347,7 @@ describe "Set Up Project", -> beforeEach -> cy.stub(@ipc, "windowOpen").resolves() cy.stub(@ipc, "logIn").resolves(@user) + @getOrgs.resolve() cy.contains("button", "Log In with GitHub").click() it "shows setup", -> diff --git a/packages/desktop-gui/cypress/integration/specs_list_spec.coffee b/packages/desktop-gui/cypress/integration/specs_list_spec.coffee index 450fa6d7e2f3..e40ec624ed17 100644 --- a/packages/desktop-gui/cypress/integration/specs_list_spec.coffee +++ b/packages/desktop-gui/cypress/integration/specs_list_spec.coffee @@ -10,9 +10,9 @@ describe "Specs List", -> cy.stub(@ipc, "getOptions").resolves({projectRoot: "/foo/bar"}) cy.stub(@ipc, "getCurrentUser").resolves(@user) - cy.stub(@ipc, "getSpecs").yields(null, @specs) + cy.stub(@ipc, "getSpecs") cy.stub(@ipc, "closeBrowser").resolves(null) - cy.stub(@ipc, "launchBrowser") + cy.stub(@ipc, "launchBrowser").resolves() cy.stub(@ipc, "openFinder") cy.stub(@ipc, "externalOpen") cy.stub(@ipc, "onboardingClosed") @@ -23,6 +23,11 @@ describe "Specs List", -> start() + it "shows loader", -> + @openProject.resolve(@config) + cy.get(".loader") + cy.contains("Loading specs...") + describe "no specs", -> beforeEach -> @ipc.getSpecs.yields(null, []) @@ -47,6 +52,7 @@ describe "Specs List", -> describe "first time onboarding specs", -> beforeEach -> + @ipc.getSpecs.yields(null, @specs) @config.isNewProject = true @openProject.resolve(@config) @@ -123,10 +129,11 @@ describe "Specs List", -> cy .contains(".btn", "Run all specs").click() .then -> - launchArgs = @ipc.launchBrowser.lastCall.args + expect(@ipc.launchBrowser).to.be.called - expect(launchArgs[0].browser.name).to.eq "chrome" - expect(launchArgs[0].spec.name).to.eq "All Specs" + launchArgs = @ipc.launchBrowser.lastCall.args[0] + expect(launchArgs.browser.name).to.eq "chrome" + expect(launchArgs.spec.name).to.eq "All Specs" describe "all specs running in browser", -> beforeEach -> @@ -266,16 +273,15 @@ describe "Specs List", -> @openProject.resolve(@config) cy.contains(".file a", "app_spec.coffee").as("firstSpec") - it "closes then launches browser on click of file", -> + it "launches browser on click of file", -> cy.get("@firstSpec") .click() .then -> - expect(@ipc.closeBrowser).to.be.called + expect(@ipc.launchBrowser).to.be.called - launchArgs = @ipc.launchBrowser.lastCall.args - - expect(launchArgs[0].browser.name).to.equal("chrome") - expect(launchArgs[0].spec.relative).to.equal("cypress/integration/app_spec.coffee") + launchArgs = @ipc.launchBrowser.lastCall.args[0] + expect(launchArgs.browser.name).to.equal("chrome") + expect(launchArgs.spec.relative).to.equal("cypress/integration/app_spec.coffee") it "adds 'active' class on click", -> cy.get("@firstSpec") @@ -315,9 +321,9 @@ describe "Specs List", -> cy.get("@deepSpec").should("have.class", "active") context "switching specs", -> - beforeEach -> @ipc.getSpecs.yields(null, @specs) + @ipc.launchBrowser @openProject.resolve(@config) cy .get(".file").contains("a", "app_spec.coffee").as("firstSpec") diff --git a/packages/desktop-gui/cypress/integration/update_banner_spec.coffee b/packages/desktop-gui/cypress/integration/update_banner_spec.coffee index b50e8f4475ea..7c8f337ee223 100644 --- a/packages/desktop-gui/cypress/integration/update_banner_spec.coffee +++ b/packages/desktop-gui/cypress/integration/update_banner_spec.coffee @@ -18,6 +18,7 @@ describe "Update Banner", -> { @start, @ipc } = win.App cy.stub(@ipc, "getCurrentUser").resolves(@user) + cy.stub(@ipc, "openProject").resolves(@config) cy.stub(@ipc, "windowOpen") cy.stub(@ipc, "externalOpen") @@ -98,7 +99,6 @@ describe "Update Banner", -> describe "in specs list", -> beforeEach -> cy.stub(@ipc, "getOptions").resolves({version: OLD_VERSION, projectRoot: "/foo/bar"}) - cy.stub(@ipc, "openProject").resolves(@config) cy.stub(@ipc, "getSpecs").yields(null, @specs) @start() @updaterCheck.resolve(NEW_VERSION) diff --git a/packages/desktop-gui/package.json b/packages/desktop-gui/package.json index a0a0827e9a89..63b8e79e0552 100644 --- a/packages/desktop-gui/package.json +++ b/packages/desktop-gui/package.json @@ -49,7 +49,6 @@ "rebuild-node-sass": "1.1.0", "react-bootstrap-modal": "4.2.0", "react-dom": "^16.7.0", - "react-loader": "^2.4.5", - "zunder": "6.3.0" + "zunder": "6.3.2" } } diff --git a/packages/desktop-gui/src/app/app.jsx b/packages/desktop-gui/src/app/app.jsx index 1e46d6b8ee37..1ac28a95afa3 100644 --- a/packages/desktop-gui/src/app/app.jsx +++ b/packages/desktop-gui/src/app/app.jsx @@ -1,7 +1,6 @@ import _ from 'lodash' import { observer } from 'mobx-react' import React, { Component } from 'react' -import Loader from 'react-loader' import appApi from '../lib/app-api' import C from '../lib/constants' @@ -12,6 +11,7 @@ import viewStore from '../lib/view-store' import Intro from './intro' import Layout from './layout' +import Loader from '../lib/loader' import Project from '../project/project' @observer @@ -30,7 +30,7 @@ class App extends Component { render () { switch (viewStore.currentView.name) { case C.LOADING: - return + return case C.INTRO: return ( diff --git a/packages/desktop-gui/src/app/layout.jsx b/packages/desktop-gui/src/app/layout.jsx index 580d618ebf66..92ed220d2d33 100644 --- a/packages/desktop-gui/src/app/layout.jsx +++ b/packages/desktop-gui/src/app/layout.jsx @@ -5,6 +5,7 @@ import GlobalError from './global-error' import Footer from '../footer/footer' import LoginModal from '../auth/login-modal' import UpdateBanner from '../update/update-banner' +import UiBlocker from './ui-blocker' export default ({ children }) => { return ( @@ -15,6 +16,7 @@ export default ({ children }) => {