Skip to content
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: wiring up test filters to the Debug page back end #25492

Merged
merged 4 commits into from
Jan 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 36 additions & 18 deletions packages/app/cypress/e2e/runner/cloud-debug-filter.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ describe('cloud debug test filtering', () => {
cy.waitForSpecToFinish()

cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = ['t2']
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/test.cy.js': ['t2'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/test.cy.js&runId=123`)
cy.visitApp(`specs/runner?file=cypress/e2e/test.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 0, failCount: 1 })

cy.get('.runnable-title').contains('t2')
Expand All @@ -23,10 +25,12 @@ describe('cloud debug test filtering', () => {
cy.waitForSpecToFinish({ passCount: 2, failCount: 2 })

cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = ['s1 t4']
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/test.cy.js': ['s1 t4'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/test.cy.js&runId=123`)
cy.visitApp(`specs/runner?file=cypress/e2e/test.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 0, failCount: 1 })

cy.get('.runnable-title').contains('t4')
Expand All @@ -40,10 +44,12 @@ describe('cloud debug test filtering', () => {
cy.waitForSpecToFinish()

cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = ['test1']
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/lots-of-tests.cy.js': ['test1'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/lots-of-tests.cy.js&runId=123`)
cy.visitApp(`specs/runner?file=cypress/e2e/lots-of-tests.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 50 })

cy.get('@reporterPanel').then((el) => el.width(500))
Expand All @@ -66,10 +72,12 @@ describe('cloud debug test filtering', () => {

// .only is respected
cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = ['t1', 't3']
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/skip-and-only.cy.js': ['t1', 't3'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&runId=123`)
cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 0, failCount: 1 })

cy.get('.runnable-title').contains('t1')
Expand All @@ -78,10 +86,12 @@ describe('cloud debug test filtering', () => {

// .only is ignored as it is not in set of filtered tests
cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = ['t3']
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/skip-and-only.cy.js': ['t3'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&runId=123`)
cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 0, failCount: 1 })

cy.get('.runnable-title').contains('t3')
Expand All @@ -90,10 +100,12 @@ describe('cloud debug test filtering', () => {

// .skip is respected
cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = ['t2', 't3']
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/skip-and-only.cy.js': ['t2', 't3'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&runId=123`)
cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 0, failCount: 1, pendingCount: 1 })
cy.get('.runnable-title').first().contains('t2')
cy.get('.runnable-title').last().contains('t3')
Expand All @@ -102,20 +114,24 @@ describe('cloud debug test filtering', () => {

// suite.only is respected
cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = ['t3', 's1 t4']
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/skip-and-only.cy.js': ['t3', 's1 t4'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&runId=123`)
cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 0, failCount: 1 })
cy.get('.runnable-title').contains('t4')
})

it('works with browser filter', () => {
cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = ['t1', 's1 t2']
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/lots-of-tests.cy.j': ['t1', 's1 t2'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/browsers.cy.js&runId=123`)
cy.visitApp(`specs/runner?file=cypress/e2e/browsers.cy.js&mode=debug`)

cy.get('.runnable-title').eq(0).contains('t1 (skipped due to browser)')
cy.get('.runnable-title').eq(1).contains('s1 (skipped due to browser)')
Expand All @@ -130,10 +146,12 @@ describe('cloud debug test filtering', () => {
cy.waitForSpecToFinish()

cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = ['t2', 't3']
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/lots-of-tests.cy.j': ['t2', 't3'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/domain-change.cy.js&runId=123`)
cy.visitApp(`specs/runner?file=cypress/e2e/domain-change.cy.js&mode=debug`)
cy.waitForSpecToFinish({ failCount: 2 })
})
})
25 changes: 0 additions & 25 deletions packages/app/src/composables/useTestsForDebug.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/app/src/debug/DebugSpec.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ describe('Run Failures button', () => {
))

cy.findByTestId('run-failures')
.should('have.attr', 'href', '#/specs/runner?file=cypress/tests/auth.spec.ts')
.should('have.attr', 'href', '#/specs/runner?file=cypress/tests/auth.spec.ts&mode=debug')
.and('not.have.attr', 'aria-disabled')
})
})
2 changes: 1 addition & 1 deletion packages/app/src/debug/DebugSpec.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
variant="white"
class="gap-x-10px inline-flex whitespace-nowrap justify-center items-center isolate"
:disabled="runAllFailuresState.disabled"
:to="{ path: '/specs/runner', query: { file: posixify(specData.fullPath) } }"
:to="{ path: '/specs/runner', query: { file: posixify(specData.fullPath), mode: 'debug' } }"
>
<template #prefix>
<IconActionRefresh
Expand Down
93 changes: 93 additions & 0 deletions packages/app/src/debug/DebugSpecList.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { SetTestsForDebugDocument } from '../generated/graphql-test'
import DebugSpecList from './DebugSpecList.vue'
import type { CloudDebugSpec } from './utils/DebugMapping'

const specs: CloudDebugSpec[] = [{
spec: {
id: '123',
basename: '',
extension: '.ts',
groupIds: [],
shortPath: '',
specDuration: {
max: 10,
min: 10,
},
status: 'FAILED',
testsFailed: {
max: 2,
min: 2,
},
testsPassed: {
max: 0,
min: 0,
},
testsPending: {
max: 0,
min: 0,
},
path: 'path/to/test.cy.ts',
},
tests: {
'ab123': [{
id: '123',
specId: '',
titleParts: ['Test', 'make it work'],
duration: 10,
instance: {
id: '123',
groupId: '',
hasScreenshots: false,
hasStdout: false,
hasVideo: false,
status: 'FAILED',
screenshotsUrl: '',
stdoutUrl: '',
videoUrl: '',
totalFailed: 3,
totalPassed: 0,
totalPending: 0,
totalRunning: 0,
totalSkipped: 0,
},
isFlaky: false,
testUrl: '',
thumbprint: 'ab123',
title: 'Test > make it work',
}],
},
testingType: 'component',
foundLocally: true,
matchesCurrentTestingType: true,
groups: { '123': {
testingType: 'component',
browser: {
id: '123',
formattedName: '',
formattedNameWithVersion: '',
},
groupName: 'group1',
id: '123',
os: {
id: '123',
name: 'MacOS',
nameWithVersion: 'MacOS 10',
},
} },
}]

describe('<DebugSpecList />', () => {
it('calls mutation to set tests for debug mode in runner on mount', (done) => {
cy.stubMutationResolver(SetTestsForDebugDocument, (defineResult, variables) => {
expect(variables.testsBySpec[0].specPath).to.eql(specs[0].spec.path)
expect(variables.testsBySpec[0].tests[0]).to.eql(specs[0].tests['ab123'][0].titleParts.join(' '))
done()
})

cy.mount(() => (
<DebugSpecList
specs={specs}
/>
))
})
})
27 changes: 25 additions & 2 deletions packages/app/src/debug/DebugSpecList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
<script setup lang="ts">
import { gql } from '@urql/core'
import { useMutation } from '@urql/vue'
import { computed } from 'vue'
import { SwitchTestingTypeAndRelaunchDocument, TestingTypeEnum } from '../generated/graphql'
import { computed, watchEffect } from 'vue'
import { SetTestsForDebugDocument, SwitchTestingTypeAndRelaunchDocument, TestingTypeEnum } from '../generated/graphql'
import DebugSpec from './DebugSpec.vue'
import type { CloudDebugSpec } from './utils/DebugMapping'

Expand Down Expand Up @@ -100,12 +100,20 @@ fragment DebugSpecListGroups on CloudRunGroup {
}
`

gql`
mutation SetTestsForDebug($testsBySpec: [TestsBySpecInput!]!) {
setTestsForRun (testsBySpec: $testsBySpec)
}
`

const props = defineProps<{
specs: CloudDebugSpec[]
}>()

const switchTestingTypeMutation = useMutation(SwitchTestingTypeAndRelaunchDocument)

const setTestsForDebug = useMutation(SetTestsForDebugDocument)

const specs = computed(() => {
return props.specs.map((specItem) => {
const fileName = specItem.spec.basename
Expand Down Expand Up @@ -134,4 +142,19 @@ function switchTestingType (testingType: TestingTypeEnum) {
switchTestingTypeMutation.executeMutation({ testingType })
}

watchEffect(() => {
const testsNamesBySpec = props.specs.map((specItem) => {
return {
specPath: specItem.spec.path,
tests: Object.values(specItem.tests)
.flat()
.map((test) => {
return test.titleParts.join(' ')
}),
}
})

setTestsForDebug.executeMutation({ testsBySpec: testsNamesBySpec })
})

</script>
8 changes: 4 additions & 4 deletions packages/app/src/runner/unifiedRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { gql, useMutation } from '@urql/vue'
import { TestsForRunDocument } from '../generated/graphql'

gql`
mutation TestsForRun ($runId: String!) {
testsForRun (runId: $runId)
mutation TestsForRun ($spec: String!) {
testsForRun (spec: $spec)
}
`

Expand Down Expand Up @@ -61,8 +61,8 @@ export function useUnifiedRunner () {
return specStore.setActiveSpec(null)
}

if (route.query.runId) {
const res = await testsForRunMutation.executeMutation({ runId: route.query.runId as string })
if (route.query.mode && route.query.mode === 'debug') {
const res = await testsForRunMutation.executeMutation({ spec: activeSpecInSpecsList.relative })

specStore.setTestFilter(res.data?.testsForRun?.length ? res.data.testsForRun : undefined)
} else {
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/runner/useEventManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function useEventManager () {
eventManager.on('testFilter:cloudDebug:dismiss', () => {
const currentRoute = router.currentRoute.value

const { runId, ...query } = currentRoute.query
const { mode, ...query } = currentRoute.query

// Delete runId from query which will remove the test filter and trigger a rerun
router.replace({ ...currentRoute, query })
Expand Down
5 changes: 2 additions & 3 deletions packages/data-context/src/data/coreDataShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ interface Diagnostics {
}

interface CloudDataShape {
testsForRunResults?: string[]
testsForRunResults?: Record<string, string[]>
}

export interface CoreDataShape {
Expand Down Expand Up @@ -224,9 +224,8 @@ export function makeCoreData (modeOptions: Partial<AllModeOptions> = {}): CoreDa
packageManager: 'npm',
forceReconfigureProject: null,
versionData: null,
// TODO: Replace stubbed data with real data from cloud
cloud: {
testsForRunResults: ['t1', 't2', 's1 t3', 's1 t4'],
testsForRunResults: {},
},
}
}
Loading