Skip to content

Commit

Permalink
after pairing w/ Muaz on polling for runs list metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
tgriesser committed Jun 8, 2022
1 parent d9eb85e commit 5c95239
Show file tree
Hide file tree
Showing 27 changed files with 458 additions and 159 deletions.
4 changes: 3 additions & 1 deletion .vscode/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
"words": [
"Chainable",
"composables",
"dedup",
"ERRORED",
"execa",
"Fetchable",
"Fetchables",
"forcedefault",
"getenv",
"graphcache",
"headlessui",
"Iconify",
"intlify",
Expand Down Expand Up @@ -46,4 +48,4 @@
],
"ignoreWords": [],
"import": []
}
}
22 changes: 20 additions & 2 deletions packages/app/src/pages/Specs/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { useI18n } from '@cy/i18n'
import SpecsList from '../../specs/SpecsList.vue'
import NoSpecsPage from '../../specs/NoSpecsPage.vue'
import CreateSpecModal from '../../specs/CreateSpecModal.vue'
import { SpecsPageContainerDocument, SpecsPageContainer_SpecsChangeDocument, SpecsPageContainer_BranchInfoDocument } from '../../generated/graphql'
import { SpecsPageContainerDocument, SpecsPageContainer_SpecsChangeDocument, SpecsPageContainer_SpecListPollingDocument, SpecsPageContainer_BranchInfoDocument } from '../../generated/graphql'
const { t } = useI18n()
Expand All @@ -39,6 +39,7 @@ query SpecsPageContainer_BranchInfo {
currentProject {
id
branch
projectId
}
}
`
Expand Down Expand Up @@ -67,6 +68,12 @@ subscription SpecsPageContainer_specsChange($fromBranch: String!, $hasBranch: Bo
}
`
gql`
subscription SpecsPageContainer_specListPolling($fromBranch: String, $projectId: String) {
startPollingForSpecs(branchName: $fromBranch, projectId: $projectId)
}
`
const branchInfo = useQuery({ query: SpecsPageContainer_BranchInfoDocument })
const variables = computed(() => {
Expand All @@ -76,11 +83,23 @@ const variables = computed(() => {
return { hasBranch, fromBranch }
})
const pollingVariables = computed(() => {
const fromBranch = branchInfo.data.value?.currentProject?.branch ?? null
const projectId = branchInfo.data.value?.currentProject?.projectId ?? null
return { fromBranch, projectId }
})
useSubscription({
query: SpecsPageContainer_SpecsChangeDocument,
variables,
})
useSubscription({
query: SpecsPageContainer_SpecListPollingDocument,
variables: pollingVariables,
})
const query = useQuery({
query: SpecsPageContainerDocument,
variables,
Expand All @@ -107,7 +126,6 @@ const closeCreateSpecModal = () => {
modalIsShown.value = false
generator.value = null
}
</script>
<route>
Expand Down
12 changes: 7 additions & 5 deletions packages/app/src/specs/AverageDuration.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div
v-if="props.gql?.avgDurationInfo?.status === 'FETCHED' && props.gql?.avgDurationInfo?.data?.averageDuration"
v-if="props.gql?.avgDurationInfo?.status === 'FETCHED' && props.gql?.avgDurationInfo.data?.__typename === 'CloudProjectSpec' && props.gql?.avgDurationInfo?.data?.averageDuration"
class="h-full grid text-gray-700 justify-end items-center"
data-cy="average-duration"
>
Expand All @@ -19,7 +19,7 @@ gql`
mutation AverageDuration_Refetch ($ids: [ID!]!) {
loadRemoteFetchables(ids: $ids){
id
status
fetchingStatus
}
}
`
Expand All @@ -38,10 +38,12 @@ fragment AverageDuration on Spec {
fileName
avgDurationInfo: cloudSpec(name: "AverageDuration") {
id
status
fetchingStatus
data {
id
averageDuration
... on CloudProjectSpec {
id
averageDuration
}
}
}
}
Expand Down
72 changes: 38 additions & 34 deletions packages/app/src/specs/RunStatusDots.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div
v-if="props.isProjectDisconnected || props.gql.cloudSpec?.status === 'FETCHED' || props.gql.cloudSpec?.status === 'ERRORED'"
v-if="props.isProjectDisconnected || props.gql.cloudSpec?.fetchingStatus === 'FETCHED' || props.gql.cloudSpec?.fetchingStatus === 'ERRORED'"
class="h-full grid justify-items-end items-center"
>
<component
Expand Down Expand Up @@ -91,7 +91,7 @@ gql`
mutation RunStatusDots_Refetch ($ids: [ID!]!) {
loadRemoteFetchables(ids: $ids){
id
status
fetchingStatus
}
}
`
Expand All @@ -108,40 +108,44 @@ gql`
fragment RunStatusDots on Spec {
id
specFileExtension
fileName
fileName
cloudSpec(name: "RunStatusDots") @include(if: $hasBranch) {
id
status
fetchingStatus
data {
id
specRuns(first: 4, fromBranch: $fromBranch) {
nodes {
id
runNumber
testsFailed{
min
max
__typename
... on CloudProjectSpec {
id
retrievedAt
specRuns(first: 4, fromBranch: $fromBranch) {
nodes {
id
runNumber
testsFailed{
min
max
}
testsPassed{
min
max
}
testsPending{
min
max
}
testsSkipped{
min
max
}
createdAt
groupCount
specDuration{
min
max
}
status
url
}
testsPassed{
min
max
}
testsPending{
min
max
}
testsSkipped{
min
max
}
createdAt
groupCount
specDuration{
min
max
}
status
url
}
}
}
Expand All @@ -160,14 +164,14 @@ const props = withDefaults(defineProps<{
watchEffect(
() => {
if (props.isOnline && (props.gql.cloudSpec?.status === 'NOT_FETCHED' || props.gql.cloudSpec?.status === undefined)) {
if (props.isOnline && (props.gql.cloudSpec?.fetchingStatus === 'NOT_FETCHED' || props.gql.cloudSpec?.fetchingStatus === undefined)) {
refetch()
}
},
)
const runs = computed(() => {
return props.gql.cloudSpec?.data?.specRuns?.nodes ?? []
return props.gql.cloudSpec?.data?.__typename === 'CloudProjectSpec' ? props.gql.cloudSpec.data.specRuns?.nodes ?? [] : []
})
const dotClasses = computed(() => {
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/specs/SpecsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ gql`
mutation CloudData_Refetch ($ids: [ID!]!) {
loadRemoteFetchables(ids: $ids){
id
status
fetchingStatus
}
}
`
Expand Down
6 changes: 6 additions & 0 deletions packages/data-context/src/DataContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { ErrorDataSource } from './sources/ErrorDataSource'
import { GraphQLDataSource } from './sources/GraphQLDataSource'
import { RemoteRequestDataSource } from './sources/RemoteRequestDataSource'
import { resetIssuedWarnings } from '@packages/config'
import { RemotePollingDataSource } from './sources/RemotePollingDataSource'

const IS_DEV_ENV = process.env.CYPRESS_INTERNAL_ENV !== 'production'

Expand Down Expand Up @@ -218,6 +219,11 @@ export class DataContext {
return new ProjectDataSource(this)
}

@cached
get remotePolling () {
return new RemotePollingDataSource(this)
}

@cached
get cloud () {
return new CloudDataSource({
Expand Down
24 changes: 23 additions & 1 deletion packages/data-context/src/actions/DataEmitterActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { DataContext } from '../DataContext'

export interface PushFragmentData {
data: any
errors: any
target: string
fragment: string
variables?: any
Expand Down Expand Up @@ -49,6 +50,13 @@ abstract class DataEmitterEvents {
this._emit('devChange')
}

/**
* Emitted when there is a change in the date related to refetching specs
*/
specPollingUpdate (lastUpdated: string | null) {
this._emit('specPollingUpdate', lastUpdated)
}

/**
* Emitted when cypress.config is re-executed and we'd like to
* either re-run a spec or update something in the App UI.
Expand Down Expand Up @@ -89,6 +97,14 @@ abstract class DataEmitterEvents {
this._emit('pushFragment', toPush)
}

/**
* This should never be triggered, but fulfills the type signatures so we can subscribeTo
* it in a situation where we want a "fake" subscription
*/
noopChange () {
throw new Error('Do not call this')
}

private _emit <Evt extends keyof DataEmitterEvents> (evt: Evt, ...args: Parameters<DataEmitterEvents[Evt]>) {
this.pub.emit(evt, ...args)
}
Expand Down Expand Up @@ -140,7 +156,7 @@ export class DataEmitterActions extends DataEmitterEvents {
* when subscribing, we want to execute the operation to get the up-to-date initial
* value, and then we keep a deferred object, resolved when the given emitter is fired
*/
subscribeTo (evt: keyof DataEmitterEvents, opts?: {sendInitial: boolean}): AsyncGenerator<any> {
subscribeTo (evt: keyof DataEmitterEvents, opts?: {sendInitial: boolean, onUnsubscribe?: () => void }): AsyncGenerator<any> {
const { sendInitial = true } = opts ?? {}
let hasSentInitial = false
let dfd: pDefer.DeferredPromise<any> | undefined
Expand All @@ -157,6 +173,7 @@ export class DataEmitterActions extends DataEmitterEvents {
pending.push({ done: false, value })
}
}

this.pub.on(evt, subscribed)

const iterator = {
Expand Down Expand Up @@ -184,6 +201,11 @@ export class DataEmitterActions extends DataEmitterEvents {
},
return: async () => {
this.pub.off(evt, subscribed)

if (opts?.onUnsubscribe) {
opts.onUnsubscribe()
}

// If we are currently waiting on a deferred promise, we need to resolve it and signify we're done to ensure that the async loop terminates
if (dfd) {
dfd.resolve({ done: true, value: undefined })
Expand Down
2 changes: 1 addition & 1 deletion packages/data-context/src/data/coreDataShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface AuthenticatedUserShape {

export interface ProjectShape {
projectRoot: string
savedState: () => Promise<Maybe<SavedStateShape>>
savedState?: () => Promise<Maybe<SavedStateShape>>
}

export interface DevStateShape {
Expand Down
Loading

0 comments on commit 5c95239

Please sign in to comment.