Skip to content

Commit

Permalink
feat: update git related messages for runs and debug (#26758)
Browse files Browse the repository at this point in the history
* feat(app): update DebugError copy

* feat: set isUsingGit project flag and consume in DebugContainer

* feat(app): update not using git icon for DebugError

* feat(app): displays alert on runs page when not using git

* feat(app): add component for when no runs for current branch

* feat(app): add warning for no runs for branch on runs container

* chore: add feat to CHANGELOG

* chore: remove logged status value

* chore: resolve import from merge conflict

* test(app): stub branch name for e2e runs spec

* chore: add line break in changelog entry

* chore: cleanup PR

* chore: fix i18n import for DebugBranchError

* chore: add utm and update Warning links to inline

* chore: capitalize Git in i18n

* ref: warning liink

* test: add i18n to tests

* test(app): change utm_source assertions

* chore: cleanup pr

* chore: remove unused prop

* test(app): remove no git warning when moving to runs page in e2e

* chore: change template logic

* chore: remove duplicate RUNS_TAB_MEDIUM const

* Changed Debug test assertion and reordered new components for Debug

---------

Co-authored-by: Stokes Player <stokes.player@gmail.com>
  • Loading branch information
jordanpowell88 and warrensplayer committed May 19, 2023
1 parent 6a56c39 commit a0efc77
Show file tree
Hide file tree
Showing 18 changed files with 245 additions and 48 deletions.
4 changes: 4 additions & 0 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

_Released 05/23/2023 (PENDING)_

**Features:**

- Add Git-related messages for the [Runs page](https://docs.cypress.io/guides/core-concepts/cypress-app#Runs) and [Debug page](https://docs.cypress.io/guides/cloud/runs#Debug) when users aren't using Git or there are no recorded runs for the current branch. Fixes [#26680](https://github.com/cypress-io/cypress/issues/26680).

**Bugfixes:**

- Reverted [#26452](https://github.com/cypress-io/cypress/pull/26630) which introduced a bug that prevents users from using End to End with Yarn 3. Fixed in [#26735](https://github.com/cypress-io/cypress/pull/26735). Fixes [#26676](https://github.com/cypress-io/cypress/issues/26676).
Expand Down
14 changes: 13 additions & 1 deletion packages/app/cypress/e2e/runs.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import defaultMessages from '@packages/frontend-shared/src/locales/en-US.json'
import type { SinonStub } from 'sinon'

function moveToRunsPage (): void {
cy.withCtx((ctx, o) => {
o.sinon.stub(ctx.lifecycleManager.git!, 'currentBranch').value('fakeBranch')
})

cy.findByTestId('sidebar-link-runs-page').click()
cy.findByTestId('app-header-bar').findByText('Runs').should('be.visible')
cy.findByTestId('runs-container').should('be.visible')
Expand Down Expand Up @@ -34,6 +38,9 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
cy.scaffoldProject('component-tests')
cy.openProject('component-tests')
cy.startAppServer('component')
cy.withCtx((ctx, o) => {
o.sinon.stub(ctx.lifecycleManager.git!, 'currentBranch').value('fakeBranch')
})
})

it('resolves the runs page', () => {
Expand Down Expand Up @@ -99,7 +106,7 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
moveToRunsPage()
cy.contains('a', 'OVERLIMIT').click()

cy.withCtx((ctx) => {
cy.withCtx((ctx, o) => {
expect((ctx.actions.electron.openExternal as SinonStub).lastCall.lastArg).to.contain('http://dummy.cypress.io/runs/4')
})
})
Expand Down Expand Up @@ -315,6 +322,7 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
cy.withCtx(async (ctx, o) => {
o.sinon.spy(ctx.cloud, 'executeRemoteGraphQL')

o.sinon.stub(ctx.lifecycleManager.git!, 'currentBranch').value('fakeBranch')
const config = await ctx.project.getConfig()

expect(config.projectId).to.not.equal('newProjectId')
Expand Down Expand Up @@ -757,6 +765,10 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
})

it('should remove the alert warning if the app reconnects to the internet', () => {
cy.withCtx((ctx, o) => {
o.sinon.stub(ctx.lifecycleManager.git!, 'currentBranch').value('fakeBranch')
})

cy.loginUser()
cy.visitApp()
cy.wait(1000)
Expand Down
2 changes: 1 addition & 1 deletion packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"dependencies": {},
"devDependencies": {
"@cypress-design/vue-button": "0.9.2",
"@cypress-design/vue-icon": "0.22.1",
"@cypress-design/vue-icon": "0.22.2",
"@cypress-design/vue-statusicon": "0.4.3",
"@graphql-typed-document-node/core": "^3.1.0",
"@headlessui/vue": "1.4.0",
Expand Down
36 changes: 32 additions & 4 deletions packages/app/src/debug/DebugContainer.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ describe('<DebugContainer />', () => {
const userProjectStatusStore = useUserProjectStatusStore()

userProjectStatusStore.setHasInitiallyLoaded()
userProjectStatusStore.setProjectFlag('isUsingGit', true)

validateEmptyState([defaultMessages.debugPage.emptyStates.connectToCypressCloud, defaultMessages.debugPage.emptyStates.connect.title, defaultMessages.debugPage.emptyStates.connect.description])
cy.findByRole('button', { name: 'Connect to Cypress Cloud' }).should('be.visible')
Expand All @@ -56,6 +57,7 @@ describe('<DebugContainer />', () => {

userProjectStatusStore.setUserFlag('isLoggedIn', true)
userProjectStatusStore.setProjectFlag('isProjectConnected', false)
userProjectStatusStore.setProjectFlag('isUsingGit', true)
userProjectStatusStore.setHasInitiallyLoaded()

validateEmptyState([defaultMessages.debugPage.emptyStates.connect.title, defaultMessages.debugPage.emptyStates.connect.description])
Expand All @@ -67,6 +69,7 @@ describe('<DebugContainer />', () => {

userProjectStatusStore.setUserFlag('isLoggedIn', true)
userProjectStatusStore.setProjectFlag('isProjectConnected', true)
userProjectStatusStore.setProjectFlag('isUsingGit', true)
userProjectStatusStore.setHasInitiallyLoaded()
cy.mountFragment(DebugSpecsFragmentDoc, {
variableTypes: DebugSpecVariableTypes,
Expand All @@ -78,20 +81,43 @@ describe('<DebugContainer />', () => {
cy.findByDisplayValue('npx cypress run --record --key 2aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa').should('be.visible')
})

it('errors', () => {
it('is not using git', () => {
const userProjectStatusStore = useUserProjectStatusStore()

userProjectStatusStore.setUserFlag('isLoggedIn', true)
userProjectStatusStore.setProjectFlag('isProjectConnected', true)
userProjectStatusStore.setProjectFlag('isUsingGit', false)
userProjectStatusStore.setHasInitiallyLoaded()
cy.mountFragment(DebugSpecsFragmentDoc, {
variableTypes: DebugSpecVariableTypes,
variables: defaultVariables,
render: (gqlVal) => <DebugContainer gql={gqlVal} showError={true} />,
render: (gqlVal) => <DebugContainer gql={gqlVal} />,
})

cy.findByTestId('debug-empty-title').should('contain.text', 'Git repository not detected')
})

it('has no runs for the current branch', () => {
const { setUserFlag, setProjectFlag, cloudStatusMatches, setHasInitiallyLoaded } = useUserProjectStatusStore()

setUserFlag('isLoggedIn', true)
setUserFlag('isMemberOfOrganization', true)
setProjectFlag('isProjectConnected', true)
setProjectFlag('hasNoRecordedRuns', true)
setProjectFlag('hasNonExampleSpec', true)
setProjectFlag('isConfigLoaded', true)
setProjectFlag('isUsingGit', true)
setHasInitiallyLoaded()

cy.mountFragment(DebugSpecsFragmentDoc, {
variableTypes: DebugSpecVariableTypes,
variables: defaultVariables,
render: (gqlVal) => <DebugContainer gql={gqlVal} />,
})

cy.findByTestId('debug-empty').should('not.exist')
cy.findByTestId('debug-alert').should('be.visible')
expect(cloudStatusMatches('needsRecordedRun')).equals(true)

cy.contains('No runs found for your branch')
})
})

Expand All @@ -101,6 +127,7 @@ describe('<DebugContainer />', () => {

userProjectStatusStore.setUserFlag('isLoggedIn', true)
userProjectStatusStore.setProjectFlag('isProjectConnected', true)
userProjectStatusStore.setProjectFlag('isUsingGit', true)
userProjectStatusStore.setHasInitiallyLoaded()
})

Expand Down Expand Up @@ -228,6 +255,7 @@ describe('<DebugContainer />', () => {

userProjectStatusStore.setUserFlag('isLoggedIn', true)
userProjectStatusStore.setProjectFlag('isProjectConnected', true)
userProjectStatusStore.setProjectFlag('isUsingGit', true)
userProjectStatusStore.setHasInitiallyLoaded()
})

Expand Down
15 changes: 10 additions & 5 deletions packages/app/src/debug/DebugContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
{{ t('launchpadErrors.noInternet.connectProject') }}
</NoInternetConnection>
<DebugLoading v-else-if="!userProjectStatusStore.hasInitiallyLoaded || userProjectStatusStore.project.isProjectConnected && isLoading" />
<DebugError
v-else-if="showError"
/>

<DebugNotLoggedIn
v-else-if="!userProjectStatusStore.user.isLoggedIn"
data-cy="debug-empty"
Expand All @@ -16,6 +14,12 @@
v-else-if="!userProjectStatusStore.project.isProjectConnected"
data-cy="debug-empty"
/>
<DebugError
v-else-if="!userProjectStatusStore.project.isUsingGit"
/>
<DebugBranchError
v-else-if="cloudStatusMatches('needsRecordedRun')"
/>
<DebugNoRuns
v-else-if="!run"
data-cy="debug-empty"
Expand Down Expand Up @@ -97,6 +101,7 @@ 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 DebugBranchError from './empty/DebugBranchError.vue'
import DebugSpecLimitBanner from './DebugSpecLimitBanner.vue'
import DebugRunNavigation from './DebugRunNavigation.vue'
import { specsList } from './utils/DebugMapping'
Expand Down Expand Up @@ -189,8 +194,6 @@ fragment DebugSpecs on Query {
const props = withDefaults(defineProps<{
gql?: DebugSpecsFragment
// This prop is just to stub the error state for now
showError?: boolean
isLoading?: boolean
commitsAhead?: number
online?: boolean
Expand All @@ -206,6 +209,8 @@ const props = withDefaults(defineProps<{
const userProjectStatusStore = useUserProjectStatusStore()
const { cloudStatusMatches } = userProjectStatusStore
const cloudProject = computed(() => {
return props.gql?.currentProject?.cloudProject?.__typename === 'CloudProject'
? props.gql.currentProject.cloudProject
Expand Down
12 changes: 12 additions & 0 deletions packages/app/src/debug/empty/DebugBranchError.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import DebugBranchError from './DebugBranchError.vue'
import { defaultMessages } from '@cy/i18n'

describe('<DebugBranchError />', () => {
it('can mount', () => {
cy.mount(<DebugBranchError />)
cy.get('[data-cy=debug-empty-title]').should('contain.text', defaultMessages.debugPage.emptyStates.noRunsFoundForBranch)
cy.get('[data-cy=debug-empty-description]').should('contain.text', defaultMessages.debugPage.emptyStates.noRunsForBranchMessage)
// The utm_source will be Binary%3A+App in production`open` mode but we assert using Binary%3A+Launchpad as this is the value in CI
cy.contains(defaultMessages.links.learnMoreButton).should('have.attr', 'href', 'https://on.cypress.io/git-info?utm_source=Binary%3A+Launchpad&utm_medium=Debug+Tab&utm_campaign=No+Runs+Found')
})
})
22 changes: 22 additions & 0 deletions packages/app/src/debug/empty/DebugBranchError.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<template>
<DebugEmptyView
:title="t('debugPage.emptyStates.noRunsFoundForBranch')"
:description="t('debugPage.emptyStates.noRunsForBranchMessage')"
:icon="IconTechnologyCommandLineError"
:utm="utm"
help-link-href="https://on.cypress.io/git-info"
/>
</template>

<script lang="ts" setup>
import DebugEmptyView from './DebugEmptyView.vue'
import { useI18n } from '@cy/i18n'
import { IconTechnologyCommandLineError } from '@cypress-design/vue-icon'
const { t } = useI18n()
const utm = {
utm_campaign: 'No Runs Found',
}
</script>
6 changes: 2 additions & 4 deletions packages/app/src/debug/empty/DebugEmptyStates.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,10 @@ describe('Debug page empty states', { defaultCommandTimeout: 250 }, () => {
})
})

context('error', () => {
context('not using git', () => {
it('renders', () => {
mountWithGql(<DebugError />)

cy.findByRole('link', { name: 'Learn more about debugging CI failures in Cypress' }).should('have.attr', 'href', 'https://on.cypress.io/debug-page?utm_source=Binary%3A+Launchpad&utm_medium=Debug+Tab&utm_campaign=Learn+More')

cy.findByText('Git repository not detected').should('be.visible')
cy.percySnapshot()
})
})
Expand Down
24 changes: 20 additions & 4 deletions packages/app/src/debug/empty/DebugEmptyView.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
<template>
<div class="flex flex-col mx-auto my-[45px] max-w-[680px] items-center">
<div class="flex flex-col items-center justify-evenly">
<div><i-cy-box-open_x48 class="icon-dark-gray-500 icon-light-indigo-100" /></div>
<component
:is="icon"
v-if="icon"
class="icon-dark-gray-500 icon-light-indigo-100"
/>
<div v-else>
<i-cy-box-open_x48 class="icon-dark-gray-500 icon-light-indigo-100" />
</div>
<div class="flex flex-col gap-1 my-6 max-w-[640px] items-center">
<div class="font-medium text-center text-gray-900 text-lg">
<div
data-cy="debug-empty-title"
class="font-medium text-center text-gray-900 text-lg"
>
{{ title }}
</div>
<div class="font-normal text-center leading-relaxed text-gray-600">
<div
data-cy="debug-empty-description"
class="font-normal text-center leading-relaxed text-gray-600"
>
{{ description }}
<span
v-if="helpLinkHref"
Expand Down Expand Up @@ -40,14 +53,17 @@ import { getUtmSource } from '@packages/frontend-shared/src/utils/getUtmSource'
import { useI18n } from '@packages/frontend-shared/src/locales/i18n'
import { DEBUG_TAB_MEDIUM } from '../utils/constants'
import type { FunctionalComponent, SVGAttributes } from 'vue'
const { t } = useI18n()
const props = defineProps<{
title: string
description?: string
icon?: FunctionalComponent<SVGAttributes, {}>
helpLinkHref?: string
helpLinkSrText?: string
utm?: { utm_campaign: string }
cohort?: string
}>()
Expand All @@ -56,7 +72,7 @@ const helpLink = getUrlWithParams({
params: {
utm_source: getUtmSource(),
utm_medium: DEBUG_TAB_MEDIUM,
utm_campaign: 'Learn More',
utm_campaign: props.utm?.utm_campaign || 'Learn More',
},
})
Expand Down
10 changes: 10 additions & 0 deletions packages/app/src/debug/empty/DebugError.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import DebugError from './DebugError.vue'
import { defaultMessages } from '@cy/i18n'

describe('<DebugError />', () => {
it('can mount', () => {
cy.mount(<DebugError />)
cy.contains(defaultMessages.debugPage.emptyStates.gitRepositoryNotDetected)
cy.contains(defaultMessages.debugPage.emptyStates.ensureGitSetupCorrectly)
})
})
21 changes: 4 additions & 17 deletions packages/app/src/debug/empty/DebugError.vue
Original file line number Diff line number Diff line change
@@ -1,28 +1,15 @@
<template>
<div class="m-[25px]">
<Alert
data-cy="debug-alert"
status="warning"
:title="t('debugPage.emptyStates.gitRepositoryNotDetected')"
:icon="WarningIcon"
dismissible
>
<p>{{ t('debugPage.emptyStates.ensureGitSetupCorrectly') }}</p>
</Alert>
</div>
<DebugEmptyView
:title="t('debugPage.emptyStates.debugDirectlyInCypress')"
:description="t('debugPage.emptyStates.reviewRerunAndDebug')"
:help-link-sr-text="t('debugPage.emptyStates.learnAboutDebuggingSrText')"
help-link-href="https://on.cypress.io/debug-page"
:title="t('debugPage.emptyStates.gitRepositoryNotDetected')"
:description="t('debugPage.emptyStates.ensureGitSetupCorrectly')"
:icon="IconTechnologyCommandLineError"
/>
</template>

<script lang="ts" setup>
import DebugEmptyView from './DebugEmptyView.vue'
import Alert from '@packages/frontend-shared/src/components/Alert.vue'
import WarningIcon from '~icons/cy/warning_x16.svg'
import { useI18n } from '@cy/i18n'
import { IconTechnologyCommandLineError } from '@cypress-design/vue-icon'
const { t } = useI18n()
Expand Down
Loading

4 comments on commit a0efc77

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on a0efc77 May 19, 2023

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 arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.13.0/linux-arm64/develop-a0efc77c4654ad0349d3f39582c22525832fdf80/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on a0efc77 May 19, 2023

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 arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.13.0/darwin-arm64/develop-a0efc77c4654ad0349d3f39582c22525832fdf80/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on a0efc77 May 19, 2023

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 build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.13.0/darwin-x64/develop-a0efc77c4654ad0349d3f39582c22525832fdf80/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on a0efc77 May 19, 2023

Choose a reason for hiding this comment

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

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

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.13.0/win32-x64/develop-a0efc77c4654ad0349d3f39582c22525832fdf80/cypress.tgz

Please sign in to comment.