diff --git a/packages/grafana-e2e-selectors/src/selectors/components.ts b/packages/grafana-e2e-selectors/src/selectors/components.ts index 75b38bc2107..d5e89cbc69c 100644 --- a/packages/grafana-e2e-selectors/src/selectors/components.ts +++ b/packages/grafana-e2e-selectors/src/selectors/components.ts @@ -332,4 +332,8 @@ export const Components = { orgsTable: 'data-testid-user-orgs-table', sessionsTable: 'data-testid-user-sessions-table', }, + FileUpload: { + inputField: 'data-testid-file-upload-input-field', + fileNameSpan: 'data-testid-file-upload-file-name', + }, }; diff --git a/packages/grafana-ui/src/components/FileUpload/FileUpload.test.tsx b/packages/grafana-ui/src/components/FileUpload/FileUpload.test.tsx index eff5555819e..01f1d9c0d78 100644 --- a/packages/grafana-ui/src/components/FileUpload/FileUpload.test.tsx +++ b/packages/grafana-ui/src/components/FileUpload/FileUpload.test.tsx @@ -1,32 +1,44 @@ +import { render, waitFor, fireEvent, screen } from '@testing-library/react'; import React from 'react'; -import { shallow } from 'enzyme'; + +import { selectors } from '@grafana/e2e-selectors'; + import { FileUpload } from './FileUpload'; describe('FileUpload', () => { it('should render upload button with default text and no file name', () => { - const wrapper = shallow( {}} />); - expect(wrapper.findWhere((comp) => comp.text() === 'Upload file').exists()).toBeTruthy(); - expect(wrapper.find({ 'aria-label': 'File name' }).exists()).toBeFalsy(); + render( {}} />); + expect(screen.getByText('Upload file')).toBeInTheDocument(); + expect(screen.queryByLabelText('File name')).toBeNull(); }); - it("should trim uploaded file's name", () => { - const wrapper = shallow( {}} />); + it('should display uploaded file name', async () => { + const testFileName = 'grafana.png'; + const file = new File(['(⌐□_□)'], testFileName, { type: 'image/png' }); + const onFileUpload = jest.fn(); + const { getByTestId } = render(); + let uploader = getByTestId(selectors.components.FileUpload.inputField); + await waitFor(() => + fireEvent.change(uploader, { + target: { files: [file] }, + }) + ); + let uploaderLabel = getByTestId(selectors.components.FileUpload.fileNameSpan); + expect(uploaderLabel).toHaveTextContent(testFileName); + }); - wrapper.find('input').simulate('change', { - currentTarget: { - files: [{ name: 'longFileName.something.png' }], - }, - }); - expect(wrapper.find({ 'aria-label': 'File name' }).exists()).toBeTruthy(); - // Trim file name longer than 16 chars - expect(wrapper.find({ 'aria-label': 'File name' }).text()).toEqual('longFileName.som....png'); - - // Keep the name below the length limit intact - wrapper.find('input').simulate('change', { - currentTarget: { - files: [{ name: 'longFileName.png' }], - }, - }); - expect(wrapper.find({ 'aria-label': 'File name' }).text()).toEqual('longFileName.png'); + it("should trim uploaded file's name", async () => { + const testFileName = 'longFileName.something.png'; + const file = new File(['(⌐□_□)'], testFileName, { type: 'image/png' }); + const onFileUpload = jest.fn(); + const { getByTestId } = render(); + let uploader = getByTestId(selectors.components.FileUpload.inputField); + await waitFor(() => + fireEvent.change(uploader, { + target: { files: [file] }, + }) + ); + let uploaderLabel = getByTestId(selectors.components.FileUpload.fileNameSpan); + expect(uploaderLabel).toHaveTextContent('longFileName.som....png'); }); }); diff --git a/packages/grafana-ui/src/components/FileUpload/FileUpload.tsx b/packages/grafana-ui/src/components/FileUpload/FileUpload.tsx index 48310576ae8..8cecbbf2998 100644 --- a/packages/grafana-ui/src/components/FileUpload/FileUpload.tsx +++ b/packages/grafana-ui/src/components/FileUpload/FileUpload.tsx @@ -1,11 +1,15 @@ -import React, { FC, FormEvent, useCallback, useState } from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; -import { Icon } from '../index'; -import { stylesFactory, useTheme2 } from '../../themes'; +import React, { FC, FormEvent, useCallback, useState } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; + +import { useStyles2 } from '../../themes'; +import { getFocusStyles } from '../../themes/mixins'; import { ComponentSize } from '../../types/size'; import { getButtonStyles } from '../Button'; import { trimFileName } from '../../utils/file'; +import { Icon } from '../index'; export interface Props { /** Callback function to handle uploaded file */ @@ -25,8 +29,7 @@ export const FileUpload: FC = ({ accept = '*', size = 'md', }) => { - const theme = useTheme2(); - const style = getStyles(theme, size); + const style = useStyles2(getStyles(size)); const [fileName, setFileName] = useState(''); const onChange = useCallback( @@ -42,20 +45,26 @@ export const FileUpload: FC = ({ return ( <> -