diff --git a/packages/desktop-gui/cypress/fixtures/specs.json b/packages/desktop-gui/cypress/fixtures/specs.json index 5c0e5905ca0e..ff5b702facec 100644 --- a/packages/desktop-gui/cypress/fixtures/specs.json +++ b/packages/desktop-gui/cypress/fixtures/specs.json @@ -27,8 +27,32 @@ "relative": "cypress/unit/admin_users/admin/users/bar_list_spec.coffee" }, { - "name": "admin_users/admin/users/all/admin/baz_list_spec.coffee", - "relative": "cypress/unit/admin_users/admin/users/all/admin/baz_list_spec.coffee" + "name": "admin_users/admin/users/all/admin/one_list_spec.coffee", + "relative": "cypress/unit/admin_users/admin/users/all/admin/one_list_spec.coffee" + }, + { + "name": "admin_users/admin/users/all/admin/two_list_spec.coffee", + "relative": "cypress/unit/admin_users/admin/users/all/admin/two_list_spec.coffee" + }, + { + "name": "admin_users/admin/users/all/admin/three_list_spec.coffee", + "relative": "cypress/unit/admin_users/admin/users/all/admin/three_list_spec.coffee" + }, + { + "name": "admin_users/admin/users/all/admin/four_list_spec.coffee", + "relative": "cypress/unit/admin_users/admin/users/all/admin/four_list_spec.coffee" + }, + { + "name": "admin_users/admin/users/all/admin/five_list_spec.coffee", + "relative": "cypress/unit/admin_users/admin/users/all/admin/five_list_spec.coffee" + }, + { + "name": "admin_users/admin/users/all/admin/six_list_spec.coffee", + "relative": "cypress/unit/admin_users/admin/users/all/admin/six_list_spec.coffee" + }, + { + "name": "admin_users/admin/users/all/admin/last_list_spec.coffee", + "relative": "cypress/unit/admin_users/admin/users/all/admin/last_list_spec.coffee" } ] } diff --git a/packages/desktop-gui/cypress/fixtures/specs_windows.json b/packages/desktop-gui/cypress/fixtures/specs_windows.json index 093c9a06d879..3d70d301dae1 100644 --- a/packages/desktop-gui/cypress/fixtures/specs_windows.json +++ b/packages/desktop-gui/cypress/fixtures/specs_windows.json @@ -27,8 +27,8 @@ "relative": "cypress\\unit\\admin_users\\admin\\users\\bar_list_spec.coffee" }, { - "name": "admin_users\\admin\\users\\all\\admin\\baz_list_spec.coffee", - "relative": "cypress\\unit\\admin_users\\admin\\users\\all\\admin\\baz_list_spec.coffee" + "name": "admin_users\\admin\\users\\all\\admin\\last_list_spec.coffee", + "relative": "cypress\\unit\\admin_users\\admin\\users\\all\\admin\\last_list_spec.coffee" } ] } diff --git a/packages/desktop-gui/cypress/integration/error_message_spec.js b/packages/desktop-gui/cypress/integration/error_message_spec.js index defa08158313..fb90b7f50462 100644 --- a/packages/desktop-gui/cypress/integration/error_message_spec.js +++ b/packages/desktop-gui/cypress/integration/error_message_spec.js @@ -67,7 +67,7 @@ describe('ErrorMessage', function () { this.ipc.openProject.rejects({ name: 'Error', message: this.longErrMessage, stack: '[object Object]↵' }) this.start() - cy.get('#updates-available').should('be.visible') + cy.get('.updates-available').should('be.visible') .contains('New updates are available') cy.get('.error') diff --git a/packages/desktop-gui/cypress/integration/project_mode_spec.js b/packages/desktop-gui/cypress/integration/project_mode_spec.js index 84ea1f3adf8d..52268f6eae7a 100644 --- a/packages/desktop-gui/cypress/integration/project_mode_spec.js +++ b/packages/desktop-gui/cypress/integration/project_mode_spec.js @@ -2,77 +2,57 @@ describe('Project Mode', function () { beforeEach(function () { cy.fixture('user').as('user') cy.fixture('config').as('config') - cy.fixture('specs').as('specs') - }) - - context('Mac', function () { - beforeEach(function () { - cy.visitIndex().then((win) => { - let start = win.App.start - - this.win = win - this.ipc = win.App.ipc - this.config.projectName = 'my-kitchen-sink' + cy.visitIndex().then((win) => { + this.start = win.App.start + this.ipc = win.App.ipc - cy.stub(this.ipc, 'onMenuClicked') - cy.stub(this.ipc, 'onFocusTests') - cy.stub(this.ipc, 'getOptions').resolves({ projectRoot: '/foo/bar' }) - cy.stub(this.ipc, 'updaterCheck').resolves(false) - cy.stub(this.ipc, 'openProject').resolves(this.config) - cy.stub(this.ipc, 'getSpecs').yields(null, this.specs) + this.config.projectName = 'my-kitchen-sink' - this.getCurrentUser = this.util.deferred() + cy.stub(this.ipc, 'onMenuClicked') + cy.stub(this.ipc, 'onFocusTests') + cy.stub(this.ipc, 'getOptions').resolves({ projectRoot: '/foo/bar' }) + cy.stub(this.ipc, 'updaterCheck').resolves(false) + cy.stub(this.ipc, 'openProject').resolves(this.config) + cy.stub(this.ipc, 'getSpecs') - start() - }) + this.getCurrentUser = this.util.deferred() }) + }) - it('goes straight to project specs list', () => { - cy.shouldBeOnProjectSpecs() - }) + it('displays footer on bottom when loading (issue #4888)', function () { + const openProject = this.util.deferred() - it('sets title as project path', () => { - cy.title().should('eq', '/foo/bar') - }) + this.ipc.openProject.resolves(openProject.promise) + this.start() - it('shows project name in nav', function () { - cy.get('.main-nav .nav:first-child div') - .should('contain', this.config.projectName) - .and('not.contain', 'foo') - }) + cy.get('footer').invoke('position').its('top').should('be.gt', 50) }) - context('Windows', function () { + describe('when specs load', function () { beforeEach(function () { - cy.visitIndex().then((win) => { - let start; - - ({ start, ipc: this.ipc } = win.App) - - cy.stub(this.ipc, 'onMenuClicked') - cy.stub(this.ipc, 'onFocusTests') - cy.stub(this.ipc, 'getOptions').resolves({ projectRoot: 'C:\\foo\\bar' }) - cy.stub(this.ipc, 'updaterCheck').resolves(false) - cy.stub(this.ipc, 'openProject').resolves(this.config) - cy.stub(this.ipc, 'getSpecs').yields(null, this.specs) - - this.getCurrentUser = this.util.deferred() - - start() - }) + this.ipc.getSpecs.yields(null, this.specs) }) - it('goes straight to project specs list', () => { + it('goes straight to project specs list', function () { + this.start() cy.shouldBeOnProjectSpecs() }) - it('sets title as project path', () => { + it('sets title as project path on Mac/Linux', function () { + this.start() + cy.title().should('eq', '/foo/bar') + }) + + it('sets title as project path on Windows', function () { + this.ipc.getOptions.resolves({ projectRoot: 'C:\\foo\\bar' }) + this.start() cy.title().should('eq', 'C:\\foo\\bar') }) it('shows project name in nav', function () { + this.start() cy.get('.main-nav .nav:first-child div') .should('contain', this.config.projectName) .and('not.contain', 'foo') diff --git a/packages/desktop-gui/cypress/integration/specs_list_spec.js b/packages/desktop-gui/cypress/integration/specs_list_spec.js index 3864e32d8a2b..cafcb9c998cf 100644 --- a/packages/desktop-gui/cypress/integration/specs_list_spec.js +++ b/packages/desktop-gui/cypress/integration/specs_list_spec.js @@ -11,6 +11,8 @@ describe('Specs List', function () { this.win = win this.ipc = win.App.ipc + this.numSpecs = this.specs.integration.length + this.specs.unit.length + cy.stub(this.ipc, 'getOptions').resolves({ projectRoot: '/foo/bar' }) cy.stub(this.ipc, 'getCurrentUser').resolves(this.user) cy.stub(this.ipc, 'getSpecs').yields(null, this.specs) @@ -144,7 +146,7 @@ describe('Specs List', function () { }) it('lists test specs', function () { - cy.get('.file a').last().should('contain', 'baz_list_spec.coffee') + cy.get('.file a').last().should('contain', 'last_list_spec.coffee') cy.get('.file a').last().should('not.contain', 'admin_users') }) }) @@ -198,7 +200,6 @@ describe('Specs List', function () { context('displays list of specs', function () { it('lists main folders of specs', function () { cy.contains('.folder.level-0', 'integration') - cy.contains('.folder.level-0', 'unit') }) @@ -211,8 +212,7 @@ describe('Specs List', function () { }) it('lists folder with \'.\'', function () { - cy.get('.file').should('have.length', 7) - + cy.get('.file').should('have.length', this.numSpecs) cy.get('.folder').should('have.length', 10) }) }) @@ -226,10 +226,10 @@ describe('Specs List', function () { }) it('hides children when folder clicked', function () { - cy.get('.file').should('have.length', 7) + cy.get('.file').should('have.length', this.numSpecs) cy.get('.folder .folder-name:first').click() - cy.get('.file').should('have.length', 2) + cy.get('.file').should('have.length', 8) }) it('sets folder expanded when clicked twice', function () { @@ -243,7 +243,7 @@ describe('Specs List', function () { it('hides children for every folder collapsed', function () { const lastExpandedFolderSelector = '.folder-expanded:last > div > .folder-name:last' - cy.get('.file').should('have.length', 7) + cy.get('.file').should('have.length', this.numSpecs) cy.get(lastExpandedFolderSelector).click() cy.get('.file').should('have.length', 6) @@ -280,6 +280,14 @@ describe('Specs List', function () { }) context('filtering specs', function () { + it('scrolls the specs and not the filter', function () { + this.ipc.getSpecs.yields(null, this.specs) + this.openProject.resolve(this.config) + + cy.contains('last_list_spec').scrollIntoView() + cy.get('.filter').should('be.visible') + }) + describe('typing the filter', function () { beforeEach(function () { this.ipc.getSpecs.yields(null, this.specs) @@ -289,13 +297,13 @@ describe('Specs List', function () { }) it('displays only matching spec', () => { - cy.get('.outer-files-container .file') + cy.get('.specs-list .file') .should('have.length', 1) .and('contain', 'account_new_spec.coffee') }) it('only shows matching folders', () => { - cy.get('.outer-files-container .folder') + cy.get('.specs-list .folder') .should('have.length', 2) }) @@ -304,21 +312,21 @@ describe('Specs List', function () { cy.get('.filter') .should('have.value', '') - cy.get('.outer-files-container .file') - .should('have.length', 7) + cy.get('.specs-list .file') + .should('have.length', this.numSpecs) }) it('clears the filter if the user press ESC key', function () { cy.get('.filter').type('{esc}') .should('have.value', '') - cy.get('.outer-files-container .file') - .should('have.length', 7) + cy.get('.specs-list .file') + .should('have.length', this.numSpecs) }) it('shows empty message if no results', function () { cy.get('.filter').clear().type('foobarbaz') - cy.get('.outer-files-container').should('not.exist') + cy.get('.specs-list').should('not.exist') cy.get('.empty-well').should('contain', 'No specs match your search: "foobarbaz"') }) @@ -328,8 +336,8 @@ describe('Specs List', function () { cy.get('.btn').contains('Clear search').click() cy.focused().should('have.id', 'filter') - cy.get('.outer-files-container .file') - .should('have.length', 7) + cy.get('.specs-list .file') + .should('have.length', this.numSpecs) }) it('saves the filter to local storage for the project', function () { @@ -427,7 +435,7 @@ describe('Specs List', function () { context('choose deeper nested spec', function () { beforeEach(() => { - cy.get('.file a').contains('a', 'baz_list_spec.coffee').as('deepSpec').click() + cy.get('.file a').contains('a', 'last_list_spec.coffee').as('deepSpec').click() }) it('updates spec icon', () => { diff --git a/packages/desktop-gui/cypress/integration/update_banner_spec.js b/packages/desktop-gui/cypress/integration/update_banner_spec.js index 527ba10b7de3..540e42ce789b 100644 --- a/packages/desktop-gui/cypress/integration/update_banner_spec.js +++ b/packages/desktop-gui/cypress/integration/update_banner_spec.js @@ -44,7 +44,7 @@ describe('Update Banner', function () { it('does not display update banner when no update available', function () { this.updaterCheck.resolve(false) - cy.get('#updates-available').should('not.exist') + cy.get('.updates-available').should('not.exist') cy.get('html').should('not.have.class', 'has-updates') }) @@ -55,7 +55,7 @@ describe('Update Banner', function () { it('displays banner if new version is available', function () { this.updaterCheck.resolve(NEW_VERSION) - cy.get('#updates-available').should('be.visible') + cy.get('.updates-available').should('be.visible') cy.contains('New updates are available') cy.get('html').should('have.class', 'has-updates') @@ -139,7 +139,7 @@ describe('Update Banner', function () { this.start() this.updaterCheck.resolve(NEW_VERSION) - cy.get('#updates-available') + cy.get('.updates-available') }) it('displays all folders/specs within visible area', () => { @@ -147,6 +147,11 @@ describe('Update Banner', function () { .last() .scrollIntoView() .should('be.visible') + + cy.get('.file-name') + .last() + .scrollIntoView() + .should('be.visible') }) }) }) diff --git a/packages/desktop-gui/src/project/project.jsx b/packages/desktop-gui/src/project/project.jsx index de5393ceaab8..6dce5c32de80 100644 --- a/packages/desktop-gui/src/project/project.jsx +++ b/packages/desktop-gui/src/project/project.jsx @@ -35,7 +35,13 @@ class Project extends Component { } render () { - if (this.props.project.isLoading) return + if (this.props.project.isLoading) { + return ( +
+ +
+ ) + } if (this.props.project.error) return diff --git a/packages/desktop-gui/src/project/project.scss b/packages/desktop-gui/src/project/project.scss index fc299d3964e2..f17403995f59 100644 --- a/packages/desktop-gui/src/project/project.scss +++ b/packages/desktop-gui/src/project/project.scss @@ -1,6 +1,6 @@ .project-content { + display: flex; flex-grow: 2; - overflow: auto; margin-bottom: 0; width: 100%; } diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index 0d071ee56c57..b93595eeecde 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -22,7 +22,7 @@ class SpecsList extends Component { if (!specsStore.filter && !specsStore.specs.length) return this._empty() return ( -
+
+
    {_.map(specsStore.specs, (spec) => this._specItem(spec, 0))}
) @@ -168,7 +168,7 @@ class SpecsList extends Component { _empty () { return ( -
+
No files found in diff --git a/packages/desktop-gui/src/specs/specs.scss b/packages/desktop-gui/src/specs/specs.scss index d3feff7cbaa2..decbe8b902cb 100644 --- a/packages/desktop-gui/src/specs/specs.scss +++ b/packages/desktop-gui/src/specs/specs.scss @@ -1,8 +1,10 @@ // maximum supported file structure nesting level $max-nesting-level: 14; -#tests-list-page { - position: relative; +.specs { + display: flex; + flex-direction: column; + width: 100%; .empty-well code { display: block; @@ -11,9 +13,6 @@ $max-nesting-level: 14; } header { - position: relative; - display: block; - width: 100%; height: 42px; background: #f5f5f5; border-bottom: 1px solid #ddd; @@ -106,9 +105,10 @@ $max-nesting-level: 14; border-top: 0; } - .outer-files-container { + .specs-list { @include list-columns(100%); margin-bottom: 0; + overflow: auto; } .file, .folder { diff --git a/packages/desktop-gui/src/styles/components/_loading.scss b/packages/desktop-gui/src/styles/components/_loading.scss index 429a2ef296cf..64502bedb226 100644 --- a/packages/desktop-gui/src/styles/components/_loading.scss +++ b/packages/desktop-gui/src/styles/components/_loading.scss @@ -1 +1,7 @@ -[data-wrapper].opacity { @include opacity(0.4); } \ No newline at end of file +[data-wrapper].opacity { + @include opacity(0.4); +} + +.loader-wrap { + flex-grow: 2; +} diff --git a/packages/desktop-gui/src/update/update-banner.jsx b/packages/desktop-gui/src/update/update-banner.jsx index 73a752a5936e..ddd0f79ff29c 100644 --- a/packages/desktop-gui/src/update/update-banner.jsx +++ b/packages/desktop-gui/src/update/update-banner.jsx @@ -33,7 +33,7 @@ class UpdateBanner extends Component { document.getElementsByTagName('html')[0].classList.add('has-updates') return ( -
+
New updates are available this._toggleModal(true)}> {' '} diff --git a/packages/desktop-gui/src/update/updates.scss b/packages/desktop-gui/src/update/updates.scss index 7a7e3fd7957d..eba5c3e21643 100644 --- a/packages/desktop-gui/src/update/updates.scss +++ b/packages/desktop-gui/src/update/updates.scss @@ -1,9 +1,6 @@ -#updates-available { +.updates-available { text-align: center; background-color: #D9EDF7; - position: fixed; - bottom: 20px; - width: 100%; color: #3A87AD; line-height: 35px; font-size: 14px;