Skip to content

Commit 95ee9b9

Browse files
Blue Femilyrohrbough
andauthored
fix: .within() now throws an error if given more than one subject. (#24975)
* fix: .within() now throws an error if given more than one subject. * Fix own tests for new .within() behavior Co-authored-by: Emily Rohrbough <[email protected]>
1 parent 101407a commit 95ee9b9

File tree

7 files changed

+61
-41
lines changed

7 files changed

+61
-41
lines changed

packages/app/cypress/e2e/runner/sessions.ui.cy.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ describe('runner/cypress sessions.ui.spec', {
106106
validateSessionsInstrumentPanel(['blank_session'])
107107

108108
cy.get('.command-name-session')
109+
.first()
109110
.within(() => {
110111
cy.contains('blank_session')
111112
cy.contains('failed')
@@ -301,6 +302,7 @@ describe('runner/cypress sessions.ui.spec', {
301302
validateSessionsInstrumentPanel(['user1'])
302303

303304
cy.get('.command-name-session')
305+
.first()
304306
.within(() => {
305307
cy.contains('failed')
306308

packages/app/cypress/e2e/runs.cy.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,10 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
941941
cy.get('[data-cy="run-card-icon-RUNNING"]').should('have.length', 3).should('be.visible')
942942
cy.wrap(obj).invoke('toCall')
943943

944-
cy.get('[data-cy="run-card-icon-PASSED"]').should('have.length', 3).should('be.visible').within(() => {
944+
cy.get('[data-cy="run-card-icon-PASSED"]')
945+
.should('have.length', 3)
946+
.should('be.visible')
947+
.first().within(() => {
945948
cy.get('[data-cy="runResults-passed-count"]').should('contain', 100)
946949
})
947950

packages/driver/cypress/e2e/commands/querying/root.cy.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ describe('src/cy/commands/querying', () => {
1717
it('returns withinSubject if exists', () => {
1818
const form = cy.$$('form')
1919

20-
cy.get('form').within(() => {
20+
cy.get('form').first().within(() => {
2121
cy
2222
.get('input')
2323
.root().then(($root) => {
@@ -100,7 +100,7 @@ describe('src/cy/commands/querying', () => {
100100
it('sets $el to withinSubject', () => {
101101
const form = cy.$$('form')
102102

103-
cy.get('form').within(() => {
103+
cy.get('form').first().within(() => {
104104
cy
105105
.get('input')
106106
.root().then(function ($root) {

packages/driver/cypress/e2e/commands/querying/within.cy.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ describe('src/cy/commands/querying/within', () => {
228228
})
229229

230230
it('provides additional information in console prop', () => {
231-
cy.get('div').within(() => {})
231+
cy.get('div').first().within(() => {})
232232
cy.then(function () {
233233
const { lastLog } = this
234234

@@ -237,7 +237,6 @@ describe('src/cy/commands/querying/within', () => {
237237
expect(consoleProps).to.be.an('object')
238238
expect(consoleProps.Command).to.eq('within')
239239
expect(consoleProps.Yielded).to.not.be.null
240-
expect(consoleProps.Yielded).to.have.length(55)
241240
})
242241
})
243242
})
@@ -304,6 +303,16 @@ describe('src/cy/commands/querying/within', () => {
304303

305304
cy.get('#list').within(() => {})
306305
})
306+
307+
it('throws when given multiple subjects', (done) => {
308+
cy.on('fail', (err) => {
309+
expect(err.message).to.include('`cy.within()` can only be called on a single element. Your subject contained 9 elements.')
310+
311+
done()
312+
})
313+
314+
cy.get('ul').within(() => {})
315+
})
307316
})
308317
})
309318

packages/driver/src/cy/commands/querying/within.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ export default (Commands, Cypress, cy, state) => {
107107
$errUtils.throwErrByPath('within.invalid_argument', { onFail: log })
108108
}
109109

110+
if (subject.length > 1) {
111+
$errUtils.throwErrByPath('within.multiple_elements', { args: { num: subject.length }, onFail: log })
112+
}
113+
110114
return withinFn(subject, fn)
111115
})
112116
},

packages/driver/src/cypress/error_messages.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,6 +2404,20 @@ export default {
24042404
message: `${cmd('within')} must be called with a function.`,
24052405
docsUrl: 'https://on.cypress.io/within',
24062406
},
2407+
multiple_elements (args) {
2408+
return {
2409+
message: stripIndent`
2410+
${cmd('within')} can only be called on a single element. Your subject contained {{num}} elements. Narrow down your subject to a single element (using \`.first()\`, for example) before calling \`.within()\`.
2411+
2412+
To run \`.within()\` over multiple subjects, use \`.each()\`.
2413+
2414+
\`cy.get('div').each($div => {\`
2415+
\` cy.wrap($div).within(() => { ... })\`
2416+
\`})\`
2417+
`,
2418+
docsUrl: 'https://on.cypress.io/within',
2419+
}
2420+
},
24072421
},
24082422

24092423
wrap: {

packages/launchpad/cypress/e2e/project-setup.cy.ts

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,10 @@ describe('Launchpad: Setup Project', () => {
8787
cy.contains('h1', 'Configuration files')
8888
cy.findByText('We added the following files to your project:')
8989

90-
cy.get('[data-cy=valid]').within(() => {
91-
cy.contains('cypress.config.js')
92-
cy.containsPath('cypress/support/e2e.js')
93-
cy.containsPath('cypress/support/commands.js')
94-
cy.containsPath('cypress/fixtures/example.json')
95-
})
90+
cy.get('[data-cy=valid]').as('valid').contains('cypress.config.js')
91+
cy.get('@valid').containsPath('cypress/support/e2e.js')
92+
cy.get('@valid').containsPath('cypress/support/commands.js')
93+
cy.get('@valid').containsPath('cypress/fixtures/example.json')
9694

9795
cy.get('[data-cy=valid] [data-cy=collapsible-header]').each((element) => {
9896
cy.wrap(element).should('have.attr', 'aria-expanded', 'false')
@@ -247,12 +245,10 @@ describe('Launchpad: Setup Project', () => {
247245
cy.contains('h1', 'Configuration files')
248246
cy.findByText('We added the following files to your project:')
249247

250-
cy.get('[data-cy=valid]').within(() => {
251-
cy.contains('cypress.config.js')
252-
cy.containsPath('cypress/support/e2e.js')
253-
cy.containsPath('cypress/support/commands.js')
254-
cy.containsPath('cypress/fixtures/example.json')
255-
})
248+
cy.get('[data-cy=valid]').as('valid').contains('cypress.config.js')
249+
cy.get('@valid').containsPath('cypress/support/e2e.js')
250+
cy.get('@valid').containsPath('cypress/support/commands.js')
251+
cy.get('@valid').containsPath('cypress/fixtures/example.json')
256252

257253
cy.get('[data-cy=valid] [data-cy=collapsible-header]').each((element) => {
258254
cy.wrap(element).should('have.attr', 'aria-expanded', 'false')
@@ -278,12 +274,10 @@ describe('Launchpad: Setup Project', () => {
278274
cy.contains('h1', 'Configuration files')
279275
cy.findByText('We added the following files to your project:')
280276

281-
cy.get('[data-cy=valid]').within(() => {
282-
cy.contains('cypress.config.js')
283-
cy.containsPath('cypress/support/e2e.js')
284-
cy.containsPath('cypress/support/commands.js')
285-
cy.containsPath('cypress/fixtures/example.json')
286-
})
277+
cy.get('[data-cy=valid]').as('valid').contains('cypress.config.js')
278+
cy.get('@valid').containsPath('cypress/support/e2e.js')
279+
cy.get('@valid').containsPath('cypress/support/commands.js')
280+
cy.get('@valid').containsPath('cypress/fixtures/example.json')
287281

288282
verifyScaffoldedFiles('e2e')
289283

@@ -317,12 +311,10 @@ describe('Launchpad: Setup Project', () => {
317311
cy.contains('h1', 'Configuration files')
318312
cy.findByText('We added the following files to your project:')
319313

320-
cy.get('[data-cy=valid]').within(() => {
321-
cy.contains('cypress.config.js')
322-
cy.containsPath('cypress/support/e2e.js')
323-
cy.containsPath('cypress/support/commands.js')
324-
cy.containsPath('cypress/fixtures/example.json')
325-
})
314+
cy.get('[data-cy=valid]').as('valid').contains('cypress.config.js')
315+
cy.get('@valid').containsPath('cypress/support/e2e.js')
316+
cy.get('@valid').containsPath('cypress/support/commands.js')
317+
cy.get('@valid').containsPath('cypress/fixtures/example.json')
326318

327319
cy.get('[data-cy=valid] [data-cy=collapsible-header]').each((element) => {
328320
cy.wrap(element).should('have.attr', 'aria-expanded', 'false')
@@ -353,12 +345,10 @@ describe('Launchpad: Setup Project', () => {
353345
cy.contains('h1', 'Configuration files')
354346
cy.findByText('We added the following files to your project:')
355347

356-
cy.get('[data-cy=valid]').within(() => {
357-
cy.contains('cypress.config.ts')
358-
cy.containsPath('cypress/support/e2e.ts')
359-
cy.containsPath('cypress/support/commands.ts')
360-
cy.containsPath('cypress/fixtures/example.json')
361-
})
348+
cy.get('[data-cy=valid]').as('valid').contains('cypress.config.ts')
349+
cy.get('@valid').containsPath('cypress/support/e2e.ts')
350+
cy.get('@valid').containsPath('cypress/support/commands.ts')
351+
cy.get('@valid').containsPath('cypress/fixtures/example.json')
362352

363353
cy.get('[data-cy=valid] [data-cy=collapsible-header]').each((element) => {
364354
cy.wrap(element).should('have.attr', 'aria-expanded', 'false')
@@ -410,12 +400,10 @@ describe('Launchpad: Setup Project', () => {
410400

411401
cy.findByRole('button', { name: 'Skip' }).click()
412402

413-
cy.get('[data-cy=valid]').within(() => {
414-
cy.contains('cypress.config.js')
415-
cy.containsPath('cypress/support/component-index.html')
416-
cy.containsPath('cypress/support/component.js')
417-
cy.containsPath('cypress/support/commands.js')
418-
})
403+
cy.get('[data-cy=valid]').as('valid').contains('cypress.config.js')
404+
cy.get('@valid').containsPath('cypress/support/component-index.html')
405+
cy.get('@valid').containsPath('cypress/support/component.js')
406+
cy.get('@valid').containsPath('cypress/support/commands.js')
419407

420408
verifyScaffoldedFiles('component')
421409
})

0 commit comments

Comments
 (0)