Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: restart Cypress server and browser on baseUrl change #22154

Merged
merged 14 commits into from Jun 10, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 22 additions & 0 deletions packages/app/cypress/e2e/cypress-in-cypress.cy.ts
Expand Up @@ -305,4 +305,26 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100
expect(ctx.actions.project.initializeActiveProject).to.be.called
})
})

it('restarts server if baseUrl is updated in the config file', () => {
startAtSpecsPage('e2e')
cy.get('[data-cy="spec-item"]')

cy.withCtx((ctx, o) => {
ctx.coreData.app.browserStatus = 'open'
o.sinon.stub(ctx.actions.project, 'initializeActiveProject')

let config = ctx.actions.file.readFileInProject('cypress.config.js')

config = config.replace(` e2e: {`, ` e2e: {\n baseUrl: 'https://example.cypress.io',\n`)
ctx.actions.file.writeFileInProject('cypress.config.js', config)
})

cy.get('[data-cy="loading-spinner"]').should('be.visible')
cy.contains('[role="alert"]', 'Loading')

cy.withRetryableCtx((ctx) => {
expect(ctx.actions.project.initializeActiveProject).to.be.called
})
})
})
1 change: 0 additions & 1 deletion packages/config/src/browser.ts
Expand Up @@ -188,7 +188,6 @@ export const validateNeedToRestartOnChange = (cachedConfig: any, updatedConfig:
const restartOnChange = {
browser: false,
server: false,
pingBaseUrl: false,
}

if (!cachedConfig || !updatedConfig) {
Expand Down
6 changes: 3 additions & 3 deletions packages/config/src/options.ts
Expand Up @@ -40,7 +40,7 @@ interface ResolvedConfigOption {
*/
canUpdateDuringTestTime?: boolean
specificTestingType?: TestingType
requireRestartOnChange?: 'server' | 'browser' | 'pingBaseUrl'
requireRestartOnChange?: 'server' | 'browser'
}

interface RuntimeConfigOption {
Expand All @@ -52,7 +52,7 @@ interface RuntimeConfigOption {
* Can be mutated with Cypress.config() or test-specific configuration overrides
*/
canUpdateDuringTestTime?: boolean
requireRestartOnChange?: 'server' | 'browser' | 'pingBaseUrl'
requireRestartOnChange?: 'server' | 'browser'
}

export interface BreakingOption {
Expand Down Expand Up @@ -135,7 +135,7 @@ const resolvedOptions: Array<ResolvedConfigOption> = [
defaultValue: null,
validation: validate.isFullyQualifiedUrl,
canUpdateDuringTestTime: true,
requireRestartOnChange: 'pingBaseUrl',
requireRestartOnChange: 'server',
}, {
name: 'blockHosts',
defaultValue: null,
Expand Down
14 changes: 5 additions & 9 deletions packages/data-context/src/data/ProjectLifecycleManager.ts
Expand Up @@ -236,8 +236,6 @@ export class ProjectLifecycleManager {
})
}

const restartOnChange = validateNeedToRestartOnChange(this._cachedFullConfig, finalConfig)

if (this._currentTestingType === 'component') {
const devServerOptions = await this.ctx._apis.projectApi.getDevServer().start({ specs: this.ctx.project.specs, config: finalConfig })

Expand All @@ -246,14 +244,12 @@ export class ProjectLifecycleManager {
}

finalConfig.baseUrl = `http://localhost:${devServerOptions?.port}`

// Devserver can pick a random port, this solve the edge case where closing
// and spawning the devserver can result in a different baseUrl
if (this._cachedFullConfig && this._cachedFullConfig.baseUrl !== finalConfig.baseUrl) {
restartOnChange.server = true
}
}

const pingBaseUrl = this._cachedFullConfig && this._cachedFullConfig.baseUrl !== finalConfig.baseUrl

const restartOnChange = validateNeedToRestartOnChange(this._cachedFullConfig, finalConfig)

this._cachedFullConfig = finalConfig

// This happens automatically with openProjectCreate in run mode
Expand All @@ -271,7 +267,7 @@ export class ProjectLifecycleManager {
await this.ctx.actions.browser.relaunchBrowser()
}

if (restartOnChange.pingBaseUrl) {
if (pingBaseUrl) {
this.ctx.actions.project.pingBaseUrl().catch(this.onLoadError)
}
}
Expand Down
8 changes: 6 additions & 2 deletions packages/launchpad/cypress/e2e/choose-a-browser.cy.ts
Expand Up @@ -190,7 +190,7 @@ describe('Choose a Browser Page', () => {
cy.get('h1').should('contain', 'Choose a Browser')
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

These changes are for unrelated flake.


cy.withCtx((ctx, o) => {
o.sinon.spy(ctx.actions.project, 'launchProject')
o.sinon.stub(ctx.actions.project, 'launchProject')
})

cy.intercept('mutation-OpenBrowser_LaunchProject', cy.stub().as('launchProject'))
Expand Down Expand Up @@ -233,7 +233,7 @@ describe('Choose a Browser Page', () => {
cy.intercept('mutation-OpenBrowser_FocusActiveBrowserWindow').as('focusBrowser')

cy.withCtx((ctx, o) => {
o.sinon.spy(ctx.actions.browser, 'focusActiveBrowserWindow')
o.sinon.stub(ctx.actions.browser, 'focusActiveBrowserWindow')
})

cy.get('@focusButton').click()
Expand Down Expand Up @@ -276,6 +276,10 @@ describe('Choose a Browser Page', () => {

cy.findByRole('radio', { name: 'Chrome v1', checked: true }).as('chromeItem')

cy.withCtx((ctx, o) => {
o.sinon.stub(ctx.actions.project, 'launchProject')
})

cy.contains('button', 'Start E2E Testing in Chrome').should('be.visible').click()

cy.withCtx((ctx) => {
Expand Down