Skip to content

Commit 2d63fae

Browse files
authored
update ajax examples with Select2 (#517)
1 parent 316dfdd commit 2d63fae

File tree

2 files changed

+121
-31
lines changed

2 files changed

+121
-31
lines changed
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# testing-dom__select2
22
> Testing select elements and Select2 widgets
33
4-
This example shows how end-to-end tests work with plain `<select>` HTML elements and with [Select2](https://select2.org/) widgets.
4+
This example shows how end-to-end tests work with plain `<select>` HTML elements and with [Select2](https://select2.org/) widgets. Read the blog post [Working with Select elements and Select2 widgets in Cypress](https://www.cypress.io/blog/2020/03/20/working-with-select-elements-and-select2-widgets-in-cypress/)
55

66
Find all tests in the [cypress/integration/spec.js](cypress/integration/spec.js) file
77

@@ -10,5 +10,6 @@ Find all tests in the [cypress/integration/spec.js](cypress/integration/spec.js)
1010
- selecting a single value using `Select2`
1111
- selecting multiple values using `Select2`
1212
- removing one of the selected values using `Select2`
13+
- selecting a value from the list dynamically populated from Ajax call using `Select2`
1314

1415
![demo](images/demo.gif)

examples/testing-dom__select2/cypress/integration/spec.js

Lines changed: 119 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -156,44 +156,86 @@ describe('select2', () => {
156156
})
157157

158158
context('ajax data source', () => {
159-
it('selects a value', () => {
160-
// https://select2.org/data-sources/ajax
161-
162-
// Approach 1 (doesn't work): click on the container to
163-
// populate the values, and then select the value
164-
// cy.get('#select2-user-container').click()
165-
// cy.get('.select2-results__option').contains('Leanne Graham').click()
166-
// cy.get('#user').should('have.value', '1')
167-
168-
// Approach 2 (doesn't work): using wait for xhr
169-
// cy.server()
170-
// cy.route('https://jsonplaceholder.cypress.io/users?_type=query').as('users')
171-
// cy.get('#select2-user-container').click()
172-
// cy.wait('@users')
173-
// cy.get('.select2-results__option').contains('Leanne Graham').click()
174-
// cy.get('#user').should('have.value', '1')
175-
176-
// Approach 3: using .should to wait (works inconsistently)
177-
cy.server()
178-
cy.route('https://jsonplaceholder.cypress.io/users*').as('users')
159+
// Select2 Ajax data fetch docs at https://select2.org/data-sources/ajax
179160

180-
// click on the select2 container, which makes the ajax call
161+
// NOTE: test shows what will NOT work
162+
it.skip('selects a value - WILL NOT WORK, JUST A DEMO', () => {
163+
// clicking on the container starts Ajax call
181164
cy.get('#select2-user-container').click()
182-
cy.wait('@users')
183165

184-
// select a value
185-
cy.get('.select2-results__option').contains('Leanne Graham').should('be.visible').click()
166+
// we know the choice elements have this class
167+
cy.get('.select2-results__option')
168+
// so let's try finding the element with the text
169+
// WILL NOT WORK because our search is limited
170+
// to the initial empty set of results
171+
// from the previous ".get" command
172+
.contains('Leanne Graham').click()
186173

187-
// confirm the value of the selected element
174+
// confirm the right user is found
188175
cy.get('#user').should('have.value', '1')
176+
cy.get('#select2-user-container').should('have.text', 'Leanne Graham')
177+
})
189178

190-
// confirm Select2 widget renders the name
179+
it('selects a value by waiting for loading class to go away', () => {
180+
// clicking on the container starts Ajax call
181+
cy.get('#select2-user-container').click()
182+
183+
cy.get('.select2-results__option')
184+
.should('not.have.class', 'loading-results')
185+
// great, now the results are shown in the DOM
186+
.contains('Leanne Graham').click()
187+
188+
// confirm the right user is found
189+
cy.get('#user').should('have.value', '1')
191190
cy.get('#select2-user-container').should('have.text', 'Leanne Graham')
192191
})
193192

194-
it('selects a value by typing and selecting', () => {
195-
// https://select2.org/data-sources/ajax
193+
it('selects a value by retrying', () => {
194+
// clicking on the container starts Ajax call
195+
cy.get('#select2-user-container').click()
196+
197+
// we need to retry getting the option until it is found
198+
// then we can click it. To retry finding the element with text
199+
// we should use https://on.cypress.io/contains
200+
cy.contains('.select2-results__option', 'Leanne Graham').click()
201+
202+
// confirm the right user is found
203+
cy.get('#user').should('have.value', '1')
204+
cy.get('#select2-user-container').should('have.text', 'Leanne Graham')
205+
})
206+
207+
it('selects a value after the list has been is populated', () => {
208+
// clicking on the container starts Ajax call
209+
cy.get('#select2-user-container').click()
210+
211+
// let's wait for the list of options to be populated
212+
// before trying to find a specific item
213+
cy.get('.select2-results__option').should('have.length.gt', 3)
214+
// and now we can find the user among the results
215+
.contains('Leanne Graham').click()
216+
217+
// confirm the right user is found
218+
cy.get('#user').should('have.value', '1')
219+
cy.get('#select2-user-container').should('have.text', 'Leanne Graham')
220+
})
196221

222+
it('selects a value after Ajax completes', () => {
223+
cy.server()
224+
cy.route('https://jsonplaceholder.cypress.io/users?_type=query').as('users')
225+
cy.get('#select2-user-container').click()
226+
cy.wait('@users')
227+
228+
// The Ajax call has completed - but that does not mean the widget
229+
// has populated the DOM elements. Thus we need to use the same
230+
// retry mechanism until an option with expected text exists
231+
cy.contains('.select2-results__option', 'Leanne Graham').click()
232+
233+
// confirm the right user is found
234+
cy.get('#user').should('have.value', '1')
235+
cy.get('#select2-user-container').should('have.text', 'Leanne Graham')
236+
})
237+
238+
it('selects a value by typing and selecting', () => {
197239
cy.server()
198240
cy.route('https://jsonplaceholder.cypress.io/users?term=clem&_type=query&q=clem').as('user_search')
199241

@@ -204,15 +246,62 @@ describe('select2', () => {
204246
cy.get('input[aria-controls="select2-user-results"]').type('clem{enter}')
205247
cy.wait('@user_search')
206248

207-
// select a value
208-
cy.get('.select2-results__option').contains('Clementine Bauch').should('be.visible').click()
249+
// select a value, again by retrying command
250+
// https://on.cypress.io/retry-ability
251+
cy.contains('.select2-results__option', 'Clementine Bauch').should('be.visible').click()
209252

210253
// confirm the value of the selected element
211254
cy.get('#user').should('have.value', '3')
212255

213256
// confirm Select2 widget renders the name
214257
cy.get('#select2-user-container').should('have.text', 'Clementine Bauch')
215258
})
259+
260+
it('selects the user returned by the Ajax call', () => {
261+
// instead of hard-coding the user id and name, let's
262+
// select the user using the Ajax response data
263+
cy.server()
264+
cy.route('https://jsonplaceholder.cypress.io/users?_type=query').as('users')
265+
cy.get('#select2-user-container').click()
266+
cy.wait('@users').its('responseBody').should('have.length', 10)
267+
// let's take user #5
268+
.its('5')
269+
.then((user) => {
270+
expect(user).to.have.property('name')
271+
expect(user).to.have.property('id')
272+
273+
cy.contains('.select2-results__option', user.name).click()
274+
// the Select2 widget picks the right user
275+
cy.get('#user').should('have.value', user.id)
276+
cy.get('#select2-user-container').should('have.text', user.name)
277+
})
278+
})
279+
280+
it('selects the user from stubbed Ajax call', () => {
281+
cy.server()
282+
// do not go to the server, mock the response instead
283+
// but return the response after a delay
284+
cy.route({
285+
url: 'https://jsonplaceholder.cypress.io/users?_type=query',
286+
response: [{
287+
id: 101,
288+
name: 'Joe Smith',
289+
}, {
290+
id: 201,
291+
name: 'Mary Jane',
292+
}],
293+
delay: 2000,
294+
})
295+
296+
cy.get('#select2-user-container').click()
297+
298+
// keep retrying finding the element until it is present
299+
cy.contains('.select2-results__option', 'Mary Jane', { timeout: 2500 }).click()
300+
301+
// confirm the user was selected
302+
cy.get('#user').should('have.value', 201)
303+
cy.get('#select2-user-container').should('have.text', 'Mary Jane')
304+
})
216305
})
217306

218307
context('programmatic control', () => {

0 commit comments

Comments
 (0)