-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
chore: wire up Cypress Studio #23413
Changes from all commits
66387f0
1131c73
0404134
a61e667
0e9863f
ab31dcc
87fb624
ba24e88
42043a1
09d2786
c3506a6
db23066
a0438da
ca309ea
5b07449
770e033
a7b714e
fc66414
55e3a31
08d023f
62a4f51
be9a801
36cc510
dd435fa
568a7f6
40327d8
b0299c3
219fc41
fd0ee2b
fa5c9eb
4fdb73f
9a4e5fd
65eeae3
5f3bd1f
82b43c4
4af852a
9c24014
c7d66f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -148,7 +148,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout: | |
}) | ||
|
||
it('shows a compilation error with a malformed spec', { viewportHeight: 596, viewportWidth: 1000 }, () => { | ||
const expectedAutHeight = 500 // based on explicitly setting viewport in this test to 596 | ||
const expectedAutHeight = 456 // based on explicitly setting viewport in this test to 596 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change |
||
|
||
cy.visitApp() | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -243,7 +243,7 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100 | |
cy.visitApp() | ||
cy.contains('dom-content.spec').click() | ||
|
||
cy.contains('http://localhost:4455/cypress/e2e/dom-content.html').should('be.visible') | ||
cy.findByTestId('aut-url-input').invoke('val').should('contain', 'http://localhost:4455/cypress/e2e/dom-content.html') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bit more specific about what's going on, just a general improvement. |
||
cy.findByLabelText('Stats').should('not.exist') | ||
cy.findByTestId('specs-list-panel').should('not.be.visible') | ||
cy.findByTestId('reporter-panel').should('not.be.visible') | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,18 +19,20 @@ describe('Reporter Header', () => { | |
it('filters the list of specs when searching for specs', () => { | ||
cy.get('body').type('f') | ||
|
||
cy.get('input').type('dom', { force: true }) | ||
cy.findByTestId('specs-list-panel').within(() => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again more specific, we've got another |
||
cy.get('input').as('searchInput').type('dom', { force: true }) | ||
}) | ||
|
||
cy.get('[data-cy="spec-file-item"]').should('have.length', 3) | ||
.should('contain', 'dom-content.spec') | ||
|
||
cy.get('input').clear() | ||
cy.get('@searchInput').clear() | ||
|
||
cy.get('[data-cy="spec-file-item"]').should('have.length', 3) | ||
|
||
cy.get('input').type('asdf', { force: true }) | ||
cy.get('@searchInput').type('asdf', { force: true }) | ||
|
||
cy.get('[data-cy="spec-file-item"]').should('have.length', 0) | ||
cy.findByTestId('spec-file-item').should('have.length', 0) | ||
}) | ||
}) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,14 +23,16 @@ | |
> | ||
<i-cy-crosshairs_x16 :class="[selectorPlaygroundStore.show ? 'icon-dark-indigo-500' : 'icon-dark-gray-500']" /> | ||
</Button> | ||
<a | ||
<input | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here is the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did we need to change this to an input? I think I missed the reason There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is here: #23413 (comment) I think it was an input in Cypress 9, which I always didn't really love - I'm hoping when we clean up the UX for this, this will only render an input when it is actually editable in studio mode, and will render a plain old link the rest of the time. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess I had a ton of problems with tailwind doing weird things - for some reason the sizing changes between |
||
target="_blank" | ||
:href="autStore.url" | ||
class="mr-12px leading-normal max-w-100% text-indigo-500 self-center hocus-link-default truncate" | ||
:value="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" | ||
@input="setStudioUrl" | ||
@click="openInNewTab" | ||
> | ||
{{ autStore.url }} | ||
</a> | ||
</div> | ||
|
||
<div | ||
v-else | ||
class="flex-grow" | ||
|
@@ -129,6 +131,8 @@ | |
:event-manager="eventManager" | ||
/> | ||
|
||
<StudioControls v-if="studioStore.isActive" /> | ||
|
||
<Alert | ||
v-model="showAlert" | ||
status="success" | ||
|
@@ -160,11 +164,13 @@ 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 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' | ||
import { allBrowsersIcons } from '@packages/frontend-shared/src/assets/browserLogos' | ||
import BookIcon from '~icons/cy/book_x16' | ||
import { useStudioStore } from '../store/studio-store' | ||
|
||
gql` | ||
fragment SpecRunnerHeader on CurrentProject { | ||
|
@@ -189,6 +195,8 @@ const specStore = useSpecStore() | |
|
||
const route = useRoute() | ||
|
||
const studioStore = useStudioStore() | ||
|
||
const props = defineProps<{ | ||
gql: SpecRunnerHeaderFragment | ||
eventManager: EventManager | ||
|
@@ -209,6 +217,14 @@ const displayScale = computed(() => { | |
return autStore.scale < 1 ? `${Math.round(autStore.scale * 100) }%` : 0 | ||
}) | ||
|
||
const autUrl = computed(() => { | ||
if (studioStore.isActive && studioStore.url) { | ||
return studioStore.url | ||
} | ||
|
||
return autStore.url | ||
}) | ||
|
||
const selectorPlaygroundStore = useSelectorPlaygroundStore() | ||
|
||
const togglePlayground = () => _togglePlayground(autIframe) | ||
|
@@ -220,4 +236,17 @@ const activeSpecPath = specStore.activeSpec?.absolute | |
|
||
const isDisabled = computed(() => autStore.isRunning || autStore.isLoading) | ||
|
||
function setStudioUrl (event: Event) { | ||
const url = (event.currentTarget as HTMLInputElement).value | ||
|
||
studioStore.setUrl(url) | ||
} | ||
|
||
function openInNewTab () { | ||
if (!autStore.url || studioStore.isActive) { | ||
return | ||
} | ||
|
||
window.open(autStore.url, '_blank')?.focus() | ||
} | ||
</script> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
<template> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not final, just some placeholder until #23337 lands |
||
<div v-if="!studioStore.url && studioStore.isActive"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are missing tests for this component. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, thanks for calling this out -- DM'd you, gonna merge this to the feature branch and add a bunch of tests here: #23461 |
||
<b>Please enter a valid URL to visit.</b> | ||
</div> | ||
|
||
<button | ||
v-if="studioStore.url && studioStore.isActive" | ||
@click="visitUrl" | ||
> | ||
Go ➜ | ||
</button> | ||
|
||
<div> | ||
<b>Studio Beta</b> | ||
</div> | ||
|
||
<button | ||
:disabled="studioStore.isLoading" | ||
@click="handleShowCommands" | ||
> | ||
Available Commands | ||
</button> | ||
|
||
<a | ||
href="https://on.cypress.io/studio-beta" | ||
target="_blank" | ||
>Give feedback</a> | ||
|
||
<div> | ||
<!-- these are the buttons that do the things --> | ||
<button | ||
:disabled="studioStore.isLoading" | ||
@click="handleClose" | ||
> | ||
Close Studio | ||
</button> | ||
|
||
<button | ||
:disabled="studioStore.isLoading" | ||
@click="handleRestart" | ||
> | ||
Restart | ||
</button> | ||
|
||
<button | ||
:disabled="studioStore.isLoading || studioStore.isEmpty" | ||
@click="handleCopyCommands" | ||
> | ||
Copy Commands | ||
</button> | ||
|
||
<button | ||
:disabled="studioStore.isLoading || studioStore.isEmpty" | ||
@click="handleSaveCommands" | ||
> | ||
Save Commands | ||
</button> | ||
|
||
<input | ||
v-if="studioStore.saveModalIsOpen" | ||
v-model="testName" | ||
style="border: 1px solid black" | ||
> | ||
<button | ||
:disabled="!testName" | ||
@click="handleSave" | ||
> | ||
Save Test | ||
</button> | ||
</div> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { ref } from 'vue' | ||
import { getEventManager } from '.' | ||
import { useStudioStore } from '../store/studio-store' | ||
|
||
const studioStore = useStudioStore() | ||
|
||
function handleShowCommands () { | ||
// TODO: Show modal with available commands' | ||
} | ||
|
||
function handleSave () { | ||
studioStore.save(testName.value) | ||
} | ||
|
||
const eventManager = getEventManager() | ||
|
||
const testName = ref('') | ||
|
||
function handleClose () { | ||
eventManager.emit('studio:cancel', undefined) | ||
} | ||
|
||
function handleRestart () { | ||
studioStore.reset() | ||
eventManager.emit('restart', undefined) | ||
} | ||
|
||
function handleCopyCommands () { | ||
eventManager.emit('studio:copy:to:clipboard', () => { | ||
// optional callback - do we need this? | ||
}) | ||
} | ||
|
||
function handleSaveCommands () { | ||
studioStore.startSave() | ||
} | ||
|
||
function visitUrl () { | ||
if (!studioStore.url) { | ||
throw Error('Cannot visit blank url') | ||
} | ||
|
||
studioStore.visitUrl(studioStore.url) | ||
} | ||
</script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the
<a>
for the AUT URL to be an<input
> so we can type into it to navigate to a URL for Cypress Studio, and for some reason the wrapping break points forflex-wrap
is slightly different. I have no idea why and was quite stuck on this, but for all intensive purposes the UI is the same, except things wrap in the AUT header slightly earlier if you have your Cypress window really small.We can probably revisit this in the final pass if needed, but I don't think it makes any difference.