mirror of
https://github.com/cypress-io/cypress.git
synced 2026-04-23 23:49:43 -05:00
feat: add runs duration, relative created at and style tweaks (#21410)
Co-authored-by: Tim Griesser <tgriesser10@gmail.com> Co-authored-by: Mark Noonan <mark@cypress.io>
This commit is contained in:
@@ -267,11 +267,11 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
|
||||
})
|
||||
|
||||
it('if project Id is specified in config file that does not exist, shows call to action', () => {
|
||||
cy.findByText(defaultMessages.runs.errors.notfound.button).should('be.visible')
|
||||
cy.findByText(defaultMessages.runs.errors.notFound.button).should('be.visible')
|
||||
})
|
||||
|
||||
it('opens Connect Project modal after clicking Reconnect Project button', () => {
|
||||
cy.findByText(defaultMessages.runs.errors.notfound.button).click()
|
||||
cy.findByText(defaultMessages.runs.errors.notFound.button).click()
|
||||
cy.get('[aria-modal="true"]').should('exist')
|
||||
cy.get('[data-cy="selectProject"] button').click()
|
||||
cy.findByText('Mock Project').click()
|
||||
@@ -497,18 +497,18 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
|
||||
|
||||
cy.get('[href="http://dummy.cypress.io/runs/0"]').first().as('firstRun')
|
||||
|
||||
cy.get('@firstRun').get('[data-cy="run-card-author"]').contains('John Appleseed')
|
||||
cy.get('@firstRun').get('[data-cy="run-card-avatar')
|
||||
cy.get('@firstRun').get('[data-cy="run-card-branch"]').contains('main')
|
||||
cy.get('@firstRun').within(() => {
|
||||
cy.get('[data-cy="run-card-author"]').contains('John Appleseed')
|
||||
cy.get('[data-cy="run-card-avatar"]')
|
||||
cy.get('[data-cy="run-card-branch"]').contains('main')
|
||||
cy.get('[data-cy="run-card-created-at"]').contains('an hour ago')
|
||||
cy.get('[data-cy="run-card-duration"]').contains('01:00')
|
||||
|
||||
// the exact timestamp string will depend on the user's browser's locale settings
|
||||
const localeTimeString = (new Date('2022-02-02T08:17:00.005Z')).toLocaleTimeString()
|
||||
|
||||
cy.get('@firstRun').contains(localeTimeString)
|
||||
cy.get('@firstRun').contains('span', 'skipped')
|
||||
cy.get('@firstRun').get('span').contains('pending')
|
||||
cy.get('@firstRun').get('span').contains('passed')
|
||||
cy.get('@firstRun').get('span').contains('failed')
|
||||
cy.contains('span', 'skipped')
|
||||
cy.get('span').contains('pending')
|
||||
cy.get('span').contains('passed')
|
||||
cy.get('span').contains('failed')
|
||||
})
|
||||
})
|
||||
|
||||
it('opens the run page if a run is clicked', () => {
|
||||
@@ -522,6 +522,38 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
|
||||
expect((ctx.actions.electron.openExternal as SinonStub).lastCall.lastArg).to.eq('http://dummy.cypress.io/runs/0')
|
||||
})
|
||||
})
|
||||
|
||||
it('shows connection failed error if no cloudProject', () => {
|
||||
let cloudData: any
|
||||
|
||||
cy.loginUser()
|
||||
cy.visitApp()
|
||||
|
||||
cy.remoteGraphQLIntercept((obj) => {
|
||||
if (obj.operationName === 'Runs_currentProject_cloudProject_cloudProjectBySlug') {
|
||||
cloudData = obj.result
|
||||
obj.result = {}
|
||||
|
||||
return obj.result
|
||||
}
|
||||
|
||||
return obj.result
|
||||
})
|
||||
|
||||
cy.get('[href="#/runs"]').click()
|
||||
cy.contains('h2', 'Cannot connect to the Cypress Dashboard')
|
||||
cy.percySnapshot()
|
||||
|
||||
cy.remoteGraphQLIntercept((obj) => {
|
||||
if (obj.operationName === 'Runs_currentProject_cloudProject_cloudProjectBySlug') {
|
||||
return cloudData
|
||||
}
|
||||
|
||||
return obj.result
|
||||
})
|
||||
|
||||
cy.contains('button', 'Try again').click().should('not.exist')
|
||||
})
|
||||
})
|
||||
|
||||
describe('no internet connection', () => {
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
"concurrently": "^6.2.0",
|
||||
"cross-env": "6.0.3",
|
||||
"cypress-real-events": "1.6.0",
|
||||
"dayjs": "^1.9.3",
|
||||
"disparity": "^3.0.0",
|
||||
"faker": "5.5.3",
|
||||
"fuzzysort": "^1.1.4",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
v-else
|
||||
:gql="query.data.value"
|
||||
:online="isOnlineRef"
|
||||
@re-execute-runs-query="reExecuteRunsQuery"
|
||||
/>
|
||||
</TransitionQuickFade>
|
||||
</div>
|
||||
@@ -42,4 +43,8 @@ watchEffect(() => {
|
||||
query.executeQuery()
|
||||
}
|
||||
})
|
||||
|
||||
function reExecuteRunsQuery () {
|
||||
query.executeQuery()
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -2,7 +2,49 @@ import { CloudRunStubs } from '@packages/graphql/test/stubCloudTypes'
|
||||
import { RunCardFragmentDoc } from '../generated/graphql-test'
|
||||
import RunCard from './RunCard.vue'
|
||||
|
||||
const SECOND = 1000
|
||||
const MINUTE = 60 * SECOND
|
||||
const HOUR = 60 * MINUTE
|
||||
|
||||
const generateTags = (num): any => new Array(num).fill(null).map((_, i) => ({ id: `${i}`, name: `tag${i}`, __typename: 'CloudRunTag' }))
|
||||
|
||||
describe('<RunCard />', { viewportHeight: 400 }, () => {
|
||||
it('renders with all run information', () => {
|
||||
cy.mountFragment(RunCardFragmentDoc, {
|
||||
onResult (result) {
|
||||
result.tags = generateTags(3)
|
||||
result.totalFlakyTests = 1
|
||||
},
|
||||
render: (gqlVal) => {
|
||||
return (
|
||||
<div class="h-screen bg-gray-100 p-3">
|
||||
<RunCard gql={gqlVal} />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
cy.percySnapshot()
|
||||
})
|
||||
|
||||
it('renders with all run information on small viewport', { viewportWidth: 600 }, () => {
|
||||
cy.mountFragment(RunCardFragmentDoc, {
|
||||
onResult (result) {
|
||||
result.tags = [1, 2, 3].map((i) => ({ id: `${i}`, name: `tag${i}`, __typename: 'CloudRunTag' }))
|
||||
result.totalFlakyTests = 1
|
||||
},
|
||||
render: (gqlVal) => {
|
||||
return (
|
||||
<div class="h-screen bg-gray-100 p-3">
|
||||
<RunCard gql={gqlVal} />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
cy.percySnapshot()
|
||||
})
|
||||
|
||||
context('when there is full commit info', () => {
|
||||
it('displays last commit info', () => {
|
||||
cy.mountFragment(RunCardFragmentDoc, {
|
||||
@@ -57,7 +99,89 @@ describe('<RunCard />', { viewportHeight: 400 }, () => {
|
||||
})
|
||||
|
||||
// this is the human readable commit time from the stub
|
||||
cy.contains('3:17:00 AM').should('be.visible')
|
||||
cy.contains('an hour ago').should('be.visible')
|
||||
|
||||
cy.percySnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
context('run timing', () => {
|
||||
it('displays HH:mm:ss format for run duration', () => {
|
||||
cy.mountFragment(RunCardFragmentDoc, {
|
||||
onResult (result) {
|
||||
result.totalDuration = HOUR + MINUTE + SECOND
|
||||
},
|
||||
render: (gqlVal) => {
|
||||
return (
|
||||
<div class="h-screen bg-gray-100 p-3">
|
||||
<RunCard gql={gqlVal} />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
// this is the human readable commit time from the stub
|
||||
cy.contains('01:01:01').should('be.visible')
|
||||
|
||||
cy.percySnapshot()
|
||||
})
|
||||
|
||||
it('displays mm:ss format for run duration if duration is less than an hour', () => {
|
||||
cy.mountFragment(RunCardFragmentDoc, {
|
||||
onResult (result) {
|
||||
result.totalDuration = MINUTE + SECOND
|
||||
},
|
||||
render: (gqlVal) => {
|
||||
return (
|
||||
<div class="h-screen bg-gray-100 p-3">
|
||||
<RunCard gql={gqlVal} />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
// this is the human readable commit time from the stub
|
||||
cy.contains('01:01').should('be.visible')
|
||||
|
||||
cy.percySnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
context('tags', () => {
|
||||
it('renders all tags if >= 2', () => {
|
||||
cy.mountFragment(RunCardFragmentDoc, {
|
||||
onResult (result) {
|
||||
result.tags = generateTags(2)
|
||||
},
|
||||
render: (gqlVal) => {
|
||||
return (
|
||||
<div class="h-screen bg-gray-100 p-3">
|
||||
<RunCard gql={gqlVal} />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
cy.get('[data-cy="run-tag"]').should('have.length', 2).each(($el, i) => cy.wrap($el).contains(`tag${i}`))
|
||||
|
||||
cy.percySnapshot()
|
||||
})
|
||||
|
||||
it('truncates tags if > 2', () => {
|
||||
cy.mountFragment(RunCardFragmentDoc, {
|
||||
onResult (result) {
|
||||
result.tags = generateTags(6)
|
||||
},
|
||||
render: (gqlVal) => {
|
||||
return (
|
||||
<div class="h-screen bg-gray-100 p-3">
|
||||
<RunCard gql={gqlVal} />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
cy.get('[data-cy="run-tag"]').should('have.length', 3).last().contains('+4')
|
||||
|
||||
cy.percySnapshot()
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<ExternalLink
|
||||
:data-cy="`runCard-${run.id}`"
|
||||
class="border rounded bg-light-50 border-gray-100 mb-4 w-full
|
||||
class="border rounded bg-light-50 border-gray-100 w-full
|
||||
block overflow-hidden hocus-default"
|
||||
:href="run.url || '#'"
|
||||
:use-default-hocus="false"
|
||||
@@ -11,42 +11,49 @@
|
||||
:data-cy="`run-card-icon-${run.status}`"
|
||||
>
|
||||
<template #header>
|
||||
{{ run.commitInfo?.summary }}
|
||||
<span class="font-semibold mr-8px whitespace-pre-wrap">{{ run.commitInfo?.summary }}</span>
|
||||
<span
|
||||
v-for="tag in tags"
|
||||
:key="tag"
|
||||
class="rounded-md font-semibold border-gray-200 border-1px text-xs mr-8px px-4px text-gray-700"
|
||||
data-cy="run-tag"
|
||||
>{{ tag }}</span>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="flex">
|
||||
<span
|
||||
<ul class="flex flex-wrap text-sm text-gray-700 gap-8px items-center whitespace-nowrap children:flex children:items-center">
|
||||
<li
|
||||
v-if="run.commitInfo?.authorName"
|
||||
class="flex mr-3 items-center"
|
||||
data-cy="run-card-author"
|
||||
>
|
||||
<i-cy-general-user_x16
|
||||
class="mr-1 icon-dark-gray-500 icon-light-gray-200 icon-secondary-light-gray-200"
|
||||
class="mr-1 icon-dark-gray-500 icon-light-gray-100 icon-secondary-light-gray-200"
|
||||
data-cy="run-card-avatar"
|
||||
/>
|
||||
<span class="font-light text-sm text-gray-500">
|
||||
{{ run.commitInfo.authorName }}
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
<span class="sr-only">Commit Author:</span>{{ run.commitInfo.authorName }}
|
||||
</li>
|
||||
|
||||
<li
|
||||
v-if="run.commitInfo?.branch"
|
||||
class="flex mr-3 items-center"
|
||||
data-cy="run-card-branch"
|
||||
>
|
||||
<i-cy-tech-branch-h_x16 class="mr-1 icon-dark-gray-300" />
|
||||
<span
|
||||
class="font-light text-sm text-gray-500"
|
||||
data-cy="run-card-branch"
|
||||
>
|
||||
{{ run.commitInfo.branch }}
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
<span class="sr-only">Branch Name:</span>{{ run.commitInfo.branch }}
|
||||
</li>
|
||||
|
||||
<li
|
||||
v-if="run.createdAt"
|
||||
class="flex mr-3 items-center"
|
||||
data-cy="run-card-created-at"
|
||||
>
|
||||
{{ new Date(run.createdAt).toLocaleTimeString() }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="sr-only">Run Created At:</span>{{ relativeCreatedAt }}
|
||||
</li>
|
||||
|
||||
<li
|
||||
v-if="run.totalDuration"
|
||||
data-cy="run-card-duration"
|
||||
>
|
||||
<span class="sr-only">Run Total Duration:</span>{{ totalDuration }}
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<template #right>
|
||||
<RunResults
|
||||
@@ -69,13 +76,19 @@ import FailedIcon from '~icons/cy/status-failed-solid_x24.svg'
|
||||
import ErroredIcon from '~icons/cy/status-errored-solid_x24.svg'
|
||||
import SkippedIcon from '~icons/cy/status-skipped_x24.svg'
|
||||
import PendingIcon from '~icons/cy/status-pending_x24.svg'
|
||||
import { dayjs } from './utils/day.js'
|
||||
|
||||
gql`
|
||||
fragment RunCard on CloudRun {
|
||||
id
|
||||
createdAt
|
||||
status
|
||||
totalDuration
|
||||
url
|
||||
tags {
|
||||
id
|
||||
name
|
||||
}
|
||||
...RunResults
|
||||
commitInfo {
|
||||
authorName
|
||||
@@ -105,4 +118,21 @@ const icon = computed(() => ICON_MAP[props.gql.status!])
|
||||
|
||||
const run = computed(() => props.gql)
|
||||
|
||||
const relativeCreatedAt = computed(() => dayjs(new Date(run.value.createdAt!)).fromNow())
|
||||
|
||||
const totalDuration = computed(() => dayjs.duration(run.value.totalDuration!).format('HH:mm:ss').replace(/^0+:/, ''))
|
||||
|
||||
const tags = computed(() => {
|
||||
const tags = (props.gql.tags ?? []).map((tag) => tag?.name).filter(Boolean) as string[]
|
||||
|
||||
return tags.length <= 2 ? tags : tags.slice(0, 2).concat(`+${tags.length - 2}`)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
li:not(:first-child)::before {
|
||||
content: '.';
|
||||
@apply -mt-8px text-lg text-gray-400 pr-8px
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -27,4 +27,19 @@ describe('<RunResults />', { viewportHeight: 150, viewportWidth: 250 }, () => {
|
||||
|
||||
cy.percySnapshot()
|
||||
})
|
||||
|
||||
it('renders flaky ribbon', () => {
|
||||
cy.mountFragment(RunCardFragmentDoc, {
|
||||
onResult (result) {
|
||||
result.totalFlakyTests = 4
|
||||
},
|
||||
render (gql) {
|
||||
return <RunResults gql={gql} />
|
||||
},
|
||||
})
|
||||
|
||||
cy.contains('4 Flaky')
|
||||
|
||||
cy.percySnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
<template>
|
||||
<div class="border rounded flex border-gray-200 h-6 text-gray-500 text-size-14px leading-20px">
|
||||
<div
|
||||
v-for="(result, i) in results"
|
||||
:key="i"
|
||||
class="flex px-2 items-center hover:bg-indigo-50"
|
||||
:title="result.name"
|
||||
:data-cy="`runResults-${result.name}-count`"
|
||||
>
|
||||
<component
|
||||
:is="result.icon"
|
||||
class="h-12px mr-1 w-12px"
|
||||
:class="result.class"
|
||||
/>
|
||||
<span class="sr-only">{{ result.name }}</span>
|
||||
{{ result.value }}
|
||||
<div class="flex gap-8px items-center">
|
||||
<span
|
||||
v-if="props.gql.totalFlakyTests"
|
||||
class="rounded-md font-semibold bg-warning-100 text-sm py-2px px-4px text-warning-600 whitespace-nowrap"
|
||||
>{{ props.gql.totalFlakyTests }} Flaky</span>
|
||||
<div class="border rounded flex border-gray-200 h-6 text-gray-700 text-size-14px leading-20px">
|
||||
<div
|
||||
v-for="(result, i) in results"
|
||||
:key="i"
|
||||
class="flex font-semibold px-2 items-center hover:bg-indigo-50"
|
||||
:title="result.name"
|
||||
:data-cy="`runResults-${result.name}-count`"
|
||||
>
|
||||
<component
|
||||
:is="result.icon"
|
||||
class="mt-px h-12px mr-1 w-12px"
|
||||
:class="result.class"
|
||||
/>
|
||||
<span class="sr-only">{{ result.name }}</span>
|
||||
{{ result.value }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -36,6 +42,7 @@ fragment RunResults on CloudRun {
|
||||
totalFailed
|
||||
totalPending
|
||||
totalSkipped
|
||||
totalFlakyTests
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
@@ -72,4 +72,29 @@ describe('<RunsContainer />', { keystrokeDelay: 0 }, () => {
|
||||
cy.percySnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
context('with errors', () => {
|
||||
it('renders connection failed', () => {
|
||||
cy.mountFragment(RunsContainerFragmentDoc, {
|
||||
onResult (result) {
|
||||
result.cloudViewer = cloudViewer
|
||||
result.currentProject!.cloudProject = null
|
||||
},
|
||||
render (gqlVal) {
|
||||
return <RunsContainer gql={gqlVal} online onReExecuteRunsQuery={cy.spy().as('reExecuteRunsQuery')}/>
|
||||
},
|
||||
})
|
||||
|
||||
const { title, description, link, button } = defaultMessages.runs.errors.connectionFailed
|
||||
|
||||
cy.contains(title).should('be.visible')
|
||||
cy.contains(description.replace('{0}', link)).should('be.visible')
|
||||
cy.contains('a', link).should('have.attr', 'href', 'https://www.cypressstatus.com/')
|
||||
cy.contains('button', button).should('be.visible').click()
|
||||
|
||||
cy.get('@reExecuteRunsQuery').should('have.been.called')
|
||||
|
||||
cy.percySnapshot()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<template>
|
||||
<div class="h-full">
|
||||
<NoInternetConnection
|
||||
v-if="!online && !isCloudProjectReturned"
|
||||
>
|
||||
<NoInternetConnection v-if="!online">
|
||||
Please check your internet connection to resolve this issue. When your internet connection is fixed, we will automatically attempt to fetch your latest runs for this project.
|
||||
</NoInternetConnection>
|
||||
<RunsConnectSuccessAlert
|
||||
@@ -16,8 +14,9 @@
|
||||
@success="showConnectSuccessAlert = true"
|
||||
/>
|
||||
<RunsErrorRenderer
|
||||
v-else-if="currentProject?.cloudProject?.__typename !== 'CloudProject'"
|
||||
v-else-if="currentProject?.cloudProject?.__typename !== 'CloudProject' || connectionFailed"
|
||||
:gql="props.gql"
|
||||
@re-execute-runs-query="emit('reExecuteRunsQuery')"
|
||||
/>
|
||||
<RunsEmpty
|
||||
v-else-if="!currentProject?.cloudProject?.runs?.nodes.length"
|
||||
@@ -26,6 +25,7 @@
|
||||
<div
|
||||
v-else
|
||||
data-cy="runs"
|
||||
class="flex flex-col pb-24px gap-16px"
|
||||
>
|
||||
<Warning
|
||||
v-if="!online"
|
||||
@@ -58,6 +58,10 @@ import RunsErrorRenderer from './RunsErrorRenderer.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'reExecuteRunsQuery'): void
|
||||
}>()
|
||||
|
||||
gql`
|
||||
fragment RunsContainer_RunsConnection on CloudRunConnection {
|
||||
nodes {
|
||||
@@ -185,9 +189,8 @@ const props = defineProps<{
|
||||
online: boolean
|
||||
}>()
|
||||
|
||||
const isCloudProjectReturned = computed(() => props.gql.currentProject?.cloudProject?.__typename === 'CloudProject')
|
||||
|
||||
const showConnectSuccessAlert = ref(false)
|
||||
const connectionFailed = computed(() => !props.gql.currentProject?.cloudProject && props.online)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -1,15 +1,32 @@
|
||||
<template>
|
||||
<RunsError
|
||||
v-if="currentProject?.cloudProject?.__typename === 'CloudProjectNotFound'"
|
||||
v-if="!currentProject?.cloudProject"
|
||||
icon="error"
|
||||
:button-text="t('runs.errors.notfound.button')"
|
||||
:button-text="t('runs.errors.connectionFailed.button')"
|
||||
:button-icon="ConnectIcon"
|
||||
:message="t('runs.errors.notfound.title')"
|
||||
:message="t('runs.errors.connectionFailed.title')"
|
||||
@button-click="emit('reExecuteRunsQuery')"
|
||||
>
|
||||
<i18n-t
|
||||
scope="global"
|
||||
keypath="runs.errors.connectionFailed.description"
|
||||
>
|
||||
<ExternalLink href="https://www.cypressstatus.com/">
|
||||
{{ t('runs.errors.connectionFailed.link') }}
|
||||
</ExternalLink>
|
||||
</i18n-t>
|
||||
</RunsError>
|
||||
<RunsError
|
||||
v-else-if="currentProject?.cloudProject?.__typename === 'CloudProjectNotFound'"
|
||||
icon="error"
|
||||
:button-text="t('runs.errors.notFound.button')"
|
||||
:button-icon="ConnectIcon"
|
||||
:message="t('runs.errors.notFound.title')"
|
||||
@button-click="showConnectDialog = true"
|
||||
>
|
||||
<i18n-t
|
||||
scope="global"
|
||||
keypath="runs.errors.notfound.description"
|
||||
keypath="runs.errors.notFound.description"
|
||||
>
|
||||
<CodeTag
|
||||
bg
|
||||
@@ -61,6 +78,7 @@ import SendIcon from '~icons/cy/paper-airplane_x16.svg'
|
||||
import { useI18n } from '@cy/i18n'
|
||||
import CodeTag from '../../../frontend-shared/src/components/CodeTag.vue'
|
||||
import CloudConnectModals from './modals/CloudConnectModals.vue'
|
||||
import ExternalLink from '@cy/gql-components/ExternalLink.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@@ -88,6 +106,10 @@ const props = defineProps<{
|
||||
gql: RunsErrorRendererFragment
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'reExecuteRunsQuery'): void
|
||||
}>()
|
||||
|
||||
const currentProject = computed(() => props.gql.currentProject)
|
||||
|
||||
const showConnectDialog = ref(false)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import dayjs from 'dayjs'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
import duration from 'dayjs/plugin/duration'
|
||||
|
||||
dayjs.extend(relativeTime)
|
||||
dayjs.extend(duration)
|
||||
|
||||
export { dayjs }
|
||||
@@ -14,6 +14,9 @@ export default makeConfig({
|
||||
'vue-router',
|
||||
'@urql/devtools',
|
||||
'@urql/exchange-graphcache',
|
||||
'dayjs',
|
||||
'dayjs/plugin/relativeTime',
|
||||
'dayjs/plugin/duration',
|
||||
],
|
||||
},
|
||||
}, {
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
/>
|
||||
</slot>
|
||||
</div>
|
||||
<div class="bg-gray-100 h-40px w-1px" />
|
||||
<div class="flex-grow h-auto px-16px">
|
||||
<div class="flex-grow h-auto border-gray-100 border-l-1px px-16px">
|
||||
<h2
|
||||
class="text-indigo-500 whitespace-nowrap"
|
||||
:class="{'text-size-18px leading-24px': bigHeader}"
|
||||
|
||||
@@ -488,7 +488,7 @@
|
||||
"failed": "failed"
|
||||
},
|
||||
"errors": {
|
||||
"notfound": {
|
||||
"notFound": {
|
||||
"title": "Couldn't find your project",
|
||||
"description": "We were unable to find an existing project matching the {0} set in your Cypress config file. You can reconnect with an existing project or create a new project.",
|
||||
"button": "Reconnect your project"
|
||||
@@ -502,6 +502,12 @@
|
||||
"title": "Your access request for this project has been sent.",
|
||||
"description": "The owner of this project has been notified of your request. We'll notify you via email when your access request has been granted.",
|
||||
"button": "Request Sent"
|
||||
},
|
||||
"connectionFailed": {
|
||||
"title": "Cannot connect to the Cypress Dashboard",
|
||||
"description": "The request times out when trying to retrieve the recorded runs from the Cypress Dashboard. Please refresh the page to try again and visit out {0} if this behavior continues.",
|
||||
"link": "Support Page",
|
||||
"button": "Try again"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -174,11 +174,11 @@ export function createCloudRun (config: Partial<CloudRun>): Required<CloudRun> {
|
||||
totalRunning: 0,
|
||||
totalTests: 10,
|
||||
totalPassed: 10,
|
||||
totalDuration: 300,
|
||||
totalDuration: 1000 * 60,
|
||||
totalFlakyTests: 0,
|
||||
tags: [],
|
||||
url: 'http://dummy.cypress.io/runs/1',
|
||||
createdAt: new Date('1995-12-17T03:17:00').toISOString(),
|
||||
createdAt: new Date(Date.now() - 1000 * 60 * 61).toISOString(),
|
||||
commitInfo: createCloudRunCommitInfo({
|
||||
sha: `fake-sha-${getNodeIdx('CloudRun')}`,
|
||||
summary: `fix: make gql work ${config.status ?? 'PASSED'}`,
|
||||
|
||||
Reference in New Issue
Block a user