Skip to content

Commit

Permalink
chore: wip add barebones studio modals
Browse files Browse the repository at this point in the history
  • Loading branch information
astone123 committed Aug 19, 2022
1 parent b0299c3 commit 933932b
Show file tree
Hide file tree
Showing 17 changed files with 460 additions and 28 deletions.
20 changes: 20 additions & 0 deletions packages/app/src/runner/SpecRunnerOpenMode.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
<template>
<StudioInitModal

This comment has been minimized.

Copy link
@lmiller1990

lmiller1990 Aug 22, 2022

Contributor

In general looks good, I have no idea where the styles are coming from for the modals, but it's probably irrelevant since I'm almost 100% sure design is going to say "Let's update the styling for the modals".

Nice job hooking all this up 💯

This comment has been minimized.

Copy link
@astone123

astone123 Aug 22, 2022

Author Contributor

The styles are coming from the StandardModal component that I use inside of each of these components.

The body of the modals are pretty much un-styled at this point... I figured it might be easier just to wait until our meeting with design to figure out what we want to do before I spend time styling everything

:open="studioStore.initModalIsOpen"
@close="studioStore.closeInitModal"
@start="eventManager.emit('studio:start', undefined)"
/>
<StudioInstructionsModal
:open="studioStore.instructionModalIsOpen"
@close="studioStore.closeInstructionModal"
/>
<StudioSaveModal
:open="studioStore.saveModalIsOpen"
:studio-store="studioStore"
@close="studioStore.closeSaveModal"
/>
<AdjustRunnerStyleDuringScreenshot
id="main-pane"
class="flex border-gray-900"
Expand Down Expand Up @@ -120,6 +134,10 @@ import { useEventManager } from './useEventManager'
import AutomationDisconnected from './automation/AutomationDisconnected.vue'
import AutomationMissing from './automation/AutomationMissing.vue'
import { runnerConstants } from './runner-constants'
import StudioInitModal from './studio/StudioInitModal.vue'
import StudioInstructionsModal from './studio/StudioInstructionsModal.vue'
import StudioSaveModal from './studio/StudioSaveModal.vue'
import { useStudioStore } from '../store/studio-store'
const {
preferredMinimumPanelWidth,
Expand Down Expand Up @@ -191,6 +209,8 @@ const {
cleanupRunner,
} = useEventManager()
const studioStore = useStudioStore()
const specsListWidthPreferences = computed(() => {
return props.gql.localSettings.preferences.specListWidth ?? runnerUiStore.specListWidth
})
Expand Down
6 changes: 1 addition & 5 deletions packages/app/src/runner/StudioControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

<button
:disabled="studioStore.isLoading"
@click="handleShowCommands"
@click="studioStore.openInstructionModal"
>
Available Commands
</button>
Expand Down Expand Up @@ -64,10 +64,6 @@ import { useStudioStore } from '../store/studio-store'
const studioStore = useStudioStore()
function handleShowCommands () {
// TODO: Show modal with available commands'
}
const eventManager = getEventManager()
function handleClose () {
Expand Down
6 changes: 3 additions & 3 deletions packages/app/src/runner/reporter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getMobxRunnerStore, MobxRunnerStore } from '../store'
import { getReporterElement } from './utils'
import { getEventManager, getRunnerConfigFromWindow } from '.'
import { getEventManager } from '.'
import type { EventManager } from './event-manager'
import { useRunnerUiStore } from '../store/runner-ui-store'

Expand Down Expand Up @@ -39,7 +39,7 @@ function renderReporter (
) {
const runnerUiStore = useRunnerUiStore()

const config = getRunnerConfigFromWindow()
// const config = getRunnerConfigFromWindow()

const reporter = window.UnifiedRunner.React.createElement(window.UnifiedRunner.Reporter, {
runMode: 'single' as const,
Expand All @@ -49,7 +49,7 @@ function renderReporter (
error: null, // errorMessages.reporterError(props.state.scriptError, props.state.spec.relative),
resetStatsOnSpecChange: true,
// @ts-ignore - https://github.com/cypress-io/cypress/issues/23338
experimentalStudioEnabled: config.experimentalStudio,
experimentalStudioEnabled: true,
runnerStore: store,
})

Expand Down
24 changes: 24 additions & 0 deletions packages/app/src/runner/studio/StudioInitModal.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import StudioInitModal from './StudioInitModal.vue'

describe('StudioInitModal', () => {
it('renders hidden by default', () => {
cy.mount(<StudioInitModal open={false} />)
cy.findByTestId('studio-init-modal').should('not.exist')
})

it('renders open with props', () => {
cy.mount(<StudioInitModal open />)
cy.findByTestId('studio-init-modal').should('be.visible')
cy.percySnapshot()
})

it('calls start when user clicks the button', () => {
const start = cy.stub()

cy.mount(<StudioInitModal onStart={start} open />)

cy.findByText('Get Started').click().then(() => {
expect(start).to.be.calledOnce
})
})
})
52 changes: 52 additions & 0 deletions packages/app/src/runner/studio/StudioInitModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<template>
<StandardModal
:model-value="props.open"
help-link="https://on.cypress.io/guides/references/cypress-studio"
:help-text="t('links.learnMoreButton')"
variant="bare"
data-cy="studio-init-modal"
@update:model-value="emit('close')"
>
<template #title>
<i className="fas fa-magic icon" />
{{ t('runner.studio.studio') }}
<span className="beta">{{ t('versions.beta') }}</span>
</template>

<div className="gif">
<img
src="../../static/studio.gif"
alt="Studio"
>
</div>

<div className="content center">
<div className="text">
{{ t('runner.studio.studioDescription') }}
</div>
<button
className="btn-main"
@click="emit('start')"
>
{{ t('runner.studio.getStartedButton') }}
</button>
</div>
</StandardModal>
</template>

<script lang="ts" setup>
import { useI18n } from '@cy/i18n'
import StandardModal from '@packages/frontend-shared/src/components/StandardModal.vue'
const { t } = useI18n()
const props = defineProps<{
open: boolean
}>()
const emit = defineEmits<{
(e: 'start'): void
(e: 'close'): void
}>()
</script>
14 changes: 14 additions & 0 deletions packages/app/src/runner/studio/StudioInstructionsModal.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import StudioInstructionsModal from './StudioInstructionsModal.vue'

describe('StudioInstructionsModal', () => {
it('renders hidden by default', () => {
cy.mount(<StudioInstructionsModal open={false} />)
cy.findByTestId('studio-instructions-modal').should('not.exist')
})

it('renders open with props', () => {
cy.mount(<StudioInstructionsModal open />)
cy.findByTestId('studio-instructions-modal').should('be.visible')
cy.percySnapshot()
})
})
70 changes: 70 additions & 0 deletions packages/app/src/runner/studio/StudioInstructionsModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<template>
<StandardModal
:model-value="props.open"
help-link="https://on.cypress.io/guides/references/cypress-studio"
:help-text="t('links.learnMoreButton')"
variant="bare"
data-cy="studio-instructions-modal"
@update:model-value="emit('close')"
>
<template #title>
<i className="fas fa-magic icon" />
{{ t('runner.studio.studio') }}
<span className="beta">{{ t('versions.beta') }}</span>
</template>

<div className="content center">
<div className="text">
{{ t('runner.studio.studioDetailedDescription') }}
</div>

<div className="text center-box">
<ul>
<li>
<pre>.check()</pre>
</li>
<li>
<pre>.click()</pre>
</li>
<li>
<pre>.select()</pre>
</li>
<li>
<pre>.type()</pre>
</li>
<li>
<pre>.uncheck()</pre>
</li>
</ul>
</div>
<div className="text">
{{ t('runner.studio.betaMessage') }}
<i18n-t
scope="global"
keypath="runner.studio.feedbackPrompt"
>
<a
href="https://on.cypress.io/studio-beta"
target="_blank"
>{{ t('runner.studio.feedbackLink') }}</a>
</i18n-t>
</div>
</div>
</StandardModal>
</template>

<script lang="ts" setup>
import { useI18n } from '@cy/i18n'
import StandardModal from '@packages/frontend-shared/src/components/StandardModal.vue'
const { t } = useI18n()
const props = defineProps<{
open: boolean
}>()
const emit = defineEmits<{
(e: 'close'): void
}>()
</script>
25 changes: 25 additions & 0 deletions packages/app/src/runner/studio/StudioSaveModal.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import StudioSaveModal from './StudioSaveModal.vue'

describe('StudioSaveModal', () => {
it('renders hidden by default', () => {
cy.mount(<StudioSaveModal studioStore={{}} open={false} />)

This comment has been minimized.

Copy link
@lmiller1990

lmiller1990 Aug 23, 2022

Contributor

This comment has been minimized.

Copy link
@lmiller1990

lmiller1990 Aug 23, 2022

Contributor

This works because we create a new set of stores in support inside of beforeEach: https://github.com/cypress-io/cypress/blob/develop/packages/app/cypress/component/support/index.ts#L34-L36

So you can just grab the store inside of StudioSaveModal with import { useStudioStore } from '../studio-store' to access it, and you don't need to pass a prop anymore.

cy.findByTestId('studio-save-modal').should('not.exist')
})

it('renders open with props', () => {
cy.mount(<StudioSaveModal studioStore={{}} open />)
cy.findByTestId('studio-save-modal').should('be.visible')
cy.percySnapshot()
})

it('submits the form', () => {
const save = cy.stub()

cy.mount(<StudioSaveModal studioStore={{ save }} open />)
cy.get('#testName').focus().type('my test')

cy.findByText('Save Test').click().then(() => {
expect(save).to.be.calledOnceWith('my test')
})
})
})
67 changes: 67 additions & 0 deletions packages/app/src/runner/studio/StudioSaveModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<template>
<StandardModal
:model-value="props.open"
variant="bare"
data-cy="studio-save-modal"
@update:model-value="emit('close')"
>
<template #title>
<i className="fas fa-magic icon" />
{{ t('runner.studio.saveNewTest') }}
</template>

<div className="content">
<form
@submit="submit"
>
<div className="text">
<label
className="text-strong"
htmlFor="testName"
>{{ t('runner.studio.testName') }}</label>
<Input
id="testName"
v-model="testName"
type="text"
:required="true"
/>
</div>
<div className="center">
<input
type="submit"
:value="t('runner.studio.saveTestButton')"
class="btn btn-block"
:disabled="!testName"
>
</div>
</form>
</div>
</StandardModal>
</template>

<script lang="ts" setup>
import { useI18n } from '@cy/i18n'
import StandardModal from '@packages/frontend-shared/src/components/StandardModal.vue'
import { ref } from 'vue'
import Input from '../../../../frontend-shared/src/components/Input.vue'
const { t } = useI18n()
const testName = ref('')
const props = defineProps<{
open: boolean
studioStore: any
}>()
const emit = defineEmits<{
(e: 'close'): void
}>()
function submit (e) {
e.preventDefault()
props.studioStore.save(testName.value)
}
</script>
Binary file added packages/app/src/static/studio.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 933932b

Please sign in to comment.