chore: fix flaky windows tests (#21354)

This commit is contained in:
Ryan Manuel
2022-05-10 10:10:09 -05:00
committed by GitHub
parent 3fd9440520
commit 35ab63307c
26 changed files with 152 additions and 95 deletions
+4 -5
View File
@@ -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')
+1 -16
View File
@@ -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()
}
+1
View File
@@ -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)
+4 -1
View File
@@ -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()
}
}
}
+3
View File
@@ -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 -11
View File
@@ -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
}
+8 -7
View File
@@ -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
}
+1 -1
View File
@@ -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()
}