diff --git a/packages/elements/src/components/ino-input-file/ino-input-file.e2e.ts b/packages/elements/src/components/ino-input-file/ino-input-file.e2e.ts deleted file mode 100644 index 57f011e2e1..0000000000 --- a/packages/elements/src/components/ino-input-file/ino-input-file.e2e.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { setupPageWithContent } from '../../util/e2etests-setup'; - -const INO_INPUT_FILE = ``; -const INPUT_FILE_SELECTOR = 'ino-input-file'; - -describe('InoInputFile', () => { - describe('Properties', () => { - it('should render with the correct css classes if inoDragAndDrop is set to false', async () => { - const page = await setupPageWithContent(INO_INPUT_FILE); - - const dnd_div = await page.find('.ino-input-file__composer'); - expect(dnd_div).toBeDefined(); - }); - - it('should render with the correct css classes if inoDragAndDrop is set to true', async () => { - const page = await setupPageWithContent(INO_INPUT_FILE); - const inputFile = await page.find(INPUT_FILE_SELECTOR); - - await inputFile.setAttribute('drag-and-drop', true); - await page.waitForChanges(); - - const dnd_div = await page.find('.ino-input-file__dnd'); - expect(dnd_div).toBeDefined(); - }); - - it('should render with the correct css classes if inoDragAndDrop and disabled are set to true', async () => { - const page = await setupPageWithContent(INO_INPUT_FILE); - const inputFile = await page.find(INPUT_FILE_SELECTOR); - - await inputFile.setAttribute('drag-and-drop', true); - await inputFile.setAttribute('disabled', true); - await page.waitForChanges(); - - const dnd_div = await page.find('.ino-input-file__dnd'); - expect(dnd_div).toBeDefined(); - expect(dnd_div).toHaveClass('ino-input-file__dnd-disabled'); - }); - }); -}); diff --git a/packages/storybook/src/stories/ino-input-file/ino-input-file.spec.ts b/packages/storybook/src/stories/ino-input-file/ino-input-file.spec.ts new file mode 100644 index 0000000000..05c7e91883 --- /dev/null +++ b/packages/storybook/src/stories/ino-input-file/ino-input-file.spec.ts @@ -0,0 +1,102 @@ +/// +import { expect, test } from '@playwright/test'; +import { goToStory } from '../test-utils'; +import { readFileSync } from 'fs'; + +test.describe('ino-input-file', () => { + test('should open file dialog on click', async ({ page }) => { + await goToStory(page, ['Input', 'ino-input-file', 'default']); + const inputFile = page.locator('ino-input-file'); + const fileChooserPromise = page.waitForEvent('filechooser'); + + await expect(inputFile).toBeVisible(); + await inputFile.click(); + const fileChooser = await fileChooserPromise; + expect(fileChooser).toBeTruthy(); + expect(fileChooser.isMultiple()).toBeFalsy(); + }); + + test('should allow multiply files', async ({ page }) => { + await goToStory(page, ['Input', 'ino-input-file', 'multiple']); + const inputFile = page.locator('ino-input-file'); + const fileChooserPromise = page.waitForEvent('filechooser'); + + await expect(inputFile).toBeVisible(); + await inputFile.click(); + const fileChooser = await fileChooserPromise; + expect(fileChooser.isMultiple()).toBeTruthy(); + }); + + test('should not open file dialog if disabled', async ({ page }) => { + await goToStory(page, ['Input', 'ino-input-file', 'disabled']); + const inputFile = page.locator('ino-input-file'); + const fileChooserPromise = page.waitForEvent('filechooser', { + timeout: 1000, + }); + await inputFile.click(); + + let error = false; + try { + await fileChooserPromise; + } catch { + error = true; + } + expect(error).toBeTruthy(); + }); + + test('should select file with drag and drop', async ({ page }) => { + await goToStory(page, ['Input', 'ino-input-file', 'drag-and-drop']); + const inputFile = page.locator('ino-input-file'); + const inputFileBtn = inputFile.locator('ino-button'); + const fileChooserPromise = page.waitForEvent('filechooser'); + + await inputFileBtn.click(); + const fileChooser = await fileChooserPromise; + expect(fileChooser).toBeTruthy(); + + // Create the DataTransfer and File + const buffer = btoa('Example file content'); // create a base64 string + const dataTransfer = await page.evaluateHandle(async (data) => { + const dt = new DataTransfer(); + const blobData = await fetch(data).then((res) => res.blob()); + const file = new File([blobData], 'myFile.txt', { + type: 'text/plain', + }); + dt.items.add(file); + return dt; + }, `data:application/octet-stream;base64,${buffer}`); + + // Now dispatch + await page.dispatchEvent('ino-input-file', 'drop', { dataTransfer }); + + await expect(page.getByText('myFile.txt')).toBeVisible(); + }); + + test('should display drag and drop area without secondary text', async ({ + page, + }) => { + await goToStory(page, ['Input', 'ino-input-file', 'drag-and-drop']); + const inputFileBtn = page.locator('ino-input-file ino-button'); + const dndLabel = page.getByText('Drag your files here'); + + await expect(dndLabel).toBeVisible(); + await expect(inputFileBtn).toBeVisible(); + }); + + test('should display drag and drop area with secondary text', async ({ + page, + }) => { + await goToStory(page, [ + 'Input', + 'ino-input-file', + 'drag-and-drop-secondary-text', + ]); + const inputFileBtn = page.locator('ino-input-file ino-button'); + const dndLabel = page.getByText('click and drag here'); + const dndSecondLabel = page.getByText('click the button below'); + + await expect(dndLabel).toBeVisible(); + await expect(dndSecondLabel).toBeVisible(); + await expect(inputFileBtn).toBeVisible(); + }); +}); diff --git a/packages/storybook/src/stories/ino-input-file/ino-input-file.stories.ts b/packages/storybook/src/stories/ino-input-file/ino-input-file.stories.ts index 7a6fce1202..1bf377602f 100644 --- a/packages/storybook/src/stories/ino-input-file/ino-input-file.stories.ts +++ b/packages/storybook/src/stories/ino-input-file/ino-input-file.stories.ts @@ -12,15 +12,23 @@ const InoInputFileMeta = { useEffect(() => { const eventHandler = function (e) { e.stopImmediatePropagation(); - const el = e.target; + const el = e.target as HTMLInoInputFileElement; if (el.tagName.toLowerCase() !== 'ino-input-file') { return; } - const fileNames = e.detail.files - .map((f) => [f.name, f.type, f.size + ' bytes'].join(', ')) - .join('\n'); - alert(fileNames); + const fileNames: string[] = e.detail.files.map((f: File) => + [f.name, f.type, f.size + ' bytes'].join(', '), + ); + + const container = document.createElement('div'); + container.classList.add('file-list'); + fileNames.forEach((fileName) => { + container.append(fileName, document.createElement('br')); + }); + + el.parentElement.querySelector('.file-list')?.remove(); + el.parentElement.append(container); }; document.addEventListener('changeFile', eventHandler);