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

fix: add top-level run-all button to allow all specs to be run at once #24846

Merged
merged 8 commits into from
Dec 1, 2022
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
16 changes: 11 additions & 5 deletions packages/app/cypress/e2e/run-all-specs.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ describe('run-all-specs', () => {
spec2: { relative: 'cypress/e2e/folder-a/spec-b.cy.js', name: 'runs folder-a/spec-b' },
spec3: { relative: 'cypress/e2e/folder-b/spec-a.cy.js', name: 'runs folder-b/spec-a' },
spec4: { relative: 'cypress/e2e/folder-b/spec-b.cy.js', name: 'runs folder-b/spec-b' },
spec5: { relative: 'folder-c/spec-a.cy.js', name: 'runs folder-c/spec-a' },
spec6: { relative: 'folder-c/spec-b.cy.js', name: 'runs folder-c/spec-b' },
}

const clickRunAllSpecs = (directory: string) => {
if (directory === 'all') {
return cy.findByTestId('run-all-specs-for-all').click()
}

const command = cy.get('[data-cy=spec-item-directory]').contains(directory)

return command.realHover().then(() => {
Expand All @@ -30,7 +36,7 @@ describe('run-all-specs', () => {
// Verify "Run All Specs" with sub-directory
const subDirectorySpecs = [ALL_SPECS.spec1, ALL_SPECS.spec2]

cy.get('[data-cy=sidebar-link-specs-page]').click()
cy.findByTestId('sidebar-link-specs-page').click()

clickRunAllSpecs('folder-a')

Expand Down Expand Up @@ -87,16 +93,16 @@ describe('run-all-specs', () => {
// Verify "Run All Specs" live-reload
cy.get('[data-cy=sidebar-link-specs-page]').click()
cy.findByLabelText('Search specs').clear()
cy.get('[data-cy=spec-list-file]').should('have.length', 4)
cy.get('[data-cy=spec-list-file]').should('have.length', 6)

clickRunAllSpecs('cypress/e2e')
clickRunAllSpecs('all')

cy.withCtx((ctx, { specs, runAllSpecsKey }) => {
expect(ctx.actions.project.launchProject).to.have.been.calledWith('e2e', undefined, runAllSpecsKey)
expect(ctx.project.runAllSpecs).to.include.members(specs.map((spec) => spec.relative))
}, { specs: Object.values(ALL_SPECS), runAllSpecsKey: RUN_ALL_SPECS_KEY })

cy.waitForSpecToFinish({ passCount: 4 })
cy.waitForSpecToFinish({ passCount: 6 })

for (const spec of Object.values(ALL_SPECS)) {
cy.get('.runnable-title').contains(spec.name)
Expand All @@ -111,6 +117,6 @@ describe('run-all-specs', () => {
await ctx.actions.file.writeFileInProject(spec.relative, newContent)
}, { spec: ALL_SPECS.spec1 })

cy.waitForSpecToFinish({ passCount: 3, failCount: 1 })
cy.waitForSpecToFinish({ passCount: 5, failCount: 1 })
})
})
69 changes: 0 additions & 69 deletions packages/app/src/composables/useRunAllSpecs.ts

This file was deleted.

9 changes: 3 additions & 6 deletions packages/app/src/pages/Specs/Runner.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import SpecRunnerContainerOpenMode from '../../runner/SpecRunnerContainerOpenMod
import SpecRunnerContainerRunMode from '../../runner/SpecRunnerContainerRunMode.vue'
import { useEventManager } from '../../runner/useEventManager'
import { useSpecStore } from '../../store'
import { isRunMode } from '@packages/frontend-shared/src/utils/isRunMode'
lmiller1990 marked this conversation as resolved.
Show resolved Hide resolved

gql`
query SpecPageContainer {
Expand Down Expand Up @@ -59,18 +60,14 @@ subscription Runner_ConfigChange {
}
`

const isRunMode = window.__CYPRESS_MODE__ === 'run'

// subscriptions are used to trigger live updates without
// reloading the page.
// this is only useful in open mode - in run mode, we don't
// use GraphQL, so we pause the
// subscriptions so they never execute.
const shouldPauseSubscriptions = isRunMode && window.top === window

useSubscription({
query: SpecPageContainer_SpecsChangeDocument,
pause: shouldPauseSubscriptions,
pause: isRunMode,
})

// in run mode, we are not using GraphQL or urql
Expand All @@ -80,7 +77,7 @@ useSubscription({
// requests, which is what we want.
const query = useQuery({
query: SpecPageContainerDocument,
pause: shouldPauseSubscriptions,
pause: isRunMode,
})

let initialLoad = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
</template>

<script lang="ts" setup>
import { isRunMode } from '@packages/frontend-shared/src/utils/isRunMode'
import { computed } from 'vue'
import { useScreenshotStore } from '../../store'
import { runnerConstants } from '../runner-constants'

const screenshotStore = useScreenshotStore()
const isRunMode = window.__CYPRESS_MODE__ === 'run'

const style = computed(() => {
if (screenshotStore.isScreenshotting) {
Expand Down
3 changes: 2 additions & 1 deletion packages/app/src/runner/useRunnerStyle.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isRunMode } from '@packages/frontend-shared/src/utils/isRunMode'
import { useWindowSize } from '@vueuse/core'
import { computed, ref, watchEffect } from 'vue'
import { usePreferences } from '../composables/usePreferences'
Expand Down Expand Up @@ -97,7 +98,7 @@ export const useRunnerStyle = () => {
return {
viewportStyle,
windowWidth: computed(() => {
if (window.__CYPRESS_MODE__ === 'run') {
if (isRunMode) {
return windowWidth.value
}

Expand Down
16 changes: 14 additions & 2 deletions packages/app/src/specs/InlineRunAllSpecs.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,27 @@ describe('<InlineRunAllSpecs/>', () => {
})

it('renders component correctly', () => {
cy.findByTestId('tooltip').children().should('have.length', 1)
cy.findByTestId('run-all-specs-for-cypress/e2e').children().should('have.length', 1)
cy.findByTestId('play-button').should('be.visible')
})

it('provides expected tooltip content', () => {
cy.findByTestId('tooltip-content').should('not.exist')
cy.findByTestId('tooltip').realHover().then(() => {
cy.findByTestId('run-all-specs-for-cypress/e2e').realHover().then(() => {
cy.findByTestId('tooltip-content').should('contain.text', 'Run 40 specs')
})
})
})

it('disables button when no specs are available', () => {
cy.mount(() => {
return (
<div class="flex justify-center">
<InlineRunAllSpecs specNumber={0} directory='cypress/e2e' />
</div>
)
})

cy.findByTestId('run-all-specs-button').should('be.disabled')
})
})
19 changes: 12 additions & 7 deletions packages/app/src/specs/InlineRunAllSpecs.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
<template>
<Tooltip
placement="right"
class="h-full truncate"
data-cy="tooltip"
:data-cy="`run-all-specs-for-${directory}`"
>
<button @click.stop="emits('runAllSpecs')">
<button
class="flex h-full w-full items-center justify-center"
data-cy="run-all-specs-button"
:disabled="specNumber === 0"
@click.stop="emits('runAllSpecs')"
>
<IconActionPlaySmall
size="16"
stroke-color="gray-700"
:stroke-color="grayscale ? 'gray-200' : 'gray-700'"
fill-color="transparent"
hocus-stroke-color="indigo-500"
hocus-fill-color="indigo-100"
:hocus-stroke-color="grayscale ? undefined : 'indigo-500'"
:hocus-fill-color="grayscale ? undefined : 'indigo-100'"
class="inline-flex align-text-bottom"
data-cy="play-button"
/>
Expand All @@ -22,7 +26,7 @@
class="font-normal text-sm inline-flex"
data-cy="tooltip-content"
>
{{ t('specPage.runAllSpecs', specNumber) }}
{{ t('specPage.runSelectedSpecs', specNumber) }}
</span>
</template>
</Tooltip>
Expand All @@ -38,6 +42,7 @@ const { t } = useI18n()
defineProps<{
specNumber: number
directory: string
grayscale?: boolean
}>()

const emits = defineEmits<{
Expand Down
38 changes: 20 additions & 18 deletions packages/app/src/specs/InlineSpecList.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,6 @@ import { defaultMessages } from '@cy/i18n'

let specs: Array<any> = []

const hoverRunAllSpecs = (directory?: string, specNumber?: number) => {
let command

if (directory) {
command = cy.contains('[data-cy=directory-item]', directory)
} else {
command = cy.get('[data-cy=directory-item]').first()
}

return command.realHover().then(() => {
cy.get('[data-cy=play-button]').should('exist')
cy.get('[data-cy=run-all-specs]').realHover().then(() => {
cy.get('[data-cy=tooltip-content]').should('contain.text', `Run ${specNumber} spec`)
})
})
}

describe('InlineSpecList', () => {
const mountInlineSpecList = ({ specFilter, experimentalRunAllSpecs }: {specFilter?: string, experimentalRunAllSpecs?: boolean} = {}) => cy.mountFragment(Specs_InlineSpecListFragmentDoc, {
onResult: (ctx) => {
Expand Down Expand Up @@ -207,18 +190,37 @@ describe('InlineSpecList', () => {
})

describe('Run all Specs', () => {
const hoverRunAllSpecs = (directory: string, specNumber: number) => {
let command = cy.contains('[data-cy=directory-item]', directory)

return command.realHover().then(() => {
cy.get('[data-cy=play-button]').should('exist')
cy.get(`[data-cy="run-all-specs-for-${directory}"]`).realHover().then(() => {
cy.get('[data-cy=tooltip-content]').should('contain.text', `Run ${specNumber} spec`)
})
})
}

beforeEach(() => {
cy.fixture('found-specs').then((foundSpecs) => specs = foundSpecs)
})

it('does not show feature unless experimentalRunAllSpecs is enabled', () => {
mountInlineSpecList({ experimentalRunAllSpecs: false })

cy.findByTestId('run-all-specs-for-all').should('not.exist')
cy.contains('[data-cy=directory-item]', 'src').realHover()
cy.findByTestId('run-all-specs-for-src').should('not.exist')
})

it('displays runAllSpecs when hovering over a spec-list directory row', () => {
mountInlineSpecList({ experimentalRunAllSpecs: true })
hoverRunAllSpecs('src', 4)
})

it('checks if functionality works after a search', () => {
mountInlineSpecList({ experimentalRunAllSpecs: true, specFilter: 'B' })
hoverRunAllSpecs('src', 1)
hoverRunAllSpecs('src/components', 1)
})
})
})
5 changes: 5 additions & 0 deletions packages/app/src/specs/InlineSpecList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
<InlineSpecListHeader
v-model:specFilterModel="specFilterModel"
:result-count="specs.length"
:is-run-all-specs-allowed="runAllSpecsStore.isRunAllSpecsAllowed"
@newSpec="showModal = true"
@run-all-specs="runAllSpecsStore.runAllSpecs"
/>
<InlineSpecListTree
:specs="specs"
Expand All @@ -31,6 +33,7 @@ import CreateSpecModal from './CreateSpecModal.vue'
import { fuzzySortSpecs, makeFuzzyFoundSpec, useCachedSpecs } from './spec-utils'
import type { FuzzyFoundSpec } from './tree/useCollapsibleTree'
import { useSpecFilter } from '../composables/useSpecFilter'
import { useRunAllSpecsStore } from '../store/run-all-specs-store'

gql`
fragment SpecNode_InlineSpecList on Spec {
Expand Down Expand Up @@ -80,4 +83,6 @@ const specs = computed<FuzzyFoundSpec[]>(() => {
return fuzzySortSpecs(specs, debouncedSpecFilterModel.value)
})

const runAllSpecsStore = useRunAllSpecsStore()
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Thoughts on just destructuring here to simplify the template expressions above?

const { isRunAllSpecsAllowed, runAllSpecs } = useRunAllSpecsStore()

Copy link
Contributor

Choose a reason for hiding this comment

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

Reactive get stale when destructured from the pinia store, which is why I've generally avoided doing it. There's a storeToRefs helper we can use if we want. But I ended up kind of liking that when we use reactive values from the store, it's clear where they are coming from, even if it's a bit verbose.

Docs for reference: https://pinia.vuejs.org/core-concepts/index.html#using-the-store

Could be swayed towards using storeToRefs if the rest of us like it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, didn't know that. Thanks for the info 👍


</script>
Loading