mirror of
https://github.com/cypress-io/cypress.git
synced 2026-05-05 14:30:32 -05:00
chore: fix flaky windows tests (#21354)
This commit is contained in:
+4
-5
@@ -29,7 +29,7 @@ mainBuildFilters: &mainBuildFilters
|
||||
only:
|
||||
- develop
|
||||
- 10.0-release
|
||||
- new-cmd-log-styles
|
||||
- ryanm/chore/fix-tests-in-10.0
|
||||
|
||||
# uncomment & add to the branch conditions below to disable the main linux
|
||||
# flow if we don't want to test it for a certain branch
|
||||
@@ -47,7 +47,7 @@ macWorkflowFilters: &mac-workflow-filters
|
||||
or:
|
||||
- equal: [ develop, << pipeline.git.branch >> ]
|
||||
- equal: [ '10.0-release', << pipeline.git.branch >> ]
|
||||
- equal: [ new-cmd-log-styles, << pipeline.git.branch >> ]
|
||||
- equal: [ ryanm/chore/fix-tests-in-10.0, << pipeline.git.branch >> ]
|
||||
- matches:
|
||||
pattern: "-release$"
|
||||
value: << pipeline.git.branch >>
|
||||
@@ -57,8 +57,7 @@ windowsWorkflowFilters: &windows-workflow-filters
|
||||
or:
|
||||
- equal: [ develop, << pipeline.git.branch >> ]
|
||||
- equal: [ '10.0-release', << pipeline.git.branch >> ]
|
||||
- equal: [ chore/cutover-to-bundled-react-mount, << pipeline.git.branch >> ]
|
||||
- equal: [ 'tbiethman/windows-mocha-tests-metrics', << pipeline.git.branch >> ]
|
||||
- equal: [ ryanm/chore/fix-tests-in-10.0, << pipeline.git.branch >> ]
|
||||
- matches:
|
||||
pattern: "-release$"
|
||||
value: << pipeline.git.branch >>
|
||||
@@ -113,7 +112,7 @@ commands:
|
||||
- run:
|
||||
name: Check current branch to persist artifacts
|
||||
command: |
|
||||
if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "new-cmd-log-styles" && "$CIRCLE_BRANCH" != "10.0-release" ]]; then
|
||||
if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "ryanm/chore/fix-tests-in-10.0" && "$CIRCLE_BRANCH" != "10.0-release" ]]; then
|
||||
echo "Not uploading artifacts or posting install comment for this branch."
|
||||
circleci-agent step halt
|
||||
fi
|
||||
|
||||
@@ -15,10 +15,7 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
it('test component', () => {
|
||||
cy.visitApp()
|
||||
cy.contains('TestComponent.spec').click()
|
||||
cy.location().should((location) => {
|
||||
expect(location.hash).to.contain('TestComponent.spec')
|
||||
})
|
||||
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test component')
|
||||
|
||||
cy.findByTestId('aut-url').should('not.exist')
|
||||
@@ -61,6 +58,7 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
it('navigation between specs and other parts of the app works', () => {
|
||||
cy.visitApp()
|
||||
cy.contains('TestComponent.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test component')
|
||||
|
||||
// go to Settings page and back to spec runner
|
||||
@@ -68,6 +66,7 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
cy.contains(defaultMessages.settingsPage.device.title).should('be.visible')
|
||||
cy.contains('a', 'Specs').click()
|
||||
cy.contains('TestComponent.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test component')
|
||||
|
||||
// go to Runs page and back to spec runner
|
||||
@@ -75,6 +74,7 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
cy.contains(defaultMessages.runs.connect.title).should('be.visible')
|
||||
cy.contains('a', 'Specs').click()
|
||||
cy.contains('TestComponent.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test component')
|
||||
})
|
||||
|
||||
@@ -122,6 +122,7 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
it('browser picker in runner calls mutation with current spec path', () => {
|
||||
cy.visitApp()
|
||||
cy.contains('TestComponent.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test component')
|
||||
|
||||
cy.withCtx((ctx, o) => {
|
||||
@@ -154,7 +155,7 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
cy.withCtx(async (ctx, { sinon }) => {
|
||||
ctx.coreData.app.browserStatus = 'open'
|
||||
|
||||
sinon.spy(ctx.actions.project, 'initializeActiveProject')
|
||||
sinon.stub(ctx.actions.project, 'initializeActiveProject')
|
||||
|
||||
const config = await ctx.file.readFileInProject('cypress.config.js')
|
||||
const newCypressConfig = config.replace(`webpackConfig: require('./webpack.config.js')`, `webpackConfig: {}`)
|
||||
@@ -176,6 +177,7 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
|
||||
cy.visitApp()
|
||||
cy.contains('TestComponent.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test component')
|
||||
cy.get('.passed > .num').should('contain', 1)
|
||||
cy.get('.failed > .num').should('contain', '--')
|
||||
@@ -187,6 +189,7 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
cy.get('[data-cy="app-header-bar"]').findByText('Specs').should('be.visible')
|
||||
|
||||
cy.contains('TestComponent.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test component')
|
||||
|
||||
cy.window().then((win) => {
|
||||
|
||||
@@ -13,9 +13,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
it('test e2e', () => {
|
||||
cy.visitApp()
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.location().should((location) => {
|
||||
expect(location.hash).to.contain('dom-content.spec')
|
||||
})
|
||||
cy.waitForSpecToFinish()
|
||||
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
|
||||
cy.findByTestId('aut-url').should('be.visible')
|
||||
@@ -79,6 +77,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
it('navigation between specs and other parts of the app works', () => {
|
||||
cy.visitApp()
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
|
||||
|
||||
// go to Settings page and back to spec runner
|
||||
@@ -86,6 +85,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
cy.contains(defaultMessages.settingsPage.device.title).should('be.visible')
|
||||
cy.contains('a', 'Specs').click()
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
|
||||
|
||||
// go to Runs page and back to spec runner
|
||||
@@ -93,6 +93,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
cy.contains(defaultMessages.runs.connect.title).should('be.visible')
|
||||
cy.contains('a', 'Specs').click()
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
|
||||
})
|
||||
|
||||
@@ -171,17 +172,20 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
it('stops correctly running spec while switching specs', () => {
|
||||
cy.visitApp()
|
||||
cy.contains('withFailure.spec').click()
|
||||
cy.contains('[aria-controls=reporter-inline-specs-list]', 'Specs')
|
||||
cy.get('body').type('f')
|
||||
cy.contains('switch spec')
|
||||
cy.contains('Search Specs')
|
||||
cy.contains('withWait.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
|
||||
cy.get('.passed > .num', { timeout: 10000 }).should('contain', 4)
|
||||
cy.get('.passed > .num').should('contain', 4)
|
||||
cy.get('.failed > .num').should('not.contain', 1)
|
||||
})
|
||||
|
||||
it('executes a test, navigates back to the spec list, creates a new spec, and runs the new spec', () => {
|
||||
cy.visitApp()
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
|
||||
cy.contains('a', 'Specs').click()
|
||||
cy.withCtx(async (ctx, o) => {
|
||||
@@ -189,12 +193,14 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
}, { path: getPathForPlatform('cypress/e2e/new-file.spec.js') })
|
||||
|
||||
cy.contains('new-file.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'expected true to be true')
|
||||
})
|
||||
|
||||
it('moves away from runner and back, disconnects websocket and reconnects it correctly', () => {
|
||||
cy.visitApp()
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
|
||||
cy.get('.passed > .num').should('contain', 1)
|
||||
cy.get('.failed > .num').should('contain', '--')
|
||||
@@ -206,6 +212,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
|
||||
cy.get('[data-cy="app-header-bar"]').findByText('Specs').should('be.visible')
|
||||
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
|
||||
|
||||
cy.window().then((win) => {
|
||||
|
||||
@@ -9,9 +9,7 @@ describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => {
|
||||
simulateRunModeInUI()
|
||||
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.location().should((location) => {
|
||||
expect(location.hash).to.contain('dom-content.spec')
|
||||
})
|
||||
cy.waitForSpecToFinish()
|
||||
|
||||
cy.findByTestId('aut-url').should('be.visible')
|
||||
cy.findByTestId('playground-activator').should('not.exist')
|
||||
@@ -43,9 +41,7 @@ describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => {
|
||||
cy.visitApp()
|
||||
simulateRunModeInUI()
|
||||
cy.contains('TestComponent.spec').click()
|
||||
cy.location().should((location) => {
|
||||
expect(location.hash).to.contain('TestComponent.spec')
|
||||
})
|
||||
cy.waitForSpecToFinish()
|
||||
|
||||
cy.findByTestId('aut-url').should('not.exist')
|
||||
cy.findByTestId('playground-activator').should('not.exist')
|
||||
|
||||
@@ -23,8 +23,7 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100
|
||||
startAtSpecsPage(testingType)
|
||||
|
||||
cy.get('[data-cy="spec-item"]').first().click()
|
||||
// Let runner stabilize
|
||||
cy.get('#unified-reporter').should('be.visible')
|
||||
cy.waitForSpecToFinish()
|
||||
|
||||
cy.withCtx((ctx) => {
|
||||
ctx.coreData.servers.appSocketServer?.emit('automation:disconnected')
|
||||
@@ -68,7 +67,7 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100
|
||||
})
|
||||
|
||||
cy.get('[data-cy="spec-item"]').first().click()
|
||||
// Let runner stabilize
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('#unified-reporter').should('be.visible').then(() => {
|
||||
connectedCallback(false)
|
||||
})
|
||||
@@ -235,8 +234,8 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100
|
||||
config = config.replace(`e2e: {`, `e2e: {\n chromeWebSecurity: false,\n`)
|
||||
ctx.actions.file.writeFileInProject('cypress.config.js', config)
|
||||
|
||||
o.sinon.spy(ctx.actions.browser, 'closeBrowser')
|
||||
o.sinon.spy(ctx.actions.browser, 'relaunchBrowser')
|
||||
o.sinon.stub(ctx.actions.browser, 'closeBrowser')
|
||||
o.sinon.stub(ctx.actions.browser, 'relaunchBrowser')
|
||||
})
|
||||
|
||||
cy.get('[data-cy="loading-spinner"]').should('be.visible')
|
||||
@@ -270,8 +269,8 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100
|
||||
config = config.replace(`e2e: {`, `e2e: {\n viewportHeight: 600,\n`)
|
||||
ctx.actions.file.writeFileInProject('cypress.config.js', config)
|
||||
|
||||
o.sinon.spy(ctx.actions.browser, 'closeBrowser')
|
||||
o.sinon.spy(ctx.actions.browser, 'relaunchBrowser')
|
||||
o.sinon.stub(ctx.actions.browser, 'closeBrowser')
|
||||
o.sinon.stub(ctx.actions.browser, 'relaunchBrowser')
|
||||
})
|
||||
|
||||
cy.get('[data-cy="loading-spinner"]').should('be.visible')
|
||||
@@ -289,7 +288,7 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100
|
||||
|
||||
cy.withCtx((ctx, o) => {
|
||||
ctx.coreData.app.browserStatus = 'open'
|
||||
o.sinon.spy(ctx.actions.project, 'initializeActiveProject')
|
||||
o.sinon.stub(ctx.actions.project, 'initializeActiveProject')
|
||||
|
||||
let config = ctx.actions.file.readFileInProject('cypress.config.js')
|
||||
|
||||
|
||||
@@ -5,14 +5,11 @@ describe('Reporter Header', () => {
|
||||
cy.startAppServer()
|
||||
cy.visitApp()
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
})
|
||||
|
||||
context('Specs Shortcut', () => {
|
||||
it('selects the correct spec in the Specs List', () => {
|
||||
cy.location().should((location) => {
|
||||
expect(location.hash).to.contain('dom-content.spec')
|
||||
})
|
||||
|
||||
cy.get('body').type('f')
|
||||
|
||||
cy.get('[data-selected-spec="true"]').should('contain', 'dom-content').should('have.length', '1')
|
||||
@@ -20,10 +17,6 @@ describe('Reporter Header', () => {
|
||||
})
|
||||
|
||||
it('filters the list of specs when searching for specs', () => {
|
||||
cy.location().should((location) => {
|
||||
expect(location.hash).to.contain('dom-content.spec')
|
||||
})
|
||||
|
||||
cy.get('body').type('f')
|
||||
|
||||
cy.get('input').type('dom', { force: true })
|
||||
@@ -43,10 +36,6 @@ describe('Reporter Header', () => {
|
||||
|
||||
context('Testing Preferences', () => {
|
||||
it('clicking the down arrow will open a panel showing Testing Preferences', () => {
|
||||
cy.location().should((location) => {
|
||||
expect(location.hash).to.contain('dom-content.spec')
|
||||
})
|
||||
|
||||
cy.get('.testing-preferences-toggle').trigger('mouseover')
|
||||
cy.get('.cy-tooltip').should('have.text', 'Open Testing Preferences')
|
||||
|
||||
@@ -60,10 +49,6 @@ describe('Reporter Header', () => {
|
||||
})
|
||||
|
||||
it('will show a toggle beside the auto-scrolling option', () => {
|
||||
cy.location().should((location) => {
|
||||
expect(location.hash).to.contain('dom-content.spec')
|
||||
})
|
||||
|
||||
const switchSelector = '[data-cy=auto-scroll-switch]'
|
||||
|
||||
cy.get('.testing-preferences-toggle').click()
|
||||
|
||||
@@ -72,9 +72,9 @@ export function runSpec ({ fileName }: { fileName: string }) {
|
||||
|
||||
cy.visitApp(`specs/runner?file=cypress/e2e/runner/${fileName}`)
|
||||
|
||||
// Wait for runner to load before continuing, otherwise we may execute
|
||||
// prior to the EventManager having been initialized.
|
||||
cy.get('#unified-reporter').should('exist')
|
||||
// First ensure the test is loaded
|
||||
cy.get('.passed > .num').should('contain', '--')
|
||||
cy.get('.failed > .num').should('contain', '--')
|
||||
|
||||
return cy.window()
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ describe('App: Settings', () => {
|
||||
cy.get('.spec-list-container').scrollTo('bottom')
|
||||
// Visit the test to trigger the ws.off() for the TR websockets
|
||||
cy.contains('test1.js').click()
|
||||
cy.waitForSpecToFinish()
|
||||
// Wait for the test to pass, so the test is completed
|
||||
cy.get('.passed > .num').should('contain', 1)
|
||||
cy.get(`[href='#/settings']`).click()
|
||||
|
||||
@@ -23,6 +23,7 @@ describe('App: Spec List (Component)', () => {
|
||||
|
||||
it('highlights the currently running spec', () => {
|
||||
cy.contains('fails').click()
|
||||
cy.contains('[aria-controls=reporter-inline-specs-list]', 'Specs')
|
||||
cy.get('body').type('f')
|
||||
cy.get('[data-selected-spec="true"]').should('contain', 'fails')
|
||||
cy.get('[data-selected-spec="false"]').should('contain', 'foo')
|
||||
|
||||
@@ -70,6 +70,7 @@ describe('App: Spec List (E2E)', () => {
|
||||
cy.get('[data-cy="spec-item-link"]').should('have.attr', 'href')
|
||||
cy.get('[data-cy="spec-item-link"]').contains('dom-content.spec.js').click()
|
||||
|
||||
cy.contains('[aria-controls=reporter-inline-specs-list]', 'Specs')
|
||||
cy.findByText('Your tests are loading...').should('not.be.visible')
|
||||
cy.get('body').type('f')
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ describe('specChange subscription', () => {
|
||||
it('responds to configChange event and re-runs spec', () => {
|
||||
// run spec
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
|
||||
// wait until it has passed
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
|
||||
@@ -46,6 +47,7 @@ describe('specChange subscription', () => {
|
||||
// update the config - the spec should re-execute with the new viewportHeight
|
||||
updateViewportHeightInCypressConfig(777)
|
||||
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
|
||||
cy.get('button').contains('1000x777')
|
||||
})
|
||||
|
||||
@@ -157,6 +157,7 @@ e2e: {
|
||||
describe('inline specs list', () => {
|
||||
it('responds to specChange event for an added file', () => {
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
|
||||
|
||||
cy.get('body').type('f')
|
||||
@@ -182,6 +183,7 @@ e2e: {
|
||||
|
||||
it('responds to specChange event for a removed file', () => {
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
|
||||
|
||||
cy.get('body').type('f')
|
||||
@@ -205,6 +207,7 @@ e2e: {
|
||||
|
||||
it('handles removing the last file', () => {
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
|
||||
|
||||
cy.withCtx(async (ctx, o) => {
|
||||
@@ -241,6 +244,7 @@ e2e: {
|
||||
|
||||
it('responds to a cypress.config.js file change', () => {
|
||||
cy.contains('dom-content.spec').click()
|
||||
cy.waitForSpecToFinish()
|
||||
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
|
||||
|
||||
cy.get('body').type('f')
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
import '@packages/frontend-shared/cypress/e2e/support/e2eSupport'
|
||||
import 'cypress-real-events/support'
|
||||
import './execute-spec'
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
declare global {
|
||||
namespace Cypress {
|
||||
interface Chainable {
|
||||
/**
|
||||
* Adapter to wait for a spec to finish in a standard way. It
|
||||
*
|
||||
* 1. Waits for the stats to reset which signifies that the test page has loaded
|
||||
* 2. Waits for 'Your tests are loading...' to not be present so that we know the tests themselves have loaded
|
||||
* 3. Waits (with a timeout of 30s) for the Rerun all tests button to be present. This ensures all tests have completed
|
||||
*
|
||||
*/
|
||||
waitForSpecToFinish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Here we export the function with no intention to import it
|
||||
// This only tells the typescript type checker that this definitely is a module
|
||||
// This way, we are allowed to use the global namespace declaration
|
||||
export const waitForSpecToFinish = () => {
|
||||
// First ensure the test is loaded
|
||||
cy.get('.passed > .num').should('contain', '--')
|
||||
cy.get('.failed > .num').should('contain', '--')
|
||||
|
||||
// Then ensure the tests are running
|
||||
cy.contains('Your tests are loading...').should('not.exist')
|
||||
|
||||
// Then ensure the tests have finished
|
||||
cy.get('[aria-label="Rerun all tests"]', { timeout: 30000 })
|
||||
}
|
||||
|
||||
Cypress.Commands.add('waitForSpecToFinish', waitForSpecToFinish)
|
||||
@@ -21,7 +21,10 @@ export function useEventManager () {
|
||||
function initializeRunnerLifecycleEvents () {
|
||||
// these events do not use GraphQL
|
||||
eventManager.on('restart', () => {
|
||||
runSpec()
|
||||
// If we get the event to restart but have already navigated away from the runner, don't execute the spec
|
||||
if (specStore.activeSpec) {
|
||||
runSpec()
|
||||
}
|
||||
})
|
||||
|
||||
eventManager.on('script:error', (err) => {
|
||||
|
||||
@@ -63,7 +63,7 @@ export class ProjectConfigManager {
|
||||
return this._state === 'loadingNodeEvents'
|
||||
}
|
||||
|
||||
get isReady () {
|
||||
get isFullConfigReady () {
|
||||
return this._state === 'ready'
|
||||
}
|
||||
|
||||
@@ -161,7 +161,8 @@ export class ProjectConfigManager {
|
||||
assert(this._testingType, 'Cannot setup node events without a testing type')
|
||||
this._registeredEventsTarget = this._testingType
|
||||
const config = await this.getFullInitialConfig()
|
||||
const setupNodeEventsReply = await this._eventsIpc?.callSetupNodeEventsWithConfig(this._testingType, config, this.options.handlers)
|
||||
|
||||
const setupNodeEventsReply = await this._eventsIpc.callSetupNodeEventsWithConfig(this._testingType, config, this.options.handlers)
|
||||
|
||||
await this.handleSetupTestingTypeReply(this._eventsIpc, loadConfigReply, setupNodeEventsReply)
|
||||
this._state = 'ready'
|
||||
|
||||
@@ -154,8 +154,8 @@ export class ProjectLifecycleManager {
|
||||
return this._configManager?.isLoadingNodeEvents
|
||||
}
|
||||
|
||||
get isReady () {
|
||||
return this._configManager?.isReady
|
||||
get isFullConfigReady () {
|
||||
return this._configManager?.isFullConfigReady
|
||||
}
|
||||
|
||||
get loadedConfigFile (): Partial<Cypress.ConfigOptions> | null {
|
||||
@@ -706,6 +706,11 @@ export class ProjectLifecycleManager {
|
||||
async initializeOpenMode (testingType: TestingType | null) {
|
||||
if (this._projectRoot && testingType && await this.waitForInitializeSuccess()) {
|
||||
this.setAndLoadCurrentTestingType(testingType)
|
||||
|
||||
if (testingType === 'e2e' && !this.ctx.migration.needsCypressJsonMigration() && !this.isTestingTypeConfigured(testingType)) {
|
||||
// E2E doesn't have a wizard, so if we have a testing type on load we just create/update their cypress.config.js.
|
||||
await this.ctx.actions.wizard.scaffoldTestingType()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -422,6 +422,9 @@ type CurrentProject implements Node & ProjectLike {
|
||||
"""Whether the user configured this project to use e2e Testing"""
|
||||
isE2EConfigured: Boolean
|
||||
|
||||
"""Whether or not the full config is ready"""
|
||||
isFullConfigReady: Boolean
|
||||
|
||||
"""Whether we are currently loading the configFile"""
|
||||
isLoadingConfigFile: Boolean
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@ export const CurrentProject = objectType({
|
||||
description: 'Whether we are currently loading the setupNodeEvents',
|
||||
})
|
||||
|
||||
t.boolean('isFullConfigReady', {
|
||||
description: 'Whether or not the full config is ready',
|
||||
})
|
||||
|
||||
t.field('currentTestingType', {
|
||||
description: 'The mode the interactive runner was launched in',
|
||||
type: TestingTypeEnum,
|
||||
|
||||
@@ -2,7 +2,7 @@ import defaultMessages from '@packages/frontend-shared/src/locales/en-US.json'
|
||||
import path from 'path'
|
||||
import type { SinonSpy } from 'sinon'
|
||||
|
||||
const sep = Cypress.platform === 'win32' ? '\\\\' : '/'
|
||||
const sep = Cypress.platform === 'win32' ? '\\' : '/'
|
||||
|
||||
describe('Launchpad: Global Mode', () => {
|
||||
describe('when no projects have been added', () => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ProjectFixtureDir } from '@tooling/system-tests'
|
||||
import { decodeBase64Unicode } from '@packages/frontend-shared/src/utils/base64'
|
||||
import { getPathForPlatform } from './support/getPathForPlatform'
|
||||
|
||||
// @ts-ignore
|
||||
const platform = window.Cypress.platform
|
||||
@@ -10,16 +10,6 @@ const renameSupportStep = `[data-cy="migration-step renameSupport"]`
|
||||
const configFileStep = `[data-cy="migration-step configFile"]`
|
||||
const setupComponentStep = `[data-cy="migration-step setupComponent"]`
|
||||
|
||||
function getPathForPlatform (posixPath: string) {
|
||||
// @ts-ignore
|
||||
const cy = window.Cypress
|
||||
const platform = cy?.platform || JSON.parse(decodeBase64Unicode(window.__CYPRESS_CONFIG__.base64Config)).platform
|
||||
|
||||
if (platform === 'win32') return posixPath.replaceAll('/', '\\')
|
||||
|
||||
return posixPath
|
||||
}
|
||||
|
||||
declare global {
|
||||
namespace Cypress {
|
||||
interface Chainable {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { getPathForPlatform } from './support/getPathForPlatform'
|
||||
|
||||
function verifyScaffoldedFiles (testingType: string) {
|
||||
const expectedFileOrder = (testingType === 'e2e') ? [
|
||||
'cypress.config.',
|
||||
@@ -17,7 +19,7 @@ function verifyScaffoldedFiles (testingType: string) {
|
||||
.each(($el, i) => {
|
||||
const relativePath = $el.text()
|
||||
|
||||
expect(relativePath, `file index ${i}`).to.include(expectedFileOrder[i]) // assert file order
|
||||
expect(relativePath, `file index ${i}`).to.include(getPathForPlatform(expectedFileOrder[i])) // assert file order
|
||||
|
||||
cy.withCtx(async (ctx, o) => { // assert file exists
|
||||
const stats = await ctx.file.checkIfFileExists(o.relativePath)
|
||||
@@ -72,7 +74,18 @@ describe('Launchpad: Setup Project', () => {
|
||||
cy.scaffoldProject('pristine')
|
||||
cy.openProject('pristine', ['--e2e'])
|
||||
cy.visitLaunchpad()
|
||||
cy.get('h1').should('contain', 'Choose a Browser')
|
||||
|
||||
cy.contains('h1', 'Configuration Files')
|
||||
cy.findByText('We added the following files to your project:')
|
||||
|
||||
cy.get('[data-cy=valid]').within(() => {
|
||||
cy.contains('cypress.config.js')
|
||||
cy.containsPath('cypress/support/e2e.js')
|
||||
cy.containsPath('cypress/support/commands.js')
|
||||
cy.containsPath('cypress/fixtures/example.json')
|
||||
})
|
||||
|
||||
verifyScaffoldedFiles('e2e')
|
||||
})
|
||||
|
||||
it('opens correctly in unconfigured project with --component', () => {
|
||||
@@ -228,6 +241,12 @@ describe('Launchpad: Setup Project', () => {
|
||||
})
|
||||
|
||||
verifyScaffoldedFiles('e2e')
|
||||
|
||||
cy.findByRole('button', { name: 'Continue' })
|
||||
.should('not.have.disabled')
|
||||
.click()
|
||||
|
||||
verifyChooseABrowserPage()
|
||||
})
|
||||
|
||||
it('moves to "Choose a Browser" page after clicking "Continue" button in first step in configuration page', () => {
|
||||
@@ -249,33 +268,22 @@ describe('Launchpad: Setup Project', () => {
|
||||
})
|
||||
|
||||
verifyScaffoldedFiles('e2e')
|
||||
|
||||
cy.findByRole('button', { name: 'Continue' })
|
||||
.should('not.have.disabled')
|
||||
.click()
|
||||
|
||||
verifyChooseABrowserPage()
|
||||
})
|
||||
|
||||
it('shows the configuration setup page when opened via cli with --component flag', () => {
|
||||
scaffoldAndOpenProject('pristine-with-ct-testing', ['--component'])
|
||||
cy.visitLaunchpad()
|
||||
cy.contains('h1', 'Choose a Browser')
|
||||
verifyChooseABrowserPage()
|
||||
})
|
||||
})
|
||||
|
||||
describe('project not been configured for cypress', () => {
|
||||
it('can go back before selecting e2e scaffold lang', () => {
|
||||
scaffoldAndOpenProject('pristine')
|
||||
cy.visitLaunchpad()
|
||||
|
||||
verifyWelcomePage({ e2eIsConfigured: false, ctIsConfigured: false })
|
||||
|
||||
cy.tabUntil((el) => {
|
||||
return el.text().includes('E2E Testing')
|
||||
})
|
||||
|
||||
cy.contains('button', 'E2E Testing')
|
||||
.should('have.focus')
|
||||
.realPress('Enter')
|
||||
|
||||
cy.contains('h1', 'Configuration Files')
|
||||
})
|
||||
|
||||
it('can setup e2e testing for a project selecting JS', () => {
|
||||
scaffoldAndOpenProject('pristine')
|
||||
cy.visitLaunchpad()
|
||||
@@ -331,6 +339,12 @@ describe('Launchpad: Setup Project', () => {
|
||||
})
|
||||
|
||||
verifyScaffoldedFiles('e2e')
|
||||
|
||||
cy.findByRole('button', { name: 'Continue' })
|
||||
.should('not.have.disabled')
|
||||
.click()
|
||||
|
||||
verifyChooseABrowserPage()
|
||||
})
|
||||
|
||||
it('can skip setup CT testing for an E2E project', () => {
|
||||
@@ -383,7 +397,7 @@ describe('Launchpad: Setup Project', () => {
|
||||
it('shows the configuration setup page when opened via cli with --e2e flag', () => {
|
||||
scaffoldAndOpenProject('pristine-with-e2e-testing', ['--e2e'])
|
||||
cy.visitLaunchpad()
|
||||
cy.contains('h1', 'Choose a Browser')
|
||||
verifyChooseABrowserPage()
|
||||
})
|
||||
|
||||
it('can reconfigure config after CT has been set up', () => {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export function getPathForPlatform (posixPath: string) {
|
||||
if (Cypress.platform === 'win32') return posixPath.replaceAll('/', '\\')
|
||||
|
||||
return posixPath
|
||||
}
|
||||
@@ -22,13 +22,6 @@
|
||||
:gql="query.data.value"
|
||||
/>
|
||||
<Spinner v-else-if="currentProject?.isLoadingConfigFile" />
|
||||
<template v-else-if="currentProject?.isLoadingNodeEvents">
|
||||
<LaunchpadHeader
|
||||
:title="t('components.loading.config.title')"
|
||||
:description="t('components.loading.config.description')"
|
||||
/>
|
||||
<Spinner />
|
||||
</template>
|
||||
<template v-else-if="!currentProject?.currentTestingType">
|
||||
<WarningList :gql="query.data.value" />
|
||||
<LaunchpadHeader
|
||||
@@ -61,6 +54,13 @@
|
||||
v-else-if="currentProject.currentTestingType === 'component' && !currentProject.isCTConfigured"
|
||||
:gql="query.data.value"
|
||||
/>
|
||||
<template v-else-if="!currentProject?.isFullConfigReady">
|
||||
<LaunchpadHeader
|
||||
:title="t('components.loading.config.title')"
|
||||
:description="t('components.loading.config.description')"
|
||||
/>
|
||||
<Spinner />
|
||||
</template>
|
||||
<OpenBrowser v-else />
|
||||
</template>
|
||||
</div>
|
||||
@@ -104,6 +104,7 @@ fragment MainLaunchpadQueryData on Query {
|
||||
isE2EConfigured
|
||||
isLoadingConfigFile
|
||||
isLoadingNodeEvents
|
||||
isFullConfigReady
|
||||
needsLegacyConfigMigration
|
||||
currentTestingType
|
||||
}
|
||||
|
||||
@@ -138,6 +138,6 @@ export class SocketE2E extends SocketBase {
|
||||
close () {
|
||||
preprocessor.emitter.removeListener('file:updated', this.onTestFileChange)
|
||||
|
||||
super.close()
|
||||
return super.close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,7 +450,7 @@ describe('Routes', () => {
|
||||
let i = 0
|
||||
|
||||
const interval = setInterval(() => {
|
||||
if (ctx.lifecycleManager.isReady) {
|
||||
if (ctx.lifecycleManager.isFullConfigReady) {
|
||||
clearInterval(interval)
|
||||
resolve()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user