Skip to content

Commit

Permalink
feat: Auto-focus and select file name for create new spec modal (cypr…
Browse files Browse the repository at this point in the history
…ess-io#22284)

* feat: Auto-focus and select file name for create new spec modal

* feat: Add comment for regex

* feat: Remove comma; add new line

* feat: Remove unnecessary function

* feat: Remove unnecessary logic

* feat: Reference prop value rather than input ref value

* feat: Add component test for unhappy path

Co-authored-by: Zachary Williams <ZachJW34@gmail.com>
  • Loading branch information
2 people authored and BeijiYang committed Jun 23, 2022
1 parent aa3017c commit 09005e2
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 1 deletion.
88 changes: 88 additions & 0 deletions packages/app/src/specs/CreateSpecModal.cy.tsx
Expand Up @@ -64,6 +64,94 @@ describe('<CreateSpecModal />', () => {
})
})

describe('Modal Text Input', () => {
it('focuses text input and selects file name by default', () => {
const show = ref(true)

cy.mount(() => (<div>
<CreateSpecModal
gql={{
currentProject: {
id: 'id',
currentTestingType: 'component',
configFile: 'cypress.config.js',
configFileAbsolutePath: '/path/to/cypress.config.js',
config: [{
field: 'e2e',
value: {
specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
},
}, {
field: 'component',
value: {
specPattern: '**/*.cy.{js,jsx,ts,tsx}',
},
}],
specs: [],
fileExtensionToUse: 'js',
defaultSpecFileName: 'cypress/e2e/ComponentName.cy.js',
},
}}
show={show.value}
onClose={() => show.value = false}
/>
</div>))

cy.focused().as('specNameInput')

// focused should yield the input element since it should be auto-focused
cy.get('@specNameInput').invoke('val').should('equal', 'cypress/e2e/ComponentName.cy.js')

// only the file name should be focused, so backspacing should erase the whole file name
cy.get('@specNameInput').type('{backspace}')

cy.get('@specNameInput').invoke('val').should('equal', 'cypress/e2e/.cy.js')
})

it('focuses text input but does not select if default file name does not match regex', () => {
const show = ref(true)

cy.mount(() => (<div>
<CreateSpecModal
gql={{
currentProject: {
id: 'id',
currentTestingType: 'component',
configFile: 'cypress.config.js',
configFileAbsolutePath: '/path/to/cypress.config.js',
config: [{
field: 'e2e',
value: {
specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
},
}, {
field: 'component',
value: {
specPattern: '**/*.cy.{js,jsx,ts,tsx}',
},
}],
specs: [],
fileExtensionToUse: 'js',
defaultSpecFileName: 'this/path/does/not/produce/regex/match-',
},
}}
show={show.value}
onClose={() => show.value = false}
/>
</div>))

cy.focused().as('specNameInput')

// focused should yield the input element since it should be auto-focused
cy.get('@specNameInput').invoke('val').should('equal', 'this/path/does/not/produce/regex/match-')

// nothing should be selected, so backspacing should only delete the last character in the file path
cy.get('@specNameInput').type('{backspace}')

cy.get('@specNameInput').invoke('val').should('equal', 'this/path/does/not/produce/regex/match')
})
})

describe('playground', () => {
it('can be opened and closed via the show prop', () => {
const show = ref(false)
Expand Down
29 changes: 28 additions & 1 deletion packages/app/src/specs/generators/EmptyGenerator.vue
Expand Up @@ -4,6 +4,7 @@
<div class="p-24px w-720px">
<Input
v-model="specFile"
:input-ref="inputRefFn"
:placeholder="t('createSpec.e2e.importEmptySpec.inputPlaceholder')"
:aria-label="t('createSpec.e2e.importEmptySpec.inputPlaceholder')"
:has-error="hasError"
Expand Down Expand Up @@ -123,7 +124,7 @@
</template>
<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import { ref, watch, computed, onMounted } from 'vue'
import { useI18n } from '@packages/frontend-shared/src/locales/i18n'
import Input from '@packages/frontend-shared/src/components/Input.vue'
import Button from '@packages/frontend-shared/src/components/Button.vue'
Expand Down Expand Up @@ -180,6 +181,10 @@ const emits = defineEmits<{
const { title } = useVModels(props, emits)
const inputRef = ref<HTMLInputElement>()
const inputRefFn = () => inputRef
const specFile = ref(props.specFileName)
const matches = useMutation(EmptyGenerator_MatchSpecFileDocument)
Expand All @@ -190,6 +195,28 @@ const hasError = computed(() => !isValidSpecFile.value && !!specFile.value)
const result = ref<GeneratorSuccessFileFragment | null>(null)
onMounted(() => {
if (!inputRef?.value) {
return
}
// Focus text input and try to pre-select file name
inputRef.value.focus()
// This regex matches a group of word characters, spaces, and '-' characters before a '.' character.
// For example 'path/to/spec/spec-name.cy.tsx' ---> 'spec-name'
const fileNameRegex = /[ \w-]+(?=\.)/
const inputValue = props.specFileName
const match = inputValue.match(fileNameRegex)
if (match) {
const startSelectionIndex = match.index || 0
const endSelectionIndex = startSelectionIndex + match[0].length
inputRef.value.setSelectionRange(startSelectionIndex, endSelectionIndex)
}
})
whenever(result, () => {
title.value = t('createSpec.successPage.header')
emits('updateTitle', t('createSpec.successPage.header'))
Expand Down

0 comments on commit 09005e2

Please sign in to comment.