diff --git a/README.md b/README.md index 0025ce7cc..09e8efd7f 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,6 @@ change the state of the checkbox. - - [Installation](#installation) - [API](#api) - [`click(element)`](#clickelement) @@ -476,6 +475,7 @@ Thanks goes to these people ([emoji key][emojis]): + This project follows the [all-contributors][all-contributors] specification. diff --git a/src/__tests__/helpers/customElement.js b/src/__tests__/helpers/customElement.js new file mode 100644 index 000000000..e3d1c8015 --- /dev/null +++ b/src/__tests__/helpers/customElement.js @@ -0,0 +1,35 @@ +const observed = ['value'] + +class CustomEl extends HTMLElement { + static getObservedAttributes() { + return observed + } + + constructor() { + super() + this.attachShadow({mode: 'open'}) + this.shadowRoot.innerHTML = `` + this.$input = this.shadowRoot.querySelector('input') + } + + connectedCallback() { + observed.forEach(name => { + this.render(name, this.getAttribute(name)) + }) + } + + attributeChangedCallback(name, oldVal, newVal) { + if (oldVal === newVal) return + this.render(name, newVal) + } + + render(name, value) { + if (value == null) { + this.$input.removeAttribute(name) + } else { + this.$input.setAttribute(name, value) + } + } +} + +customElements.define('custom-el', CustomEl) diff --git a/src/__tests__/helpers/utils.js b/src/__tests__/helpers/utils.js index 50f5d68de..a8bf05383 100644 --- a/src/__tests__/helpers/utils.js +++ b/src/__tests__/helpers/utils.js @@ -37,14 +37,21 @@ function addEventListener(el, type, listener, options) { el.addEventListener(type, hijackedListener, options) } -function setup(ui) { - const { +function setup(ui, {shadowRootSelector} = {}) { + let hostElement + let { container: {firstChild: element}, } = render(ui) + + if (shadowRootSelector) { + hostElement = element + element = element.shadowRoot.querySelector(shadowRootSelector) + } + element.previousTestData = getTestData(element) const {getEventCalls, clearEventCalls} = addListeners(element) - return {element, getEventCalls, clearEventCalls} + return {element, hostElement, getEventCalls, clearEventCalls} } function addListeners(element) { diff --git a/src/__tests__/type.js b/src/__tests__/type.js index 71ab097b9..ea773541a 100644 --- a/src/__tests__/type.js +++ b/src/__tests__/type.js @@ -2,6 +2,7 @@ import React, {Fragment} from 'react' import {render, screen} from '@testing-library/react' import userEvent from '..' import {setup} from './helpers/utils' +import './helpers/customElement' it('types text in input', async () => { const {element, getEventCalls} = setup() @@ -23,6 +24,29 @@ it('types text in input', async () => { `) }) +it('types text inside custom element', async () => { + const {element, hostElement, getEventCalls} = setup(, { + shadowRootSelector: 'input', + }) + + await userEvent.type(element, 'Sup', {hostElement}) + expect(getEventCalls()).toMatchInlineSnapshot(` + focus + keydown: S (83) + keypress: S (83) + input: "{CURSOR}" -> "S" + keyup: S (83) + keydown: u (117) + keypress: u (117) + input: "S{CURSOR}" -> "Su" + keyup: u (117) + keydown: p (112) + keypress: p (112) + input: "Su{CURSOR}" -> "Sup" + keyup: p (112) + `) +}) + it('types text in textarea', async () => { const {element, getEventCalls} = setup(