Skip to content

Commit

Permalink
chore: Add Studio UI to Cypress 10 (#23537)
Browse files Browse the repository at this point in the history
* wip

* wip

* wip - spike

* more wip [skip ci]

* update style

* fix ts

* move types around

* extract types

* lint

* fixing tests

* fix component test

* skip some tests

* do not error on experimentalStudio flag

* add studio controls placeholder

* fixing tests

* revert

* revert changes

* rename store

* rename method

* remove comment

* refactor

* correctly feature flag studio

* chore: wip add barebones studio modals

* simplify code

* simplify code

* lift check into useEventManager

* correctly hide create studio prompt based on flag;

* remove superfulous css

* chore: style studio toolbar

* chore: misc feedback

* chore: remove studio store prop

* chore: studio URL prompt and other changes

* update component

* chore: UI styling and remove studio init modal

* chore: revert unnecessary changes

* chore: fix types

* chore: fix some tests, minor refactor (#23545)

* fix test

* fix test

* add noHelp link to StandardModal

Co-authored-by: Lachlan Miller <lachlan.miller.1990@outlook.com>
  • Loading branch information
astone123 and lmiller1990 authored Aug 25, 2022
1 parent e90cca7 commit 849409c
Show file tree
Hide file tree
Showing 26 changed files with 596 additions and 181 deletions.
2 changes: 1 addition & 1 deletion packages/app/src/navigation/KeyboardBindingsModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
:title="t('sidebar.keyboardShortcuts.title')"
:model-value="show"
data-cy="keyboard-modal"
help-link=""
:no-help="true"
@update:model-value="emits('close')"
>
<ul class="m-24px w-384px">
Expand Down
32 changes: 28 additions & 4 deletions packages/app/src/runner/SpecRunnerHeaderOpenMode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,22 @@
<i-cy-crosshairs_x16 :class="[selectorPlaygroundStore.show ? 'icon-dark-indigo-500' : 'icon-dark-gray-500']" />
</Button>
<input
ref="autUrlInputRef"
target="_blank"
:value="autUrl"
:value="studioStore.needsUrl ? urlInProgress : autUrl"
data-cy="aut-url-input"
class="mr-12px leading-normal max-w-100% text-indigo-500 self-center hocus-link-default truncate flex flex-grow"
class="flex flex-grow mr-12px leading-normal max-w-100% text-indigo-500 z-51 self-center hocus-link-default truncate"
@input="setStudioUrl"
@click="openInNewTab"
@keyup.enter="visitUrl"
>
<StudioUrlPrompt
v-if="studioStore.needsUrl"
:aut-url-input-ref="autUrlInputRef"
:url-in-progress="urlInProgress"
@submit="visitUrl"
@cancel="() => eventManager.emit('studio:cancel', undefined)"
/>
</div>

<div
Expand Down Expand Up @@ -164,7 +173,8 @@ import SelectorPlayground from './selector-playground/SelectorPlayground.vue'
import ExternalLink from '@packages/frontend-shared/src/gql-components/ExternalLink.vue'
import Alert from '@packages/frontend-shared/src/components/Alert.vue'
import Button from '@packages/frontend-shared/src/components/Button.vue'
import StudioControls from './StudioControls.vue'
import StudioControls from './studio/StudioControls.vue'
import StudioUrlPrompt from './studio/StudioUrlPrompt.vue'
import VerticalBrowserListItems from '@packages/frontend-shared/src/gql-components/topnav/VerticalBrowserListItems.vue'
import InlineCodeFragment from '@packages/frontend-shared/src/components/InlineCodeFragment.vue'
import SpecRunnerDropdown from './SpecRunnerDropdown.vue'
Expand Down Expand Up @@ -197,6 +207,10 @@ const route = useRoute()
const studioStore = useStudioStore()
const urlInProgress = ref('')
const autUrlInputRef = ref<HTMLInputElement>()
const props = defineProps<{
gql: SpecRunnerHeaderFragment
eventManager: EventManager
Expand Down Expand Up @@ -239,7 +253,17 @@ const isDisabled = computed(() => autStore.isRunning || autStore.isLoading)
function setStudioUrl (event: Event) {
const url = (event.currentTarget as HTMLInputElement).value
studioStore.setUrl(url)
urlInProgress.value = url
}
function visitUrl () {
studioStore.setUrl(urlInProgress.value)
if (!studioStore.url) {
throw Error('Cannot visit blank url')
}
studioStore.visitUrl(studioStore.url)
}
function openInNewTab () {
Expand Down
13 changes: 13 additions & 0 deletions packages/app/src/runner/SpecRunnerOpenMode.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
<template>
<StudioInstructionsModal
:open="studioStore.instructionModalIsOpen"
@close="studioStore.closeInstructionModal"
/>
<StudioSaveModal
:open="studioStore.saveModalIsOpen"
@close="studioStore.closeSaveModal"
/>
<AdjustRunnerStyleDuringScreenshot
id="main-pane"
class="flex border-gray-900"
Expand Down Expand Up @@ -120,6 +128,9 @@ import { useEventManager } from './useEventManager'
import AutomationDisconnected from './automation/AutomationDisconnected.vue'
import AutomationMissing from './automation/AutomationMissing.vue'
import { runnerConstants } from './runner-constants'
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 +202,8 @@ const {
cleanupRunner,
} = useEventManager()
const studioStore = useStudioStore()
const specsListWidthPreferences = computed(() => {
return props.gql.localSettings.preferences.specListWidth ?? runnerUiStore.specListWidth
})
Expand Down
118 changes: 0 additions & 118 deletions packages/app/src/runner/StudioControls.vue

This file was deleted.

9 changes: 2 additions & 7 deletions packages/app/src/runner/event-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,12 +280,8 @@ export class EventManager {
})

const studioInit = () => {
this.ws.emit('studio:init', (showedStudioModal) => {
if (!showedStudioModal) {
this.studioStore.showInitModal()
} else {
rerun()
}
this.ws.emit('studio:init', () => {
rerun()
})
}

Expand Down Expand Up @@ -319,7 +315,6 @@ export class EventManager {
})

this.localBus.on('studio:start', () => {
this.studioStore.closeInitModal()
rerun()
})

Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/runner/reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ function renderReporter (
isSpecsListOpen: runnerUiStore.isSpecsListOpen,
error: null,
resetStatsOnSpecChange: true,
// @ts-ignore - https://github.com/cypress-io/cypress/issues/23338
studioEnabled: config.experimentalStudio,
// Studio can only be enabled for e2e testing
studioEnabled: window.__CYPRESS_TESTING_TYPE__ === 'e2e' && config.experimentalStudio,
runnerStore: store,
})

Expand Down
129 changes: 129 additions & 0 deletions packages/app/src/runner/studio/StudioControls.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<template>
<div class="border-y flex border-gray-50 w-full justify-between">
<div class="flex">
<div class="flex pr-5 pl-5 items-center">
<span
v-if="studioStore.url && studioStore.isActive && !studioStore.isFailed"
class="mr-2"
><i-cy-action-record_x16 class="animate-pulse icon-dark-red-500 icon-light-red-500" /></span>
<span
v-else
class="px-2"
><i-cy-object-magic-wand-dark-mode_x16 class="fill-purple-300 stroke-purple-300" /></span>
<div class="font-semibold text-base text-gray-800">
<span>{{ t('runner.studio.studio').toUpperCase() }}</span>
<span class="ml-1"> {{ t('versions.beta').toUpperCase() }}</span>
</div>
</div>

<div class="flex items-center">
<a
class="cursor-pointer font-medium text-base text-indigo-500 hocus-link hover:underline"
@click="studioStore.openInstructionModal"
>
{{ t('runner.studio.availableCommands') }}
</a>
</div>
</div>

<div class="flex">
<div class="border rounded-md flex border-gray-100 m-1">
<Tooltip
placement="top"
>
<button
:class="`border-r ${controlsClassName}`"
:disabled="studioStore.isLoading"
@click="handleClose"
>
<i-cy-delete_x16 />
</button>
<template #popper>
{{ t('runner.studio.closeStudio') }}
</template>
</Tooltip>

<Tooltip
placement="top"
>
<button
:class="`border-r ${controlsClassName}`"
:disabled="studioStore.isLoading"
@click="handleRestart"
>
<i-cy-action-restart_x16 />
</button>
<template #popper>
{{ t('runner.studio.restartStudio') }}
</template>
</Tooltip>

<Tooltip
placement="top"
>
<button
:class="controlsClassName"
:disabled="studioStore.isLoading || studioStore.isEmpty"
@click="handleCopyCommands"
@mouseleave="() => commandsCopied = false"
>
<span
v-if="commandsCopied"
><i-cy-checkmark_x16 class="icon-dark-green-400 icon-light-green-400" /></span>
<span v-else> <i-cy-general-clipboard_x16 /></span>
</button>
<template #popper>
{{ t(commandsCopied ? 'runner.studio.commandsCopied' : 'runner.studio.copyCommands') }}
</template>
</Tooltip>
</div>

<div class="flex items-center">
<button
class="rounded-md bg-indigo-500 mx-3 text-white py-2 px-3 hover:bg-indigo-400 disabled:opacity-50 disabled:pointer-events-none"
:disabled="studioStore.isLoading || studioStore.isEmpty || studioStore.isFailed"
@click="handleSaveCommands"
>
{{ t('runner.studio.saveTestButton') }}
</button>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { useI18n } from '@cy/i18n'
import { getEventManager } from '../'
import { useStudioStore } from '../../store/studio-store'
import Tooltip from '@packages/frontend-shared/src/components/Tooltip.vue'
const controlsClassName = 'border-gray-100 py-2 px-3 disabled:stroke-gray-400 disabled:pointer-events-none disabled:opacity-50'
const { t } = useI18n()
const studioStore = useStudioStore()
const eventManager = getEventManager()
const commandsCopied = ref(false)
function handleClose () {
eventManager.emit('studio:cancel', undefined)
}
function handleRestart () {
studioStore.reset()
eventManager.emit('restart', undefined)
}
function handleCopyCommands () {
eventManager.emit('studio:copy:to:clipboard', () => {
commandsCopied.value = true
})
}
function handleSaveCommands () {
studioStore.startSave()
}
</script>
Loading

0 comments on commit 849409c

Please sign in to comment.