import { fireEvent, render } from '@testing-library/react' import React, { ReactElement, RefObject, useRef, MouseEventHandler } from 'react' import { withWebComponent } from '.' const TestComponent = withWebComponent('test-component') const RefWrapper = (props: any): ReactElement => { const innerRef = useRef(null) testRef = innerRef return } let testRef: RefObject = { current: null } describe('withWebComponent', () => { beforeEach(() => { testRef = { current: null } }) it('can pass an html tag name and get a component out thatll pass through all the important standard html props', async () => { const FancyInput = withWebComponent('input') // this throws an error cause react is not pleased w/ `class` showing up on a standard element // you shouldn't be doing this in the first place tho, so ima just ignore it const origError = console.error console.error = jest.fn() const { findByTestId } = render() const theInput = await findByTestId('testTestId') expect(theInput).toHaveAttribute('id', 'testId') expect(theInput).toHaveAttribute('class', 'testClass') console.error = origError }) it('will correctly wire all the things on an actual web component', async () => { const callback = jest.fn((val: string | null) => {}) const onButtonClicked = jest.fn((ev: CustomEvent) => {}) const { findByTestId, findByText } = render() await findByText('this had better render') const theElement = await findByTestId('testComponent') expect(theElement).toHaveAttribute('simple-attr', 'this had better render') expect(theElement).toHaveAttribute('class', 'testClass') expect(theElement).not.toHaveAttribute('callback') const theButton = await findByTestId('button') fireEvent.click(theButton) expect(callback).toHaveBeenCalledWith('this had better render') expect(onButtonClicked.mock.calls[0][0].type).toBe('button-clicked') expect(onButtonClicked.mock.calls[0][0].detail).toStrictEqual({ attributeValue: 'this had better render' }) }) it('will still wire a click as expected even if that runs through the hook', async () => { const onClick = jest.fn((e => {}) as MouseEventHandler) const { findByTestId, findByText } = render() await findByText('test for click') const theElement = await findByTestId('testComponent') fireEvent.click(theElement) expect(onClick.mock.calls[0][0].type).toBe('click') expect(onClick.mock.calls[0][0].target).toBe(theElement) }) it('will forward the ref correctly and also wire all the rest of the things', async () => { const onButtonClicked = jest.fn((ev: CustomEvent) => {}) const { findByTestId } = render() const theElement = await findByTestId('testComponent') expect(theElement).toBe(testRef.current) const theButton = await findByTestId('button') fireEvent.click(theButton) expect(onButtonClicked.mock.calls[0][0].type).toBe('button-clicked') expect(onButtonClicked.mock.calls[0][0].detail).toStrictEqual({ attributeValue: 'ref test' }) }) it('will pass anything sent in on `className` to the `class` prop since react wont process className for you here', async () => { const { findByTestId } = render() const theElement = await findByTestId('testComponent') expect(theElement).toHaveAttribute('class', 'this should show up on class') }) })