From 868472c7dad6e02c3c1ab7c883838aaf1efbccdb Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Tue, 6 Apr 2021 15:29:32 -0400 Subject: [PATCH 01/54] update example build scripts --- packages/example/README.md | 2 +- packages/example/bin/build.js | 2 ++ packages/example/bin/convert.js | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/example/README.md b/packages/example/README.md index a9f94349e587..6ab87bd6b9f7 100644 --- a/packages/example/README.md +++ b/packages/example/README.md @@ -11,7 +11,7 @@ The actual example repo you're probably looking for is [the kitchen sink app her **THERE'S LIKELY NO REASON YOU NEED TO EDIT ANY OF THE CODE ON THIS REPO.** -- Want to edit the `example` tests? -> edit it [here](https://github.com/cypress-io/cypress-example-kitchensink/blob/master/cypress/integration/examples) instead. +- Want to edit the `example` tests? -> edit it [here](https://github.com/cypress-io/cypress-example-kitchensink/blob/master/cypress/integration) instead. - Want to edit the actual [https://example.cypress.io](https://example.cypress.io) website? edit it [here](https://github.com/cypress-io/cypress-example-kitchensink/tree/master/app) instead. ## Updating the `example` app diff --git a/packages/example/bin/build.js b/packages/example/bin/build.js index e46b80331f1e..b68192ea6945 100644 --- a/packages/example/bin/build.js +++ b/packages/example/bin/build.js @@ -15,4 +15,6 @@ shell.rm('-rf', 'cypress') shell.cp('-r', join(resolvePkg('cypress-example-kitchensink'), 'cypress'), '.') +shell.rm('-rf', join('cypress', 'integration', 'examples')) + shell.exec('node ./bin/convert.js') diff --git a/packages/example/bin/convert.js b/packages/example/bin/convert.js index 4936485cd923..6ed5ac0bd9da 100755 --- a/packages/example/bin/convert.js +++ b/packages/example/bin/convert.js @@ -41,7 +41,7 @@ function replaceStringsIn (file) { glob('./app/**/*.html', { realpath: true }, (err, htmlFiles) => { if (err) throw err - glob('./cypress/integration/examples/**/*', { realpath: true }, (err, specFiles) => { + glob('./cypress/integration/**/*', { realpath: true }, (err, specFiles) => { if (err) throw err htmlFiles.concat(specFiles).forEach(function (file) { From 735a9badefa4068a7ce7b595cd6c60690733b72f Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Tue, 6 Apr 2021 16:15:01 -0400 Subject: [PATCH 02/54] remove old scaffolding relics --- cli/types/cypress.d.ts | 2 -- .../desktop-gui/cypress/fixtures/config.json | 2 -- .../cypress/integration/specs_list_spec.js | 6 ----- .../desktop-gui/src/project/onboarding.jsx | 23 +++++++------------ .../desktop-gui/src/project/project-model.js | 4 ---- packages/example/lib/example.d.ts | 1 - packages/example/lib/example.js | 5 ---- packages/example/test/example_spec.js | 2 +- packages/server/lib/config.js | 3 --- packages/server/lib/scaffold.js | 7 +----- packages/server/test/unit/config_spec.js | 10 ++++---- packages/server/test/unit/scaffold_spec.js | 9 +------- 12 files changed, 16 insertions(+), 58 deletions(-) diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index a50afbaf9f6a..e5c3619b6780 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -2726,8 +2726,6 @@ declare namespace Cypress { clientRoute: string configFile: string cypressEnv: string - integrationExampleName: string - integrationExamplePath: string isNewProject: boolean isTextTerminal: boolean morgan: boolean diff --git a/packages/desktop-gui/cypress/fixtures/config.json b/packages/desktop-gui/cypress/fixtures/config.json index b7b740f7fd05..beb7a51cd09d 100644 --- a/packages/desktop-gui/cypress/fixtures/config.json +++ b/packages/desktop-gui/cypress/fixtures/config.json @@ -128,8 +128,6 @@ "execTimeout": 60000, "fileServerFolder": "/Users/jennifer/Dev/Projects/cypress-example-kitchensink", "fixturesFolder": "/Users/jennifer/Dev/Projects/cypress-example-kitchensink/cypress/fixtures", - "integrationExamplePath": "/Users/jennifer/Dev/Projects/cypress-example-kitchensink/cypress/integration/examples", - "integrationExampleName": "examples", "integrationFolder": "/Users/jennifer/Dev/Projects/cypress-example-kitchensink/cypress/integration", "isHeadless": false, "isNewProject": false, diff --git a/packages/desktop-gui/cypress/integration/specs_list_spec.js b/packages/desktop-gui/cypress/integration/specs_list_spec.js index 6416ff31e4cf..0b6b6d0a1801 100644 --- a/packages/desktop-gui/cypress/integration/specs_list_spec.js +++ b/packages/desktop-gui/cypress/integration/specs_list_spec.js @@ -157,12 +157,6 @@ describe('Specs List', function () { }) }) - it('triggers open:finder on click of example folder', function () { - cy.get('.modal').contains('examples').click().then(() => { - expect(this.ipc.openFinder).to.be.calledWith(this.config.integrationExamplePath) - }) - }) - it('triggers open:finder on click of text folder', function () { cy.get('.modal').contains('cypress/integration').click().then(() => { expect(this.ipc.openFinder).to.be.calledWith(this.config.integrationFolder) diff --git a/packages/desktop-gui/src/project/onboarding.jsx b/packages/desktop-gui/src/project/onboarding.jsx index 851b8ff89277..f308c0abca3f 100644 --- a/packages/desktop-gui/src/project/onboarding.jsx +++ b/packages/desktop-gui/src/project/onboarding.jsx @@ -41,14 +41,11 @@ class OnBoarding extends Component {

To help you get started...

- We've added some folders and example tests to your project. Try running the tests in the - - {' '} - {project.integrationExampleName}{' '} - - folder or add your own test files to + We've added an example test file to your project. Try running{' '} + example.spec.js{' '} + or add your own test files to - {' '} + {' '} cypress/integration .

@@ -56,13 +53,13 @@ class OnBoarding extends Component {
  • - {' '} + {' '} {project.name}
    • - {' '} + {' '} ...
    • @@ -98,7 +95,7 @@ class OnBoarding extends Component { return (
    • - {' '} + {' '} {file.name}
        @@ -111,7 +108,7 @@ class OnBoarding extends Component { return (
      • - {' '} + {' '} {file.name}
      • @@ -119,10 +116,6 @@ class OnBoarding extends Component { }) } - _openExampleSpec = () => { - ipc.openFinder(this.props.project.integrationExamplePath) - } - _openIntegrationFolder = () => { ipc.openFinder(this.props.project.integrationFolder) } diff --git a/packages/desktop-gui/src/project/project-model.js b/packages/desktop-gui/src/project/project-model.js index eadb7105f333..f5e7ac074300 100644 --- a/packages/desktop-gui/src/project/project-model.js +++ b/packages/desktop-gui/src/project/project-model.js @@ -26,7 +26,6 @@ const validProps = cacheProps.concat([ 'browserState', 'resolvedConfig', 'parentTestsFolderDisplay', - 'integrationExampleName', 'scaffoldedFiles', 'resolvedNodePath', 'resolvedNodeVersion', @@ -62,7 +61,6 @@ export default class Project { @observable _warnings = {} @observable apiError @observable parentTestsFolderDisplay - @observable integrationExampleName @observable scaffoldedFiles = [] @observable resolvedNodePath @observable resolvedNodeVersion @@ -207,8 +205,6 @@ export default class Project { this.integrationFolder = config.integrationFolder this.parentTestsFolderDisplay = config.parentTestsFolderDisplay this.fileServerFolder = config.fileServerFolder - this.integrationExampleName = config.integrationExampleName - this.integrationExamplePath = config.integrationExamplePath this.scaffoldedFiles = config.scaffoldedFiles } diff --git a/packages/example/lib/example.d.ts b/packages/example/lib/example.d.ts index 35ea4dbef283..538f7529821d 100644 --- a/packages/example/lib/example.d.ts +++ b/packages/example/lib/example.d.ts @@ -1,6 +1,5 @@ declare const example: { getPathToExamples(): Promise; - getFolderName(): string; getPathToPlugins(): string; getPathToSupportFiles(): Promise; getPathToTsConfig(): string; diff --git a/packages/example/lib/example.js b/packages/example/lib/example.js index e5e95a541c1f..dc83800630b6 100644 --- a/packages/example/lib/example.js +++ b/packages/example/lib/example.js @@ -10,16 +10,11 @@ module.exports = { '..', 'cypress', 'integration', - 'examples', '**', '*' ) ) }, - - getFolderName () { - return 'examples' - }, getPathToPlugins() { return path.resolve(__dirname, '..', 'cypress', 'plugins', 'index.js') diff --git a/packages/example/test/example_spec.js b/packages/example/test/example_spec.js index f793c968705e..16e6892279ba 100644 --- a/packages/example/test/example_spec.js +++ b/packages/example/test/example_spec.js @@ -9,7 +9,7 @@ const cwd = process.cwd() /* global describe, it */ describe('Cypress Example', function () { it('returns path to example_spec', function () { - const expected = path.normalize(`${cwd}/cypress/integration/examples`) + const expected = path.normalize(`${cwd}/cypress/integration`) return example.getPathToExamples() .then(expectToAllEqual(expected)) diff --git a/packages/server/lib/config.js b/packages/server/lib/config.js index e996da02d0b4..0ae8da6afafc 100644 --- a/packages/server/lib/config.js +++ b/packages/server/lib/config.js @@ -472,9 +472,6 @@ module.exports = { setScaffoldPaths (obj) { obj = _.clone(obj) - obj.integrationExampleName = scaffold.integrationExampleName() - obj.integrationExamplePath = path.join(obj.integrationFolder, obj.integrationExampleName) - debug('set scaffold paths') return scaffold.fileTree(obj) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 2dbb92f0fd7f..bbcd2bb79f67 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -9,7 +9,6 @@ const debug = require('debug')('cypress:server:scaffold') const { isEmpty } = require('ramda') const { isDefault } = require('./util/config') -const exampleFolderName = cypressEx.getFolderName() const getExampleSpecsFullPaths = cypressEx.getPathToExamples() const getPathFromIntegrationFolder = (file) => { @@ -121,10 +120,6 @@ const isNewProject = (integrationFolder) => { module.exports = { isNewProject, - integrationExampleName () { - return exampleFolderName - }, - integration (folder, config) { debug(`integration folder ${folder}`) @@ -140,7 +135,7 @@ module.exports = { return getExampleSpecs() .then(({ fullPaths }) => { return Promise.all(_.map(fullPaths, (file) => { - return this._copy(file, path.join(folder, exampleFolderName), config) + return this._copy(file, folder, config) })) }) }) diff --git a/packages/server/test/unit/config_spec.js b/packages/server/test/unit/config_spec.js index 9929a43d5c64..33f9a650215d 100644 --- a/packages/server/test/unit/config_spec.js +++ b/packages/server/test/unit/config_spec.js @@ -1879,19 +1879,19 @@ describe('lib/config', () => { }) context('.setScaffoldPaths', () => { - it('sets integrationExamplePath + integrationExampleName + scaffoldedFiles', () => { + it('sets scaffoldedFiles', () => { const obj = { integrationFolder: '/_test-output/path/to/project/cypress/integration', } - sinon.stub(scaffold, 'fileTree').resolves([]) + const scaffoldedFiles = ['/_test-output/path/to/project/cypress/integration/example.spec.js'] + + sinon.stub(scaffold, 'fileTree').resolves(scaffoldedFiles) return config.setScaffoldPaths(obj).then((result) => { expect(result).to.deep.eq({ integrationFolder: '/_test-output/path/to/project/cypress/integration', - integrationExamplePath: '/_test-output/path/to/project/cypress/integration/examples', - integrationExampleName: 'examples', - scaffoldedFiles: [], + scaffoldedFiles, }) }) }) diff --git a/packages/server/test/unit/scaffold_spec.js b/packages/server/test/unit/scaffold_spec.js index 48483e719426..7daaaefb03f4 100644 --- a/packages/server/test/unit/scaffold_spec.js +++ b/packages/server/test/unit/scaffold_spec.js @@ -20,12 +20,6 @@ describe('lib/scaffold', () => { return Fixtures.remove() }) - context('.integrationExampleName', () => { - it('returns examples', () => { - expect(scaffold.integrationExampleName()).to.eq('examples') - }) - }) - // TODO: fix it later context.skip('.isNewProject', () => { beforeEach(function () { @@ -90,8 +84,7 @@ describe('lib/scaffold', () => { .then((cfg) => { return pristine.scaffold(cfg).return(cfg) }).then((cfg) => { - const example = scaffold.integrationExampleName() - const file = path.join(cfg.integrationFolder, example) + const file = path.join(cfg.integrationFolder, 'example.spec.js') // write some data to the file so it is now // different in file size From 8ebce4b104c2f3f91d085e9dd71127e2fa96acea Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Tue, 13 Apr 2021 18:27:27 -0400 Subject: [PATCH 03/54] update --- packages/example/bin/build.js | 2 -- packages/example/bin/convert.js | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/example/bin/build.js b/packages/example/bin/build.js index b68192ea6945..e46b80331f1e 100644 --- a/packages/example/bin/build.js +++ b/packages/example/bin/build.js @@ -15,6 +15,4 @@ shell.rm('-rf', 'cypress') shell.cp('-r', join(resolvePkg('cypress-example-kitchensink'), 'cypress'), '.') -shell.rm('-rf', join('cypress', 'integration', 'examples')) - shell.exec('node ./bin/convert.js') diff --git a/packages/example/bin/convert.js b/packages/example/bin/convert.js index 6ed5ac0bd9da..c1fd6aa3c569 100755 --- a/packages/example/bin/convert.js +++ b/packages/example/bin/convert.js @@ -41,7 +41,7 @@ function replaceStringsIn (file) { glob('./app/**/*.html', { realpath: true }, (err, htmlFiles) => { if (err) throw err - glob('./cypress/integration/**/*', { realpath: true }, (err, specFiles) => { + glob('./cypress/integration/**/*.js', { realpath: true }, (err, specFiles) => { if (err) throw err htmlFiles.concat(specFiles).forEach(function (file) { From 141b1637279c939682387b4313845bfcab49d8e4 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Tue, 20 Apr 2021 23:41:39 -0400 Subject: [PATCH 04/54] Fix some issues with scaffolding --- packages/example/bin/build.js | 4 +--- packages/example/package.json | 2 +- packages/server/lib/scaffold.js | 21 ++++++++++++++++----- packages/server/test/unit/scaffold_spec.js | 2 +- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/packages/example/bin/build.js b/packages/example/bin/build.js index e46b80331f1e..3873aabd2046 100644 --- a/packages/example/bin/build.js +++ b/packages/example/bin/build.js @@ -8,11 +8,9 @@ shell.set('-v') // verbose shell.set('-e') // any error is fatal shell.rm('-rf', 'app') -shell.mkdir('app') - shell.cp('-r', join(resolvePkg('cypress-example-kitchensink'), 'app'), '.') -shell.rm('-rf', 'cypress') +shell.rm('-rf', 'cypress') shell.cp('-r', join(resolvePkg('cypress-example-kitchensink'), 'cypress'), '.') shell.exec('node ./bin/convert.js') diff --git a/packages/example/package.json b/packages/example/package.json index 7b9a4cbc3b1f..899db5f43d00 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -35,6 +35,6 @@ "gulp-rev-all": "2.0.2", "mocha": "2.5.3", "resolve-pkg": "2.0.0", - "shelljs": "0.8.3" + "shelljs": "0.8.4" } } diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index bbcd2bb79f67..d200c662c172 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -135,7 +135,7 @@ module.exports = { return getExampleSpecs() .then(({ fullPaths }) => { return Promise.all(_.map(fullPaths, (file) => { - return this._copy(file, folder, config) + return this._copy(file, folder, config, true) })) }) }) @@ -193,14 +193,20 @@ module.exports = { }) }, - _copy (file, folder, config) { + _copy (file, folder, config, integration = false) { // allow file to be relative or absolute const src = path.resolve(cwd('lib', 'scaffold'), file) - const dest = path.join(folder, path.basename(file)) + const destFile = integration ? getPathFromIntegrationFolder(file) : path.basename(file) + const dest = path.join(folder, destFile) return this._assertInFileTree(dest, config) .then(() => { - return fs.copyAsync(src, dest) + return fs.copyAsync(src, dest).catch((e) => { + // catch if copy tries to create a directory that already exists + if (e.code !== 'EEXIST' || e.syscall !== 'mkdir') { + throw e + } + }) }) }, @@ -283,10 +289,11 @@ module.exports = { _.each(parts, (part, index) => { let entry = _.find(placeholder, { name: part }) + const isDirectory = index < (parts.length - 1) if (!entry) { entry = { name: part } - if (index < (parts.length - 1)) { + if (isDirectory) { // if it's not the last, it's a directory entry.children = [] } @@ -294,6 +301,10 @@ module.exports = { placeholder.push(entry) } + if (!entry.children && isDirectory) { + entry.children = [] + } + placeholder = entry.children }) diff --git a/packages/server/test/unit/scaffold_spec.js b/packages/server/test/unit/scaffold_spec.js index 7daaaefb03f4..aa36dfb57b14 100644 --- a/packages/server/test/unit/scaffold_spec.js +++ b/packages/server/test/unit/scaffold_spec.js @@ -120,7 +120,7 @@ describe('lib/scaffold', () => { .spread((exampleSpecs) => { return Promise.join( fs.statAsync(`${this.integrationFolder}/examples/actions.spec.js`).get('size'), - fs.statAsync(exampleSpecs[0]).get('size'), + fs.statAsync(exampleSpecs[1]).get('size'), fs.statAsync(`${this.integrationFolder}/examples/location.spec.js`).get('size'), fs.statAsync(exampleSpecs[8]).get('size'), ).spread((size1, size2, size3, size4) => { From b1a965cdee2225ed2b10f5cb6f2aba3b1b199cec Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Wed, 21 Apr 2021 17:18:12 -0400 Subject: [PATCH 05/54] Correctly fix issues with scaffolding --- packages/example/lib/example.js | 3 ++- packages/example/test/example_spec.js | 2 +- packages/server/lib/scaffold.js | 14 ++---------- packages/server/test/unit/scaffold_spec.js | 25 +++++++++------------- 4 files changed, 15 insertions(+), 29 deletions(-) diff --git a/packages/example/lib/example.js b/packages/example/lib/example.js index dc83800630b6..d7607158fa42 100644 --- a/packages/example/lib/example.js +++ b/packages/example/lib/example.js @@ -12,7 +12,8 @@ module.exports = { 'integration', '**', '*' - ) + ), + { nodir: true } ) }, diff --git a/packages/example/test/example_spec.js b/packages/example/test/example_spec.js index 16e6892279ba..3e1d38374452 100644 --- a/packages/example/test/example_spec.js +++ b/packages/example/test/example_spec.js @@ -8,7 +8,7 @@ const cwd = process.cwd() /* global describe, it */ describe('Cypress Example', function () { - it('returns path to example_spec', function () { + it('returns path to examples', function () { const expected = path.normalize(`${cwd}/cypress/integration`) return example.getPathToExamples() diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index d200c662c172..e4fbe88f504b 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -201,12 +201,7 @@ module.exports = { return this._assertInFileTree(dest, config) .then(() => { - return fs.copyAsync(src, dest).catch((e) => { - // catch if copy tries to create a directory that already exists - if (e.code !== 'EEXIST' || e.syscall !== 'mkdir') { - throw e - } - }) + return fs.copyAsync(src, dest) }) }, @@ -289,11 +284,10 @@ module.exports = { _.each(parts, (part, index) => { let entry = _.find(placeholder, { name: part }) - const isDirectory = index < (parts.length - 1) if (!entry) { entry = { name: part } - if (isDirectory) { + if (index < (parts.length - 1)) { // if it's not the last, it's a directory entry.children = [] } @@ -301,10 +295,6 @@ module.exports = { placeholder.push(entry) } - if (!entry.children && isDirectory) { - entry.children = [] - } - placeholder = entry.children }) diff --git a/packages/server/test/unit/scaffold_spec.js b/packages/server/test/unit/scaffold_spec.js index aa36dfb57b14..d061613f9d5f 100644 --- a/packages/server/test/unit/scaffold_spec.js +++ b/packages/server/test/unit/scaffold_spec.js @@ -20,21 +20,16 @@ describe('lib/scaffold', () => { return Fixtures.remove() }) - // TODO: fix it later - context.skip('.isNewProject', () => { + context('.isNewProject', () => { beforeEach(function () { - const todosPath = Fixtures.projectPath('todos') - - return config.get(todosPath) - .then((cfg) => { - this.cfg = cfg; - ({ integrationFolder: this.integrationFolder } = this.cfg) - }) + this.pristinePath = Fixtures.projectPath('pristine') }) it('is false when files.length isnt 1', function () { const id = () => { - this.ids = new ProjectE2E(this.idsPath) + const idsPath = Fixtures.projectPath('ids') + + this.ids = new ProjectE2E(idsPath) return this.ids.getConfig() .then((cfg) => { @@ -47,7 +42,9 @@ describe('lib/scaffold', () => { } const todo = () => { - this.todos = new ProjectE2E(this.todosPath) + const todosPath = Fixtures.projectPath('todos') + + this.todos = new ProjectE2E(todosPath) return this.todos.getConfig() .then((cfg) => { @@ -63,7 +60,6 @@ describe('lib/scaffold', () => { }) it('is true when files, name + bytes match to scaffold', function () { - // TODO this test really can move to scaffold const pristine = new ProjectE2E(this.pristinePath) return pristine.getConfig() @@ -77,14 +73,13 @@ describe('lib/scaffold', () => { }) it('is false when bytes dont match scaffold', function () { - // TODO this test really can move to scaffold const pristine = new ProjectE2E(this.pristinePath) return pristine.getConfig() .then((cfg) => { return pristine.scaffold(cfg).return(cfg) }).then((cfg) => { - const file = path.join(cfg.integrationFolder, 'example.spec.js') + const file = path.join(cfg.integrationFolder, 'examples', 'actions.spec.js') // write some data to the file so it is now // different in file size @@ -120,7 +115,7 @@ describe('lib/scaffold', () => { .spread((exampleSpecs) => { return Promise.join( fs.statAsync(`${this.integrationFolder}/examples/actions.spec.js`).get('size'), - fs.statAsync(exampleSpecs[1]).get('size'), + fs.statAsync(exampleSpecs[0]).get('size'), fs.statAsync(`${this.integrationFolder}/examples/location.spec.js`).get('size'), fs.statAsync(exampleSpecs[8]).get('size'), ).spread((size1, size2, size3, size4) => { From 83aff16940f90bba7cf03ef1269adc32ce3fc293 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Thu, 22 Apr 2021 14:12:22 -0400 Subject: [PATCH 06/54] Replace old onboarding with new banner --- packages/desktop-gui/src/app/intro.jsx | 6 +- packages/desktop-gui/src/lib/ipc.js | 2 +- .../desktop-gui/src/project-nav/browsers.jsx | 2 +- .../src/project-nav/project-nav.jsx | 6 +- .../desktop-gui/src/project/onboarding.jsx | 124 ---------------- .../desktop-gui/src/project/onboarding.scss | 137 ------------------ .../desktop-gui/src/project/project-model.js | 12 +- packages/desktop-gui/src/project/project.jsx | 2 - .../src/project/warning-message.jsx | 2 +- .../src/projects/projects-list.jsx | 2 +- packages/desktop-gui/src/specs/specs-list.jsx | 28 +++- packages/server/lib/gui/events.js | 4 +- packages/server/lib/project-base.ts | 6 +- packages/server/lib/saved_state.js | 2 +- packages/server/test/unit/project_spec.js | 6 +- 15 files changed, 46 insertions(+), 295 deletions(-) delete mode 100644 packages/desktop-gui/src/project/onboarding.jsx delete mode 100644 packages/desktop-gui/src/project/onboarding.scss diff --git a/packages/desktop-gui/src/app/intro.jsx b/packages/desktop-gui/src/app/intro.jsx index 0aa0d6ab8159..00a6b5dd57dc 100644 --- a/packages/desktop-gui/src/app/intro.jsx +++ b/packages/desktop-gui/src/app/intro.jsx @@ -34,8 +34,8 @@ class Default extends Component { onDrop={this._drop} > - - + +

        Drag your project here or select manually.

@@ -51,7 +51,7 @@ class Default extends Component { return (

- {' '} + {' '} We recommend versioning Cypress per project and{' '} installing it via npm diff --git a/packages/desktop-gui/src/lib/ipc.js b/packages/desktop-gui/src/lib/ipc.js index 904f6eb428aa..9e3cbb912cc1 100644 --- a/packages/desktop-gui/src/lib/ipc.js +++ b/packages/desktop-gui/src/lib/ipc.js @@ -71,7 +71,7 @@ register('updater:check', false) register('updater:run', false) register('window:open') register('window:close') -register('onboarding:closed') +register('new:project:banner:closed') register('set:clipboard:text') export default ipc diff --git a/packages/desktop-gui/src/project-nav/browsers.jsx b/packages/desktop-gui/src/project-nav/browsers.jsx index 38becbd202c2..359bda1d58ba 100644 --- a/packages/desktop-gui/src/project-nav/browsers.jsx +++ b/packages/desktop-gui/src/project-nav/browsers.jsx @@ -35,7 +35,7 @@ export default class Browsers extends Component { return (

  • diff --git a/packages/desktop-gui/src/project-nav/project-nav.jsx b/packages/desktop-gui/src/project-nav/project-nav.jsx index 08b5915a9976..3dd55d873c15 100644 --- a/packages/desktop-gui/src/project-nav/project-nav.jsx +++ b/packages/desktop-gui/src/project-nav/project-nav.jsx @@ -12,19 +12,19 @@ export default class ProjectNav extends Component {
    • - {' '} + {' '} Tests
    • - {' '} + {' '} Runs
    • - {' '} + {' '} Settings
    • diff --git a/packages/desktop-gui/src/project/onboarding.jsx b/packages/desktop-gui/src/project/onboarding.jsx deleted file mode 100644 index f308c0abca3f..000000000000 --- a/packages/desktop-gui/src/project/onboarding.jsx +++ /dev/null @@ -1,124 +0,0 @@ -import cs from 'classnames' -import _ from 'lodash' -import React, { Component } from 'react' -import { observer } from 'mobx-react' -import BootstrapModal from 'react-bootstrap-modal' - -import ipc from '../lib/ipc' - -@observer -class OnBoarding extends Component { - componentDidMount () { - this._maybeShowModal() - } - - componentDidUpdate () { - this._maybeShowModal() - } - - _maybeShowModal () { - if (!this.showedModal && this.props.project.isNew) { - this.showedModal = true - this.props.project.openModal() - } - } - - render () { - const { project } = this.props - - let closeModal = () => { - project.closeModal() - ipc.onboardingClosed() - } - - return ( - -
      -
      -

      To help you get started...

      -

      - We've added an example test file to your project. Try running{' '} - example.spec.js{' '} - or add your own test files to - - {' '} - cypress/integration - . -

      -
      -
        -
      • - - {' '} - {project.name} - -
          -
        • - - {' '} - ... - -
        • - {this._scaffoldedFiles(project.scaffoldedFiles, 'new-code')} -
        -
      • -
      -
      -
      - - OK, got it! - -
      -
      -
      -
      - ) - } - - _scaffoldedFiles (files, className) { - files = _.sortBy(files, 'name') - - const notFolders = _.every(files, (file) => !file.children) - - if (notFolders && files.length > 3) { - const numHidden = files.length - 2 - - files = files.slice(0, 2).concat({ name: `... ${numHidden} more files ...`, more: true }) - } - - return _.map(files, (file) => { - if (file.children) { - return ( -
    • - - {' '} - {file.name} - -
        - {this._scaffoldedFiles(file.children)} -
      -
    • - ) - } - - return ( -
    • - - {' '} - {file.name} - -
    • - ) - }) - } - - _openIntegrationFolder = () => { - ipc.openFinder(this.props.project.integrationFolder) - } -} - -export default OnBoarding diff --git a/packages/desktop-gui/src/project/onboarding.scss b/packages/desktop-gui/src/project/onboarding.scss deleted file mode 100644 index cc939162c1e4..000000000000 --- a/packages/desktop-gui/src/project/onboarding.scss +++ /dev/null @@ -1,137 +0,0 @@ -.empty-onboarding { - margin: 0px auto 0; - overflow: auto; - - strong { - margin-left: 4px; - white-space: nowrap; - } - - strong:hover { - cursor: pointer; - border-bottom: 1px dotted #333; - } - - hr { - margin: 5px 0; - } - - h1 { - text-align: center; - color: $pass; - font-size: 18.5px; - margin: 0px 0 10px; - } - - img { - text-align: center; - margin: 20px auto; - } - - p { - font-size: 14px; - line-height: 21px; - margin-bottom: 0; - - a { - border-bottom: 1px dotted lighten($brand-primary, 30%); - } - - } - - .helper-line { - bottom: 0; - position: inherit; - } - - h6 { - margin-top: 30px; - font-weight: bold; - font-size: 14px; - font-style: italic; - color: #999; - margin-bottom: 2px; - } - - .folder-preview-onboarding { - background-color: #fcfcfc; - padding: 0; - border: 1px solid #e9e9e9; - box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.04); - margin: 0 auto 10px; - color: #555; - margin-top: 10px; - - ul { - list-style-type: none; - margin-left: 0; - font-size: 13.5px; - -webkit-padding-start: 0; - - - &>li { - position: relative; - margin: 3px 0; - - &.app-code { - color: #aaa; - font-style: italic; - font-weight: 200; - } - - &.new-code { - padding: 2px 0 0 31px; - margin-left: -30px; - margin-bottom: 0; - border-top: 1px solid lighten($pass, 54%); - background-color: lighten($pass, 58%); - overflow: auto; - } - - &>ul { - padding-left: 20px; - } - } - - } - - &>ul { - margin-bottom: 0; - &>li { - margin-bottom: 0; - padding-left: 10px; - } - } - - .new-item:after { - color: lighten($pass, 5%); - content: "+"; - position: absolute; - top: 0; - left: 10px; - } - - .new-item .new-item:after { - top: -2px; - left: -40px; - } - - .new-item .new-item .new-item:after { - top: -2px; - left: -60px; - } - - .new-item .new-item .new-item .new-item:after { - top: -2px; - left: -80px; - } - - .is-more { - i { - display: none; - } - - opacity: 0.7; - } - } -} diff --git a/packages/desktop-gui/src/project/project-model.js b/packages/desktop-gui/src/project/project-model.js index f5e7ac074300..0c489f90d83e 100644 --- a/packages/desktop-gui/src/project/project-model.js +++ b/packages/desktop-gui/src/project/project-model.js @@ -22,7 +22,7 @@ const validProps = cacheProps.concat([ 'isNew', 'configFile', 'browsers', - 'onBoardingModalOpen', + 'newProjectBannerOpen', 'browserState', 'resolvedConfig', 'parentTestsFolderDisplay', @@ -53,7 +53,7 @@ export default class Project { @observable isLoading = false @observable isNew = false @observable browsers = [] - @observable onBoardingModalOpen = false + @observable newProjectBannerOpen = false @observable browserState = 'closed' @observable resolvedConfig @observable error @@ -143,12 +143,12 @@ export default class Project { this.isLoading = isLoading } - @action openModal () { - this.onBoardingModalOpen = true + @action openNewProjectBanner () { + this.newProjectBannerOpen = true } - @action closeModal () { - this.onBoardingModalOpen = false + @action closeNewProjectBanner () { + this.newProjectBannerOpen = false } @action browserOpening () { diff --git a/packages/desktop-gui/src/project/project.jsx b/packages/desktop-gui/src/project/project.jsx index ce1a1828dc25..433460088394 100644 --- a/packages/desktop-gui/src/project/project.jsx +++ b/packages/desktop-gui/src/project/project.jsx @@ -10,7 +10,6 @@ import viewStore from '../lib/view-store' import ipc from '../lib/ipc' import Settings from '../settings/settings' -import OnBoarding from './onboarding' import ProjectNav from '../project-nav/project-nav' import RunsList from '../runs/runs-list' import SpecsList from '../specs/specs-list' @@ -53,7 +52,6 @@ class Project extends Component { {this._renderWarnings()} {this._currentView()}
    - ) } diff --git a/packages/desktop-gui/src/project/warning-message.jsx b/packages/desktop-gui/src/project/warning-message.jsx index 156a6c8d9149..dec4d868e695 100644 --- a/packages/desktop-gui/src/project/warning-message.jsx +++ b/packages/desktop-gui/src/project/warning-message.jsx @@ -12,7 +12,7 @@ class WarningMessage extends Component { return (

    - {' '} + {' '} Warning

    diff --git a/packages/desktop-gui/src/projects/projects-list.jsx b/packages/desktop-gui/src/projects/projects-list.jsx index 86b21af8a904..035f9ac61d2d 100644 --- a/packages/desktop-gui/src/projects/projects-list.jsx +++ b/packages/desktop-gui/src/projects/projects-list.jsx @@ -46,7 +46,7 @@ class ProjectsList extends Component { return (

    - {' '} + {' '} Error

    - {this._firstTestBanner()} + {this._newProjectBanner()}

    - +
    {this._specsList()} @@ -418,14 +427,19 @@ class SpecsList extends Component { ) } - _firstTestBanner () { - if (!this.props.project.isNew || this.state.firstTestBannerDismissed) return + _closeNewProjectBanner = () => { + this.props.project.closeNewProjectBanner() + ipc.newProjectBannerClosed() + } + + _newProjectBanner () { + if (!this.props.project.newProjectBannerOpen) return return (
    -

    We've created some sample tests around key Cypress concepts. Run the first one or create your own test file.

    -

    How to write tests

    - +

    We've created some sample tests around key Cypress concepts. Click on the first file or create a new spec file.

    +

    {}}>No thanks, delete example files  |  How to write tests

    +
    ) } diff --git a/packages/server/lib/gui/events.js b/packages/server/lib/gui/events.js index 29e4c6ea4635..c6f4dd69891c 100644 --- a/packages/server/lib/gui/events.js +++ b/packages/server/lib/gui/events.js @@ -392,9 +392,9 @@ const handleEvent = function (options, bus, event, id, type, arg) { return sendErr(err) }) - case 'onboarding:closed': + case 'new:project:banner:closed': return openProject.getProject() - .saveState({ showedOnBoardingModal: true }) + .saveState({ showedNewProjectBanner: true }) .then(sendNull) case 'ping:api:server': diff --git a/packages/server/lib/project-base.ts b/packages/server/lib/project-base.ts index 5252ff909e6f..d70e029d6762 100644 --- a/packages/server/lib/project-base.ts +++ b/packages/server/lib/project-base.ts @@ -458,10 +458,10 @@ export class ProjectBase extends EE { return this.determineIsNewProject(cfg.integrationFolder) .then((untouchedScaffold) => { - const userHasSeenOnBoarding = _.get(cfg, 'state.showedOnBoardingModal', false) + const userHasSeenBanner = _.get(cfg, 'state.showedNewProjectBanner', false) - debugScaffold(`untouched scaffold ${untouchedScaffold} modal closed ${userHasSeenOnBoarding}`) - cfg.isNewProject = untouchedScaffold && !userHasSeenOnBoarding + debugScaffold(`untouched scaffold ${untouchedScaffold} banner closed ${userHasSeenBanner}`) + cfg.isNewProject = untouchedScaffold && !userHasSeenBanner }) } diff --git a/packages/server/lib/saved_state.js b/packages/server/lib/saved_state.js index 36126ebbfa31..17678fb49ee2 100644 --- a/packages/server/lib/saved_state.js +++ b/packages/server/lib/saved_state.js @@ -22,7 +22,7 @@ browserY isAppDevToolsOpen isBrowserDevToolsOpen reporterWidth -showedOnBoardingModal +showedNewProjectBanner showedStudioModal preferredOpener ctReporterWidth diff --git a/packages/server/test/unit/project_spec.js b/packages/server/test/unit/project_spec.js index e97409f76f08..330eb0a19ca8 100644 --- a/packages/server/test/unit/project_spec.js +++ b/packages/server/test/unit/project_spec.js @@ -146,10 +146,10 @@ xdescribe('lib/project-e2e', () => { }) }) - it('sets cfg.isNewProject to false when state.showedOnBoardingModal is true', function () { + it('sets cfg.isNewProject to false when state.showedNewProjectBanner is true', function () { return savedState.create(this.todosPath) .then((state) => { - sinon.stub(state, 'get').resolves({ showedOnBoardingModal: true }) + sinon.stub(state, 'get').resolves({ showedNewProjectBanner: true }) this.project.getConfig({ foo: 'bar' }) .then((cfg) => { @@ -158,7 +158,7 @@ xdescribe('lib/project-e2e', () => { isNewProject: false, baz: 'quux', state: { - showedOnBoardingModal: true, + showedNewProjectBanner: true, }, }) }) From 7483d91972f00d751b27dba57f1ba2b466dc5dcd Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Thu, 22 Apr 2021 15:11:28 -0400 Subject: [PATCH 07/54] Add ability to remove scaffolded files --- packages/desktop-gui/src/lib/ipc.js | 1 + packages/desktop-gui/src/specs/specs-list.jsx | 18 ++++++- packages/example/lib/example.js | 25 +++++----- packages/server/lib/gui/events.js | 5 ++ packages/server/lib/project-base.ts | 8 ++++ packages/server/lib/scaffold.js | 47 ++++++++++++++++++- 6 files changed, 90 insertions(+), 14 deletions(-) diff --git a/packages/desktop-gui/src/lib/ipc.js b/packages/desktop-gui/src/lib/ipc.js index 9e3cbb912cc1..2e08a6c018ba 100644 --- a/packages/desktop-gui/src/lib/ipc.js +++ b/packages/desktop-gui/src/lib/ipc.js @@ -72,6 +72,7 @@ register('updater:run', false) register('window:open') register('window:close') register('new:project:banner:closed') +register('remove:scaffolded:files') register('set:clipboard:text') export default ipc diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index 11ab29907c8d..7f4f6cb3f787 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -432,13 +432,29 @@ class SpecsList extends Component { ipc.newProjectBannerClosed() } + _removeScaffoldedFiles = () => { + this.props.project.closeNewProjectBanner() + ipc.removeScaffoldedFiles() + } + + _openHowToBanner = (e) => { + e.preventDefault() + ipc.externalOpen({ + url: 'https://on.cypress.io/writing-first-test', + params: { + utm_medium: 'New Project Banner', + utm_campaign: 'How To', + }, + }) + } + _newProjectBanner () { if (!this.props.project.newProjectBannerOpen) return return (

    We've created some sample tests around key Cypress concepts. Click on the first file or create a new spec file.

    -

    {}}>No thanks, delete example files  |  How to write tests

    +

    No thanks, delete example files  |  How to write tests

    ) diff --git a/packages/example/lib/example.js b/packages/example/lib/example.js index d7607158fa42..6c070722e328 100644 --- a/packages/example/lib/example.js +++ b/packages/example/lib/example.js @@ -2,19 +2,22 @@ const path = require('path') const Promise = require('bluebird') const glob = Promise.promisify(require('glob')) +const pathToExamples = path.join( + __dirname, + '..', + 'cypress', + 'integration', + '**', + '*' +) + module.exports = { getPathToExamples () { - return glob( - path.join( - __dirname, - '..', - 'cypress', - 'integration', - '**', - '*' - ), - { nodir: true } - ) + return glob(pathToExamples, { nodir: true }) + }, + + getPathToExampleFolders () { + return glob(`${pathToExamples}${path.sep}`) }, getPathToPlugins() { diff --git a/packages/server/lib/gui/events.js b/packages/server/lib/gui/events.js index c6f4dd69891c..50b2ad18bc2c 100644 --- a/packages/server/lib/gui/events.js +++ b/packages/server/lib/gui/events.js @@ -397,6 +397,11 @@ const handleEvent = function (options, bus, event, id, type, arg) { .saveState({ showedNewProjectBanner: true }) .then(sendNull) + case 'remove:scaffolded:files': + return openProject.getProject() + .removeScaffoldedFiles() + .then(sendNull) + case 'ping:api:server': const apiUrl = konfig('api_url') diff --git a/packages/server/lib/project-base.ts b/packages/server/lib/project-base.ts index d70e029d6762..83810c8da4f9 100644 --- a/packages/server/lib/project-base.ts +++ b/packages/server/lib/project-base.ts @@ -425,6 +425,14 @@ export class ProjectBase extends EE { return this.automation } + removeScaffoldedFiles () { + if (!this.cfg) { + throw new Error('Missing project config') + } + + return scaffold.removeIntegration(this.cfg.integrationFolder, this.cfg) + } + // do not check files again and again - keep previous promise // to refresh it - just close and open the project again. determineIsNewProject (folder) { diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index e4fbe88f504b..7d15e4e614fb 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -10,6 +10,7 @@ const { isEmpty } = require('ramda') const { isDefault } = require('./util/config') const getExampleSpecsFullPaths = cypressEx.getPathToExamples() +const getExampleFolderFullPaths = cypressEx.getPathToExampleFolders() const getPathFromIntegrationFolder = (file) => { return file.substring(file.indexOf('integration/') + 'integration/'.length) @@ -19,8 +20,10 @@ const isDifferentNumberOfFiles = (files, exampleSpecs) => { return files.length !== exampleSpecs.length } -const getExampleSpecs = () => { - return getExampleSpecsFullPaths +const getExampleSpecs = (foldersOnly = false) => { + const paths = foldersOnly ? getExampleFolderFullPaths : getExampleSpecsFullPaths + + return paths .then((fullPaths) => { // short paths relative to integration folder (i.e. examples/actions.spec.js) const shortPaths = _.map(fullPaths, (file) => { @@ -141,6 +144,30 @@ module.exports = { }) }, + removeIntegration (folder, config) { + debug(`integration folder ${folder}`) + + // skip if user has explicitly set integrationFolder + // since we wouldn't have scaffolded anything + if (!isDefault(config, 'integrationFolder')) { + return Promise.resolve() + } + + return getExampleSpecs() + .then(({ shortPaths }) => { + return Promise.all(_.map(shortPaths, (file) => { + return this._removeFile(file, folder) + })) + }).then(() => { + // remove folders after we've removed all files + return getExampleSpecs(true).then(({ shortPaths }) => { + return Promise.all(_.map(shortPaths, (folderPath) => { + return this._removeFolder(folderPath, folder) + })) + }) + }) + }, + fixture (folder, config) { debug(`fixture folder ${folder}`) @@ -205,6 +232,22 @@ module.exports = { }) }, + _removeFile (file, folder) { + const dest = path.join(folder, file) + + // catch all errors since the user may have already removed + // the file or changed permissions, etc. + return fs.unlinkAsync(dest).catch(_.noop) + }, + + _removeFolder (folderPath, folder) { + const dest = path.join(folder, folderPath) + + // catch all errors since the user may have already removed + // the folder, changed permissions, add their own files etc. + return fs.rmdirAsync(dest).catch(_.noop) + }, + verifyScaffolding (folder, fn) { // we want to build out the folder + and example files // but only create the example files if the folder doesn't From c8d4c2d102f523bcc6be23a8212ad57ea0002aa5 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Thu, 22 Apr 2021 23:42:18 -0400 Subject: [PATCH 08/54] Add banner for new users --- packages/desktop-gui/src/lib/ipc.js | 1 + .../desktop-gui/src/project/project-model.js | 5 +- packages/desktop-gui/src/specs/specs-list.jsx | 70 ++++++++++++++----- packages/server/lib/gui/events.js | 16 +++++ packages/server/lib/saved_state.js | 1 + packages/server/test/unit/saved_state_spec.js | 8 +++ 6 files changed, 83 insertions(+), 18 deletions(-) diff --git a/packages/desktop-gui/src/lib/ipc.js b/packages/desktop-gui/src/lib/ipc.js index 2e08a6c018ba..4a7bad14007a 100644 --- a/packages/desktop-gui/src/lib/ipc.js +++ b/packages/desktop-gui/src/lib/ipc.js @@ -72,6 +72,7 @@ register('updater:run', false) register('window:open') register('window:close') register('new:project:banner:closed') +register('has:opened:cypress') register('remove:scaffolded:files') register('set:clipboard:text') diff --git a/packages/desktop-gui/src/project/project-model.js b/packages/desktop-gui/src/project/project-model.js index 0c489f90d83e..020bfc76c406 100644 --- a/packages/desktop-gui/src/project/project-model.js +++ b/packages/desktop-gui/src/project/project-model.js @@ -23,6 +23,7 @@ const validProps = cacheProps.concat([ 'configFile', 'browsers', 'newProjectBannerOpen', + 'newUserBannerOpen', 'browserState', 'resolvedConfig', 'parentTestsFolderDisplay', @@ -54,6 +55,7 @@ export default class Project { @observable isNew = false @observable browsers = [] @observable newProjectBannerOpen = false + @observable newUserBannerOpen = false @observable browserState = 'closed' @observable resolvedConfig @observable error @@ -147,8 +149,9 @@ export default class Project { this.newProjectBannerOpen = true } - @action closeNewProjectBanner () { + @action closeBanners () { this.newProjectBannerOpen = false + this.newUserBannerOpen = false } @action browserOpening () { diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index 7f4f6cb3f787..8bb2be4cb530 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -24,9 +24,7 @@ const formRunButtonLabel = (areTestsAlreadyRunning, specType, specsN) => { return `Running ${specType} tests` } - const label = specsN === 1 ? `Run 1 ${specType} spec` : `Run ${specsN} ${specType} specs` - - return label + return specsN === 1 ? `Run 1 ${specType} spec` : `Run ${specsN} ${specType} specs` } /** @@ -88,6 +86,10 @@ class SpecsList extends Component { this.showedBanner = true project.openNewProjectBanner() } + + ipc.hasOpenedCypress().then((opened) => { + project.update({ newUserBannerOpen: !opened }) + }) } componentDidUpdate () { @@ -130,7 +132,7 @@ class SpecsList extends Component { return (
    - {this._newProjectBanner()} + {this._banners()}
    { - this.props.project.closeNewProjectBanner() + _closeBanners = () => { + this.props.project.closeBanners() ipc.newProjectBannerClosed() } _removeScaffoldedFiles = () => { - this.props.project.closeNewProjectBanner() + this._closeBanners() ipc.removeScaffoldedFiles() } - _openHowToBanner = (e) => { + _openHowToNewProjectBanner = (e) => { e.preventDefault() ipc.externalOpen({ url: 'https://on.cypress.io/writing-first-test', @@ -448,16 +450,50 @@ class SpecsList extends Component { }) } - _newProjectBanner () { - if (!this.props.project.newProjectBannerOpen) return + _openHowToNewUserBanner = (e) => { + e.preventDefault() + ipc.externalOpen({ + url: 'https://on.cypress.io/writing-first-test', + params: { + utm_medium: 'New User Banner', + utm_campaign: 'How To', + }, + }) + } - return ( -
    -

    We've created some sample tests around key Cypress concepts. Click on the first file or create a new spec file.

    -

    No thanks, delete example files  |  How to write tests

    - -
    - ) + _openIntroNewUserBanner = (e) => { + e.preventDefault() + ipc.externalOpen({ + url: 'https://on.cypress.io/writing-first-test', + params: { + utm_medium: 'New User Banner', + utm_campaign: 'Intro Guide', + }, + }) + } + + _banners () { + if (this.props.project.newProjectBannerOpen) { + return ( +
    +

    We've created some sample tests around key Cypress concepts. Click on the first file or create a new spec file.

    +

    No thanks, delete example files  |  How to write tests

    + +
    + ) + } + + if (this.props.project.newUserBannerOpen) { + return ( +
    +

    Welcome to Cypress! Click a test file to get started or take a look at our guides to help get started.

    +

    How to write your first test  |  Introduction guide to Cypress

    + +
    + ) + } + + return null } _newSpecNotification () { diff --git a/packages/server/lib/gui/events.js b/packages/server/lib/gui/events.js index 50b2ad18bc2c..72deded287d9 100644 --- a/packages/server/lib/gui/events.js +++ b/packages/server/lib/gui/events.js @@ -25,6 +25,7 @@ const konfig = require('../konfig') const editors = require('../util/editors') const fileOpener = require('../util/file-opener') const api = require('../api') +const savedState = require('../saved_state') const nullifyUnserializableValues = (obj) => { // nullify values that cannot be cloned @@ -397,6 +398,21 @@ const handleEvent = function (options, bus, event, id, type, arg) { .saveState({ showedNewProjectBanner: true }) .then(sendNull) + case 'has:opened:cypress': + return savedState.create() + .then(async (state) => { + const currentState = await state.get() + const hasOpenedCypress = !!Object.keys(currentState).length + + if (!hasOpenedCypress) { + // save something so the object is no longer empty + await state.set('hasOpenedCypress', true) + } + + return hasOpenedCypress + }) + .then(send) + case 'remove:scaffolded:files': return openProject.getProject() .removeScaffoldedFiles() diff --git a/packages/server/lib/saved_state.js b/packages/server/lib/saved_state.js index 17678fb49ee2..8ea599237833 100644 --- a/packages/server/lib/saved_state.js +++ b/packages/server/lib/saved_state.js @@ -23,6 +23,7 @@ isAppDevToolsOpen isBrowserDevToolsOpen reporterWidth showedNewProjectBanner +hasOpenedCypress showedStudioModal preferredOpener ctReporterWidth diff --git a/packages/server/test/unit/saved_state_spec.js b/packages/server/test/unit/saved_state_spec.js index 76676957153c..3e71d4b74098 100644 --- a/packages/server/test/unit/saved_state_spec.js +++ b/packages/server/test/unit/saved_state_spec.js @@ -62,6 +62,14 @@ describe('lib/saved_state', () => { }) }) + it('has an empty state by default', () => { + return savedState.create() + .then((state) => state.get()) + .then((state) => { + expect(state).to.be.empty + }) + }) + it('only saves allowed keys', () => { return savedState.create() .then((state) => { From 3300c6b3955d7538dcf33193cd2ec74d48d83b64 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Tue, 27 Apr 2021 16:06:34 -0400 Subject: [PATCH 09/54] Update tests for new scaffolding --- .../server/__snapshots__/scaffold_spec.js | 490 ++++++++++-------- packages/server/test/unit/scaffold_spec.js | 8 +- 2 files changed, 269 insertions(+), 229 deletions(-) diff --git a/packages/server/__snapshots__/scaffold_spec.js b/packages/server/__snapshots__/scaffold_spec.js index 2e80a884555b..462513b3def3 100644 --- a/packages/server/__snapshots__/scaffold_spec.js +++ b/packages/server/__snapshots__/scaffold_spec.js @@ -1,390 +1,422 @@ exports['lib/scaffold .fileTree returns tree-like structure of scaffolded 1'] = [ { - "name": "tests", - "children": [ + 'name': 'tests', + 'children': [ { - "name": "examples", - "children": [ + 'name': 'example-getting-started', + 'children': [ { - "name": "actions.spec.js" + 'name': 'todo.spec.js', + }, + ], + }, + { + 'name': 'examples-advanced', + 'children': [ + { + 'name': 'actions.spec.js', }, { - "name": "aliasing.spec.js" + 'name': 'aliasing.spec.js', }, { - "name": "assertions.spec.js" + 'name': 'assertions.spec.js', }, { - "name": "connectors.spec.js" + 'name': 'connectors.spec.js', }, { - "name": "cookies.spec.js" + 'name': 'cookies.spec.js', }, { - "name": "cypress_api.spec.js" + 'name': 'cypress_api.spec.js', }, { - "name": "files.spec.js" + 'name': 'files.spec.js', }, { - "name": "local_storage.spec.js" + 'name': 'local_storage.spec.js', }, { - "name": "location.spec.js" + 'name': 'location.spec.js', }, { - "name": "misc.spec.js" + 'name': 'misc.spec.js', }, { - "name": "navigation.spec.js" + 'name': 'navigation.spec.js', }, { - "name": "network_requests.spec.js" + 'name': 'network_requests.spec.js', }, { - "name": "querying.spec.js" + 'name': 'querying.spec.js', }, { - "name": "spies_stubs_clocks.spec.js" + 'name': 'spies_stubs_clocks.spec.js', }, { - "name": "traversal.spec.js" + 'name': 'traversal.spec.js', }, { - "name": "utilities.spec.js" + 'name': 'utilities.spec.js', }, { - "name": "viewport.spec.js" + 'name': 'viewport.spec.js', }, { - "name": "waiting.spec.js" + 'name': 'waiting.spec.js', }, { - "name": "window.spec.js" - } - ] + 'name': 'window.spec.js', + }, + ], }, { - "name": "_fixtures", - "children": [ + 'name': '_fixtures', + 'children': [ { - "name": "example.json" - } - ] + 'name': 'example.json', + }, + ], }, { - "name": "_support", - "children": [ + 'name': '_support', + 'children': [ { - "name": "commands.js" + 'name': 'commands.js', }, { - "name": "index.js" - } - ] - } - ] + 'name': 'index.js', + }, + ], + }, + ], }, { - "name": "cypress", - "children": [ + 'name': 'cypress', + 'children': [ { - "name": "plugins", - "children": [ - { - "name": "index.js" - } - ] - } - ] - } + 'name': 'plugins', + 'children': [ + { + 'name': 'index.js', + }, + ], + }, + ], + }, ] exports['lib/scaffold .fileTree leaves out integration tests if using component testing 1'] = [ { - "name": "tests", - "children": [ + 'name': 'tests', + 'children': [ + { + 'name': 'example-getting-started', + 'children': [ + { + 'name': 'todo.spec.js', + }, + ], + }, { - "name": "examples", - "children": [ + 'name': 'examples-advanced', + 'children': [ { - "name": "actions.spec.js" + 'name': 'actions.spec.js', }, { - "name": "aliasing.spec.js" + 'name': 'aliasing.spec.js', }, { - "name": "assertions.spec.js" + 'name': 'assertions.spec.js', }, { - "name": "connectors.spec.js" + 'name': 'connectors.spec.js', }, { - "name": "cookies.spec.js" + 'name': 'cookies.spec.js', }, { - "name": "cypress_api.spec.js" + 'name': 'cypress_api.spec.js', }, { - "name": "files.spec.js" + 'name': 'files.spec.js', }, { - "name": "local_storage.spec.js" + 'name': 'local_storage.spec.js', }, { - "name": "location.spec.js" + 'name': 'location.spec.js', }, { - "name": "misc.spec.js" + 'name': 'misc.spec.js', }, { - "name": "navigation.spec.js" + 'name': 'navigation.spec.js', }, { - "name": "network_requests.spec.js" + 'name': 'network_requests.spec.js', }, { - "name": "querying.spec.js" + 'name': 'querying.spec.js', }, { - "name": "spies_stubs_clocks.spec.js" + 'name': 'spies_stubs_clocks.spec.js', }, { - "name": "traversal.spec.js" + 'name': 'traversal.spec.js', }, { - "name": "utilities.spec.js" + 'name': 'utilities.spec.js', }, { - "name": "viewport.spec.js" + 'name': 'viewport.spec.js', }, { - "name": "waiting.spec.js" + 'name': 'waiting.spec.js', }, { - "name": "window.spec.js" - } - ] + 'name': 'window.spec.js', + }, + ], }, { - "name": "_fixtures", - "children": [ + 'name': '_fixtures', + 'children': [ { - "name": "example.json" - } - ] + 'name': 'example.json', + }, + ], }, { - "name": "_support", - "children": [ + 'name': '_support', + 'children': [ { - "name": "commands.js" + 'name': 'commands.js', }, { - "name": "index.js" - } - ] - } - ] + 'name': 'index.js', + }, + ], + }, + ], }, { - "name": "cypress", - "children": [ + 'name': 'cypress', + 'children': [ { - "name": "plugins", - "children": [ - { - "name": "index.js" - } - ] - } - ] - } + 'name': 'plugins', + 'children': [ + { + 'name': 'index.js', + }, + ], + }, + ], + }, ] exports['lib/scaffold .fileTree leaves out fixtures if configured to false 1'] = [ { - "name": "tests", - "children": [ + 'name': 'tests', + 'children': [ + { + 'name': 'example-getting-started', + 'children': [ + { + 'name': 'todo.spec.js', + }, + ], + }, { - "name": "examples", - "children": [ + 'name': 'examples-advanced', + 'children': [ { - "name": "actions.spec.js" + 'name': 'actions.spec.js', }, { - "name": "aliasing.spec.js" + 'name': 'aliasing.spec.js', }, { - "name": "assertions.spec.js" + 'name': 'assertions.spec.js', }, { - "name": "connectors.spec.js" + 'name': 'connectors.spec.js', }, { - "name": "cookies.spec.js" + 'name': 'cookies.spec.js', }, { - "name": "cypress_api.spec.js" + 'name': 'cypress_api.spec.js', }, { - "name": "files.spec.js" + 'name': 'files.spec.js', }, { - "name": "local_storage.spec.js" + 'name': 'local_storage.spec.js', }, { - "name": "location.spec.js" + 'name': 'location.spec.js', }, { - "name": "misc.spec.js" + 'name': 'misc.spec.js', }, { - "name": "navigation.spec.js" + 'name': 'navigation.spec.js', }, { - "name": "network_requests.spec.js" + 'name': 'network_requests.spec.js', }, { - "name": "querying.spec.js" + 'name': 'querying.spec.js', }, { - "name": "spies_stubs_clocks.spec.js" + 'name': 'spies_stubs_clocks.spec.js', }, { - "name": "traversal.spec.js" + 'name': 'traversal.spec.js', }, { - "name": "utilities.spec.js" + 'name': 'utilities.spec.js', }, { - "name": "viewport.spec.js" + 'name': 'viewport.spec.js', }, { - "name": "waiting.spec.js" + 'name': 'waiting.spec.js', }, { - "name": "window.spec.js" - } - ] + 'name': 'window.spec.js', + }, + ], }, { - "name": "_support", - "children": [ + 'name': '_support', + 'children': [ { - "name": "commands.js" + 'name': 'commands.js', }, { - "name": "index.js" - } - ] - } - ] + 'name': 'index.js', + }, + ], + }, + ], }, { - "name": "cypress", - "children": [ + 'name': 'cypress', + 'children': [ { - "name": "plugins", - "children": [ - { - "name": "index.js" - } - ] - } - ] - } + 'name': 'plugins', + 'children': [ + { + 'name': 'index.js', + }, + ], + }, + ], + }, ] exports['lib/scaffold .fileTree leaves out support if configured to false 1'] = [ { - "name": "tests", - "children": [ + 'name': 'tests', + 'children': [ { - "name": "examples", - "children": [ + 'name': 'example-getting-started', + 'children': [ { - "name": "actions.spec.js" + 'name': 'todo.spec.js', + }, + ], + }, + { + 'name': 'examples-advanced', + 'children': [ + { + 'name': 'actions.spec.js', }, { - "name": "aliasing.spec.js" + 'name': 'aliasing.spec.js', }, { - "name": "assertions.spec.js" + 'name': 'assertions.spec.js', }, { - "name": "connectors.spec.js" + 'name': 'connectors.spec.js', }, { - "name": "cookies.spec.js" + 'name': 'cookies.spec.js', }, { - "name": "cypress_api.spec.js" + 'name': 'cypress_api.spec.js', }, { - "name": "files.spec.js" + 'name': 'files.spec.js', }, { - "name": "local_storage.spec.js" + 'name': 'local_storage.spec.js', }, { - "name": "location.spec.js" + 'name': 'location.spec.js', }, { - "name": "misc.spec.js" + 'name': 'misc.spec.js', }, { - "name": "navigation.spec.js" + 'name': 'navigation.spec.js', }, { - "name": "network_requests.spec.js" + 'name': 'network_requests.spec.js', }, { - "name": "querying.spec.js" + 'name': 'querying.spec.js', }, { - "name": "spies_stubs_clocks.spec.js" + 'name': 'spies_stubs_clocks.spec.js', }, { - "name": "traversal.spec.js" + 'name': 'traversal.spec.js', }, { - "name": "utilities.spec.js" + 'name': 'utilities.spec.js', }, { - "name": "viewport.spec.js" + 'name': 'viewport.spec.js', }, { - "name": "waiting.spec.js" + 'name': 'waiting.spec.js', }, { - "name": "window.spec.js" - } - ] + 'name': 'window.spec.js', + }, + ], }, { - "name": "_fixtures", - "children": [ - { - "name": "example.json" - } - ] - } - ] + 'name': '_fixtures', + 'children': [ + { + 'name': 'example.json', + }, + ], + }, + ], }, { - "name": "cypress", - "children": [ + 'name': 'cypress', + 'children': [ { - "name": "plugins", - "children": [ - { - "name": "index.js" - } - ] - } - ] - } + 'name': 'plugins', + 'children': [ + { + 'name': 'index.js', + }, + ], + }, + ], + }, ] exports['lib/scaffold .support creates supportFolder and commands.js and index.js when supportFolder does not exist 1'] = ` @@ -442,91 +474,99 @@ import './commands' exports['lib/scaffold .fileTree leaves out plugins if configured to false 1'] = [ { - "name": "tests", - "children": [ + 'name': 'tests', + 'children': [ + { + 'name': 'example-getting-started', + 'children': [ + { + 'name': 'todo.spec.js', + }, + ], + }, { - "name": "examples", - "children": [ + 'name': 'examples-advanced', + 'children': [ { - "name": "actions.spec.js" + 'name': 'actions.spec.js', }, { - "name": "aliasing.spec.js" + 'name': 'aliasing.spec.js', }, { - "name": "assertions.spec.js" + 'name': 'assertions.spec.js', }, { - "name": "connectors.spec.js" + 'name': 'connectors.spec.js', }, { - "name": "cookies.spec.js" + 'name': 'cookies.spec.js', }, { - "name": "cypress_api.spec.js" + 'name': 'cypress_api.spec.js', }, { - "name": "files.spec.js" + 'name': 'files.spec.js', }, { - "name": "local_storage.spec.js" + 'name': 'local_storage.spec.js', }, { - "name": "location.spec.js" + 'name': 'location.spec.js', }, { - "name": "misc.spec.js" + 'name': 'misc.spec.js', }, { - "name": "navigation.spec.js" + 'name': 'navigation.spec.js', }, { - "name": "network_requests.spec.js" + 'name': 'network_requests.spec.js', }, { - "name": "querying.spec.js" + 'name': 'querying.spec.js', }, { - "name": "spies_stubs_clocks.spec.js" + 'name': 'spies_stubs_clocks.spec.js', }, { - "name": "traversal.spec.js" + 'name': 'traversal.spec.js', }, { - "name": "utilities.spec.js" + 'name': 'utilities.spec.js', }, { - "name": "viewport.spec.js" + 'name': 'viewport.spec.js', }, { - "name": "waiting.spec.js" + 'name': 'waiting.spec.js', }, { - "name": "window.spec.js" - } - ] + 'name': 'window.spec.js', + }, + ], }, { - "name": "_fixtures", - "children": [ + 'name': '_fixtures', + 'children': [ { - "name": "example.json" - } - ] + 'name': 'example.json', + }, + ], }, { - "name": "_support", - "children": [ + 'name': '_support', + 'children': [ { - "name": "commands.js" + 'name': 'commands.js', }, { - "name": "index.js" - } - ] - } - ] - } + 'name': 'index.js', + }, + ], + }, + ], + }, ] exports['lib/scaffold .plugins creates pluginsFile when pluginsFolder does not exist 1'] = ` diff --git a/packages/server/test/unit/scaffold_spec.js b/packages/server/test/unit/scaffold_spec.js index d061613f9d5f..8b70fe8edac2 100644 --- a/packages/server/test/unit/scaffold_spec.js +++ b/packages/server/test/unit/scaffold_spec.js @@ -79,7 +79,7 @@ describe('lib/scaffold', () => { .then((cfg) => { return pristine.scaffold(cfg).return(cfg) }).then((cfg) => { - const file = path.join(cfg.integrationFolder, 'examples', 'actions.spec.js') + const file = path.join(cfg.integrationFolder, 'example-getting-started', 'todo.spec.js') // write some data to the file so it is now // different in file size @@ -114,10 +114,10 @@ describe('lib/scaffold', () => { ) .spread((exampleSpecs) => { return Promise.join( - fs.statAsync(`${this.integrationFolder}/examples/actions.spec.js`).get('size'), + fs.statAsync(`${this.integrationFolder}/example-getting-started/todo.spec.js`).get('size'), fs.statAsync(exampleSpecs[0]).get('size'), - fs.statAsync(`${this.integrationFolder}/examples/location.spec.js`).get('size'), - fs.statAsync(exampleSpecs[8]).get('size'), + fs.statAsync(`${this.integrationFolder}/examples-advanced/location.spec.js`).get('size'), + fs.statAsync(exampleSpecs[9]).get('size'), ).spread((size1, size2, size3, size4) => { expect(size1).to.eq(size2) From 78059e2b5fa6779f28e907c8346b1c07b599b354 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Tue, 27 Apr 2021 16:40:10 -0400 Subject: [PATCH 10/54] Compare file sizes before removing --- packages/server/lib/scaffold.js | 44 ++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 7d15e4e614fb..c6d289499aca 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -53,6 +53,15 @@ const getFileSize = (file) => { return fs.statAsync(file).get('size') } +const fileSizeIsSame = (file, index) => { + return Promise.join( + getFileSize(file), + getFileSize(getIndexedExample(file, index)), + ).spread((fileSize, originalFileSize) => { + return fileSize === originalFileSize + }) +} + const filesSizesAreSame = (files, index) => { return Promise.join( Promise.all(_.map(files, getFileSize)), @@ -154,15 +163,15 @@ module.exports = { } return getExampleSpecs() - .then(({ shortPaths }) => { + .then(({ shortPaths, index }) => { return Promise.all(_.map(shortPaths, (file) => { - return this._removeFile(file, folder) + return this._removeFile(file, folder, config, index) })) }).then(() => { // remove folders after we've removed all files - return getExampleSpecs(true).then(({ shortPaths }) => { + return getExampleSpecs(true).then(({ shortPaths, index }) => { return Promise.all(_.map(shortPaths, (folderPath) => { - return this._removeFolder(folderPath, folder) + return this._removeFolder(folderPath, folder, config) })) }) }) @@ -232,20 +241,31 @@ module.exports = { }) }, - _removeFile (file, folder) { + _removeFile (file, folder, config, index) { const dest = path.join(folder, file) - // catch all errors since the user may have already removed - // the file or changed permissions, etc. - return fs.unlinkAsync(dest).catch(_.noop) + return this._assertInFileTree(dest, config) + .then(() => { + return fileSizeIsSame(dest, index) + .then((isSame) => { + if (isSame) { + // catch all errors since the user may have already removed + // the file or changed permissions, etc. + return fs.unlinkAsync(dest).catch(_.noop) + } + }) + }) }, - _removeFolder (folderPath, folder) { + _removeFolder (folderPath, folder, config) { const dest = path.join(folder, folderPath) - // catch all errors since the user may have already removed - // the folder, changed permissions, add their own files etc. - return fs.rmdirAsync(dest).catch(_.noop) + return this._assertInFileTree(dest, config) + .then(() => { + // catch all errors since the user may have already removed + // the folder, changed permissions, added their own files to the folder, etc. + return fs.rmdirAsync(dest).catch(_.noop) + }) }, verifyScaffolding (folder, fn) { From 8965decdaf3352e3071c5c8de01be52e7f9d263a Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Tue, 27 Apr 2021 23:31:08 -0400 Subject: [PATCH 11/54] Add tests for remove file --- packages/server/lib/scaffold.js | 5 +- packages/server/test/unit/scaffold_spec.js | 111 +++++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index c6d289499aca..74293054bc72 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -59,6 +59,9 @@ const fileSizeIsSame = (file, index) => { getFileSize(getIndexedExample(file, index)), ).spread((fileSize, originalFileSize) => { return fileSize === originalFileSize + }).catch(() => { + // if the file does not exist, return false + return false }) } @@ -169,7 +172,7 @@ module.exports = { })) }).then(() => { // remove folders after we've removed all files - return getExampleSpecs(true).then(({ shortPaths, index }) => { + return getExampleSpecs(true).then(({ shortPaths }) => { return Promise.all(_.map(shortPaths, (folderPath) => { return this._removeFolder(folderPath, folder, config) })) diff --git a/packages/server/test/unit/scaffold_spec.js b/packages/server/test/unit/scaffold_spec.js index 8b70fe8edac2..29df98e18a8e 100644 --- a/packages/server/test/unit/scaffold_spec.js +++ b/packages/server/test/unit/scaffold_spec.js @@ -180,6 +180,117 @@ describe('lib/scaffold', () => { }) }) + context('.removeIntegration', () => { + beforeEach(function () { + const pristinePath = Fixtures.projectPath('pristine') + + return config.get(pristinePath).then((cfg) => { + this.cfg = cfg; + ({ integrationFolder: this.integrationFolder } = this.cfg) + }) + }) + + it('removes all scaffolded files and folders', function () { + return scaffold.integration(this.integrationFolder, this.cfg) + .then(() => { + return glob('**/*', { cwd: this.integrationFolder }) + }) + .then((files) => { + expect(files.length).to.be.greaterThan(0) + }) + .then(() => { + return scaffold.removeIntegration(this.integrationFolder, this.cfg) + }) + .then(() => { + return glob('**/*', { cwd: this.integrationFolder }) + }) + .then((files) => { + expect(files.length).to.equal(0) + }) + }) + + it('removes all scaffolded files and folders after the user has deleted files', function () { + return scaffold.integration(this.integrationFolder, this.cfg) + .then(() => { + return glob('**/*', { cwd: this.integrationFolder }) + }) + .then((files) => { + expect(files.length).to.be.greaterThan(0) + + return Promise.join( + fs.unlinkAsync(`${this.integrationFolder}/examples-advanced/actions.spec.js`), + fs.unlinkAsync(`${this.integrationFolder}/examples-advanced/assertions.spec.js`), + fs.unlinkAsync(`${this.integrationFolder}/examples-advanced/location.spec.js`), + ) + }) + .then(() => { + return scaffold.removeIntegration(this.integrationFolder, this.cfg) + }) + .then(() => { + return glob('**/*', { cwd: this.integrationFolder }) + }) + .then((files) => { + expect(files.length).to.equal(0) + }) + }) + + it('does not remove files created by user', function () { + return scaffold.integration(this.integrationFolder, this.cfg) + .then(() => { + return glob('**/*', { cwd: this.integrationFolder }) + }) + .then((files) => { + expect(files.length).to.be.greaterThan(0) + + return Promise.join( + fs.writeFileAsync(`${this.integrationFolder}/examples-advanced/custom1.spec.js`, 'foo'), + fs.writeFileAsync(`${this.integrationFolder}/examples-advanced/custom2.spec.js`, 'bar'), + ) + }) + .then(() => { + return scaffold.removeIntegration(this.integrationFolder, this.cfg) + }) + .then(() => { + return glob('**/*', { cwd: this.integrationFolder }) + }) + .then((files) => { + expect(files).to.have.same.members([ + 'examples-advanced', + 'examples-advanced/custom1.spec.js', + 'examples-advanced/custom2.spec.js', + ]) + }) + }) + + it('does not remove files modified by user', function () { + return scaffold.integration(this.integrationFolder, this.cfg) + .then(() => { + return glob('**/*', { cwd: this.integrationFolder }) + }) + .then((files) => { + expect(files.length).to.be.greaterThan(0) + + return Promise.join( + fs.writeFileAsync(`${this.integrationFolder}/examples-advanced/actions.spec.js`, 'foo'), + fs.writeFileAsync(`${this.integrationFolder}/examples-advanced/location.spec.js`, 'bar'), + ) + }) + .then(() => { + return scaffold.removeIntegration(this.integrationFolder, this.cfg) + }) + .then(() => { + return glob('**/*', { cwd: this.integrationFolder }) + }) + .then((files) => { + expect(files).to.have.same.members([ + 'examples-advanced', + 'examples-advanced/actions.spec.js', + 'examples-advanced/location.spec.js', + ]) + }) + }) + }) + context('.support', () => { beforeEach(function () { const pristinePath = Fixtures.projectPath('pristine') From 89710b3f9e8e0594d6c3b128637c8b8911a63efe Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Wed, 28 Apr 2021 00:04:45 -0400 Subject: [PATCH 12/54] Save when user opened cypress rather than boolean --- packages/server/lib/gui/events.js | 8 ++-- packages/server/test/unit/gui/events_spec.js | 47 ++++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/packages/server/lib/gui/events.js b/packages/server/lib/gui/events.js index 72deded287d9..c9ad52fd7a17 100644 --- a/packages/server/lib/gui/events.js +++ b/packages/server/lib/gui/events.js @@ -402,11 +402,13 @@ const handleEvent = function (options, bus, event, id, type, arg) { return savedState.create() .then(async (state) => { const currentState = await state.get() + + // we check if there is any state at all so users existing before + // we added firstOpenedCypress are not marked as new const hasOpenedCypress = !!Object.keys(currentState).length - if (!hasOpenedCypress) { - // save something so the object is no longer empty - await state.set('hasOpenedCypress', true) + if (!currentState.firstOpenedCypress) { + await state.set('firstOpenedCypress', Date.now()) } return hasOpenedCypress diff --git a/packages/server/test/unit/gui/events_spec.js b/packages/server/test/unit/gui/events_spec.js index 61ae3a1d8c7b..463db504a127 100644 --- a/packages/server/test/unit/gui/events_spec.js +++ b/packages/server/test/unit/gui/events_spec.js @@ -24,6 +24,7 @@ const files = require(`${root}../lib/gui/files`) const ensureUrl = require(`${root}../lib/util/ensure-url`) const konfig = require(`${root}../lib/konfig`) const api = require(`${root}../lib/api`) +const savedState = require(`${root}../lib/saved_state`) describe('lib/gui/events', () => { beforeEach(function () { @@ -496,6 +497,52 @@ describe('lib/gui/events', () => { }) }) }) + + describe('has:opened:cypress', function () { + beforeEach(function () { + this.state = { + set: sinon.stub().resolves(), + get: sinon.stub().resolves({}), + } + + sinon.stub(savedState, 'create').resolves(this.state) + }) + + it('returns false when there is no existing saved state', function () { + return this.handleEvent('has:opened:cypress') + .then((assert) => { + assert.sendCalledWith(false) + }) + }) + + it('returns true when there is any existing saved state', function () { + this.state.get.resolves({ shownOnboardingModal: true }) + + return this.handleEvent('has:opened:cypress') + .then((assert) => { + assert.sendCalledWith(true) + }) + }) + + it('sets firstOpenedCypress when the user first opened Cypress if not already set', function () { + this.state.get.resolves({ shownOnboardingModal: true }) + sinon.stub(Date, 'now').returns(12345) + + return this.handleEvent('has:opened:cypress') + .then(() => { + expect(this.state.set).to.be.calledWith('firstOpenedCypress', 12345) + }) + }) + + it('does not set firstOpenedCypress if already set', function () { + this.state.get.resolves({ firstOpenedCypress: 12345 }) + + return this.handleEvent('has:opened:cypress') + .then(() => { + expect(this.state.set).not.to.be.called + }) + }) + }) }) context('project events', () => { From a569a68ef1dc49e81ffe47ecae65b21c83502287 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Wed, 28 Apr 2021 00:32:49 -0400 Subject: [PATCH 13/54] Update intro link and add tets for banners --- .../cypress/integration/specs_list_spec.js | 95 ++++++++----------- packages/desktop-gui/src/specs/specs-list.jsx | 6 +- packages/desktop-gui/src/specs/specs.scss | 2 +- 3 files changed, 42 insertions(+), 61 deletions(-) diff --git a/packages/desktop-gui/cypress/integration/specs_list_spec.js b/packages/desktop-gui/cypress/integration/specs_list_spec.js index 0796195b3b30..80ff0f622792 100644 --- a/packages/desktop-gui/cypress/integration/specs_list_spec.js +++ b/packages/desktop-gui/cypress/integration/specs_list_spec.js @@ -24,10 +24,11 @@ describe('Specs List', function () { cy.stub(this.ipc, 'openFinder') cy.stub(this.ipc, 'openFile') cy.stub(this.ipc, 'externalOpen') - cy.stub(this.ipc, 'onboardingClosed') + cy.stub(this.ipc, 'hasOpenedCypress').resolves(true) cy.stub(this.ipc, 'onSpecChanged') cy.stub(this.ipc, 'setUserEditor') cy.stub(this.ipc, 'showNewSpecDialog').resolves({ specs: null, path: null }) + cy.stub(this.ipc, 'removeScaffoldedFiles') this.openProject = this.util.deferred() cy.stub(this.ipc, 'openProject').returns(this.openProject.promise) @@ -103,85 +104,65 @@ describe('Specs List', function () { this.openProject.resolve(this.config) }) - context('modal', () => { - it('displays', () => { - cy.contains('.modal', 'To help you get started').should('be.visible') + context('banner', function () { + it('displays', function () { + cy.get('.new-project-banner') cy.percySnapshot() }) - it('displays the scaffolded files', () => { - cy.get('.folder-preview-onboarding').within(function () { - cy.contains('span', 'fixtures').siblings('ul').within(function () { - }) - - cy.contains('example.json') - cy.contains('span', 'integration').siblings('ul').within(() => { - cy.contains('examples') - }) - - cy.contains('span', 'support').siblings('ul').within(function () { - cy.contains('commands.js') - cy.contains('defaults.js') - - cy.contains('index.js') - }) - - cy.contains('span', 'plugins').siblings('ul').within(() => { - cy.contains('index.js') - }) - }) + it('is dismissable', function () { + cy.get('.new-project-banner').find('.close').click() + cy.get('.new-project-banner').should('not.exist') }) - it('lists folders and files alphabetically', () => { - cy.get('.folder-preview-onboarding').within(() => { - cy.contains('fixtures').parent().next() - .contains('integration') - }) + it('does not display new user banner even when closed', function () { + cy.get('.new-user-banner').should('not.exist') + cy.get('.new-project-banner').find('.close').click() + cy.get('.new-project-banner').should('not.exist') + cy.get('.new-user-banner').should('not.exist') }) - it('truncates file lists with more than 3 items', () => { - cy.get('.folder-preview-onboarding').within(function () { - cy.contains('examples').closest('.new-item').find('li') - .should('have.length', 3) - - cy.get('.is-more').should('have.text', ' ... 17 more files ...') + it('opens link to docs on click of help link', function () { + cy.contains('a', 'How to write tests').click().then(function () { + expect(this.ipc.externalOpen).to.be.calledWithMatch({ url: 'https://on.cypress.io/writing-first-test' }) }) }) - it('can dismiss the modal', function () { - cy.contains('OK, got it!').click() - - cy.get('.modal').should('not.be.visible') - .then(function () { - expect(this.ipc.onboardingClosed).to.be.called + it('removes scaffolded files on click and gets dismissed', function () { + cy.contains('a', 'delete example files').click().then(function () { + expect(this.ipc.removeScaffoldedFiles).to.be.called + cy.get('.new-project-banner').should('not.exist') }) }) + }) + }) - it('triggers open:finder on click of text folder', function () { - cy.get('.modal').contains('cypress/integration').click().then(() => { - expect(this.ipc.openFinder).to.be.calledWith(this.config.integrationFolder) - }) - }) + describe('first time user in existing project', function () { + beforeEach(function () { + this.openProject.resolve(this.config) + this.ipc.hasOpenedCypress.resolves(false) }) context('banner', function () { - beforeEach(function () { - cy.get('.modal').find('.btn-success').click() - }) - it('displays', function () { - cy.get('.first-test-banner') + cy.get('.new-user-banner') cy.percySnapshot() }) it('is dismissable', function () { - cy.get('.first-test-banner').find('.close').click() - cy.get('.first-test-banner').should('not.exist') + cy.get('.new-user-banner').find('.close').click() + cy.get('.new-user-banner').should('not.exist') }) - it('opens link to docs on click of help link', function () { - cy.contains('a', 'How to write tests').click().then(function () { - expect(this.ipc.externalOpen).to.be.calledWith('https://on.cypress.io/writing-first-test') + it('opens link to docs on click of how to link', function () { + cy.contains('a', 'How to write your first test').click().then(function () { + expect(this.ipc.externalOpen).to.be.calledWithMatch({ url: 'https://on.cypress.io/writing-first-test' }) + }) + }) + + it('opens link to intro guide on click of intro link', function () { + cy.contains('a', 'Introduction guide to Cypress').click().then(function () { + expect(this.ipc.externalOpen).to.be.calledWithMatch({ url: 'https://on.cypress.io/intro-to-cypress' }) }) }) }) diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index 5affd14d541a..b072f399b9d5 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -470,7 +470,7 @@ class SpecsList extends Component { _openIntroNewUserBanner = (e) => { e.preventDefault() ipc.externalOpen({ - url: 'https://on.cypress.io/writing-first-test', + url: 'https://on.cypress.io/intro-to-cypress', params: { utm_medium: 'New User Banner', utm_campaign: 'Intro Guide', @@ -481,7 +481,7 @@ class SpecsList extends Component { _banners () { if (this.props.project.newProjectBannerOpen) { return ( -
    +

    We've created some sample tests around key Cypress concepts. Click on the first file or create a new spec file.

    No thanks, delete example files  |  How to write tests

    @@ -491,7 +491,7 @@ class SpecsList extends Component { if (this.props.project.newUserBannerOpen) { return ( -
    +

    Welcome to Cypress! Click a test file to get started or take a look at our guides to help get started.

    How to write your first test  |  Introduction guide to Cypress

    diff --git a/packages/desktop-gui/src/specs/specs.scss b/packages/desktop-gui/src/specs/specs.scss index a255240ef5f3..61a07154e7cd 100644 --- a/packages/desktop-gui/src/specs/specs.scss +++ b/packages/desktop-gui/src/specs/specs.scss @@ -282,7 +282,7 @@ $max-nesting-level: 14; } } - .first-test-banner { + .onboarding-banner { margin: 6px; padding-left: 20px; } From e4321a19304b79f3bbcf902a56c37ecfd35908eb Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 3 May 2021 11:59:24 -0400 Subject: [PATCH 14/54] fix small issue --- packages/server/lib/saved_state.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/lib/saved_state.js b/packages/server/lib/saved_state.js index 8ea599237833..d6e8f9cf24c3 100644 --- a/packages/server/lib/saved_state.js +++ b/packages/server/lib/saved_state.js @@ -23,7 +23,7 @@ isAppDevToolsOpen isBrowserDevToolsOpen reporterWidth showedNewProjectBanner -hasOpenedCypress +firstOpenedCypress showedStudioModal preferredOpener ctReporterWidth From f3d0638ab5b35d3529aa387c9ca3d9932e164607 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Wed, 5 May 2021 17:19:05 -0400 Subject: [PATCH 15/54] Update design and copy of onboarding banners --- .../desktop-gui/src/project/project-model.js | 5 +-- packages/desktop-gui/src/specs/specs-list.jsx | 32 ++++++++++--------- packages/desktop-gui/src/specs/specs.scss | 13 ++++++++ .../src/styles/components/_buttons.scss | 16 ++++++++++ 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/packages/desktop-gui/src/project/project-model.js b/packages/desktop-gui/src/project/project-model.js index 020bfc76c406..38994bf16eea 100644 --- a/packages/desktop-gui/src/project/project-model.js +++ b/packages/desktop-gui/src/project/project-model.js @@ -145,10 +145,6 @@ export default class Project { this.isLoading = isLoading } - @action openNewProjectBanner () { - this.newProjectBannerOpen = true - } - @action closeBanners () { this.newProjectBannerOpen = false this.newUserBannerOpen = false @@ -205,6 +201,7 @@ export default class Project { @action setOnBoardingConfig (config) { this.isNew = config.isNewProject + this.newProjectBannerOpen = config.isNewProject this.integrationFolder = config.integrationFolder this.parentTestsFolderDisplay = config.parentTestsFolderDisplay this.fileServerFolder = config.fileServerFolder diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index b072f399b9d5..4084b27bb5df 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -80,15 +80,8 @@ class SpecsList extends Component { } componentDidMount () { - const { project } = this.props - - if (!this.showedBanner && project.isNew) { - this.showedBanner = true - project.openNewProjectBanner() - } - ipc.hasOpenedCypress().then((opened) => { - project.update({ newUserBannerOpen: !opened }) + this.props.project.update({ newUserBannerOpen: !opened }) }) } @@ -109,7 +102,7 @@ class SpecsList extends Component { } render () { - if (specsStore.isLoading) return + if (specsStore.isLoading) return const filteredSpecs = specsStore.getFilteredSpecs() @@ -441,8 +434,7 @@ class SpecsList extends Component { } _removeScaffoldedFiles = () => { - this._closeBanners() - ipc.removeScaffoldedFiles() + ipc.removeScaffoldedFiles().then(this._closeBanners) } _openHowToNewProjectBanner = (e) => { @@ -482,8 +474,15 @@ class SpecsList extends Component { if (this.props.project.newProjectBannerOpen) { return (
    -

    We've created some sample tests around key Cypress concepts. Click on the first file or create a new spec file.

    -

    No thanks, delete example files  |  How to write tests

    +
    +
    +

    Welcome to your new Cypress project! We've created some sample test files that demonstrate key Cypress concepts to help you get started.

    +

    Learn how to write your first test

    +
    +
    + +
    +
    ) @@ -492,8 +491,11 @@ class SpecsList extends Component { if (this.props.project.newUserBannerOpen) { return (
    -

    Welcome to Cypress! Click a test file to get started or take a look at our guides to help get started.

    -

    How to write your first test  |  Introduction guide to Cypress

    +

    Welcome to Cypress! We've created some new user guides on key Cypress concepts to help you get started.

    +

    + How to write your first test +   |   + Introduction guide to Cypress

    ) diff --git a/packages/desktop-gui/src/specs/specs.scss b/packages/desktop-gui/src/specs/specs.scss index 61a07154e7cd..9e38d9640509 100644 --- a/packages/desktop-gui/src/specs/specs.scss +++ b/packages/desktop-gui/src/specs/specs.scss @@ -286,6 +286,19 @@ $max-nesting-level: 14; margin: 6px; padding-left: 20px; } + + .new-project-banner { + .content-wrapper { + align-items: center; + display: flex; + + .button-wrapper { + flex-grow: 1; + padding-left: 4px; + text-align: center; + } + } + } } // overwrite file opener styles diff --git a/packages/desktop-gui/src/styles/components/_buttons.scss b/packages/desktop-gui/src/styles/components/_buttons.scss index 960fec703dca..b4b1125fb4ac 100644 --- a/packages/desktop-gui/src/styles/components/_buttons.scss +++ b/packages/desktop-gui/src/styles/components/_buttons.scss @@ -32,3 +32,19 @@ font-weight: 600; font-size: 12px; } + +.btn-outline { + background-color: transparent; + border-color: #3385d4 !important; + color: #3385d4 !important; + + &:hover, &:focus { + background-color: #3385d4; + border-color: #3385d4 !important; + color: white !important; + } + + &:active, &:focus { + outline: 0 + } +} From f8b3a01398915ad9eb35ed0e265c666969abad22 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Wed, 5 May 2021 17:20:18 -0400 Subject: [PATCH 16/54] Update style of new spec file button --- packages/desktop-gui/src/specs/specs-list.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index 4084b27bb5df..20e3e3a1002f 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -155,7 +155,7 @@ class SpecsList extends Component {
    - +
    {this._specsList()} From 708b6fa356ff37a2b3f914e73136e512bf498786 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Wed, 5 May 2021 17:23:06 -0400 Subject: [PATCH 17/54] Improve outline button active statE --- packages/desktop-gui/src/styles/components/_buttons.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/desktop-gui/src/styles/components/_buttons.scss b/packages/desktop-gui/src/styles/components/_buttons.scss index b4b1125fb4ac..298b51c4f529 100644 --- a/packages/desktop-gui/src/styles/components/_buttons.scss +++ b/packages/desktop-gui/src/styles/components/_buttons.scss @@ -44,6 +44,11 @@ color: white !important; } + &:active { + background-color: darken(#3385d4, 10%) !important; + border-color: darken(#3385d4, 10%) !important; + } + &:active, &:focus { outline: 0 } From 4944a99ec3c9e8df355c9588ee34b5fc949488b1 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Wed, 5 May 2021 18:15:16 -0400 Subject: [PATCH 18/54] Update design of new project a bit more --- packages/desktop-gui/src/specs/specs-list.jsx | 19 ++++++++----------- packages/desktop-gui/src/specs/specs.scss | 13 ++++++------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index 20e3e3a1002f..71fa49fded8f 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -474,15 +474,11 @@ class SpecsList extends Component { if (this.props.project.newProjectBannerOpen) { return (
    -
    -
    -

    Welcome to your new Cypress project! We've created some sample test files that demonstrate key Cypress concepts to help you get started.

    -

    Learn how to write your first test

    -
    -
    - -
    -
    +

    Welcome to your new Cypress project! We've created some sample test files that demonstrate key Cypress concepts to help you get started.

    +

    + + Learn how to write your first test +

    ) @@ -493,9 +489,10 @@ class SpecsList extends Component {

    Welcome to Cypress! We've created some new user guides on key Cypress concepts to help you get started.

    - How to write your first test + How to write your first test   |   - Introduction guide to Cypress

    + Introduction guide to Cypress +

    ) diff --git a/packages/desktop-gui/src/specs/specs.scss b/packages/desktop-gui/src/specs/specs.scss index 9e38d9640509..e94cf739e4f4 100644 --- a/packages/desktop-gui/src/specs/specs.scss +++ b/packages/desktop-gui/src/specs/specs.scss @@ -288,14 +288,13 @@ $max-nesting-level: 14; } .new-project-banner { - .content-wrapper { - align-items: center; - display: flex; + .actions-wrapper { + padding-top: 4px; - .button-wrapper { - flex-grow: 1; - padding-left: 4px; - text-align: center; + .btn { + margin-right: 12px; + padding: 3px 6px !important; + font-size: 13px !important; } } } From b708e25ae4622e9f7e6533f4a5363978f7ee1208 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Wed, 5 May 2021 18:21:41 -0400 Subject: [PATCH 19/54] Fix specs list tests --- packages/desktop-gui/cypress/integration/specs_list_spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/desktop-gui/cypress/integration/specs_list_spec.js b/packages/desktop-gui/cypress/integration/specs_list_spec.js index 80ff0f622792..447f60ebf2b3 100644 --- a/packages/desktop-gui/cypress/integration/specs_list_spec.js +++ b/packages/desktop-gui/cypress/integration/specs_list_spec.js @@ -28,7 +28,7 @@ describe('Specs List', function () { cy.stub(this.ipc, 'onSpecChanged') cy.stub(this.ipc, 'setUserEditor') cy.stub(this.ipc, 'showNewSpecDialog').resolves({ specs: null, path: null }) - cy.stub(this.ipc, 'removeScaffoldedFiles') + cy.stub(this.ipc, 'removeScaffoldedFiles').resolves() this.openProject = this.util.deferred() cy.stub(this.ipc, 'openProject').returns(this.openProject.promise) @@ -123,13 +123,13 @@ describe('Specs List', function () { }) it('opens link to docs on click of help link', function () { - cy.contains('a', 'How to write tests').click().then(function () { + cy.contains('a', 'Learn how to write your first test').click().then(function () { expect(this.ipc.externalOpen).to.be.calledWithMatch({ url: 'https://on.cypress.io/writing-first-test' }) }) }) it('removes scaffolded files on click and gets dismissed', function () { - cy.contains('a', 'delete example files').click().then(function () { + cy.contains('Delete example files').click().then(function () { expect(this.ipc.removeScaffoldedFiles).to.be.called cy.get('.new-project-banner').should('not.exist') }) From ce249b9e799b05de088af3961e65c116d5926036 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Thu, 13 May 2021 14:59:54 -0400 Subject: [PATCH 20/54] Update banner copy and layout --- packages/desktop-gui/cypress/integration/specs_list_spec.js | 2 +- packages/desktop-gui/src/specs/specs-list.jsx | 2 +- packages/desktop-gui/src/specs/specs.scss | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/desktop-gui/cypress/integration/specs_list_spec.js b/packages/desktop-gui/cypress/integration/specs_list_spec.js index 447f60ebf2b3..105669f04170 100644 --- a/packages/desktop-gui/cypress/integration/specs_list_spec.js +++ b/packages/desktop-gui/cypress/integration/specs_list_spec.js @@ -123,7 +123,7 @@ describe('Specs List', function () { }) it('opens link to docs on click of help link', function () { - cy.contains('a', 'Learn how to write your first test').click().then(function () { + cy.contains('a', 'How to write your first test').click().then(function () { expect(this.ipc.externalOpen).to.be.calledWithMatch({ url: 'https://on.cypress.io/writing-first-test' }) }) }) diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index 71fa49fded8f..f3e1f1649117 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -476,8 +476,8 @@ class SpecsList extends Component {

    Welcome to your new Cypress project! We've created some sample test files that demonstrate key Cypress concepts to help you get started.

    + How to write your first test - Learn how to write your first test

    diff --git a/packages/desktop-gui/src/specs/specs.scss b/packages/desktop-gui/src/specs/specs.scss index e94cf739e4f4..7ecba9a8c403 100644 --- a/packages/desktop-gui/src/specs/specs.scss +++ b/packages/desktop-gui/src/specs/specs.scss @@ -289,9 +289,10 @@ $max-nesting-level: 14; .new-project-banner { .actions-wrapper { - padding-top: 4px; + display: flex; .btn { + margin-left: auto; margin-right: 12px; padding: 3px 6px !important; font-size: 13px !important; From b0d75f9243a2262820d0f1fd1875867ff2a15058 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Fri, 14 May 2021 18:10:43 -0400 Subject: [PATCH 21/54] Update banner copy and layout --- .../desktop-gui/src/project/project-model.js | 2 +- packages/desktop-gui/src/specs/specs-list.jsx | 14 +++++++++---- packages/desktop-gui/src/specs/specs.scss | 11 ++++++---- .../src/styles/components/_buttons.scss | 21 ------------------- yarn.lock | 10 +-------- 5 files changed, 19 insertions(+), 39 deletions(-) diff --git a/packages/desktop-gui/src/project/project-model.js b/packages/desktop-gui/src/project/project-model.js index 38994bf16eea..6578a290f6f3 100644 --- a/packages/desktop-gui/src/project/project-model.js +++ b/packages/desktop-gui/src/project/project-model.js @@ -201,7 +201,7 @@ export default class Project { @action setOnBoardingConfig (config) { this.isNew = config.isNewProject - this.newProjectBannerOpen = config.isNewProject + this.newProjectBannerOpen = config.isNewProject || true this.integrationFolder = config.integrationFolder this.parentTestsFolderDisplay = config.parentTestsFolderDisplay this.fileServerFolder = config.fileServerFolder diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index f3e1f1649117..e78fd82030b4 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -155,7 +155,7 @@ class SpecsList extends Component {
    - +
    {this._specsList()} @@ -474,10 +474,13 @@ class SpecsList extends Component { if (this.props.project.newProjectBannerOpen) { return (
    -

    Welcome to your new Cypress project! We've created some sample test files that demonstrate key Cypress concepts to help you get started.

    +

    + Welcome to your new Cypress project! +

    +

    We've created some sample test files that demonstrate key Cypress concepts to help you get started.

    How to write your first test - + Delete example files

    @@ -487,7 +490,10 @@ class SpecsList extends Component { if (this.props.project.newUserBannerOpen) { return (
    -

    Welcome to Cypress! We've created some new user guides on key Cypress concepts to help you get started.

    +

    + New to Cypress? +

    +

    We've created some new user guides on key Cypress concepts to help you get started.

    How to write your first test   |   diff --git a/packages/desktop-gui/src/specs/specs.scss b/packages/desktop-gui/src/specs/specs.scss index 7ecba9a8c403..e2d9eeefd1d9 100644 --- a/packages/desktop-gui/src/specs/specs.scss +++ b/packages/desktop-gui/src/specs/specs.scss @@ -77,8 +77,13 @@ $max-nesting-level: 14; padding-right: 15px; button { + color: #637eb9; font-size: 13px; padding: 6px 10px; + + &:hover, &:focus { + color: #38589c; + } } } @@ -291,11 +296,9 @@ $max-nesting-level: 14; .actions-wrapper { display: flex; - .btn { + .text-danger { margin-left: auto; - margin-right: 12px; - padding: 3px 6px !important; - font-size: 13px !important; + margin-right: 16px; } } } diff --git a/packages/desktop-gui/src/styles/components/_buttons.scss b/packages/desktop-gui/src/styles/components/_buttons.scss index 298b51c4f529..960fec703dca 100644 --- a/packages/desktop-gui/src/styles/components/_buttons.scss +++ b/packages/desktop-gui/src/styles/components/_buttons.scss @@ -32,24 +32,3 @@ font-weight: 600; font-size: 12px; } - -.btn-outline { - background-color: transparent; - border-color: #3385d4 !important; - color: #3385d4 !important; - - &:hover, &:focus { - background-color: #3385d4; - border-color: #3385d4 !important; - color: white !important; - } - - &:active { - background-color: darken(#3385d4, 10%) !important; - border-color: darken(#3385d4, 10%) !important; - } - - &:active, &:focus { - outline: 0 - } -} diff --git a/yarn.lock b/yarn.lock index 94925340ca52..320d7914e7e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6857,14 +6857,6 @@ dependencies: defer-to-connect "^2.0.0" -"@testing-library/cypress@7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@testing-library/cypress/-/cypress-7.0.1.tgz#2843033acaefe96cb4cf789f16e98d957383e59d" - integrity sha512-LtggqG/7Hdc1EiKdmqXQwxWOO3ET1dkZtq0S8mIe8o+xaOtaVLrdCn0dE8Bi4Aj7z3w51w6wN9STdYymnUPlnQ== - dependencies: - "@babel/runtime" "^7.11.2" - "@testing-library/dom" "^7.22.2" - "@testing-library/cypress@7.0.4": version "7.0.4" resolved "https://registry.yarnpkg.com/@testing-library/cypress/-/cypress-7.0.4.tgz#38a55880712f222ddb9671bc899fe80f8c41bfc0" @@ -6873,7 +6865,7 @@ "@babel/runtime" "^7.12.5" "@testing-library/dom" "^7.28.1" -"@testing-library/dom@^7.22.2", "@testing-library/dom@^7.28.1": +"@testing-library/dom@^7.28.1": version "7.30.0" resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.30.0.tgz#53697851f7708a1448cc30b74a2ea056dd709cd6" integrity sha512-v4GzWtltaiDE0yRikLlcLAfEiiK8+ptu6OuuIebm9GdC2XlZTNDPGEfM2UkEtnH7hr9TRq2sivT5EA9P1Oy7bw== From f1ac9cf56551da5acc87d72df9159c0ed543740e Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Fri, 14 May 2021 18:23:23 -0400 Subject: [PATCH 22/54] Switch to docs style alerts --- .../desktop-gui/src/project/project-model.js | 2 +- packages/desktop-gui/src/specs/specs-list.jsx | 4 +-- .../src/styles/components/_alerts.scss | 28 ++++++++++++++----- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/packages/desktop-gui/src/project/project-model.js b/packages/desktop-gui/src/project/project-model.js index 6578a290f6f3..38994bf16eea 100644 --- a/packages/desktop-gui/src/project/project-model.js +++ b/packages/desktop-gui/src/project/project-model.js @@ -201,7 +201,7 @@ export default class Project { @action setOnBoardingConfig (config) { this.isNew = config.isNewProject - this.newProjectBannerOpen = config.isNewProject || true + this.newProjectBannerOpen = config.isNewProject this.integrationFolder = config.integrationFolder this.parentTestsFolderDisplay = config.parentTestsFolderDisplay this.fileServerFolder = config.fileServerFolder diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index e78fd82030b4..f9858ba3c713 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -473,7 +473,7 @@ class SpecsList extends Component { _banners () { if (this.props.project.newProjectBannerOpen) { return ( -

    +

    Welcome to your new Cypress project!

    @@ -489,7 +489,7 @@ class SpecsList extends Component { if (this.props.project.newUserBannerOpen) { return ( -
    +

    New to Cypress?

    diff --git a/packages/desktop-gui/src/styles/components/_alerts.scss b/packages/desktop-gui/src/styles/components/_alerts.scss index 8282565eb998..750f491f30ad 100644 --- a/packages/desktop-gui/src/styles/components/_alerts.scss +++ b/packages/desktop-gui/src/styles/components/_alerts.scss @@ -113,12 +113,26 @@ .project-content .alert-warning, .global-error { - margin-bottom: 0; + margin-bottom: 0; - button { - font-size: 1em; - position: absolute; - top: 10px; - right: 10px; - } + button { + font-size: 1em; + position: absolute; + top: 10px; + right: 10px; + } +} + +.info-box { + border-left: 4px solid #2a98b9; + background-color: #f2fafd; + padding: 12px 16px; + position: relative; + + &.info-box-dismissible .close { + position: absolute; + top: 10px; + right: 10px; + cursor: pointer; } +} From 5ea7094efb81ba29f8fedac9e149969a37a2d49c Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Fri, 14 May 2021 18:24:13 -0400 Subject: [PATCH 23/54] Fix testing logic --- packages/desktop-gui/src/project/project-model.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/desktop-gui/src/project/project-model.js b/packages/desktop-gui/src/project/project-model.js index 6578a290f6f3..38994bf16eea 100644 --- a/packages/desktop-gui/src/project/project-model.js +++ b/packages/desktop-gui/src/project/project-model.js @@ -201,7 +201,7 @@ export default class Project { @action setOnBoardingConfig (config) { this.isNew = config.isNewProject - this.newProjectBannerOpen = config.isNewProject || true + this.newProjectBannerOpen = config.isNewProject this.integrationFolder = config.integrationFolder this.parentTestsFolderDisplay = config.parentTestsFolderDisplay this.fileServerFolder = config.fileServerFolder From e3bb397c699d7d840410894e6f919876b8849a2e Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 17 May 2021 22:31:46 -0400 Subject: [PATCH 24/54] Update banner styles a bit --- packages/desktop-gui/src/specs/specs-list.jsx | 15 ++++---------- packages/desktop-gui/src/specs/specs.scss | 20 +++++++++++-------- .../src/styles/components/_alerts.scss | 4 ++-- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index f9858ba3c713..87d2dce9ed3e 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -73,10 +73,6 @@ class SpecsList extends Component { // @ts-ignore window.__project = this.props.project } - - this.state = { - firstTestBannerDismissed: false, - } } componentDidMount () { @@ -475,12 +471,13 @@ class SpecsList extends Component { return (

    - Welcome to your new Cypress project! + Welcome to Cypress!

    We've created some sample test files that demonstrate key Cypress concepts to help you get started.

    -

    +

    How to write your first test - Delete example files +   |   + No thanks, delete example files

    @@ -525,10 +522,6 @@ class SpecsList extends Component { e.preventDefault() ipc.externalOpen('https://on.cypress.io/writing-first-test') } - - _removeFirstTestBanner = () => { - this.setState({ firstTestBannerDismissed: true }) - } } export default SpecsList diff --git a/packages/desktop-gui/src/specs/specs.scss b/packages/desktop-gui/src/specs/specs.scss index e2d9eeefd1d9..25ca6f86dec7 100644 --- a/packages/desktop-gui/src/specs/specs.scss +++ b/packages/desktop-gui/src/specs/specs.scss @@ -289,16 +289,20 @@ $max-nesting-level: 14; .onboarding-banner { margin: 6px; - padding-left: 20px; - } - .new-project-banner { - .actions-wrapper { - display: flex; + p { + margin-bottom: 2px; + } - .text-danger { - margin-left: auto; - margin-right: 16px; + .header { + margin-bottom: 10px; + } + + .link-danger { + color: darken($brand-danger, 25%); + + &:hover, &:focus { + color: darken($brand-danger, 5%); } } } diff --git a/packages/desktop-gui/src/styles/components/_alerts.scss b/packages/desktop-gui/src/styles/components/_alerts.scss index 750f491f30ad..c9545e85e77d 100644 --- a/packages/desktop-gui/src/styles/components/_alerts.scss +++ b/packages/desktop-gui/src/styles/components/_alerts.scss @@ -126,12 +126,12 @@ .info-box { border-left: 4px solid #2a98b9; background-color: #f2fafd; - padding: 12px 16px; + padding: 10px 14px; position: relative; &.info-box-dismissible .close { position: absolute; - top: 10px; + top: 5px; right: 10px; cursor: pointer; } From d8628411414d9fca0fe6563aa3bde1b66737e3d3 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Tue, 18 May 2021 22:36:53 -0400 Subject: [PATCH 25/54] Update banners --- packages/desktop-gui/src/specs/specs-list.jsx | 4 ++-- packages/desktop-gui/src/specs/specs.scss | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index 87d2dce9ed3e..c496846ba080 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -474,7 +474,7 @@ class SpecsList extends Component { Welcome to Cypress!

    We've created some sample test files that demonstrate key Cypress concepts to help you get started.

    -

    +

    How to write your first test   |   No thanks, delete example files @@ -491,7 +491,7 @@ class SpecsList extends Component { New to Cypress?

    We've created some new user guides on key Cypress concepts to help you get started.

    -

    +

    How to write your first test   |   Introduction guide to Cypress diff --git a/packages/desktop-gui/src/specs/specs.scss b/packages/desktop-gui/src/specs/specs.scss index 25ca6f86dec7..053741c79c53 100644 --- a/packages/desktop-gui/src/specs/specs.scss +++ b/packages/desktop-gui/src/specs/specs.scss @@ -298,8 +298,12 @@ $max-nesting-level: 14; margin-bottom: 10px; } + .action-links { + margin-top: 5px; + } + .link-danger { - color: darken($brand-danger, 25%); + color: #666; &:hover, &:focus { color: darken($brand-danger, 5%); From 6a5932e22a8d0251d23aaef221e333e64bcc9434 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Wed, 19 May 2021 17:05:49 -0400 Subject: [PATCH 26/54] Add confirmation modal for delete specs --- packages/desktop-gui/src/specs/specs-list.jsx | 43 ++++++++++++++++--- packages/desktop-gui/src/specs/specs.scss | 22 ++++++++-- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index c496846ba080..01f2b83a6d16 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -5,6 +5,7 @@ import _ from 'lodash' import React, { Component } from 'react' import { observer } from 'mobx-react' import Loader from 'react-loader' +import BootstrapModal from 'react-bootstrap-modal' import Tooltip from '@cypress/react-tooltip' import FileOpener from './file-opener' @@ -58,6 +59,7 @@ class SpecsList extends Component { super(props) this.state = { isFocused: false, + confirmRemoveScaffoldedFiles: true, } this.filterRef = React.createRef() @@ -122,6 +124,7 @@ class SpecsList extends Component { return (

    {this._banners()} + {this._confirmRemoveScaffoldedFilesDialog()}
    ) @@ -433,6 +441,14 @@ class SpecsList extends Component { ipc.removeScaffoldedFiles().then(this._closeBanners) } + _openRemoveScaffoldedFilesDialog = () => { + this.setState({ confirmRemoveScaffoldedFiles: true }) + } + + _closeRemoveScaffoldedFilesDialog = () => { + this.setState({ confirmRemoveScaffoldedFiles: false }) + } + _openHowToNewProjectBanner = (e) => { e.preventDefault() ipc.externalOpen({ @@ -477,7 +493,7 @@ class SpecsList extends Component {

    How to write your first test   |   - No thanks, delete example files + No thanks, delete example files

    @@ -504,6 +520,23 @@ class SpecsList extends Component { return null } + _confirmRemoveScaffoldedFilesDialog = () => { + // if (!this.props.project.newProjectBannerOpen) return null + + return ( + +
    + × +

    Are you sure that you want to delete all example spec files?

    +
    +
    + Cancel + +
    +
    + ) + } + _newSpecNotification () { return ( diff --git a/packages/desktop-gui/src/specs/specs.scss b/packages/desktop-gui/src/specs/specs.scss index 053741c79c53..f7e3e4ac75f3 100644 --- a/packages/desktop-gui/src/specs/specs.scss +++ b/packages/desktop-gui/src/specs/specs.scss @@ -7,10 +7,18 @@ $max-nesting-level: 14; width: 100%; min-height: 0; - .empty-well code { - display: block; - line-height: 1.8; - margin-top: 5px; + .empty-well { + code { + color: #666; + background: $light-gray; + display: block; + line-height: 1.8; + margin-top: 5px; + + &:hover, &:focus { + color: #333; + } + } } header { @@ -312,6 +320,12 @@ $max-nesting-level: 14; } } +.confirm-remove-scaffolded-files { + h4 { + line-height: 24px; + } +} + // overwrite file opener styles [data-reach-dialog-content] { font-size: 1em; From a26bacfc639d1d1b03b85be6027d28e6c62c8d77 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Wed, 19 May 2021 20:56:13 -0400 Subject: [PATCH 27/54] Update tests and fix states --- .../cypress/integration/specs_list_spec.js | 14 +++++++++----- packages/desktop-gui/src/specs/specs-list.jsx | 4 ++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/desktop-gui/cypress/integration/specs_list_spec.js b/packages/desktop-gui/cypress/integration/specs_list_spec.js index 105669f04170..8e76bed8b550 100644 --- a/packages/desktop-gui/cypress/integration/specs_list_spec.js +++ b/packages/desktop-gui/cypress/integration/specs_list_spec.js @@ -59,8 +59,10 @@ describe('Specs List', function () { }) }) - it('displays help link', () => { - cy.contains('a', 'Need help?') + it('launches system save dialog on click of new spec file', function () { + cy.contains('New Spec File').click().then(function () { + expect(this.ipc.showNewSpecDialog).to.be.called + }) }) it('opens link to docs on click of help link', () => { @@ -97,7 +99,7 @@ describe('Specs List', function () { }) }) - describe('first time onboarding specs', function () { + describe('new project onboarding', function () { beforeEach(function () { this.config.isNewProject = true @@ -128,8 +130,10 @@ describe('Specs List', function () { }) }) - it('removes scaffolded files on click and gets dismissed', function () { - cy.contains('Delete example files').click().then(function () { + it('removes scaffolded files on click and confirmation', function () { + cy.contains('delete example files').click() + cy.get('.confirm-remove-scaffolded-files').should('be.visible') + cy.contains('Yes, delete files').click().then(function () { expect(this.ipc.removeScaffoldedFiles).to.be.called cy.get('.new-project-banner').should('not.exist') }) diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index 01f2b83a6d16..06b6edaa0a16 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -59,7 +59,7 @@ class SpecsList extends Component { super(props) this.state = { isFocused: false, - confirmRemoveScaffoldedFiles: true, + confirmRemoveScaffoldedFiles: false, } this.filterRef = React.createRef() @@ -521,7 +521,7 @@ class SpecsList extends Component { } _confirmRemoveScaffoldedFilesDialog = () => { - // if (!this.props.project.newProjectBannerOpen) return null + if (!this.props.project.newProjectBannerOpen) return null return ( From ddd187c5086a9d31c173a205f2b5bf995b493ec5 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Fri, 21 May 2021 14:04:54 -0400 Subject: [PATCH 28/54] Upgrade kitchensink dep --- packages/example/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/example/package.json b/packages/example/package.json index 899db5f43d00..64cabbe71c53 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -28,7 +28,7 @@ "devDependencies": { "chai": "3.5.0", "cross-env": "6.0.3", - "cypress-example-kitchensink": "1.14.0", + "cypress-example-kitchensink": "1.15.0", "gulp": "4.0.2", "gulp-clean": "0.4.0", "gulp-gh-pages": "0.6.0-6", diff --git a/yarn.lock b/yarn.lock index 43ecfbe3f0ed..b5a1d488c2ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15431,10 +15431,10 @@ cypress-circleci-reporter@0.2.0: strip-ansi "^6.0.0" xmlbuilder2 "^2.1.1" -cypress-example-kitchensink@1.14.0: - version "1.14.0" - resolved "https://registry.yarnpkg.com/cypress-example-kitchensink/-/cypress-example-kitchensink-1.14.0.tgz#f7048172f5871e64e4e8bc4c065900289d80824a" - integrity sha512-szaMnRjR9EqEDbQ4DE5Xdy8kHZx9F3qA/M55xNDuAsIm60Z9THbJxygKbz+C+sdpr0Rn6z2/cTxH/QzMJ8isNw== +cypress-example-kitchensink@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/cypress-example-kitchensink/-/cypress-example-kitchensink-1.15.0.tgz#0e12010b402138506ddb67542ac6c5c4782c3165" + integrity sha512-V/zLJwX9dMqtDuLv29a1xu2JMYsPv/WKdlE6ZxO0eTFY8OFGsjEENRYyHzJ21NEtIj5D/Jpbi7AqjNq2JaXeRg== dependencies: npm-run-all "^4.1.2" serve "11.3.0" From 0630a361cb6c79dd5b2cca82ea5cf3fd51e37bc3 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Fri, 21 May 2021 17:08:02 -0400 Subject: [PATCH 29/54] Upgrade kitchen sink version and fix unit tests --- packages/example/cypress/plugins/index.js | 20 +- packages/example/package.json | 2 +- .../server/__snapshots__/scaffold_spec.js | 500 +++++++++--------- packages/server/test/unit/scaffold_spec.js | 32 +- yarn.lock | 8 +- 5 files changed, 273 insertions(+), 289 deletions(-) diff --git a/packages/example/cypress/plugins/index.js b/packages/example/cypress/plugins/index.js index 66196698d756..59b2bab6e4e6 100644 --- a/packages/example/cypress/plugins/index.js +++ b/packages/example/cypress/plugins/index.js @@ -17,22 +17,6 @@ */ // eslint-disable-next-line no-unused-vars module.exports = (on, config) => { - on('before:browser:launch', (browser, launchOptions) => { - if (browser.name === 'chrome' && browser.isHeadless) { - launchOptions.args.push('--window-size=1280,720') - launchOptions.args.push('--force-device-scale-factor=1') - } - - if (browser.name === 'electron' && browser.isHeadless) { - launchOptions.preferences.width = 1280 - launchOptions.preferences.height = 720 - } - - if (browser.name === 'firefox' && browser.isHeadless) { - launchOptions.args.push('--width=1280') - launchOptions.args.push('--height=720') - } - - return launchOptions - }) + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config } diff --git a/packages/example/package.json b/packages/example/package.json index 64cabbe71c53..3ec88a493049 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -28,7 +28,7 @@ "devDependencies": { "chai": "3.5.0", "cross-env": "6.0.3", - "cypress-example-kitchensink": "1.15.0", + "cypress-example-kitchensink": "1.15.1", "gulp": "4.0.2", "gulp-clean": "0.4.0", "gulp-gh-pages": "0.6.0-6", diff --git a/packages/server/__snapshots__/scaffold_spec.js b/packages/server/__snapshots__/scaffold_spec.js index 462513b3def3..31ecc78eb865 100644 --- a/packages/server/__snapshots__/scaffold_spec.js +++ b/packages/server/__snapshots__/scaffold_spec.js @@ -1,422 +1,422 @@ exports['lib/scaffold .fileTree returns tree-like structure of scaffolded 1'] = [ { - 'name': 'tests', - 'children': [ + "name": "tests", + "children": [ { - 'name': 'example-getting-started', - 'children': [ + "name": "1-getting-started", + "children": [ { - 'name': 'todo.spec.js', - }, - ], + "name": "todo.spec.js" + } + ] }, { - 'name': 'examples-advanced', - 'children': [ + "name": "2-advanced-examples", + "children": [ { - 'name': 'actions.spec.js', + "name": "actions.spec.js" }, { - 'name': 'aliasing.spec.js', + "name": "aliasing.spec.js" }, { - 'name': 'assertions.spec.js', + "name": "assertions.spec.js" }, { - 'name': 'connectors.spec.js', + "name": "connectors.spec.js" }, { - 'name': 'cookies.spec.js', + "name": "cookies.spec.js" }, { - 'name': 'cypress_api.spec.js', + "name": "cypress_api.spec.js" }, { - 'name': 'files.spec.js', + "name": "files.spec.js" }, { - 'name': 'local_storage.spec.js', + "name": "local_storage.spec.js" }, { - 'name': 'location.spec.js', + "name": "location.spec.js" }, { - 'name': 'misc.spec.js', + "name": "misc.spec.js" }, { - 'name': 'navigation.spec.js', + "name": "navigation.spec.js" }, { - 'name': 'network_requests.spec.js', + "name": "network_requests.spec.js" }, { - 'name': 'querying.spec.js', + "name": "querying.spec.js" }, { - 'name': 'spies_stubs_clocks.spec.js', + "name": "spies_stubs_clocks.spec.js" }, { - 'name': 'traversal.spec.js', + "name": "traversal.spec.js" }, { - 'name': 'utilities.spec.js', + "name": "utilities.spec.js" }, { - 'name': 'viewport.spec.js', + "name": "viewport.spec.js" }, { - 'name': 'waiting.spec.js', + "name": "waiting.spec.js" }, { - 'name': 'window.spec.js', - }, - ], + "name": "window.spec.js" + } + ] }, { - 'name': '_fixtures', - 'children': [ + "name": "_fixtures", + "children": [ { - 'name': 'example.json', - }, - ], + "name": "example.json" + } + ] }, { - 'name': '_support', - 'children': [ + "name": "_support", + "children": [ { - 'name': 'commands.js', + "name": "commands.js" }, { - 'name': 'index.js', - }, - ], - }, - ], + "name": "index.js" + } + ] + } + ] }, { - 'name': 'cypress', - 'children': [ + "name": "cypress", + "children": [ { - 'name': 'plugins', - 'children': [ - { - 'name': 'index.js', - }, - ], - }, - ], - }, + "name": "plugins", + "children": [ + { + "name": "index.js" + } + ] + } + ] + } ] exports['lib/scaffold .fileTree leaves out integration tests if using component testing 1'] = [ { - 'name': 'tests', - 'children': [ + "name": "tests", + "children": [ { - 'name': 'example-getting-started', - 'children': [ + "name": "1-getting-started", + "children": [ { - 'name': 'todo.spec.js', - }, - ], + "name": "todo.spec.js" + } + ] }, { - 'name': 'examples-advanced', - 'children': [ + "name": "2-advanced-examples", + "children": [ { - 'name': 'actions.spec.js', + "name": "actions.spec.js" }, { - 'name': 'aliasing.spec.js', + "name": "aliasing.spec.js" }, { - 'name': 'assertions.spec.js', + "name": "assertions.spec.js" }, { - 'name': 'connectors.spec.js', + "name": "connectors.spec.js" }, { - 'name': 'cookies.spec.js', + "name": "cookies.spec.js" }, { - 'name': 'cypress_api.spec.js', + "name": "cypress_api.spec.js" }, { - 'name': 'files.spec.js', + "name": "files.spec.js" }, { - 'name': 'local_storage.spec.js', + "name": "local_storage.spec.js" }, { - 'name': 'location.spec.js', + "name": "location.spec.js" }, { - 'name': 'misc.spec.js', + "name": "misc.spec.js" }, { - 'name': 'navigation.spec.js', + "name": "navigation.spec.js" }, { - 'name': 'network_requests.spec.js', + "name": "network_requests.spec.js" }, { - 'name': 'querying.spec.js', + "name": "querying.spec.js" }, { - 'name': 'spies_stubs_clocks.spec.js', + "name": "spies_stubs_clocks.spec.js" }, { - 'name': 'traversal.spec.js', + "name": "traversal.spec.js" }, { - 'name': 'utilities.spec.js', + "name": "utilities.spec.js" }, { - 'name': 'viewport.spec.js', + "name": "viewport.spec.js" }, { - 'name': 'waiting.spec.js', + "name": "waiting.spec.js" }, { - 'name': 'window.spec.js', - }, - ], + "name": "window.spec.js" + } + ] }, { - 'name': '_fixtures', - 'children': [ + "name": "_fixtures", + "children": [ { - 'name': 'example.json', - }, - ], + "name": "example.json" + } + ] }, { - 'name': '_support', - 'children': [ + "name": "_support", + "children": [ { - 'name': 'commands.js', + "name": "commands.js" }, { - 'name': 'index.js', - }, - ], - }, - ], + "name": "index.js" + } + ] + } + ] }, { - 'name': 'cypress', - 'children': [ + "name": "cypress", + "children": [ { - 'name': 'plugins', - 'children': [ - { - 'name': 'index.js', - }, - ], - }, - ], - }, + "name": "plugins", + "children": [ + { + "name": "index.js" + } + ] + } + ] + } ] exports['lib/scaffold .fileTree leaves out fixtures if configured to false 1'] = [ { - 'name': 'tests', - 'children': [ + "name": "tests", + "children": [ { - 'name': 'example-getting-started', - 'children': [ + "name": "1-getting-started", + "children": [ { - 'name': 'todo.spec.js', - }, - ], + "name": "todo.spec.js" + } + ] }, { - 'name': 'examples-advanced', - 'children': [ + "name": "2-advanced-examples", + "children": [ { - 'name': 'actions.spec.js', + "name": "actions.spec.js" }, { - 'name': 'aliasing.spec.js', + "name": "aliasing.spec.js" }, { - 'name': 'assertions.spec.js', + "name": "assertions.spec.js" }, { - 'name': 'connectors.spec.js', + "name": "connectors.spec.js" }, { - 'name': 'cookies.spec.js', + "name": "cookies.spec.js" }, { - 'name': 'cypress_api.spec.js', + "name": "cypress_api.spec.js" }, { - 'name': 'files.spec.js', + "name": "files.spec.js" }, { - 'name': 'local_storage.spec.js', + "name": "local_storage.spec.js" }, { - 'name': 'location.spec.js', + "name": "location.spec.js" }, { - 'name': 'misc.spec.js', + "name": "misc.spec.js" }, { - 'name': 'navigation.spec.js', + "name": "navigation.spec.js" }, { - 'name': 'network_requests.spec.js', + "name": "network_requests.spec.js" }, { - 'name': 'querying.spec.js', + "name": "querying.spec.js" }, { - 'name': 'spies_stubs_clocks.spec.js', + "name": "spies_stubs_clocks.spec.js" }, { - 'name': 'traversal.spec.js', + "name": "traversal.spec.js" }, { - 'name': 'utilities.spec.js', + "name": "utilities.spec.js" }, { - 'name': 'viewport.spec.js', + "name": "viewport.spec.js" }, { - 'name': 'waiting.spec.js', + "name": "waiting.spec.js" }, { - 'name': 'window.spec.js', - }, - ], + "name": "window.spec.js" + } + ] }, { - 'name': '_support', - 'children': [ + "name": "_support", + "children": [ { - 'name': 'commands.js', + "name": "commands.js" }, { - 'name': 'index.js', - }, - ], - }, - ], + "name": "index.js" + } + ] + } + ] }, { - 'name': 'cypress', - 'children': [ + "name": "cypress", + "children": [ { - 'name': 'plugins', - 'children': [ - { - 'name': 'index.js', - }, - ], - }, - ], - }, + "name": "plugins", + "children": [ + { + "name": "index.js" + } + ] + } + ] + } ] exports['lib/scaffold .fileTree leaves out support if configured to false 1'] = [ { - 'name': 'tests', - 'children': [ + "name": "tests", + "children": [ { - 'name': 'example-getting-started', - 'children': [ + "name": "1-getting-started", + "children": [ { - 'name': 'todo.spec.js', - }, - ], + "name": "todo.spec.js" + } + ] }, { - 'name': 'examples-advanced', - 'children': [ + "name": "2-advanced-examples", + "children": [ { - 'name': 'actions.spec.js', + "name": "actions.spec.js" }, { - 'name': 'aliasing.spec.js', + "name": "aliasing.spec.js" }, { - 'name': 'assertions.spec.js', + "name": "assertions.spec.js" }, { - 'name': 'connectors.spec.js', + "name": "connectors.spec.js" }, { - 'name': 'cookies.spec.js', + "name": "cookies.spec.js" }, { - 'name': 'cypress_api.spec.js', + "name": "cypress_api.spec.js" }, { - 'name': 'files.spec.js', + "name": "files.spec.js" }, { - 'name': 'local_storage.spec.js', + "name": "local_storage.spec.js" }, { - 'name': 'location.spec.js', + "name": "location.spec.js" }, { - 'name': 'misc.spec.js', + "name": "misc.spec.js" }, { - 'name': 'navigation.spec.js', + "name": "navigation.spec.js" }, { - 'name': 'network_requests.spec.js', + "name": "network_requests.spec.js" }, { - 'name': 'querying.spec.js', + "name": "querying.spec.js" }, { - 'name': 'spies_stubs_clocks.spec.js', + "name": "spies_stubs_clocks.spec.js" }, { - 'name': 'traversal.spec.js', + "name": "traversal.spec.js" }, { - 'name': 'utilities.spec.js', + "name": "utilities.spec.js" }, { - 'name': 'viewport.spec.js', + "name": "viewport.spec.js" }, { - 'name': 'waiting.spec.js', + "name": "waiting.spec.js" }, { - 'name': 'window.spec.js', - }, - ], + "name": "window.spec.js" + } + ] }, { - 'name': '_fixtures', - 'children': [ - { - 'name': 'example.json', - }, - ], - }, - ], + "name": "_fixtures", + "children": [ + { + "name": "example.json" + } + ] + } + ] }, { - 'name': 'cypress', - 'children': [ + "name": "cypress", + "children": [ { - 'name': 'plugins', - 'children': [ - { - 'name': 'index.js', - }, - ], - }, - ], - }, + "name": "plugins", + "children": [ + { + "name": "index.js" + } + ] + } + ] + } ] exports['lib/scaffold .support creates supportFolder and commands.js and index.js when supportFolder does not exist 1'] = ` @@ -474,99 +474,99 @@ import './commands' exports['lib/scaffold .fileTree leaves out plugins if configured to false 1'] = [ { - 'name': 'tests', - 'children': [ + "name": "tests", + "children": [ { - 'name': 'example-getting-started', - 'children': [ + "name": "1-getting-started", + "children": [ { - 'name': 'todo.spec.js', - }, - ], + "name": "todo.spec.js" + } + ] }, { - 'name': 'examples-advanced', - 'children': [ + "name": "2-advanced-examples", + "children": [ { - 'name': 'actions.spec.js', + "name": "actions.spec.js" }, { - 'name': 'aliasing.spec.js', + "name": "aliasing.spec.js" }, { - 'name': 'assertions.spec.js', + "name": "assertions.spec.js" }, { - 'name': 'connectors.spec.js', + "name": "connectors.spec.js" }, { - 'name': 'cookies.spec.js', + "name": "cookies.spec.js" }, { - 'name': 'cypress_api.spec.js', + "name": "cypress_api.spec.js" }, { - 'name': 'files.spec.js', + "name": "files.spec.js" }, { - 'name': 'local_storage.spec.js', + "name": "local_storage.spec.js" }, { - 'name': 'location.spec.js', + "name": "location.spec.js" }, { - 'name': 'misc.spec.js', + "name": "misc.spec.js" }, { - 'name': 'navigation.spec.js', + "name": "navigation.spec.js" }, { - 'name': 'network_requests.spec.js', + "name": "network_requests.spec.js" }, { - 'name': 'querying.spec.js', + "name": "querying.spec.js" }, { - 'name': 'spies_stubs_clocks.spec.js', + "name": "spies_stubs_clocks.spec.js" }, { - 'name': 'traversal.spec.js', + "name": "traversal.spec.js" }, { - 'name': 'utilities.spec.js', + "name": "utilities.spec.js" }, { - 'name': 'viewport.spec.js', + "name": "viewport.spec.js" }, { - 'name': 'waiting.spec.js', + "name": "waiting.spec.js" }, { - 'name': 'window.spec.js', - }, - ], + "name": "window.spec.js" + } + ] }, { - 'name': '_fixtures', - 'children': [ + "name": "_fixtures", + "children": [ { - 'name': 'example.json', - }, - ], + "name": "example.json" + } + ] }, { - 'name': '_support', - 'children': [ + "name": "_support", + "children": [ { - 'name': 'commands.js', + "name": "commands.js" }, { - 'name': 'index.js', - }, - ], - }, - ], - }, + "name": "index.js" + } + ] + } + ] + } ] exports['lib/scaffold .plugins creates pluginsFile when pluginsFolder does not exist 1'] = ` diff --git a/packages/server/test/unit/scaffold_spec.js b/packages/server/test/unit/scaffold_spec.js index 29df98e18a8e..c1c9a303909b 100644 --- a/packages/server/test/unit/scaffold_spec.js +++ b/packages/server/test/unit/scaffold_spec.js @@ -79,7 +79,7 @@ describe('lib/scaffold', () => { .then((cfg) => { return pristine.scaffold(cfg).return(cfg) }).then((cfg) => { - const file = path.join(cfg.integrationFolder, 'example-getting-started', 'todo.spec.js') + const file = path.join(cfg.integrationFolder, '1-getting-started', 'todo.spec.js') // write some data to the file so it is now // different in file size @@ -114,9 +114,9 @@ describe('lib/scaffold', () => { ) .spread((exampleSpecs) => { return Promise.join( - fs.statAsync(`${this.integrationFolder}/example-getting-started/todo.spec.js`).get('size'), + fs.statAsync(`${this.integrationFolder}/1-getting-started/todo.spec.js`).get('size'), fs.statAsync(exampleSpecs[0]).get('size'), - fs.statAsync(`${this.integrationFolder}/examples-advanced/location.spec.js`).get('size'), + fs.statAsync(`${this.integrationFolder}/2-advanced-examples/location.spec.js`).get('size'), fs.statAsync(exampleSpecs[9]).get('size'), ).spread((size1, size2, size3, size4) => { expect(size1).to.eq(size2) @@ -218,9 +218,9 @@ describe('lib/scaffold', () => { expect(files.length).to.be.greaterThan(0) return Promise.join( - fs.unlinkAsync(`${this.integrationFolder}/examples-advanced/actions.spec.js`), - fs.unlinkAsync(`${this.integrationFolder}/examples-advanced/assertions.spec.js`), - fs.unlinkAsync(`${this.integrationFolder}/examples-advanced/location.spec.js`), + fs.unlinkAsync(`${this.integrationFolder}/2-advanced-examples/actions.spec.js`), + fs.unlinkAsync(`${this.integrationFolder}/2-advanced-examples/assertions.spec.js`), + fs.unlinkAsync(`${this.integrationFolder}/2-advanced-examples/location.spec.js`), ) }) .then(() => { @@ -243,8 +243,8 @@ describe('lib/scaffold', () => { expect(files.length).to.be.greaterThan(0) return Promise.join( - fs.writeFileAsync(`${this.integrationFolder}/examples-advanced/custom1.spec.js`, 'foo'), - fs.writeFileAsync(`${this.integrationFolder}/examples-advanced/custom2.spec.js`, 'bar'), + fs.writeFileAsync(`${this.integrationFolder}/2-advanced-examples/custom1.spec.js`, 'foo'), + fs.writeFileAsync(`${this.integrationFolder}/2-advanced-examples/custom2.spec.js`, 'bar'), ) }) .then(() => { @@ -255,9 +255,9 @@ describe('lib/scaffold', () => { }) .then((files) => { expect(files).to.have.same.members([ - 'examples-advanced', - 'examples-advanced/custom1.spec.js', - 'examples-advanced/custom2.spec.js', + '2-advanced-examples', + '2-advanced-examples/custom1.spec.js', + '2-advanced-examples/custom2.spec.js', ]) }) }) @@ -271,8 +271,8 @@ describe('lib/scaffold', () => { expect(files.length).to.be.greaterThan(0) return Promise.join( - fs.writeFileAsync(`${this.integrationFolder}/examples-advanced/actions.spec.js`, 'foo'), - fs.writeFileAsync(`${this.integrationFolder}/examples-advanced/location.spec.js`, 'bar'), + fs.writeFileAsync(`${this.integrationFolder}/2-advanced-examples/actions.spec.js`, 'foo'), + fs.writeFileAsync(`${this.integrationFolder}/2-advanced-examples/location.spec.js`, 'bar'), ) }) .then(() => { @@ -283,9 +283,9 @@ describe('lib/scaffold', () => { }) .then((files) => { expect(files).to.have.same.members([ - 'examples-advanced', - 'examples-advanced/actions.spec.js', - 'examples-advanced/location.spec.js', + '2-advanced-examples', + '2-advanced-examples/actions.spec.js', + '2-advanced-examples/location.spec.js', ]) }) }) diff --git a/yarn.lock b/yarn.lock index 758e0a615f66..c83d5c37d898 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15389,10 +15389,10 @@ cyclist@^1.0.1: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= -cypress-example-kitchensink@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/cypress-example-kitchensink/-/cypress-example-kitchensink-1.15.0.tgz#0e12010b402138506ddb67542ac6c5c4782c3165" - integrity sha512-V/zLJwX9dMqtDuLv29a1xu2JMYsPv/WKdlE6ZxO0eTFY8OFGsjEENRYyHzJ21NEtIj5D/Jpbi7AqjNq2JaXeRg== +cypress-example-kitchensink@1.15.1: + version "1.15.1" + resolved "https://registry.yarnpkg.com/cypress-example-kitchensink/-/cypress-example-kitchensink-1.15.1.tgz#60edc092d65816ac6d53b25815693c6b86338a25" + integrity sha512-kbLf4LPnXgVrm0X4KAC7EaNNWKYFfWBbqFrP110iADBeRdmTNe2Go1udZUos/qGDRW0lQoMl3q/kUXoAtS+5xg== dependencies: npm-run-all "^4.1.2" serve "11.3.0" From ee241ae4d0dff0797c9aba1ca5a7a63de21a6769 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Fri, 21 May 2021 17:27:28 -0400 Subject: [PATCH 30/54] Update integration scaffolding test --- packages/server/test/integration/cypress_spec.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/server/test/integration/cypress_spec.js b/packages/server/test/integration/cypress_spec.js index 4f75a8eaa115..00d63dd49bc3 100644 --- a/packages/server/test/integration/cypress_spec.js +++ b/packages/server/test/integration/cypress_spec.js @@ -606,9 +606,10 @@ describe('lib/cypress', () => { return fs.statAsync(cfg.integrationFolder) }).then(() => { return Promise.join( - fs.statAsync(path.join(cfg.integrationFolder, 'examples', 'actions.spec.js')), - fs.statAsync(path.join(cfg.integrationFolder, 'examples', 'files.spec.js')), - fs.statAsync(path.join(cfg.integrationFolder, 'examples', 'viewport.spec.js')), + fs.statAsync(path.join(cfg.integrationFolder, '1-getting-started', 'todo.spec.js')), + fs.statAsync(path.join(cfg.integrationFolder, '2-advanced-examples', 'actions.spec.js')), + fs.statAsync(path.join(cfg.integrationFolder, '2-advanced-examples', 'files.spec.js')), + fs.statAsync(path.join(cfg.integrationFolder, '2-advanced-examples', 'viewport.spec.js')), ) }) }) From 8715eeb3032daa250cf39b7b51c6e81bb7197d29 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 24 May 2021 13:17:48 -0400 Subject: [PATCH 31/54] Add further description to warning modal --- packages/desktop-gui/src/specs/specs-list.jsx | 1 + packages/desktop-gui/src/specs/specs.scss | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index 06b6edaa0a16..a41278aa81db 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -528,6 +528,7 @@ class SpecsList extends Component {
    ×

    Are you sure that you want to delete all example spec files?

    +

    Note: this will not delete any new or edited files.

    Cancel diff --git a/packages/desktop-gui/src/specs/specs.scss b/packages/desktop-gui/src/specs/specs.scss index f7e3e4ac75f3..222c3a2b7d6c 100644 --- a/packages/desktop-gui/src/specs/specs.scss +++ b/packages/desktop-gui/src/specs/specs.scss @@ -323,6 +323,10 @@ $max-nesting-level: 14; .confirm-remove-scaffolded-files { h4 { line-height: 24px; + + &.note { + font-style: italic; + } } } From b5b962d2196d392d0de496262cbfb33857a48f03 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 24 May 2021 13:22:50 -0400 Subject: [PATCH 32/54] Update test for new user and new project case --- packages/desktop-gui/cypress/integration/specs_list_spec.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/desktop-gui/cypress/integration/specs_list_spec.js b/packages/desktop-gui/cypress/integration/specs_list_spec.js index 8e76bed8b550..0cdd87393c15 100644 --- a/packages/desktop-gui/cypress/integration/specs_list_spec.js +++ b/packages/desktop-gui/cypress/integration/specs_list_spec.js @@ -118,6 +118,8 @@ describe('Specs List', function () { }) it('does not display new user banner even when closed', function () { + this.ipc.hasOpenedCypress.resolves(false) + cy.get('.new-user-banner').should('not.exist') cy.get('.new-project-banner').find('.close').click() cy.get('.new-project-banner').should('not.exist') From 5ea7155cbcd1fce5d012f6dcb9c2d4b3a6846358 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 24 May 2021 17:53:11 -0400 Subject: [PATCH 33/54] Remove check to file tree when removing files --- packages/server/lib/scaffold.js | 34 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 74293054bc72..766e99b9608a 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -168,13 +168,13 @@ module.exports = { return getExampleSpecs() .then(({ shortPaths, index }) => { return Promise.all(_.map(shortPaths, (file) => { - return this._removeFile(file, folder, config, index) + return this._removeFile(file, folder, index) })) }).then(() => { // remove folders after we've removed all files return getExampleSpecs(true).then(({ shortPaths }) => { return Promise.all(_.map(shortPaths, (folderPath) => { - return this._removeFolder(folderPath, folder, config) + return this._removeFolder(folderPath, folder) })) }) }) @@ -244,31 +244,25 @@ module.exports = { }) }, - _removeFile (file, folder, config, index) { + _removeFile (file, folder, index) { const dest = path.join(folder, file) - return this._assertInFileTree(dest, config) - .then(() => { - return fileSizeIsSame(dest, index) - .then((isSame) => { - if (isSame) { - // catch all errors since the user may have already removed - // the file or changed permissions, etc. - return fs.unlinkAsync(dest).catch(_.noop) - } - }) + return fileSizeIsSame(dest, index) + .then((isSame) => { + if (isSame) { + // catch all errors since the user may have already removed + // the file or changed permissions, etc. + return fs.unlinkAsync(dest).catch(_.noop) + } }) }, - _removeFolder (folderPath, folder, config) { + _removeFolder (folderPath, folder) { const dest = path.join(folder, folderPath) - return this._assertInFileTree(dest, config) - .then(() => { - // catch all errors since the user may have already removed - // the folder, changed permissions, added their own files to the folder, etc. - return fs.rmdirAsync(dest).catch(_.noop) - }) + // catch all errors since the user may have already removed + // the folder, changed permissions, added their own files to the folder, etc. + return fs.rmdirAsync(dest).catch(_.noop) }, verifyScaffolding (folder, fn) { From 36875b8257557f1e6ce00856867529c02ee3d729 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Thu, 10 Jun 2021 04:11:06 +0300 Subject: [PATCH 34/54] Update kitchensink version --- packages/example/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/example/package.json b/packages/example/package.json index 3ec88a493049..d9fe37f507fe 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -28,7 +28,7 @@ "devDependencies": { "chai": "3.5.0", "cross-env": "6.0.3", - "cypress-example-kitchensink": "1.15.1", + "cypress-example-kitchensink": "1.15.2", "gulp": "4.0.2", "gulp-clean": "0.4.0", "gulp-gh-pages": "0.6.0-6", diff --git a/yarn.lock b/yarn.lock index 11bdc0857ddb..e929c76172b0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15456,10 +15456,10 @@ cyclist@^1.0.1: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= -cypress-example-kitchensink@1.15.1: - version "1.15.1" - resolved "https://registry.yarnpkg.com/cypress-example-kitchensink/-/cypress-example-kitchensink-1.15.1.tgz#60edc092d65816ac6d53b25815693c6b86338a25" - integrity sha512-kbLf4LPnXgVrm0X4KAC7EaNNWKYFfWBbqFrP110iADBeRdmTNe2Go1udZUos/qGDRW0lQoMl3q/kUXoAtS+5xg== +cypress-example-kitchensink@1.15.2: + version "1.15.2" + resolved "https://registry.yarnpkg.com/cypress-example-kitchensink/-/cypress-example-kitchensink-1.15.2.tgz#325015726291a5e1e0d0cf89177eb9dec1c13e19" + integrity sha512-Ni/xbpMEllrNBrDVxh9juu7W4sbyBGpENuWvFdiojjBxzyvCCHaYCJIdF5kgGNzE5aP4AkoGW/jEk1KiKQzALA== dependencies: npm-run-all "^4.1.2" serve "11.3.0" From 8109c01ddc702119158e96c2b2775ab606155f67 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Sat, 12 Jun 2021 21:12:25 +0300 Subject: [PATCH 35/54] Fix edge case where banner could appear when no files have been scaffolded --- packages/server/lib/project-base.ts | 2 +- packages/server/lib/scaffold.js | 25 +++++++++++------ packages/server/test/unit/scaffold_spec.js | 32 ++++++++++++++++++---- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/packages/server/lib/project-base.ts b/packages/server/lib/project-base.ts index c3e02d29bd1a..ce45b42933b9 100644 --- a/packages/server/lib/project-base.ts +++ b/packages/server/lib/project-base.ts @@ -519,7 +519,7 @@ export class ProjectBase extends EE { throw new Error('Missing integration folder') } - return this.determineIsNewProject(cfg.integrationFolder) + return this.determineIsNewProject(cfg) .then((untouchedScaffold) => { const userHasSeenBanner = _.get(cfg, 'state.showedNewProjectBanner', false) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 766e99b9608a..a601c01f0f0a 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -85,16 +85,23 @@ const componentTestingEnabled = (config) => { return componentTestingEnabled && !isDefault(config, 'componentFolder') } -const isNewProject = (integrationFolder) => { +const isNewProject = (config) => { // logic to determine if new project - // 1. component testing is not enabled - // 2. there are no files in 'integrationFolder' - // 3. there is the same number of files in 'integrationFolder' - // 4. the files are named the same as the example files - // 5. the bytes of the files match the example files + // 1. 'integrationFolder' is still the default + // 2. component testing is not enabled + // 3. there are no files in 'integrationFolder' + // 4. there is the same number of files in 'integrationFolder' + // 5. the files are named the same as the example files + // 6. the bytes of the files match the example files + + const { integrationFolder } = config debug('determine if new project by globbing files in %o', { integrationFolder }) + if (!isDefault(config, 'integrationFolder')) { + return Promise.resolve(false) + } + // checks for file up to 3 levels deep return glob('{*,*/*,*/*/*}', { cwd: integrationFolder, realpath: true, nodir: true }) .then((files) => { @@ -105,7 +112,7 @@ const isNewProject = (integrationFolder) => { debug('- empty?', isEmpty(files)) if (isEmpty(files)) { return true - } // 1 + } return getExampleSpecs() .then((exampleSpecs) => { @@ -114,14 +121,14 @@ const isNewProject = (integrationFolder) => { debug('- different number of files?', numFilesDifferent) if (numFilesDifferent) { return false - } // 2 + } const filesNamesDifferent = filesNamesAreDifferent(files, exampleSpecs.index) debug('- different file names?', filesNamesDifferent) if (filesNamesDifferent) { return false - } // 3 + } return filesSizesAreSame(files, exampleSpecs.index) }) diff --git a/packages/server/test/unit/scaffold_spec.js b/packages/server/test/unit/scaffold_spec.js index c1c9a303909b..8faa7e3edb2e 100644 --- a/packages/server/test/unit/scaffold_spec.js +++ b/packages/server/test/unit/scaffold_spec.js @@ -25,6 +25,28 @@ describe('lib/scaffold', () => { this.pristinePath = Fixtures.projectPath('pristine') }) + it('is true when integrationFolder is empty', function () { + const pristine = new ProjectE2E(this.pristinePath) + + return pristine.getConfig() + .then((cfg) => { + return pristine.determineIsNewProject(cfg) + }).then((ret) => { + expect(ret).to.be.true + }) + }) + + it('is false when integrationFolder has been changed', function () { + const pristine = new ProjectE2E(this.pristinePath) + + return pristine.getConfig({ integrationFolder: 'foo' }) + .then((cfg) => { + return pristine.determineIsNewProject(cfg) + }).then((ret) => { + expect(ret).to.be.false + }) + }) + it('is false when files.length isnt 1', function () { const id = () => { const idsPath = Fixtures.projectPath('ids') @@ -35,7 +57,7 @@ describe('lib/scaffold', () => { .then((cfg) => { return this.ids.scaffold(cfg).return(cfg) }).then((cfg) => { - return this.ids.determineIsNewProject(cfg.integrationFolder) + return this.ids.determineIsNewProject(cfg) }).then((ret) => { expect(ret).to.be.false }) @@ -50,7 +72,7 @@ describe('lib/scaffold', () => { .then((cfg) => { return this.todos.scaffold(cfg).return(cfg) }).then((cfg) => { - return this.todos.determineIsNewProject(cfg.integrationFolder) + return this.todos.determineIsNewProject(cfg) }).then((ret) => { expect(ret).to.be.false }) @@ -66,7 +88,7 @@ describe('lib/scaffold', () => { .then((cfg) => { return pristine.scaffold(cfg).return(cfg) }).then((cfg) => { - return pristine.determineIsNewProject(cfg.integrationFolder) + return pristine.determineIsNewProject(cfg) }).then((ret) => { expect(ret).to.be.true }) @@ -79,7 +101,7 @@ describe('lib/scaffold', () => { .then((cfg) => { return pristine.scaffold(cfg).return(cfg) }).then((cfg) => { - const file = path.join(cfg.integrationFolder, '1-getting-started', 'todo.spec.js') + const file = path.join(cfg, '1-getting-started', 'todo.spec.js') // write some data to the file so it is now // different in file size @@ -90,7 +112,7 @@ describe('lib/scaffold', () => { return fs.writeFileAsync(file, str).return(cfg) }) }).then((cfg) => { - return pristine.determineIsNewProject(cfg.integrationFolder) + return pristine.determineIsNewProject(cfg) }).then((ret) => { expect(ret).to.be.false }) From 9d55ae12ed7f7446a46ec04e1cdd30c6b886fa5f Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Wed, 16 Jun 2021 23:52:34 +0300 Subject: [PATCH 36/54] Fix tests --- packages/server/test/unit/modes/run_spec.js | 5 +++++ packages/server/test/unit/scaffold_spec.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/server/test/unit/modes/run_spec.js b/packages/server/test/unit/modes/run_spec.js index 382c391bca01..09d0e2c1477c 100644 --- a/packages/server/test/unit/modes/run_spec.js +++ b/packages/server/test/unit/modes/run_spec.js @@ -669,6 +669,11 @@ describe('lib/modes/run', () => { video: true, videosFolder: 'videos', integrationFolder: '/path/to/integrationFolder', + resolved: { + integrationFolder: { + integrationFolder: { value: '/path/to/integrationFolder', from: 'config' }, + }, + }, }) sinon.stub(specsUtil, 'find').resolves([ diff --git a/packages/server/test/unit/scaffold_spec.js b/packages/server/test/unit/scaffold_spec.js index 8faa7e3edb2e..558fe0ceb468 100644 --- a/packages/server/test/unit/scaffold_spec.js +++ b/packages/server/test/unit/scaffold_spec.js @@ -101,7 +101,7 @@ describe('lib/scaffold', () => { .then((cfg) => { return pristine.scaffold(cfg).return(cfg) }).then((cfg) => { - const file = path.join(cfg, '1-getting-started', 'todo.spec.js') + const file = path.join(cfg.integrationFolder, '1-getting-started', 'todo.spec.js') // write some data to the file so it is now // different in file size From 957553b6818a22add95fadd25166b3de60291d47 Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Thu, 17 Jun 2021 13:37:44 -0500 Subject: [PATCH 37/54] Update styling for 'note' when deleting files --- packages/desktop-gui/src/specs/specs.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/desktop-gui/src/specs/specs.scss b/packages/desktop-gui/src/specs/specs.scss index 222c3a2b7d6c..f4ce5e9755ad 100644 --- a/packages/desktop-gui/src/specs/specs.scss +++ b/packages/desktop-gui/src/specs/specs.scss @@ -326,6 +326,9 @@ $max-nesting-level: 14; &.note { font-style: italic; + font-size: 14px; + font-weight: 400; + color: #888; } } } From db8fe5ee6583f952d7485017bae75f973b107a45 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Thu, 17 Jun 2021 23:36:46 +0300 Subject: [PATCH 38/54] fix issue with path on windows --- packages/server/lib/scaffold.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index a601c01f0f0a..9fcf74b7be1a 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -13,7 +13,9 @@ const getExampleSpecsFullPaths = cypressEx.getPathToExamples() const getExampleFolderFullPaths = cypressEx.getPathToExampleFolders() const getPathFromIntegrationFolder = (file) => { - return file.substring(file.indexOf('integration/') + 'integration/'.length) + const integrationFolder = `integration${path.sep}` + + return file.substring(file.indexOf(integrationFolder) + integrationFolder.length) } const isDifferentNumberOfFiles = (files, exampleSpecs) => { From 1cdc34292719f331bd599d2dc640348b44b109be Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Thu, 17 Jun 2021 23:50:36 +0300 Subject: [PATCH 39/54] Change remove command --- packages/server/lib/scaffold.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 9fcf74b7be1a..8eda3513c502 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -261,7 +261,7 @@ module.exports = { if (isSame) { // catch all errors since the user may have already removed // the file or changed permissions, etc. - return fs.unlinkAsync(dest).catch(_.noop) + return fs.removeAsync(dest).catch(_.noop) } }) }, @@ -271,7 +271,7 @@ module.exports = { // catch all errors since the user may have already removed // the folder, changed permissions, added their own files to the folder, etc. - return fs.rmdirAsync(dest).catch(_.noop) + return fs.removeAsync(dest).catch(_.noop) }, verifyScaffolding (folder, fn) { From 0db6a32e49c61158dc326a5ae5b049a3471b887f Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Fri, 18 Jun 2021 00:01:53 +0300 Subject: [PATCH 40/54] Fix rm dir --- packages/server/lib/scaffold.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 8eda3513c502..4d59aae91735 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -271,7 +271,7 @@ module.exports = { // catch all errors since the user may have already removed // the folder, changed permissions, added their own files to the folder, etc. - return fs.removeAsync(dest).catch(_.noop) + return fs.rmdirAsync(dest).catch(_.noop) }, verifyScaffolding (folder, fn) { From 93e5c17c8c9796772cff732207e2666ebd4967db Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 21 Jun 2021 18:16:55 +0300 Subject: [PATCH 41/54] Fix for windows --- packages/server/lib/scaffold.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 4d59aae91735..678678466ecb 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -13,9 +13,7 @@ const getExampleSpecsFullPaths = cypressEx.getPathToExamples() const getExampleFolderFullPaths = cypressEx.getPathToExampleFolders() const getPathFromIntegrationFolder = (file) => { - const integrationFolder = `integration${path.sep}` - - return file.substring(file.indexOf(integrationFolder) + integrationFolder.length) + return file.substring(file.indexOf('integration/') + 'integration/'.length) } const isDifferentNumberOfFiles = (files, exampleSpecs) => { From 7c9945a01ab0a7ccd4b97c1050101c9d65b079fb Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 21 Jun 2021 18:25:19 +0300 Subject: [PATCH 42/54] Try to use appveyor to test --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 825cc32c2f38..074d32d9a70a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -84,6 +84,7 @@ test_script: # make sure mocha runs - yarn test-mocha + - yarn workspace @packages/server test-unit 'scaffold_spec.js' # make sure our snapshots are compared correctly # - npm run test-mocha-snapshot # the other larger tests From 01a9ae8d6fd91410ce1342641c244d22e4729a88 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 21 Jun 2021 18:45:31 +0300 Subject: [PATCH 43/54] appveyor please --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 074d32d9a70a..1c873310609a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -84,7 +84,7 @@ test_script: # make sure mocha runs - yarn test-mocha - - yarn workspace @packages/server test-unit 'scaffold_spec.js' + - yarn workspace @packages/server test-unit scaffold_spec.js # make sure our snapshots are compared correctly # - npm run test-mocha-snapshot # the other larger tests From f8fa1826b981011f0cf8c96eb8db6cea5ad0444c Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 21 Jun 2021 19:08:48 +0300 Subject: [PATCH 44/54] getting some feedback --- packages/server/lib/scaffold.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 678678466ecb..5102cc9c2f67 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -254,8 +254,12 @@ module.exports = { _removeFile (file, folder, index) { const dest = path.join(folder, file) + console.log(dest) + return fileSizeIsSame(dest, index) .then((isSame) => { + console.log(isSame) + if (isSame) { // catch all errors since the user may have already removed // the file or changed permissions, etc. @@ -267,6 +271,8 @@ module.exports = { _removeFolder (folderPath, folder) { const dest = path.join(folder, folderPath) + console.log(dest) + // catch all errors since the user may have already removed // the folder, changed permissions, added their own files to the folder, etc. return fs.rmdirAsync(dest).catch(_.noop) From 55fac95612cbf8c28fd0b2e92673e1bf7c0e2cda Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 21 Jun 2021 19:33:04 +0300 Subject: [PATCH 45/54] Why doesn't this work --- packages/server/lib/scaffold.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 5102cc9c2f67..4f504744697f 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -58,8 +58,13 @@ const fileSizeIsSame = (file, index) => { getFileSize(file), getFileSize(getIndexedExample(file, index)), ).spread((fileSize, originalFileSize) => { + console.log(fileSize) + console.log(originalFileSize) + return fileSize === originalFileSize - }).catch(() => { + }).catch((e) => { + console.log(e) + // if the file does not exist, return false return false }) @@ -254,8 +259,6 @@ module.exports = { _removeFile (file, folder, index) { const dest = path.join(folder, file) - console.log(dest) - return fileSizeIsSame(dest, index) .then((isSame) => { console.log(isSame) @@ -271,8 +274,6 @@ module.exports = { _removeFolder (folderPath, folder) { const dest = path.join(folder, folderPath) - console.log(dest) - // catch all errors since the user may have already removed // the folder, changed permissions, added their own files to the folder, etc. return fs.rmdirAsync(dest).catch(_.noop) From b184aaccddf9d6105ed4ad4e265a20973c3cf699 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 21 Jun 2021 19:34:29 +0300 Subject: [PATCH 46/54] more info --- packages/server/lib/scaffold.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 4f504744697f..a685304f8f72 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -179,6 +179,8 @@ module.exports = { return getExampleSpecs() .then(({ shortPaths, index }) => { + console.log(index) + return Promise.all(_.map(shortPaths, (file) => { return this._removeFile(file, folder, index) })) From 28bb6b49954fb3b3c574a305697287039d366a70 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 21 Jun 2021 20:03:28 +0300 Subject: [PATCH 47/54] I have a feeling this works --- packages/server/lib/scaffold.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index a685304f8f72..cab6af5fef1c 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -16,6 +16,10 @@ const getPathFromIntegrationFolder = (file) => { return file.substring(file.indexOf('integration/') + 'integration/'.length) } +const convertPathForOS = (filePath) => { + return filePath.split(path.posix.sep).join(path.sep) +} + const isDifferentNumberOfFiles = (files, exampleSpecs) => { return files.length !== exampleSpecs.length } @@ -40,7 +44,7 @@ const getExampleSpecs = (foldersOnly = false) => { } const getIndexedExample = (file, index) => { - return index[getPathFromIntegrationFolder(file)] + return convertPathForOS(index[getPathFromIntegrationFolder(file)]) } const filesNamesAreDifferent = (files, index) => { @@ -54,13 +58,12 @@ const getFileSize = (file) => { } const fileSizeIsSame = (file, index) => { + console.log(getIndexedExample(file, index)) + return Promise.join( getFileSize(file), getFileSize(getIndexedExample(file, index)), ).spread((fileSize, originalFileSize) => { - console.log(fileSize) - console.log(originalFileSize) - return fileSize === originalFileSize }).catch((e) => { console.log(e) From c27d5a50c141791c0d846f27cad615f2845104cc Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 21 Jun 2021 20:26:59 +0300 Subject: [PATCH 48/54] maybe its the other path --- packages/server/lib/scaffold.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index cab6af5fef1c..3e8a3fccf046 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -1,6 +1,7 @@ const _ = require('lodash') const Promise = require('bluebird') const path = require('path') +const os = require('os') const cypressEx = require('@packages/example') const { fs } = require('./util/fs') const glob = require('./util/glob') @@ -17,6 +18,8 @@ const getPathFromIntegrationFolder = (file) => { } const convertPathForOS = (filePath) => { + // converts posix paths for current OS + // on posix systems nothing changes, but it fixes the path for win32 return filePath.split(path.posix.sep).join(path.sep) } @@ -44,7 +47,7 @@ const getExampleSpecs = (foldersOnly = false) => { } const getIndexedExample = (file, index) => { - return convertPathForOS(index[getPathFromIntegrationFolder(file)]) + return index[getPathFromIntegrationFolder(file)] } const filesNamesAreDifferent = (files, index) => { @@ -58,10 +61,14 @@ const getFileSize = (file) => { } const fileSizeIsSame = (file, index) => { - console.log(getIndexedExample(file, index)) + console.log(file) + + const filePath = convertPathForOS(file) + + console.log(filePath) return Promise.join( - getFileSize(file), + getFileSize(filePath), getFileSize(getIndexedExample(file, index)), ).spread((fileSize, originalFileSize) => { return fileSize === originalFileSize From 93417e5ac4e6e36db33692947823a17da76e2ba8 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 21 Jun 2021 21:48:30 +0300 Subject: [PATCH 49/54] please --- packages/server/lib/scaffold.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 3e8a3fccf046..cd48987b0a0b 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -47,6 +47,9 @@ const getExampleSpecs = (foldersOnly = false) => { } const getIndexedExample = (file, index) => { + console.log('getting inndexed example', file) + console.log(getPathFromIntegrationFolder(file)) + return index[getPathFromIntegrationFolder(file)] } @@ -62,13 +65,10 @@ const getFileSize = (file) => { const fileSizeIsSame = (file, index) => { console.log(file) - - const filePath = convertPathForOS(file) - - console.log(filePath) + console.log(getIndexedExample(file, index)) return Promise.join( - getFileSize(filePath), + getFileSize(file), getFileSize(getIndexedExample(file, index)), ).spread((fileSize, originalFileSize) => { return fileSize === originalFileSize From 724ec3c51d3900a0587f2788e86b6b86ebc686ac Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 21 Jun 2021 22:17:14 +0300 Subject: [PATCH 50/54] this is the one --- packages/server/lib/scaffold.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index cd48987b0a0b..6f0db1a0b2c4 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -14,13 +14,11 @@ const getExampleSpecsFullPaths = cypressEx.getPathToExamples() const getExampleFolderFullPaths = cypressEx.getPathToExampleFolders() const getPathFromIntegrationFolder = (file) => { - return file.substring(file.indexOf('integration/') + 'integration/'.length) -} - -const convertPathForOS = (filePath) => { - // converts posix paths for current OS - // on posix systems nothing changes, but it fixes the path for win32 - return filePath.split(path.posix.sep).join(path.sep) + // always try with posix paths first and fallback to win if failed + // using path.sep will not work since sometimes posix paths are used + // in our scaffolding even when on windows + return file.substring(file.indexOf('integration/') + 'integration/'.length) || + file.substring(file.indexOf('integration\\') + 'integration\\'.length) } const isDifferentNumberOfFiles = (files, exampleSpecs) => { From 20194108134df483cc83f6340c956945dc06f8c1 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 21 Jun 2021 22:42:28 +0300 Subject: [PATCH 51/54] this is it --- packages/server/lib/scaffold.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 6f0db1a0b2c4..008d1cde25c1 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -17,8 +17,13 @@ const getPathFromIntegrationFolder = (file) => { // always try with posix paths first and fallback to win if failed // using path.sep will not work since sometimes posix paths are used // in our scaffolding even when on windows - return file.substring(file.indexOf('integration/') + 'integration/'.length) || - file.substring(file.indexOf('integration\\') + 'integration\\'.length) + const index = file.indexOf('integration/') + + if (index > -1) { + return file.substring(index + 'integration/'.length) + } + + return file.substring(file.indexOf('integration\\') + 'integration\\'.length) } const isDifferentNumberOfFiles = (files, exampleSpecs) => { From ce7183fafb0b6292d82914cbf3edae361745aa03 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Tue, 22 Jun 2021 15:02:07 +0300 Subject: [PATCH 52/54] this should work --- packages/server/lib/scaffold.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 008d1cde25c1..b21fe6e151d4 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -51,6 +51,12 @@ const getExampleSpecs = (foldersOnly = false) => { const getIndexedExample = (file, index) => { console.log('getting inndexed example', file) + + // convert to using posix sep if on win + if (os.platform() === 'win32') { + file = file.split(path.sep).join(path.posix.sep) + } + console.log(getPathFromIntegrationFolder(file)) return index[getPathFromIntegrationFolder(file)] From 95a4ae68aef9303d3e8e835dcbf1c35cbb5821ee Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Tue, 22 Jun 2021 15:25:13 +0300 Subject: [PATCH 53/54] try reverting that change that might not be needed --- packages/server/lib/scaffold.js | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index b21fe6e151d4..7f29e59608ef 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -14,16 +14,7 @@ const getExampleSpecsFullPaths = cypressEx.getPathToExamples() const getExampleFolderFullPaths = cypressEx.getPathToExampleFolders() const getPathFromIntegrationFolder = (file) => { - // always try with posix paths first and fallback to win if failed - // using path.sep will not work since sometimes posix paths are used - // in our scaffolding even when on windows - const index = file.indexOf('integration/') - - if (index > -1) { - return file.substring(index + 'integration/'.length) - } - - return file.substring(file.indexOf('integration\\') + 'integration\\'.length) + return file.substring(file.indexOf('integration/') + 'integration/'.length) } const isDifferentNumberOfFiles = (files, exampleSpecs) => { @@ -50,15 +41,11 @@ const getExampleSpecs = (foldersOnly = false) => { } const getIndexedExample = (file, index) => { - console.log('getting inndexed example', file) - // convert to using posix sep if on win if (os.platform() === 'win32') { file = file.split(path.sep).join(path.posix.sep) } - console.log(getPathFromIntegrationFolder(file)) - return index[getPathFromIntegrationFolder(file)] } @@ -73,17 +60,12 @@ const getFileSize = (file) => { } const fileSizeIsSame = (file, index) => { - console.log(file) - console.log(getIndexedExample(file, index)) - return Promise.join( getFileSize(file), getFileSize(getIndexedExample(file, index)), ).spread((fileSize, originalFileSize) => { return fileSize === originalFileSize }).catch((e) => { - console.log(e) - // if the file does not exist, return false return false }) @@ -198,8 +180,6 @@ module.exports = { return getExampleSpecs() .then(({ shortPaths, index }) => { - console.log(index) - return Promise.all(_.map(shortPaths, (file) => { return this._removeFile(file, folder, index) })) @@ -282,8 +262,6 @@ module.exports = { return fileSizeIsSame(dest, index) .then((isSame) => { - console.log(isSame) - if (isSame) { // catch all errors since the user may have already removed // the file or changed permissions, etc. From e1e0178a8b58d4acc24f8a1e0f2c85ed78d56d29 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Tue, 22 Jun 2021 15:51:18 +0300 Subject: [PATCH 54/54] remove appveyor testing scaffolding --- appveyor.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 1c873310609a..825cc32c2f38 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -84,7 +84,6 @@ test_script: # make sure mocha runs - yarn test-mocha - - yarn workspace @packages/server test-unit scaffold_spec.js # make sure our snapshots are compared correctly # - npm run test-mocha-snapshot # the other larger tests