Skip to content

Commit

Permalink
fix: studio save to definitions with config and surface save errs (#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
panzarino authored Feb 20, 2021
1 parent 9c64236 commit 26edc21
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 21 deletions.
6 changes: 3 additions & 3 deletions packages/runner/src/lib/event-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,9 @@ const eventManager = {
})

localBus.on('studio:save', (saveInfo) => {
ws.emit('studio:save', saveInfo, (success) => {
if (!success) {
reporterBus.emit('test:set:state', studioRecorder.saveError, _.noop)
ws.emit('studio:save', saveInfo, (err) => {
if (err) {
reporterBus.emit('test:set:state', studioRecorder.saveError(err), _.noop)
}
})
})
Expand Down
19 changes: 11 additions & 8 deletions packages/runner/src/studio/studio-recorder.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import $driverUtils from '@packages/driver/src/cypress/utils'

import eventManager from '../lib/event-manager'

const saveErrorMessage = `\
const saveErrorMessage = (message) => {
return `\
${message}\n\n\
Cypress was unable to save these commands to your spec file. \
Cypress Studio is still in beta and the team is working hard to \
resolve issues like this. To help us fix this issue more quickly, \
you can provide us with more information by clicking 'Learn more' below.`
}

const eventTypes = [
'click',
Expand Down Expand Up @@ -75,21 +78,21 @@ export class StudioRecorder {
}
}

@computed get saveError () {
get Cypress () {
return eventManager.getCypress()
}

saveError (err) {
return {
id: this.testId,
err: {
name: 'CypressError',
message: saveErrorMessage,
...err,
message: saveErrorMessage(err.message),
docsUrl: 'https://on.cypress.io/studio-beta',
},
}
}

get Cypress () {
return eventManager.getCypress()
}

@action setTestId = (testId) => {
this.testId = testId
}
Expand Down
132 changes: 132 additions & 0 deletions packages/server/__snapshots__/spec_writer_spec.ts.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ describe('top level suite', () => {
it.only('test with it.only', () => {
cy.get('.btn').click()
})
it('test with config', { responseTimeout: 60000 }, () => {
cy.get('.btn').click()
})
})
context('inner suite with context', () => {
Expand All @@ -60,6 +64,10 @@ describe('top level suite', () => {
describe.only('inner suite with describe.only', () => {
})
describe('suite with config', { responseTimeout: 60000 }, () => {
})
})
`
Expand All @@ -83,6 +91,10 @@ describe('top level suite', () => {
it.only('test with it.only', () => {
cy.get('.btn').click()
})
it('test with config', { responseTimeout: 60000 }, () => {
cy.get('.btn').click()
})
})
context('inner suite with context', () => {
Expand All @@ -93,6 +105,10 @@ describe('top level suite', () => {
describe.only('inner suite with describe.only', () => {
})
describe('suite with config', { responseTimeout: 60000 }, () => {
})
})
`
Expand All @@ -113,6 +129,10 @@ describe('top level suite', () => {
cy.get('.btn').click()
})
it('test with config', { responseTimeout: 60000 }, () => {
cy.get('.btn').click()
})
/* === Test Created with Cypress Studio === */
it('test added to describe', function() {
/* ==== Generated with Cypress Studio ==== */
Expand All @@ -130,6 +150,10 @@ describe('top level suite', () => {
describe.only('inner suite with describe.only', () => {
})
describe('suite with config', { responseTimeout: 60000 }, () => {
})
})
`
Expand All @@ -149,6 +173,10 @@ describe('top level suite', () => {
it.only('test with it.only', () => {
cy.get('.btn').click()
})
it('test with config', { responseTimeout: 60000 }, () => {
cy.get('.btn').click()
})
})
context('inner suite with context', () => {
Expand All @@ -165,6 +193,10 @@ describe('top level suite', () => {
describe.only('inner suite with describe.only', () => {
})
describe('suite with config', { responseTimeout: 60000 }, () => {
})
})
`
Expand All @@ -188,6 +220,10 @@ describe('top level suite', () => {
cy.get('.btn').click();
/* ==== End Cypress Studio ==== */
})
it('test with config', { responseTimeout: 60000 }, () => {
cy.get('.btn').click()
})
})
context('inner suite with context', () => {
Expand All @@ -198,6 +234,10 @@ describe('top level suite', () => {
describe.only('inner suite with describe.only', () => {
})
describe('suite with config', { responseTimeout: 60000 }, () => {
})
})
`
Expand All @@ -217,6 +257,10 @@ describe('top level suite', () => {
it.only('test with it.only', () => {
cy.get('.btn').click()
})
it('test with config', { responseTimeout: 60000 }, () => {
cy.get('.btn').click()
})
})
context('inner suite with context', () => {
Expand All @@ -233,6 +277,94 @@ describe('top level suite', () => {
/* ==== End Cypress Studio ==== */
});
})
describe('suite with config', { responseTimeout: 60000 }, () => {
})
})
`

exports['lib/util/spec_writer #appendCommandsToTest can add commands to an existing test with config 1'] = `
describe('top level suite', () => {
describe('inner suite with describe', () => {
it('test with it', () => {
cy.get('.btn').click()
})
specify('test with specify', () => {
cy.get('.btn').click()
})
// eslint-disable-next-line mocha/no-exclusive-tests
it.only('test with it.only', () => {
cy.get('.btn').click()
})
it('test with config', { responseTimeout: 60000 }, () => {
cy.get('.btn').click()
/* ==== Generated with Cypress Studio ==== */
cy.get('.input').type('typed text');
cy.get('.btn').click();
/* ==== End Cypress Studio ==== */
})
})
context('inner suite with context', () => {
})
// eslint-disable-next-line mocha/no-exclusive-tests
describe.only('inner suite with describe.only', () => {
})
describe('suite with config', { responseTimeout: 60000 }, () => {
})
})
`

exports['lib/util/spec_writer #createNewTestInSuite can create a new test in a suite with config 1'] = `
describe('top level suite', () => {
describe('inner suite with describe', () => {
it('test with it', () => {
cy.get('.btn').click()
})
specify('test with specify', () => {
cy.get('.btn').click()
})
// eslint-disable-next-line mocha/no-exclusive-tests
it.only('test with it.only', () => {
cy.get('.btn').click()
})
it('test with config', { responseTimeout: 60000 }, () => {
cy.get('.btn').click()
})
})
context('inner suite with context', () => {
})
// eslint-disable-next-line mocha/no-exclusive-tests
describe.only('inner suite with describe.only', () => {
})
describe('suite with config', { responseTimeout: 60000 }, () => {
/* === Test Created with Cypress Studio === */
it('test added to describe with config', function() {
/* ==== Generated with Cypress Studio ==== */
cy.get('.input').type('typed text');
cy.get('.btn').click();
/* ==== End Cypress Studio ==== */
});
})
})
`
12 changes: 7 additions & 5 deletions packages/server/lib/socket-e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,19 @@ export class SocketE2E extends SocketBase {
})

socket.on('studio:save', (saveInfo, cb) => {
// even if the user has turned off file watching
// we want to force a reload on save
// even if the user has turned off file watching
// we want to force a reload on save
if (!config.watchForFileChanges) {
preprocessor.emitter.on('file:updated', this.onStudioTestFileChange)
}

studio.save(saveInfo)
.then((success) => {
cb(success)
.then((err) => {
cb(err)

if (!success && !config.watchForFileChanges) {
// onStudioTestFileChange will remove itself after being called
// but if there's an error, it never gets called so we manually remove it
if (err && !config.watchForFileChanges) {
this.removeOnStudioTestFileChange()
}
})
Expand Down
26 changes: 24 additions & 2 deletions packages/server/lib/studio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ interface SaveInfo {
testName?: string
}

class StudioSaveError extends Error {
static errMessage = (isSuite) => `Studio was unable to find your ${isSuite ? 'suite' : 'test'} in the spec file.`

constructor (isSuite) {
super(StudioSaveError.errMessage(isSuite))
this.name = 'StudioSaveError'
}
}

export const setStudioModalShown = () => {
return savedState.create()
.then((state) => {
Expand Down Expand Up @@ -35,7 +44,20 @@ export const save = (saveInfo: SaveInfo) => {
return saveToFile()
.then((success) => {
return setStudioModalShown()
.then(() => success)
.then(() => {
if (!success) {
throw new StudioSaveError(isSuite)
}

return null
})
})
.catch((err) => {
return {
type: err.type,
name: err.name,
message: err.message,
stack: err.stack,
}
})
.catch(() => false)
}
4 changes: 3 additions & 1 deletion packages/server/lib/util/spec_writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ export const generateAstRules = (fileDetails: { line: number, column: number },
const columnEnd = identifier.loc.end.column + 2

if (fnNames.includes(identifier.name) && identifier.loc.start.line === line && columnStart <= column && column <= columnEnd) {
const fn = node.arguments[1] as n.FunctionExpression
const arg1 = node.arguments[1]

const fn = (arg1.type === 'ObjectExpression' ? node.arguments[2] : arg1) as n.FunctionExpression

if (!fn) {
return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ describe('top level suite', () => {
it.only('test with it.only', () => {
cy.get('.btn').click()
})

it('test with config', { responseTimeout: 60000 }, () => {
cy.get('.btn').click()
})
})

context('inner suite with context', () => {
Expand All @@ -22,4 +26,8 @@ describe('top level suite', () => {
describe.only('inner suite with describe.only', () => {

})

describe('suite with config', { responseTimeout: 60000 }, () => {

})
})
Loading

4 comments on commit 26edc21

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 26edc21 Feb 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/6.6.1/circle-develop-26edc21ce7b9858f82144068b74f81e67983146f/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 26edc21 Feb 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppVeyor has built the win32 ia32 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/6.6.1/appveyor-develop-26edc21ce7b9858f82144068b74f81e67983146f/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 26edc21 Feb 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppVeyor has built the win32 x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/6.6.1/appveyor-develop-26edc21ce7b9858f82144068b74f81e67983146f/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 26edc21 Feb 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/6.6.1/circle-develop-26edc21ce7b9858f82144068b74f81e67983146f/cypress.tgz

Please sign in to comment.