Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
3 changes: 3 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

// List of extensions which are recommended for Cypress contributors using VS Code:
"recommendations": [
// Name: Apollo GraphQL
// Description: Rich editor support for GraphQL client and server development that seamlessly integrates with the Apollo platform
"apollographql.vscode-apollo",
// Name: ESLint
// Description: Integrates ESLint JavaScript into VS Code.
"dbaeumer.vscode-eslint",
Expand Down
21 changes: 21 additions & 0 deletions packages/app/cypress/e2e/integration/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
describe('Index', () => {
beforeEach(() => {
cy.setupE2E('component-tests')
cy.initializeApp()
})

context('with no specs', () => {
beforeEach(() => {
cy.visitApp()
cy.withCtx((ctx, o) => {
ctx.actions.file.removeFileInProject('cypress/integration/integration-spec.js')
})
})

it('shows "Create your first spec"', () => {
// after removing the default scaffolded spec, we should be prompted to create a first spec
cy.visitApp()
cy.contains('Create your first spec')
})
})
})
2 changes: 1 addition & 1 deletion packages/app/src/pages/Index.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div v-if="query.data.value">
<SpecsList
v-if="query.data.value.currentProject?.specs"
v-if="query.data.value.currentProject?.specs?.edges.length"
:gql="query.data.value"
/>
<CreateSpecPage
Expand Down
135 changes: 86 additions & 49 deletions packages/app/src/specs/SpecsList.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import SpecsList from './SpecsList.vue'
import { Specs_SpecsListFragmentDoc, SpecNode_SpecsListFragment } from '../generated/graphql-test'
import { Specs_SpecsListFragmentDoc, SpecNode_SpecsListFragment, TestingTypeEnum } from '../generated/graphql-test'
import { defaultMessages } from '@cy/i18n'

const rowSelector = '[data-testid=specs-list-row]'
Expand All @@ -16,65 +16,102 @@ const hasSpecText = (_node: JQuery<HTMLElement>, spec: SpecNode_SpecsListFragmen
return $node
}

function mountWithTestingType (testingType: TestingTypeEnum) {
cy.mountFragment(Specs_SpecsListFragmentDoc, {
onResult: (ctx) => {
if (!ctx.currentProject) throw new Error('need current project')

ctx.currentProject.currentTestingType = testingType

return ctx
},
render: (gqlVal) => {
return <SpecsList gql={gqlVal} />
},
})
}

let specs: Array<SpecNode_SpecsListFragment> = []

describe('<SpecsList />', { keystrokeDelay: 0 }, () => {
beforeEach(() => {
cy.mountFragment(Specs_SpecsListFragmentDoc, {
onResult: (ctx) => {
specs = ctx.currentProject?.specs?.edges || []

return ctx
},
render: (gqlVal) => {
return <SpecsList gql={gqlVal} />
},
context('when testingType is unset', () => {
beforeEach(() => {
cy.mountFragment(Specs_SpecsListFragmentDoc, {
onResult: (ctx) => {
specs = ctx.currentProject?.specs?.edges || []

return ctx
},
render: (gqlVal) => {
return <SpecsList gql={gqlVal} />
},
})
})
})

it('renders specs', () => {
cy.get(rowSelector).first()
.should(($node) => hasSpecText($node, specs[0]))
it('renders specs', () => {
cy.get(rowSelector).first()
.should(($node) => hasSpecText($node, specs[0]))

cy.percySnapshot()
})
cy.percySnapshot()
})

it('filters the specs', () => {
cy.get(rowSelector).first()
// Establish a baseline for what the spec rendered is
.should(($node) => hasSpecText($node, specs[0]))
.should('be.visible')

// Cause an empty spec state
.get(inputSelector).type('garbage 🗑', { delay: 0 })
.get(rowSelector)
.should('not.exist')

it('filters the specs', () => {
cy.get(rowSelector).first()
// Establish a baseline for what the spec rendered is
.should(($node) => hasSpecText($node, specs[0]))
.should('be.visible')

// Cause an empty spec state
.get(inputSelector).type('garbage 🗑', { delay: 0 })
.get(rowSelector)
.should('not.exist')

// Clear the input, make sure that the right spec is showing up
.get(inputSelector)
.type('{selectall}{backspace}', { delay: 0 })

// Check the spec and its values
.get(rowSelector).first()
.should('be.visible')
.should(($node) => hasSpecText($node, specs[0]))
.get(inputSelector)
.type(fullFile(specs[0]), { delay: 0 })
.get(rowSelector).first()
.should('contain.text', specs[0].node.fileName)
.and('contain.text', specs[0].node.fileExtension)
.click()
// Clear the input, make sure that the right spec is showing up
.get(inputSelector)
.type('{selectall}{backspace}', { delay: 0 })

// Check the spec and its values
.get(rowSelector).first()
.should('be.visible')
.should(($node) => hasSpecText($node, specs[0]))
.get(inputSelector)
.type(fullFile(specs[0]), { delay: 0 })
.get(rowSelector).first()
.should('contain.text', specs[0].node.fileName)
.and('contain.text', specs[0].node.fileExtension)
.click()
})

it('changes to tree view', () => {
cy.get('[data-cy="file-tree-radio-option"]').click()

// close all directories
;['src', 'packages', 'frontend', '__test__', 'lib', 'tests'].forEach((dir) => {
cy.get('[data-cy="row-directory-depth-0"]').contains(dir).click()
})

// all directories closed; no specs should be showing.
cy.get('[data-cy="spec-item"]').should('not.exist')
})
})

it('changes to tree view', () => {
cy.get('[data-cy="file-tree-radio-option"]').click()
context('when testingType is e2e', () => {
beforeEach(() => {
mountWithTestingType('e2e')
})

// close all directories
;['src', 'packages', 'frontend', '__test__', 'lib', 'tests'].forEach((dir) => {
cy.get('[data-cy="row-directory-depth-0"]').contains(dir).click()
it('should display the e2e testing header', () => {
cy.get('[data-cy="specs-testing-type-header"]').should('have.text', 'E2E Specs')
})
})

// all directories closed; no specs should be showing.
cy.get('[data-cy="spec-item"]').should('not.exist')
context('when testingType is component', () => {
beforeEach(() => {
mountWithTestingType('component')
})

it('should display the component testing header', () => {
cy.get('[data-cy="specs-testing-type-header"]').should('have.text', 'Component Specs')
})
})
})
9 changes: 7 additions & 2 deletions packages/app/src/specs/SpecsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@

<div class="grid items-center divide-y-1 children:h-40px">
<div class="grid grid-cols-2 children:text-gray-800 children:font-medium">
<div class="flex justify-between items-center">
{{ t('specPage.componentSpecsHeader') }}
<div
class="flex justify-between items-center"
data-cy="specs-testing-type-header"
>
{{ props.gql.currentProject?.currentTestingType === 'component' ?
t('specPage.componentSpecsHeader') : t('specPage.e2eSpecsHeader') }}
</div>
<div class="flex justify-between items-center">
<div>{{ t('specPage.gitStatusHeader') }}</div>
Expand Down Expand Up @@ -133,6 +137,7 @@ fragment Specs_SpecsList on Query {
currentProject {
id
projectRoot
currentTestingType
specs: specs(first: 100) {
edges {
...SpecNode_SpecsList
Expand Down