Skip to content

Commit 4cd02e0

Browse files
committed
Merge branch 'tgriesser/10.0-release/refactor-lifecycle' into tgriesser/10.0-release/refactor-lifecycle-ui
* tgriesser/10.0-release/refactor-lifecycle: fix: remove copy button when not available (#19417) test: Adding tests for Page Top Nav workflows (#19375) fix: fuzzy sort accuracy (#19420)
2 parents d6253c3 + e02921f commit 4cd02e0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+549
-109
lines changed

packages/app/cypress/e2e/integration/settings.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ describe('App: Settings', { viewportWidth: 600 }, () => {
1212
cy.visitApp()
1313
cy.findByText('Settings').click()
1414

15-
cy.get('div[data-testid="header-bar"]').should('contain', 'Settings')
15+
cy.get('div[data-cy="app-header-bar"]').should('contain', 'Settings')
1616
cy.findByText('Device Settings').should('be.visible')
1717
cy.findByText('Project Settings').should('be.visible')
1818
})

packages/app/cypress/e2e/integration/sidebar_navigation.spec.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -131,32 +131,32 @@ describe('Sidebar Navigation', () => {
131131
it('has a menu item labeled "Runs" which takes you to the Runs page', () => {
132132
cy.get('[aria-expanded]').should('have.attr', 'aria-expanded', 'true')
133133

134-
cy.get('[data-testid="header-bar"]').findByText('Runs').should('not.exist')
134+
cy.get('[data-cy="app-header-bar"]').findByText('Runs').should('not.exist')
135135
cy.findByText('Runs').should('be.visible')
136136
cy.findByText('Runs').click()
137-
cy.get('[data-testid="header-bar"]').findByText('Runs').should('be.visible')
137+
cy.get('[data-cy="app-header-bar"]').findByText('Runs').should('be.visible')
138138
cy.get('.router-link-active').findByText('Runs').should('be.visible')
139139
cy.get('[data-e2e-href="/runs"] > svg > path').should('have.css', 'fill', 'rgb(0, 50, 32)')
140140
})
141141

142142
it('has a menu item labeled "Specs" which takes you to the Spec List page', () => {
143143
cy.get('[aria-expanded]').should('have.attr', 'aria-expanded', 'true')
144144

145-
cy.get('[data-testid="header-bar"]').findByText('Specs-Index').should('not.exist')
145+
cy.get('[data-cy="app-header-bar"]').findByText('Specs-Index').should('not.exist')
146146
cy.findByText('Specs').should('be.visible')
147147
cy.findByText('Specs').click()
148-
cy.get('[data-testid="header-bar"]').findByText('Specs-Index').should('be.visible')
148+
cy.get('[data-cy="app-header-bar"]').findByText('Specs-Index').should('be.visible')
149149
cy.get('.router-link-active').findByText('Specs').should('be.visible')
150150
cy.get('[data-e2e-href="/specs"] > svg > path').should('have.css', 'fill', 'rgb(0, 50, 32)')
151151
})
152152

153153
it('has a menu item labeled "Settings" which takes you to the Settings page', () => {
154154
cy.get('[aria-expanded]').should('have.attr', 'aria-expanded', 'true')
155155

156-
cy.get('[data-testid="header-bar"]').findByText('Settings').should('not.exist')
156+
cy.get('[data-cy="app-header-bar"]').findByText('Settings').should('not.exist')
157157
cy.findByText('Settings').should('be.visible')
158158
cy.findByText('Settings').click()
159-
cy.get('[data-testid="header-bar"]').findByText('Settings').should('be.visible')
159+
cy.get('[data-cy="app-header-bar"]').findByText('Settings').should('be.visible')
160160
cy.get('.router-link-active').findByText('Settings').should('be.visible')
161161
cy.get('[data-e2e-href="/settings"] > svg > path').should('have.css', 'fill', 'rgb(0, 50, 32)')
162162
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
describe('App Top Nav Workflows', () => {
2+
beforeEach(() => {
3+
cy.scaffoldProject('launchpad')
4+
5+
cy.clock(Date.UTC(2021, 9, 30), ['Date'])
6+
})
7+
8+
describe('Page Name', () => {
9+
it('shows the current page name in the top nav', () => {
10+
cy.findBrowsers()
11+
cy.openProject('launchpad')
12+
cy.startAppServer()
13+
cy.visitApp()
14+
15+
cy.findByTestId('app-header-bar').should('be.visible').and('contain', 'Specs-Index')
16+
})
17+
})
18+
19+
describe('Browser List', () => {
20+
context('with command line args', () => {
21+
it('shows current browser when launched with browser option', () => {
22+
cy.findBrowsers()
23+
cy.openProject('launchpad', ['--browser', 'firefox'])
24+
cy.startAppServer()
25+
cy.visitApp()
26+
27+
cy.findByTestId('top-nav-active-browser-icon')
28+
.should('have.attr', 'src')
29+
.and('contain', 'firefox')
30+
31+
cy.findByTestId('top-nav-active-browser').should('contain', 'Firefox v5')
32+
})
33+
})
34+
35+
context('without command line args', () => {
36+
beforeEach(() => {
37+
cy.findBrowsers({
38+
filter: (browser) => {
39+
return Cypress._.includes(['chrome', 'firefox', 'electron', 'edge'], browser.name) && browser.channel === 'stable'
40+
},
41+
})
42+
43+
cy.openProject('launchpad')
44+
cy.startAppServer()
45+
cy.visitApp()
46+
})
47+
48+
it('shows the current browser in the top nav browser list button', () => {
49+
cy.findByTestId('top-nav-active-browser-icon')
50+
.should('have.attr', 'src')
51+
.and('contain', 'chrome')
52+
53+
cy.findByTestId('top-nav-active-browser').should('contain', 'Chrome v1')
54+
})
55+
56+
it('shows list of browser options in dropdown when selected', () => {
57+
cy.findByTestId('top-nav-active-browser').click()
58+
59+
cy.findAllByTestId('top-nav-browser-list-item').as('browserItems').should('have.length', 4)
60+
61+
cy.get('@browserItems').eq(0)
62+
.should('contain', 'Chrome')
63+
.and('contain', 'Version 1.2.3')
64+
.findByTestId('top-nav-browser-list-selected-item')
65+
.should('exist')
66+
67+
cy.get('@browserItems').eq(1)
68+
.should('contain', 'Firefox')
69+
.and('contain', 'Version 5.6.7')
70+
.findByTestId('top-nav-browser-list-selected-item')
71+
.should('not.exist')
72+
73+
cy.get('@browserItems').eq(2)
74+
.should('contain', 'Edge')
75+
.and('contain', 'Version 8.9.10')
76+
.findByTestId('top-nav-browser-list-selected-item')
77+
.should('not.exist')
78+
79+
cy.get('@browserItems').eq(3)
80+
.should('contain', 'Electron')
81+
.and('contain', 'Version 12.13.14')
82+
.findByTestId('top-nav-browser-list-selected-item')
83+
.should('not.exist')
84+
})
85+
86+
it('performs mutations to update and relaunch browser', () => {
87+
cy.findByTestId('top-nav-active-browser').click()
88+
89+
cy.intercept('mutation-TopNav_SetBrowser').as('setBrowser')
90+
cy.intercept('mutation-TopNav_LaunchOpenProject').as('launchOpenProject')
91+
92+
cy.findAllByTestId('top-nav-browser-list-item').eq(1).click().then(($element) => {
93+
cy.wait('@setBrowser').then(({ request }) => {
94+
expect(request.body.variables.id).to.eq($element.attr('data-browser-id'))
95+
})
96+
97+
cy.wait('@launchOpenProject')
98+
})
99+
})
100+
})
101+
})
102+
103+
describe('Cypress Version', () => {
104+
context('user version current', () => {
105+
it('renders link to external docs if version is current', () => {
106+
cy.findBrowsers()
107+
cy.withCtx(async (ctx) => {
108+
// @ts-ignore sinon is a global in the node process where this is executed
109+
sinon.stub(ctx, 'versions').resolves({
110+
current: {
111+
id: '1',
112+
version: '10.0.0',
113+
released: '2021-10-15T21:38:59.983Z',
114+
},
115+
latest: {
116+
id: '1',
117+
version: '10.0.0',
118+
released: '2021-10-25T21:38:59.983Z',
119+
},
120+
})
121+
})
122+
123+
cy.openProject('launchpad')
124+
cy.startAppServer()
125+
cy.visitApp()
126+
127+
cy.findByTestId('top-nav-cypress-version-current-link').should('have.attr', 'href', 'https://github.com/cypress-io/cypress/releases/tag/v10.0.0')
128+
})
129+
})
130+
131+
context('user version outdated', () => {
132+
beforeEach(() => {
133+
cy.findBrowsers()
134+
cy.withCtx(async (ctx) => {
135+
const currRelease = new Date(Date.UTC(2021, 9, 30))
136+
const prevRelease = new Date(Date.UTC(2021, 9, 29))
137+
138+
// @ts-ignore sinon is a global in the node process where this is executed
139+
sinon.stub(ctx, 'versions').resolves({
140+
current: {
141+
id: '1',
142+
version: '10.0.0',
143+
released: prevRelease.toISOString(),
144+
},
145+
latest: {
146+
id: '2',
147+
version: '10.1.0',
148+
released: currRelease.toISOString(),
149+
},
150+
})
151+
})
152+
153+
cy.openProject('launchpad')
154+
cy.startAppServer()
155+
cy.visitApp()
156+
})
157+
158+
it('shows dropdown with version info if user version is outdated', () => {
159+
cy.findByTestId('top-nav-version-list').contains('v10.0.0 • Upgrade').click()
160+
161+
cy.findByTestId('update-hint').findByRole('link', { name: '10.1.0' })
162+
.should('have.attr', 'href', 'https://github.com/cypress-io/cypress/releases/tag/v10.1.0')
163+
164+
cy.findByTestId('update-hint').findByText('Latest')
165+
166+
cy.findByTestId('cypress-update-popover').findByRole('button', { name: 'Update to 10.1.0' })
167+
168+
cy.findByTestId('current-hint').findByRole('link', { name: '10.0.0' })
169+
.should('have.attr', 'href', 'https://github.com/cypress-io/cypress/releases/tag/v10.0.0')
170+
171+
cy.findByTestId('current-hint').findByText('Installed')
172+
173+
cy.findByTestId('cypress-update-popover').findByRole('link', { name: 'See all releases' })
174+
.should('have.attr', 'href', 'https://github.com/cypress-io/cypress/releases')
175+
})
176+
177+
it('hides dropdown when version in header is clicked', () => {
178+
cy.findByTestId('cypress-update-popover').findByRole('button', { expanded: false }).as('topNavVersionButton').click()
179+
180+
cy.get('@topNavVersionButton').should('have.attr', 'aria-expanded', 'true')
181+
182+
cy.get('@topNavVersionButton').click()
183+
184+
cy.get('@topNavVersionButton').should('have.attr', 'aria-expanded', 'false')
185+
})
186+
187+
it('shows upgrade modal when update button is pressed', () => {
188+
cy.findByTestId('top-nav-version-list').contains('v10.0.0 • Upgrade').click()
189+
190+
cy.findByTestId('cypress-update-popover').findByRole('button', { name: 'Update to 10.1.0' }).click()
191+
192+
cy.findByRole('dialog', { name: 'Upgrade to Cypress 10.1.0 Need help?' }).as('upgradeModal')
193+
.should('contain', 'You are currently running Version 10.0.0 of Cypress')
194+
.and('contain', 'npm install --save-dev cypress@10.1.0')
195+
196+
cy.get('@upgradeModal').findByRole('button', { name: 'Close' }).click()
197+
198+
cy.findAllByRole('dialog').should('not.exist')
199+
})
200+
})
201+
})
202+
203+
describe('Docs', () => {
204+
beforeEach(() => {
205+
cy.findBrowsers()
206+
cy.openProject('launchpad')
207+
cy.startAppServer()
208+
cy.visitApp()
209+
210+
cy.findByTestId('app-header-bar').findByRole('button', { name: 'Docs', expanded: false }).as('docsButton')
211+
})
212+
213+
it('shows shows popover with additional doc links', () => {
214+
cy.get('@docsButton').click().should('have.attr', 'aria-expanded', 'true')
215+
216+
cy.findByRole('heading', { name: 'Getting Started', level: 2 })
217+
cy.findByRole('heading', { name: 'References', level: 2 })
218+
cy.findByRole('heading', { name: 'Run in CI/CD', level: 2 })
219+
220+
cy.findByRole('link', { name: 'Write your first test' }).should('have.attr', 'href', 'https://on.cypress.io/writing-first-test?utm_medium=Docs+Menu&utm_content=First+Test')
221+
cy.findByRole('link', { name: 'Testing your app' }).should('have.attr', 'href', 'https://on.cypress.io/testing-your-app?utm_medium=Docs+Menu&utm_content=Testing+Your+App')
222+
cy.findByRole('link', { name: 'Organizing Tests' }).should('have.attr', 'href', 'https://on.cypress.io/writing-and-organizing-tests?utm_medium=Docs+Menu&utm_content=Organizing+Tests')
223+
224+
cy.findByRole('link', { name: 'Best Practices' }).should('have.attr', 'href', 'https://on.cypress.io/best-practices?utm_medium=Docs+Menu&utm_content=Best+Practices')
225+
cy.findByRole('link', { name: 'Configuration' }).should('have.attr', 'href', 'https://on.cypress.io/configuration?utm_medium=Docs+Menu&utm_content=Configuration')
226+
cy.findByRole('link', { name: 'API' }).should('have.attr', 'href', 'https://on.cypress.io/api?utm_medium=Docs+Menu&utm_content=API')
227+
228+
cy.findByRole('link', { name: 'Run tests faster' }).should('have.attr', 'href', 'https://on.cypress.io/parallelization?utm_medium=Docs+Menu&utm_content=Parallelization')
229+
230+
cy.findByRole('button', { name: 'Set up CI' }).click()
231+
cy.findByText('Configure CI').should('be.visible')
232+
cy.findByRole('button', { name: 'Close' }).click()
233+
234+
cy.findByRole('button', { name: 'Smart Orchestration' }).click()
235+
cy.findByText('Run tests faster in CI').should('be.visible')
236+
cy.findByRole('button', { name: 'Close' }).click()
237+
})
238+
})
239+
240+
describe('Login', () => {
241+
context('user logged in', () => {
242+
beforeEach(() => {
243+
cy.findBrowsers()
244+
cy.openProject('launchpad')
245+
cy.startAppServer()
246+
cy.loginUser()
247+
cy.visitApp()
248+
249+
cy.findByTestId('app-header-bar').findByRole('button', { name: 'Log In', expanded: false }).as('logInButton')
250+
})
251+
252+
it('shows user in top nav when logged in', () => {
253+
cy.get('@logInButton').click()
254+
255+
cy.findByTestId('login-panel').contains('Test User').should('be.visible')
256+
cy.findByTestId('login-panel').contains('test@example.com').should('be.visible')
257+
cy.findByRole('link', { name: 'Profile Settings' }).should('be.visible').and('have.attr', 'href', 'https://on.cypress.io/dashboard/profile')
258+
259+
cy.intercept('mutation-Logout').as('logout')
260+
261+
cy.findByRole('button', { name: 'Log Out' }).should('be.visible').click()
262+
263+
cy.wait('@logout')
264+
})
265+
})
266+
267+
context('user not logged in', () => {
268+
beforeEach(() => {
269+
cy.findBrowsers()
270+
cy.openProject('launchpad')
271+
cy.startAppServer()
272+
cy.visitApp()
273+
274+
cy.findByTestId('app-header-bar').findByRole('button', { name: 'Log In' }).as('logInButton')
275+
})
276+
277+
it('shows log in modal when button is pressed', () => {
278+
cy.get('@logInButton').click()
279+
280+
cy.findByRole('dialog', { name: 'Log In To Cypress' }).as('logInModal')
281+
cy.get('@logInModal').findByRole('button', { name: 'Log In' })
282+
cy.get('@logInModal').findByRole('button', { name: 'Close' }).click()
283+
})
284+
})
285+
})
286+
})

packages/app/src/components/FileMatch.spec.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import { each } from 'lodash'
88
const anyFilenameInputSelector = `[placeholder="${defaultMessages.components.fileSearch.byFilenameInput}"]`
99
const filenameInputSelector = `${anyFilenameInputSelector}:first`
1010
const extensionInputSelector = `[placeholder="${defaultMessages.components.fileSearch.byExtensionInput}"]`
11-
const fileMatchButtonSelector = '[data-testid=file-match-button]'
11+
const fileMatchButtonSelector = '[data-cy=file-match-button]'
1212

1313
// File Match Indicator
1414
// X out of Y Matches when searching the file list
15-
const fileMatchIndicatorSelector = '[data-testid=file-match-indicator]'
15+
const fileMatchIndicatorSelector = '[data-cy=file-match-indicator]'
1616

1717
const initialExtension = '*.stories.*'
1818
const initialPattern = ''

packages/app/src/components/FileMatch.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
<slot name="matches">
5858
<FileMatchIndicator
5959
class="truncate"
60-
data-testid="file-match-indicator"
60+
data-cy="file-match-indicator"
6161
>
6262
{{ indicatorText }}
6363
</FileMatchIndicator>

packages/app/src/components/FileMatchButton.spec.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import FileMatchButton from './FileMatchButton.vue'
55
import faker from 'faker'
66
import { ref } from 'vue'
7-
const fileMatchButtonSelector = '[data-testid=file-match-button]'
7+
const fileMatchButtonSelector = '[data-cy=file-match-button]'
88

99
describe('<FileMatchButton />', () => {
1010
it('renders a small extension', () => {

packages/app/src/components/FileMatchButton.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<button
3-
data-testid="file-match-button"
3+
data-cy="file-match-button"
44
class="inline-flex items-center h-full text-gray-700 transition duration-150 rounded-l outline-none group bg-gray-50 border-r-gray-100 border-r-1 hocus:bg-indigo-50 hocus:border-r-indigo-300 hocus:text-indigo-500 px-12px"
55
>
66
<i-cy-chevron-right-small_x16

packages/app/src/layouts/default.vue

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
v-if="showHeader"
77
:show-browsers="true"
88
:page-name="currentRoute.name?.toString()"
9+
data-cy="app-header-bar"
910
/>
1011

1112
<main

0 commit comments

Comments
 (0)