Skip to content

Commit 969f01a

Browse files
Merge branch 'develop' into checkout-improvements-ci
2 parents bc21d58 + b533189 commit 969f01a

File tree

12 files changed

+1539
-1501
lines changed

12 files changed

+1539
-1501
lines changed

packages/app/cypress/e2e/studio/helper.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ export function launchStudio ({ specName = 'spec.cy.js', createNewTestFromSuite
3434
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
3535
cy.get('[data-cy="runnable-popover-new-test"]').click()
3636
} else {
37-
cy.get('@runnable-wrapper').realHover().findByTestId('create-new-test-from-suite').click()
37+
cy.get('@runnable-wrapper').realHover()
38+
cy.findByTestId('create-new-test-from-suite').click()
3839
}
3940

4041
cy.findByTestId('studio-panel').should('be.visible')
@@ -54,6 +55,31 @@ export function launchStudio ({ specName = 'spec.cy.js', createNewTestFromSuite
5455
}
5556
}
5657

58+
export function inputNewTestName (name: string = 'new-test') {
59+
cy.findByTestId('new-test-button').click()
60+
cy.findByTestId('test-name-input').type(name)
61+
cy.findByTestId('create-test-button').click()
62+
63+
// verify recording is enabled to ensure the panel is fully ready
64+
cy.findByTestId('record-button-recording').should('have.text', 'Recording...')
65+
66+
cy.get('.studio-single-test-container').should('be.visible')
67+
}
68+
69+
export function incrementCounter (initialCount: number) {
70+
cy.getAutIframe().within(() => {
71+
cy.get('p').contains(`Count is ${initialCount}`)
72+
73+
// (1) First Studio action - get
74+
cy.get('#increment')
75+
76+
// (2) Second Studio action - click
77+
.realClick().then(() => {
78+
cy.get('p').contains(`Count is ${initialCount + 1}`)
79+
})
80+
})
81+
}
82+
5783
export function assertClosingPanelWithoutChanges () {
5884
// Cypress re-runs after you cancel Studio.
5985
// Original spec should pass
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
import { launchStudio } from './helper'
2+
3+
describe('Cypress Studio - Assertions and Right-Click Menu', () => {
4+
it('updates an existing test with assertions', () => {
5+
launchStudio()
6+
7+
cy.waitForSpecToFinish()
8+
9+
cy.getAutIframe().within(() => {
10+
cy.get('#increment').rightclick().then(() => {
11+
cy.get('.__cypress-studio-assertions-menu').shadow().contains('be enabled').realClick()
12+
})
13+
})
14+
15+
cy.get('.cm-line').should('contain.text', `cy.get('#increment').should('be.enabled');`)
16+
17+
cy.getAutIframe().within(() => {
18+
cy.get('#increment').rightclick().then(() => {
19+
cy.get('.__cypress-studio-assertions-menu').shadow().contains('be visible').realClick()
20+
})
21+
})
22+
23+
cy.get('.cm-line').should('contain.text', `cy.get('#increment').should('be.visible');`)
24+
25+
cy.getAutIframe().within(() => {
26+
cy.get('#increment').rightclick().then(() => {
27+
cy.get('.__cypress-studio-assertions-menu').shadow().contains('have text').realHover()
28+
cy.get('.__cypress-studio-assertions-menu').shadow().contains('Increment').realClick()
29+
})
30+
})
31+
32+
cy.get('.cm-line').should('contain.text', `cy.get('#increment').should('have.text', 'Increment');`)
33+
34+
cy.getAutIframe().within(() => {
35+
cy.get('#increment').rightclick().then(() => {
36+
cy.get('.__cypress-studio-assertions-menu').shadow().contains('have id').realHover()
37+
cy.get('.__cypress-studio-assertions-menu').shadow().contains('increment').realClick()
38+
})
39+
})
40+
41+
cy.get('.cm-line').should('contain.text', `cy.get('#increment').should('have.id', 'increment');`)
42+
43+
cy.getAutIframe().within(() => {
44+
cy.get('#increment').rightclick().then(() => {
45+
cy.get('.__cypress-studio-assertions-menu').shadow().contains('have attr').realHover()
46+
cy.get('.__cypress-studio-assertions-menu').shadow().contains('onclick').realClick()
47+
})
48+
})
49+
50+
cy.get('.cm-line').should('contain.text', `cy.get('#increment').should('have.attr', 'onclick', 'increment()');`)
51+
52+
cy.get('[data-cy="studio-save-button"]').click()
53+
54+
cy.withCtx(async (ctx) => {
55+
const spec = await ctx.actions.file.readFileInProject('cypress/e2e/spec.cy.js')
56+
57+
expect(spec.trim().replace(/\r/g, '')).to.eq(`
58+
describe('studio functionality', () => {
59+
it('visits a basic html page', () => {
60+
cy.visit('cypress/e2e/index.html')
61+
cy.get('#increment').should('be.enabled');
62+
cy.get('#increment').should('be.visible');
63+
cy.get('#increment').should('have.text', 'Increment');
64+
cy.get('#increment').should('have.id', 'increment');
65+
cy.get('#increment').should('have.attr', 'onclick', 'increment()');
66+
})
67+
})`.trim())
68+
})
69+
})
70+
71+
describe('assertions menu', () => {
72+
const showAssertionsMenu = (autAssertions?: () => void) => {
73+
launchStudio()
74+
75+
cy.waitForSpecToFinish()
76+
77+
cy.contains('No commands were issued in this test.').should('not.exist')
78+
79+
cy.getAutIframe().within(() => {
80+
// Show menu
81+
cy.get('h1').realClick({
82+
button: 'right',
83+
})
84+
85+
cy.get('.__cypress-studio-assertions-menu').shadow()
86+
.find('.assertions-menu').should('be.visible')
87+
88+
// Show submenu
89+
cy.get('.__cypress-studio-assertions-menu').shadow()
90+
.find('.assertion-type-text:first').realHover()
91+
92+
cy.get('.__cypress-studio-assertions-menu').shadow()
93+
.find('.assertion-option')
94+
.should('have.text', 'Hello, Studio!')
95+
.should('be.visible')
96+
97+
autAssertions?.()
98+
})
99+
}
100+
101+
const showAssertionsMenuForModal = (autAssertions?: () => void) => {
102+
launchStudio({ specName: 'spec-w-modal.cy.js' })
103+
104+
cy.waitForSpecToFinish()
105+
106+
cy.contains('No commands were issued in this test.').should('not.exist')
107+
108+
cy.getAutIframe().within(() => {
109+
// Show menu
110+
cy.get('.modal-body').realClick({
111+
button: 'right',
112+
})
113+
114+
cy.get('.__cypress-studio-assertions-menu').shadow()
115+
.find('.assertions-menu').should('be.visible')
116+
117+
// Show submenu
118+
cy.get('.__cypress-studio-assertions-menu').shadow()
119+
.find('.assertion-type-text:first').realHover()
120+
121+
cy.get('.__cypress-studio-assertions-menu').shadow()
122+
.find('.assertion-option')
123+
.should('have.text', 'Semi-transparent background overlay')
124+
.should('be.visible')
125+
126+
autAssertions?.()
127+
})
128+
}
129+
130+
const assertionsMenuFns = [
131+
{ fn: showAssertionsMenu, name: 'handles normal element' },
132+
{ fn: showAssertionsMenuForModal, name: 'handles high z-index modal' },
133+
]
134+
135+
assertionsMenuFns.forEach(({ fn, name }) => {
136+
it(`${name} - shows assertions menu and submenu correctly`, () => {
137+
fn()
138+
})
139+
140+
it(`${name} - closes assertions menu when clicking outside`, () => {
141+
fn(() => {
142+
// click outside the menu
143+
cy.get('.__cypress-studio-assertions-menu').shadow().find('.vue-container').click()
144+
// check that the menu is closed
145+
cy.get('.__cypress-studio-assertions-menu').should('not.exist')
146+
})
147+
})
148+
149+
it(`${name} - closes assertions menu on the highlighted element`, () => {
150+
fn(() => {
151+
// click on the highlighted element
152+
cy.get('.__cypress-studio-assertions-menu').shadow().find('.highlight').click()
153+
// check that the menu is closed
154+
cy.get('.__cypress-studio-assertions-menu').should('not.exist')
155+
})
156+
})
157+
})
158+
159+
it('shows the assertions menu for an element inside an invisible wrapper', () => {
160+
launchStudio({ specName: 'spec-w-invisible-wrapper.cy.js' })
161+
162+
cy.getAutIframe().within(() => {
163+
// Show menu
164+
cy.contains('Increment').realClick({
165+
button: 'right',
166+
})
167+
168+
cy.get('.__cypress-studio-assertions-menu').shadow()
169+
.find('.assertions-menu').should('be.visible').then(($el) => {
170+
const transform = $el.css('transform')
171+
172+
// Extract all matrix values: matrix(a, b, c, d, tx, ty)
173+
const match = transform.match(/matrix\(([^)]+)\)/)
174+
175+
if (match) {
176+
const values = match[1].split(',').map((v) => parseFloat(v.trim()))
177+
const [scaleX, skewY, skewX, scaleY, translateX, translateY] = values
178+
179+
expect(scaleX).to.equal(1)
180+
expect(skewY).to.equal(0)
181+
expect(skewX).to.equal(0)
182+
expect(scaleY).to.equal(1)
183+
expect(translateX).to.equal(0)
184+
expect(translateY).to.be.closeTo(141, 1) // translateY (allow ±1 pixel)
185+
} else {
186+
throw new Error(`Could not parse transform value: ${transform}`)
187+
}
188+
})
189+
190+
// Show submenu
191+
cy.get('.__cypress-studio-assertions-menu').shadow()
192+
.find('.assertion-type-text:first').realHover()
193+
194+
cy.get('.__cypress-studio-assertions-menu').shadow()
195+
.find('.assertion-option')
196+
.contains('Increment')
197+
.should('be.visible')
198+
})
199+
})
200+
})
201+
})

0 commit comments

Comments
 (0)