mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
FileUpload: associate the label with the input (#48766)
* FileUpload: associate the label with the input * generate a unique id and set the correct role * add a test to prevent regressions
This commit is contained in:
parent
ea96c42545
commit
10db618204
@ -1,4 +1,5 @@
|
|||||||
import { render, waitFor, fireEvent, screen } from '@testing-library/react';
|
import { render, waitFor, fireEvent, screen } from '@testing-library/react';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
@ -8,10 +9,23 @@ import { FileUpload } from './FileUpload';
|
|||||||
describe('FileUpload', () => {
|
describe('FileUpload', () => {
|
||||||
it('should render upload button with default text and no file name', () => {
|
it('should render upload button with default text and no file name', () => {
|
||||||
render(<FileUpload onFileUpload={() => {}} />);
|
render(<FileUpload onFileUpload={() => {}} />);
|
||||||
expect(screen.getByText('Upload file')).toBeInTheDocument();
|
expect(screen.getByRole('button', { name: 'Upload file' })).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText('File name')).toBeNull();
|
expect(screen.queryByLabelText('File name')).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('clicking the button should trigger the input', async () => {
|
||||||
|
const mockInputOnClick = jest.fn();
|
||||||
|
const { getByTestId } = render(<FileUpload onFileUpload={() => {}} />);
|
||||||
|
const button = screen.getByRole('button', { name: 'Upload file' });
|
||||||
|
const input = getByTestId(selectors.components.FileUpload.inputField);
|
||||||
|
|
||||||
|
// attach a click listener to the input
|
||||||
|
input.onclick = mockInputOnClick;
|
||||||
|
|
||||||
|
await userEvent.click(button);
|
||||||
|
expect(mockInputOnClick).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it('should display uploaded file name', async () => {
|
it('should display uploaded file name', async () => {
|
||||||
const testFileName = 'grafana.png';
|
const testFileName = 'grafana.png';
|
||||||
const file = new File(['(⌐□_□)'], testFileName, { type: 'image/png' });
|
const file = new File(['(⌐□_□)'], testFileName, { type: 'image/png' });
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { css, cx } from '@emotion/css';
|
import { css, cx } from '@emotion/css';
|
||||||
import React, { FC, FormEvent, useCallback, useState } from 'react';
|
import React, { FC, FormEvent, useCallback, useState } from 'react';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
@ -31,6 +32,7 @@ export const FileUpload: FC<Props> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const style = useStyles2(getStyles(size));
|
const style = useStyles2(getStyles(size));
|
||||||
const [fileName, setFileName] = useState('');
|
const [fileName, setFileName] = useState('');
|
||||||
|
const id = uuidv4();
|
||||||
|
|
||||||
const onChange = useCallback(
|
const onChange = useCallback(
|
||||||
(event: FormEvent<HTMLInputElement>) => {
|
(event: FormEvent<HTMLInputElement>) => {
|
||||||
@ -47,14 +49,14 @@ export const FileUpload: FC<Props> = ({
|
|||||||
<>
|
<>
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
id="fileUpload"
|
id={id}
|
||||||
className={style.fileUpload}
|
className={style.fileUpload}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
multiple={false}
|
multiple={false}
|
||||||
accept={accept}
|
accept={accept}
|
||||||
data-testid={selectors.components.FileUpload.inputField}
|
data-testid={selectors.components.FileUpload.inputField}
|
||||||
/>
|
/>
|
||||||
<label className={cx(style.labelWrapper, className)}>
|
<label role="button" htmlFor={id} className={cx(style.labelWrapper, className)}>
|
||||||
<Icon name="upload" className={style.icon} />
|
<Icon name="upload" className={style.icon} />
|
||||||
{children}
|
{children}
|
||||||
</label>
|
</label>
|
||||||
|
Loading…
Reference in New Issue
Block a user