diff --git a/packages/app/cypress/e2e/runs.cy.ts b/packages/app/cypress/e2e/runs.cy.ts index 448352e8a14d..0cdce03ba58b 100644 --- a/packages/app/cypress/e2e/runs.cy.ts +++ b/packages/app/cypress/e2e/runs.cy.ts @@ -279,7 +279,7 @@ describe('App: Runs', { viewportWidth: 1200 }, () => { name: 'Test User A', } }) - cy.contains('button', 'Log in to Cypress Cloud').click() + cy.contains('button', 'Connect to Cypress Cloud').click() cy.findByRole('dialog', { name: 'Log in to Cypress' }).as('logInModal').within(() => { cy.findByRole('button', { name: 'Log in' }).click() diff --git a/packages/app/cypress/e2e/settings.cy.ts b/packages/app/cypress/e2e/settings.cy.ts index d49f3c8408be..89b693907bcd 100644 --- a/packages/app/cypress/e2e/settings.cy.ts +++ b/packages/app/cypress/e2e/settings.cy.ts @@ -402,7 +402,7 @@ describe('App: Settings without cloud', () => { o.sinon.stub(ctx._apis.authApi, 'logIn') }) - cy.contains('button', 'Log in to Cypress Cloud').click() + cy.contains('button', 'Connect to Cypress Cloud').click() cy.findByRole('dialog', { name: 'Log in to Cypress' }).within(() => { cy.contains('button', 'Log in').click() }) diff --git a/packages/app/src/debug/DebugContainer.cy.tsx b/packages/app/src/debug/DebugContainer.cy.tsx index 7090046cb30a..1928cddb0a74 100644 --- a/packages/app/src/debug/DebugContainer.cy.tsx +++ b/packages/app/src/debug/DebugContainer.cy.tsx @@ -7,7 +7,7 @@ import { CloudRunStubs } from '@packages/graphql/test/stubCloudTypes' describe('', () => { context('empty states', () => { - const validateEmptyState = (expectedMessage: string) => { + const validateEmptyState = (expectedMessages: string[]) => { cy.mountFragment(DebugSpecsFragmentDoc, { render: (gqlVal) => { return ( @@ -18,19 +18,24 @@ describe('', () => { }, }) - cy.findByTestId('debug-empty').contains(expectedMessage) + expectedMessages.forEach((message) => { + cy.findByTestId('debug-empty').contains(message) + }) } it('shows not logged in', () => { - validateEmptyState(defaultMessages.debugPage.notLoggedIn) + validateEmptyState([defaultMessages.debugPage.emptyStates.connectToCypressCloud, defaultMessages.debugPage.emptyStates.debugDirectlyInCypress, defaultMessages.debugPage.emptyStates.notLoggedInTestMessage]) + cy.findByRole('button', { name: 'Connect to Cypress Cloud' }).should('be.visible') }) - it('is logged in', () => { + it('is logged in with no project', () => { const loginConnectStore = useLoginConnectStore() loginConnectStore.setUserFlag('isLoggedIn', true) + loginConnectStore.setProjectFlag('isProjectConnected', false) - validateEmptyState(defaultMessages.debugPage.notConnected) + validateEmptyState([defaultMessages.debugPage.emptyStates.debugDirectlyInCypress, defaultMessages.debugPage.emptyStates.reviewRerunAndDebug, defaultMessages.debugPage.emptyStates.noProjectTestMessage]) + cy.findByRole('button', { name: 'Connect a Cypress Cloud project' }).should('be.visible') }) it('has no runs', () => { @@ -39,16 +44,24 @@ describe('', () => { loginConnectStore.setUserFlag('isLoggedIn', true) loginConnectStore.setProjectFlag('isProjectConnected', true) cy.mountFragment(DebugSpecsFragmentDoc, { - render: (gqlVal) => { - return ( - - ) - }, + render: (gqlVal) => , + }) + + validateEmptyState([defaultMessages.debugPage.emptyStates.recordYourFirstRun, defaultMessages.debugPage.emptyStates.almostThere, defaultMessages.debugPage.emptyStates.noRunsTestMessage]) + cy.findByDisplayValue('npx cypress run --record --key 2aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa').should('be.visible') + }) + + it('errors', () => { + const loginConnectStore = useLoginConnectStore() + + loginConnectStore.setUserFlag('isLoggedIn', true) + loginConnectStore.setProjectFlag('isProjectConnected', true) + cy.mountFragment(DebugSpecsFragmentDoc, { + render: (gqlVal) => , }) - cy.findByTestId('debug-empty').contains(defaultMessages.debugPage.noRuns) + cy.findByTestId('debug-empty').should('not.exist') + cy.findByTestId('debug-alert').should('be.visible') }) }) diff --git a/packages/app/src/debug/DebugContainer.vue b/packages/app/src/debug/DebugContainer.vue index 162c13b3cbce..8e8e613a9c19 100644 --- a/packages/app/src/debug/DebugContainer.vue +++ b/packages/app/src/debug/DebugContainer.vue @@ -1,7 +1,10 @@ @@ -41,11 +32,12 @@ import type { DebugSpecsFragment, TestingTypeEnum } from '../generated/graphql' import { useLoginConnectStore } from '@packages/frontend-shared/src/store/login-connect-store' import DebugPageHeader from './DebugPageHeader.vue' import DebugSpecList from './DebugSpecList.vue' -import { useI18n } from 'vue-i18n' +import DebugNotLoggedIn from './empty/DebugNotLoggedIn.vue' +import DebugNoProject from './empty/DebugNoProject.vue' +import DebugNoRuns from './empty/DebugNoRuns.vue' +import DebugError from './empty/DebugError.vue' import { specsList } from './utils/DebugMapping' -const { t } = useI18n() - gql` fragment DebugLocalSpecs on Spec { id @@ -94,17 +86,19 @@ fragment DebugSpecs on Query { ` const props = defineProps<{ - gql: DebugSpecsFragment + gql?: DebugSpecsFragment + // This prop is just to stub the error state for now + showError?: boolean }>() const loginConnectStore = useLoginConnectStore() const run = computed(() => { - return props.gql.currentProject?.cloudProject?.__typename === 'CloudProject' ? props.gql.currentProject.cloudProject.runByNumber : null + return props.gql?.currentProject?.cloudProject?.__typename === 'CloudProject' ? props.gql.currentProject.cloudProject.runByNumber : null }) const debugSpecsArray = computed(() => { - if (run.value && props.gql.currentProject) { + if (run.value && props.gql?.currentProject) { const specs = run.value.specs || [] const tests = run.value.testsForReview || [] const groups = run.value.groups || [] diff --git a/packages/app/src/debug/empty/DebugEmptyStates.cy.tsx b/packages/app/src/debug/empty/DebugEmptyStates.cy.tsx new file mode 100644 index 000000000000..a5992f1a94a6 --- /dev/null +++ b/packages/app/src/debug/empty/DebugEmptyStates.cy.tsx @@ -0,0 +1,58 @@ +import DebugNotLoggedIn from './DebugNotLoggedIn.vue' +import DebugNoProject from './DebugNoProject.vue' +import DebugNoRuns from './DebugNoRuns.vue' +import DebugLoading from './DebugLoading.vue' +import DebugError from './DebugError.vue' +import { useLoginConnectStore } from '@packages/frontend-shared/src/store/login-connect-store' + +describe('Debug page empty states', () => { + context('not logged in', () => { + it('renders', () => { + const loginConnectStore = useLoginConnectStore() + + // We need to set isLoggedIn so that CloudConnectButton shows the correct state + loginConnectStore.setUserFlag('isLoggedIn', false) + + cy.mount() + + cy.percySnapshot() + }) + }) + + context('no project', () => { + it('renders', () => { + const loginConnectStore = useLoginConnectStore() + + // We need to set isLoggedIn so that CloudConnectButton shows the correct state + loginConnectStore.setUserFlag('isLoggedIn', true) + + cy.mount() + + cy.percySnapshot() + }) + }) + + context('no runs', () => { + it('renders', () => { + cy.mount() + + cy.percySnapshot() + }) + }) + + context('loading', () => { + it('renders', () => { + cy.mount() + + cy.percySnapshot() + }) + }) + + context('error', () => { + it('renders', () => { + cy.mount() + + cy.percySnapshot() + }) + }) +}) diff --git a/packages/app/src/debug/empty/DebugEmptyView.vue b/packages/app/src/debug/empty/DebugEmptyView.vue new file mode 100644 index 000000000000..46a55981ebc8 --- /dev/null +++ b/packages/app/src/debug/empty/DebugEmptyView.vue @@ -0,0 +1,57 @@ + + + diff --git a/packages/app/src/debug/empty/DebugError.vue b/packages/app/src/debug/empty/DebugError.vue new file mode 100644 index 000000000000..485d8fa804ad --- /dev/null +++ b/packages/app/src/debug/empty/DebugError.vue @@ -0,0 +1,27 @@ + + + diff --git a/packages/app/src/debug/empty/DebugLoading.vue b/packages/app/src/debug/empty/DebugLoading.vue new file mode 100644 index 000000000000..8c019ce14f2e --- /dev/null +++ b/packages/app/src/debug/empty/DebugLoading.vue @@ -0,0 +1,90 @@ + + + diff --git a/packages/app/src/debug/empty/DebugLoadingDivider.vue b/packages/app/src/debug/empty/DebugLoadingDivider.vue new file mode 100644 index 000000000000..5dc6a66d0705 --- /dev/null +++ b/packages/app/src/debug/empty/DebugLoadingDivider.vue @@ -0,0 +1,3 @@ + diff --git a/packages/app/src/debug/empty/DebugNoProject.vue b/packages/app/src/debug/empty/DebugNoProject.vue new file mode 100644 index 000000000000..3f8136a42a33 --- /dev/null +++ b/packages/app/src/debug/empty/DebugNoProject.vue @@ -0,0 +1,20 @@ + + + diff --git a/packages/app/src/debug/empty/DebugNoRuns.vue b/packages/app/src/debug/empty/DebugNoRuns.vue new file mode 100644 index 000000000000..75b3b3190e0a --- /dev/null +++ b/packages/app/src/debug/empty/DebugNoRuns.vue @@ -0,0 +1,20 @@ + + + diff --git a/packages/app/src/debug/empty/DebugNotLoggedIn.vue b/packages/app/src/debug/empty/DebugNotLoggedIn.vue new file mode 100644 index 000000000000..0de2abc75a81 --- /dev/null +++ b/packages/app/src/debug/empty/DebugNotLoggedIn.vue @@ -0,0 +1,20 @@ + + + diff --git a/packages/app/src/debug/empty/DebugTestLoadingContainer.vue b/packages/app/src/debug/empty/DebugTestLoadingContainer.vue new file mode 100644 index 000000000000..4bc676fe7b1c --- /dev/null +++ b/packages/app/src/debug/empty/DebugTestLoadingContainer.vue @@ -0,0 +1,45 @@ + + + diff --git a/packages/app/src/pages/Debug.vue b/packages/app/src/pages/Debug.vue index d91741096e5b..c29d53230250 100644 --- a/packages/app/src/pages/Debug.vue +++ b/packages/app/src/pages/Debug.vue @@ -1,10 +1,5 @@