-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
feat: IATR empty states #25219
feat: IATR empty states #25219
Changes from 16 commits
ee26a51
9d976e7
b643e03
c7e9f15
a720e17
1adae96
0cabb21
2a48509
ff76b0a
2ede916
55b0b9c
d225bcc
2eb9636
8904a16
a31c1f5
9681604
1bede16
92f5837
e9ed2bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ import { CloudRunStubs } from '@packages/graphql/test/stubCloudTypes' | |
|
||
describe('<DebugContainer />', () => { | ||
context('empty states', () => { | ||
const validateEmptyState = (expectedMessage: string) => { | ||
const validateEmptyState = (expectedMessages: string[]) => { | ||
cy.mountFragment(DebugSpecsFragmentDoc, { | ||
render: (gqlVal) => { | ||
return ( | ||
|
@@ -18,19 +18,24 @@ describe('<DebugContainer />', () => { | |
}, | ||
}) | ||
|
||
cy.findByTestId('debug-empty').contains(expectedMessage) | ||
expectedMessages.forEach((message) => { | ||
cy.findByTestId('debug-empty').contains(message) | ||
}) | ||
astone123 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
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', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In ACI there were three separate "no project" states - are these all being rolled into this single "no project connected" condition?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I believe here we're just doing one view that is based on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @astone123 I am going to check with Peter and I will file a follow up issue if we need to add these additional states. I do not want to increase the scope of this issue beyond the original requirements. |
||
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('<DebugContainer />', () => { | |
loginConnectStore.setUserFlag('isLoggedIn', true) | ||
loginConnectStore.setProjectFlag('isProjectConnected', true) | ||
cy.mountFragment(DebugSpecsFragmentDoc, { | ||
render: (gqlVal) => { | ||
return ( | ||
<DebugContainer | ||
gql={gqlVal} | ||
/> | ||
) | ||
}, | ||
render: (gqlVal) => <DebugContainer gql={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) => <DebugContainer gql={gqlVal} showError={true} />, | ||
}) | ||
|
||
cy.findByTestId('debug-empty').contains(defaultMessages.debugPage.noRuns) | ||
cy.findByTestId('debug-empty').should('not.exist') | ||
cy.findByTestId('debug-alert').should('be.visible') | ||
}) | ||
}) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(<DebugNotLoggedIn />) | ||
|
||
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(<DebugNoProject />) | ||
|
||
cy.percySnapshot() | ||
}) | ||
}) | ||
|
||
context('no runs', () => { | ||
it('renders', () => { | ||
cy.mount(<DebugNoRuns />) | ||
|
||
cy.percySnapshot() | ||
}) | ||
}) | ||
|
||
context('loading', () => { | ||
it('renders', () => { | ||
cy.mount(<DebugLoading />) | ||
|
||
cy.percySnapshot() | ||
}) | ||
}) | ||
|
||
context('error', () => { | ||
it('renders', () => { | ||
cy.mount(<DebugError />) | ||
|
||
cy.percySnapshot() | ||
}) | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<template> | ||
<div class="flex flex-col my-45px 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> | ||
<div class="flex flex-col mx-[20%] mt-25px mb-20px items-center"> | ||
<div class="font-medium my-5px text-center text-gray-900 text-18px"> | ||
{{ title }} | ||
</div> | ||
<div class="font-normal my-5px text-center leading-relaxed text-16px text-gray-600"> | ||
{{ description }} | ||
</div> | ||
</div> | ||
<slot name="cta" /> | ||
</div> | ||
<div class="flex flex-col my-40px w-full items-center"> | ||
<DebugTestLoadingContainer | ||
width-class="w-[75%]" | ||
dot-class="icon-light-gray-200" | ||
:rows="loadingRows" | ||
> | ||
<template #header> | ||
<div class="bg-white border rounded-md flex border-gray-100 w-max p-5px text-14px text-gray-700"> | ||
<div><i-cy-status-failed_x12 /></div> | ||
<div class="bg-gray-700 h-1px mx-5px mt-7px w-5px" /> | ||
<div | ||
v-if="exampleTestName" | ||
class="bg-gray-100 h-13px mx-1 pb-1px w-1px" | ||
/> | ||
<div | ||
v-if="exampleTestName" | ||
class="mx-1 text-14px text-gray-700" | ||
> | ||
{{ exampleTestName }} | ||
</div> | ||
</div> | ||
</template> | ||
</DebugTestLoadingContainer> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script lang="ts" setup> | ||
import DebugTestLoadingContainer from './DebugTestLoadingContainer.vue' | ||
defineProps<{ | ||
title: string | ||
description?: string | ||
exampleTestName?: string | ||
}>() | ||
const loadingRows = [ | ||
['w-40px', 'w-[40%]'], | ||
['w-40px', 'w-[50%]'], | ||
['w-40px', 'w-[65%]'], | ||
] | ||
</script> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<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')" | ||
/> | ||
</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' | ||
const { t } = useI18n() | ||
</script> |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,91 @@ | ||||||||||||||
<template> | ||||||||||||||
<div | ||||||||||||||
data-cy="debug-loading" | ||||||||||||||
class="p-30px" | ||||||||||||||
> | ||||||||||||||
<div> | ||||||||||||||
<div class="flex items-center"> | ||||||||||||||
<div class="rounded-full bg-gray-50 h-16px w-344px" /> | ||||||||||||||
<DebugLoadingDivider /> | ||||||||||||||
<div class="rounded-full bg-gray-50 h-8px ml-8px w-120px" /> | ||||||||||||||
</div> | ||||||||||||||
|
||||||||||||||
<div class="flex mt-15px items-center"> | ||||||||||||||
<div class="rounded-full bg-gray-50 h-16px w-72px" /> | ||||||||||||||
<div class="rounded-full bg-gray-50 h-16px ml-8px w-160px" /> | ||||||||||||||
<div class="rounded-full bg-gray-50 h-16px ml-8px w-72px" /> | ||||||||||||||
<DebugLoadingDivider /> | ||||||||||||||
<div class="rounded-full bg-gray-50 h-8px ml-8px w-80px" /> | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Nit-pick: you can repeat this same content 4 times using this There are other places in this file you could do that with as well. |
||||||||||||||
<DebugLoadingDivider /> | ||||||||||||||
<div class="rounded-full bg-gray-50 h-8px ml-8px w-80px" /> | ||||||||||||||
<DebugLoadingDivider /> | ||||||||||||||
<div class="rounded-full bg-gray-50 h-8px ml-8px w-80px" /> | ||||||||||||||
<DebugLoadingDivider /> | ||||||||||||||
<div class="rounded-full bg-gray-50 h-8px ml-8px w-80px" /> | ||||||||||||||
</div> | ||||||||||||||
</div> | ||||||||||||||
<div class="mt-20px"> | ||||||||||||||
<DebugTestLoadingContainer | ||||||||||||||
width-class="w-full" | ||||||||||||||
dot-class="icon-light-gray-50" | ||||||||||||||
:rows="[['w-200px', 'w-200px'], ['w-200px', 'w-200px'], ['w-200px', 'w-200px']]" | ||||||||||||||
> | ||||||||||||||
<template #header> | ||||||||||||||
<div class="flex items center justify-between"> | ||||||||||||||
<div> | ||||||||||||||
<div class="flex items-center"> | ||||||||||||||
<i-cy-dot-solid_x4 class="icon-light-gray-100" /> | ||||||||||||||
<div class="rounded-full bg-gray-100 h-16px ml-8px w-200px" /> | ||||||||||||||
</div> | ||||||||||||||
<div class="flex mt-20px items-center"> | ||||||||||||||
<div class="rounded-full bg-gray-100 h-8px w-180px" /> | ||||||||||||||
<DebugLoadingDivider /> | ||||||||||||||
|
||||||||||||||
<div class="rounded-full bg-gray-100 h-8px ml-8px w-99px" /> | ||||||||||||||
<DebugLoadingDivider /> | ||||||||||||||
<div class="rounded-full bg-gray-100 h-8px ml-8px w-99px" /> | ||||||||||||||
</div> | ||||||||||||||
</div> | ||||||||||||||
<div class="mt-12px"> | ||||||||||||||
<div class="rounded-full bg-gray-100 h-20px w-120px" /> | ||||||||||||||
</div> | ||||||||||||||
</div> | ||||||||||||||
</template> | ||||||||||||||
</DebugTestLoadingContainer> | ||||||||||||||
</div> | ||||||||||||||
<div class="mt-20px"> | ||||||||||||||
<DebugTestLoadingContainer | ||||||||||||||
width-class="w-full" | ||||||||||||||
dot-class="icon-light-gray-50" | ||||||||||||||
:rows="[['w-200px', 'w-200px'], ['w-200px', 'w-200px']]" | ||||||||||||||
> | ||||||||||||||
<template #header> | ||||||||||||||
<div class="flex items center justify-between"> | ||||||||||||||
<div> | ||||||||||||||
<div class="flex items-center"> | ||||||||||||||
<i-cy-dot-solid_x4 class="icon-light-gray-100" /> | ||||||||||||||
<div class="rounded-full bg-gray-100 h-16px ml-8px w-200px" /> | ||||||||||||||
</div> | ||||||||||||||
<div class="flex mt-20px items-center"> | ||||||||||||||
<div class="rounded-full bg-gray-100 h-8px w-180px" /> | ||||||||||||||
<DebugLoadingDivider /> | ||||||||||||||
<div class="rounded-full bg-gray-100 h-8px ml-8px w-99px" /> | ||||||||||||||
<DebugLoadingDivider /> | ||||||||||||||
<div class="rounded-full bg-gray-100 h-8px ml-8px w-99px" /> | ||||||||||||||
</div> | ||||||||||||||
</div> | ||||||||||||||
<div class="mt-12px"> | ||||||||||||||
<div class="rounded-full bg-gray-100 h-20px w-120px" /> | ||||||||||||||
</div> | ||||||||||||||
</div> | ||||||||||||||
</template> | ||||||||||||||
</DebugTestLoadingContainer> | ||||||||||||||
</div> | ||||||||||||||
</div> | ||||||||||||||
</template> | ||||||||||||||
|
||||||||||||||
<script lang="ts" setup> | ||||||||||||||
import DebugLoadingDivider from './DebugLoadingDivider.vue' | ||||||||||||||
import DebugTestLoadingContainer from './DebugTestLoadingContainer.vue' | ||||||||||||||
|
||||||||||||||
</script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re: updating from "Log in" to "Connect" - there were conversations around this back when we put this in for ACI, concern then was that the top-level "Log In" button in the upper-right would have the same action so this button should use the same wording.
I'm assuming this was an update driven by design? If so then okay, just felt weird to see this get reversed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I talked to Emil about this - I think this should only affect the wording for the button on the runs page