Skip to content

Latest commit

 

History

History
196 lines (138 loc) · 4.42 KB

interactions.md

File metadata and controls

196 lines (138 loc) · 4.42 KB

emulating user interactions

The query helper ($ parameter passed to testRender() and testGlobalRender() handlers) partially wraps @testing-library/user-event to provide convenient methods for emulating user interaction:

testRender((renderer, { render, $, tab, press }) => {
  const s = state('')
  render(<>
    <input _state={s} type='text'/>
    <button onclick={() => s.set('')}>Clear</button>
  </>)

  tab()                  // 👉 press <tab> key to focus an input
  press('hellow there')  // 👉 press this key sequence
  s.get().should.equal('hellow there')

  $('button').click()    // 👉 clear the input
  $('input').resolveOne()!.value.should.equal('')
})

For convenience, methods on $ have limited customizability. For more customized interaction emulation you can use @testing-library/user-event directly.


👉 .click() emulates a click:

$(someElement).click()
$('button').last().click()

👉 .dblclick() emulates a double click:

$(someElement).dblclick()

These methods also trigger hover events.


👉 .hover() emulates a mouse enter event:

$(someElement).hover()

👉 .unhover() emulates a mouse exit event:

$(someElement).unhover()

👉 .type() writes given text inside an <input> or <textarea>:

$('input#id').type('hellow')

You can also provide a delay, which will cause a delay between each keypress:

await spec.textarea().type('Hey there!', 200)

.type() will also click the element beforehand.

👉 .type() also supports special characters:

$('textarea').type('hellow! {backspace} world')

👉 .clear() clears value of an input:

$('input').clear()

This method selects the text inside the element and deletes it.


👉 .paste() pastes some value into input:

$('input').paste('hellow there!')

Note that .paste() does not trigger keyboard events.


👉 .select() selects a given option of a select element:

const Jack = { name: 'Jack' }

render(<select>
  <option>A</option>
  <option value='B'>Choose B</option>
  <option value={Jack}>Choose Jack</option>
</select>)

$('select').select('A')     // 👉 pick option by option label
$('select').select('B')     // 👉 pick option by option value
$('select').select(Jack)    // 👉 pick option via object value

For multi-selects, you can provide multiple options to .select():

$('select').select('A', Jack)

You can also use .deselect() to deselect option(s):

$('select').deselect(Jack, 'B')

👉 .upload() will emulate uploading files into an input:

const fileA = new File(['hellow'], 'hellow.png', {type: 'image/png'})
const fileB = new File(['goodbye'], 'goodbye.png', {type: 'image/png'})

$('input').upload(fileA, fileB)

👉 .tab() will rotate focus through children of the element:

render(<>
  <div class='A'>
    <input type='text' class='A1'/>
    <button class='A2'/>
  </div>
  <input class='B'/>
</>)

$('.A').tab()     // 👉 input.A1 is focused
$('.A').tab()     // 👉 button.A2 is focused
$('.A').tab()     // 👉 input.A1 is focused again
$('.A').tab(-1)   // 👉 goes back, so button.A2 is focused

// 👉 input.B is never focused

👉 Call .tab(-1) to emulating Shift + Tab.



Global Interactions

Additional methods are provided to testRender() and testGlobalRender() handlers for emulating global events (global tab press, global keyboard press):

testRender((renderer, { render, $, tab, press }) => {
  const s = state('')
  render(<>
    <input _state={s} type='text'/>
    <button onclick={() => s.set('')}>Clear</button>
  </>)

  tab()                  // 👉 press <tab> key to focus an input
  press('hellow there')  // 👉 press this key sequence
  s.get().should.equal('hellow there')

  $('button').click()    // 👉 clear the input
  $('input').resolveOne()!.value.should.equal('')
})

👉 Call tab(-1) to emulating Shift + Tab.

👉 press() supports the same special characters as .type().