+Subject: Test Email for Convert Tool
+Content-Type: multipart/alternative;
+ boundary="------------boundary123456789"
+
+This is a multi-part message in MIME format.
+--------------boundary123456789
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 7bit
+
+Test Email for Convert Tool
+===========================
+
+This is a test email for testing the EML to PDF conversion functionality.
+
+Email Details:
+- From: test@example.com
+- To: recipient@example.com
+- Subject: Test Email for Convert Tool
+- Date: January 1, 2024
+
+Content Features:
+- Plain text content
+- HTML content (in alternative part)
+- Headers and metadata
+- MIME structure
+
+This email should convert to a PDF that includes:
+1. Email headers (From, To, Subject, Date)
+2. Email body content
+3. Proper formatting
+
+Important Notes:
+- This is a test email only
+- Generated for Stirling PDF testing
+- Contains no sensitive information
+- Should preserve email formatting in PDF
+
+Best regards,
+Test Email System
+
+--------------boundary123456789
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: 7bit
+
+
+
+
+
+ Test Email
+
+
+ Test Email for Convert Tool
+
+ This is a test email for testing the EML to PDF conversion functionality.
+
+ Email Details:
+
+ - From: test@example.com
+ - To: recipient@example.com
+ - Subject: Test Email for Convert Tool
+ - Date: January 1, 2024
+
+
+ Content Features:
+
+ - Plain text content
+ - HTML content (this part)
+ - Headers and metadata
+ - MIME structure
+
+
+
+
This email should convert to a PDF that includes:
+
+ - Email headers (From, To, Subject, Date)
+ - Email body content
+ - Proper formatting
+
+
+
+ Important Notes:
+
+ - This is a test email only
+ - Generated for Stirling PDF testing
+ - Contains no sensitive information
+ - Should preserve email formatting in PDF
+
+
+ Best regards,
+ Test Email System
+
+
+
+--------------boundary123456789--
\ No newline at end of file
diff --git a/frontend/src/tests/test-fixtures/sample.html b/frontend/src/tests/test-fixtures/sample.html
new file mode 100644
index 000000000..83a5260a7
--- /dev/null
+++ b/frontend/src/tests/test-fixtures/sample.html
@@ -0,0 +1,125 @@
+
+
+
+
+
+ Test HTML Document
+
+
+
+ Test HTML Document for Convert Tool
+
+ This is a test HTML file for testing the HTML to PDF conversion functionality. It contains various HTML elements to ensure proper conversion.
+
+ Text Formatting
+ This paragraph contains bold text, italic text, and inline code
.
+
+
+
Important: This is a highlighted section that should be preserved in the PDF output.
+
+
+ Lists
+ Unordered List
+
+ - First item
+ - Second item with a link
+ - Third item
+
+
+ Ordered List
+
+ - Primary point
+ - Secondary point
+ - Tertiary point
+
+
+ Table
+
+
+
+ Column 1 |
+ Column 2 |
+ Column 3 |
+
+
+
+
+ Data A |
+ Data B |
+ Data C |
+
+
+ Test 1 |
+ Test 2 |
+ Test 3 |
+
+
+ Sample X |
+ Sample Y |
+ Sample Z |
+
+
+
+
+ Code Block
+ function testFunction() {
+ console.log("This is a test function");
+ return "Hello from HTML to PDF conversion";
+}
+
+ Final Notes
+ This HTML document should convert to a well-formatted PDF that preserves:
+
+ - Text formatting (bold, italic)
+ - Headings and hierarchy
+ - Tables with proper borders
+ - Lists (ordered and unordered)
+ - Code formatting
+ - Basic CSS styling
+
+
+ Generated for Stirling PDF Convert Tool testing purposes.
+
+
\ No newline at end of file
diff --git a/frontend/src/tests/test-fixtures/sample.jpg b/frontend/src/tests/test-fixtures/sample.jpg
new file mode 100644
index 000000000..a2dc48c27
Binary files /dev/null and b/frontend/src/tests/test-fixtures/sample.jpg differ
diff --git a/frontend/src/tests/test-fixtures/sample.md b/frontend/src/tests/test-fixtures/sample.md
new file mode 100644
index 000000000..fba73ad74
--- /dev/null
+++ b/frontend/src/tests/test-fixtures/sample.md
@@ -0,0 +1,49 @@
+# Test Document for Convert Tool
+
+This is a **test** markdown file for testing the markdown to PDF conversion functionality.
+
+## Features Being Tested
+
+- **Bold text**
+- *Italic text*
+- [Links](https://example.com)
+- Lists and formatting
+
+### Code Block
+
+```javascript
+console.log('Hello, world!');
+function testFunction() {
+ return "This is a test";
+}
+```
+
+### Table
+
+| Column 1 | Column 2 | Column 3 |
+|----------|----------|----------|
+| Data 1 | Data 2 | Data 3 |
+| Test A | Test B | Test C |
+
+## Lists
+
+### Unordered List
+- Item 1
+- Item 2
+ - Nested item
+ - Another nested item
+- Item 3
+
+### Ordered List
+1. First item
+2. Second item
+3. Third item
+
+## Blockquote
+
+> This is a blockquote for testing purposes.
+> It should be properly formatted in the PDF output.
+
+## Conclusion
+
+This markdown file contains various elements to test the conversion functionality. The PDF output should preserve formatting, tables, code blocks, and other markdown elements.
\ No newline at end of file
diff --git a/frontend/src/tests/test-fixtures/sample.pdf b/frontend/src/tests/test-fixtures/sample.pdf
new file mode 100644
index 000000000..a7fb3ba0b
Binary files /dev/null and b/frontend/src/tests/test-fixtures/sample.pdf differ
diff --git a/frontend/src/tests/test-fixtures/sample.png b/frontend/src/tests/test-fixtures/sample.png
new file mode 100644
index 000000000..b6993935a
Binary files /dev/null and b/frontend/src/tests/test-fixtures/sample.png differ
diff --git a/frontend/src/tests/test-fixtures/sample.pptx b/frontend/src/tests/test-fixtures/sample.pptx
new file mode 100644
index 000000000..2067ee215
--- /dev/null
+++ b/frontend/src/tests/test-fixtures/sample.pptx
@@ -0,0 +1,12 @@
+# Test PPTX Presentation
+
+## Slide 1: Title
+This is a test PowerPoint presentation for conversion testing.
+
+## Slide 2: Content
+- Test bullet point 1
+- Test bullet point 2
+- Test bullet point 3
+
+## Slide 3: Conclusion
+This file should be sufficient for testing presentation conversions.
\ No newline at end of file
diff --git a/frontend/src/tests/test-fixtures/sample.svg b/frontend/src/tests/test-fixtures/sample.svg
new file mode 100644
index 000000000..c2056280a
--- /dev/null
+++ b/frontend/src/tests/test-fixtures/sample.svg
@@ -0,0 +1,32 @@
+
\ No newline at end of file
diff --git a/frontend/src/tests/test-fixtures/sample.txt b/frontend/src/tests/test-fixtures/sample.txt
new file mode 100644
index 000000000..903e18f09
--- /dev/null
+++ b/frontend/src/tests/test-fixtures/sample.txt
@@ -0,0 +1,8 @@
+This is a test text file for conversion testing.
+
+It contains multiple lines of text to test various conversion scenarios.
+Special characters: àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
+Numbers: 1234567890
+Symbols: !@#$%^&*()_+-=[]{}|;':\",./<>?
+
+This file should be sufficient for testing text-based conversions.
\ No newline at end of file
diff --git a/frontend/src/tests/test-fixtures/sample.xlsx b/frontend/src/tests/test-fixtures/sample.xlsx
new file mode 100644
index 000000000..7eb45724b
--- /dev/null
+++ b/frontend/src/tests/test-fixtures/sample.xlsx
@@ -0,0 +1,6 @@
+Name,Age,City,Country,Department,Salary
+John Doe,30,New York,USA,Engineering,75000
+Jane Smith,25,London,UK,Marketing,65000
+Bob Johnson,35,Toronto,Canada,Sales,70000
+Alice Brown,28,Sydney,Australia,Design,68000
+Charlie Wilson,42,Berlin,Germany,Operations,72000
\ No newline at end of file
diff --git a/frontend/src/tests/test-fixtures/sample.xml b/frontend/src/tests/test-fixtures/sample.xml
new file mode 100644
index 000000000..f39b92f6f
--- /dev/null
+++ b/frontend/src/tests/test-fixtures/sample.xml
@@ -0,0 +1,18 @@
+
+
+ Test Document
+
+
+ Introduction
+ This is a test XML document for conversion testing.
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/tools/Convert.test.tsx b/frontend/src/tools/Convert.test.tsx
new file mode 100644
index 000000000..ea764e204
--- /dev/null
+++ b/frontend/src/tools/Convert.test.tsx
@@ -0,0 +1,304 @@
+import React from 'react';
+import { render, screen, fireEvent, waitFor } from '@testing-library/react';
+import { describe, test, expect, beforeEach, vi } from 'vitest';
+import { MantineProvider } from '@mantine/core';
+import { I18nextProvider } from 'react-i18next';
+import i18n from '../i18n/config';
+import { FileContextProvider } from '../contexts/FileContext';
+import ConvertSettings from '../components/tools/convert/ConvertSettings';
+import { useConvertParameters } from '../hooks/tools/convert/useConvertParameters';
+
+// Mock the hooks
+vi.mock('../hooks/tools/convert/useConvertParameters');
+vi.mock('../hooks/useEndpointConfig');
+
+const mockUseConvertParameters = vi.mocked(useConvertParameters);
+
+// Mock endpoint availability - based on the real data you provided
+const mockEndpointStatus = {
+ 'file-to-pdf': true,
+ 'img-to-pdf': true,
+ 'markdown-to-pdf': true,
+ 'pdf-to-csv': true,
+ 'pdf-to-img': true,
+ 'pdf-to-text': true,
+ 'eml-to-pdf': false,
+ 'html-to-pdf': false,
+ 'pdf-to-html': false,
+ 'pdf-to-markdown': false,
+ 'pdf-to-pdfa': false,
+ 'pdf-to-presentation': false,
+ 'pdf-to-word': false,
+ 'pdf-to-xml': false
+};
+
+// Mock useMultipleEndpointsEnabled
+vi.mock('../hooks/useEndpointConfig', () => ({
+ useMultipleEndpointsEnabled: () => ({
+ endpointStatus: mockEndpointStatus,
+ loading: false,
+ error: null
+ })
+}));
+
+const TestWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => (
+
+
+
+ {children}
+
+
+
+);
+
+describe('Convert Tool Navigation Tests', () => {
+ const mockOnParameterChange = vi.fn();
+ const mockGetAvailableToExtensions = vi.fn();
+
+ beforeEach(() => {
+ vi.clearAllMocks();
+
+ mockUseConvertParameters.mockReturnValue({
+ parameters: {
+ fromExtension: '',
+ toExtension: '',
+ imageOptions: {
+ colorType: 'color',
+ dpi: 300,
+ singleOrMultiple: 'multiple'
+ }
+ },
+ updateParameter: mockOnParameterChange,
+ resetParameters: vi.fn(),
+ validateParameters: vi.fn(() => true),
+ getEndpointName: vi.fn(() => ''),
+ getEndpoint: vi.fn(() => ''),
+ getAvailableToExtensions: mockGetAvailableToExtensions,
+ detectFileExtension: vi.fn()
+ });
+ });
+
+ describe('FROM Dropdown - Endpoint Availability', () => {
+ test('should enable formats with available endpoints', async () => {
+ // Mock available conversions for formats with working endpoints
+ mockGetAvailableToExtensions.mockImplementation((fromExt) => {
+ const mockConversions = {
+ 'pdf': [{ value: 'png', label: 'PNG', group: 'Image' }, { value: 'csv', label: 'CSV', group: 'Spreadsheet' }],
+ 'docx': [{ value: 'pdf', label: 'PDF', group: 'Document' }],
+ 'png': [{ value: 'pdf', label: 'PDF', group: 'Document' }],
+ 'md': [{ value: 'pdf', label: 'PDF', group: 'Document' }],
+ 'eml': [{ value: 'pdf', label: 'PDF', group: 'Document' }],
+ 'html': [{ value: 'pdf', label: 'PDF', group: 'Document' }]
+ };
+ return mockConversions[fromExt] || [];
+ });
+
+ render(
+
+
+
+ );
+
+ // Open FROM dropdown by test id
+ const fromDropdown = screen.getByTestId('convert-from-dropdown');
+ fireEvent.click(fromDropdown);
+
+ await waitFor(() => {
+ // Should enable formats with available endpoints
+ expect(screen.getByTestId('format-option-pdf')).not.toBeDisabled();
+ expect(screen.getByTestId('format-option-docx')).not.toBeDisabled();
+ expect(screen.getByTestId('format-option-png')).not.toBeDisabled();
+ expect(screen.getByTestId('format-option-md')).not.toBeDisabled();
+
+ // Should disable formats without available endpoints
+ const emlButton = screen.getByTestId('format-option-eml');
+ expect(emlButton).toBeDisabled();
+ });
+ });
+
+ test('should show correct format groups', async () => {
+ render(
+
+
+
+ );
+
+ const fromDropdown = screen.getByTestId('convert-from-dropdown');
+ fireEvent.click(fromDropdown);
+
+ await waitFor(() => {
+ // Check if format groups are displayed
+ expect(screen.getByText('Document')).toBeInTheDocument();
+ expect(screen.getByText('Image')).toBeInTheDocument();
+ expect(screen.getByText('Text')).toBeInTheDocument();
+ expect(screen.getByText('Email')).toBeInTheDocument();
+ });
+ });
+ });
+
+ describe('TO Dropdown - Available Conversions', () => {
+ test('should show available conversions for PDF', async () => {
+ // Mock PDF conversions
+ mockGetAvailableToExtensions.mockReturnValue([
+ { value: 'png', label: 'PNG', group: 'Image' },
+ { value: 'csv', label: 'CSV', group: 'Spreadsheet' },
+ { value: 'txt', label: 'TXT', group: 'Text' },
+ { value: 'docx', label: 'DOCX', group: 'Document' },
+ { value: 'html', label: 'HTML', group: 'Web' }
+ ]);
+
+ render(
+
+
+
+ );
+
+ // Open TO dropdown
+ const toDropdown = screen.getByTestId('convert-to-dropdown');
+ fireEvent.click(toDropdown);
+
+ await waitFor(() => {
+ // Should enable formats with available endpoints
+ expect(screen.getByTestId('format-option-png')).not.toBeDisabled();
+ expect(screen.getByTestId('format-option-csv')).not.toBeDisabled();
+ expect(screen.getByTestId('format-option-txt')).not.toBeDisabled();
+
+ // Should disable formats without available endpoints
+ expect(screen.getByTestId('format-option-docx')).toBeDisabled(); // pdf-to-word is false
+ expect(screen.getByTestId('format-option-html')).toBeDisabled(); // pdf-to-html is false
+ });
+ });
+
+ test('should show image-specific options when converting to image formats', async () => {
+ mockGetAvailableToExtensions.mockReturnValue([
+ { value: 'png', label: 'PNG', group: 'Image' }
+ ]);
+
+ render(
+
+
+
+ );
+
+ // Should show image conversion settings
+ await waitFor(() => {
+ expect(screen.getByTestId('image-options-section')).toBeInTheDocument();
+ expect(screen.getByTestId('dpi-input')).toHaveValue('300');
+ });
+ });
+
+ test('should show email-specific note for EML conversions', async () => {
+ mockGetAvailableToExtensions.mockReturnValue([
+ { value: 'pdf', label: 'PDF', group: 'Document' }
+ ]);
+
+ render(
+
+
+
+ );
+
+ // Should show EML-specific options
+ await waitFor(() => {
+ expect(screen.getByTestId('eml-options-section')).toBeInTheDocument();
+ expect(screen.getByTestId('eml-options-note')).toBeInTheDocument();
+ });
+ });
+ });
+
+ describe('Conversion Flow Navigation', () => {
+ test('should reset TO extension when FROM extension changes', async () => {
+ mockGetAvailableToExtensions.mockImplementation((fromExt) => {
+ if (fromExt === 'pdf') return [{ value: 'png', label: 'PNG', group: 'Image' }];
+ if (fromExt === 'docx') return [{ value: 'pdf', label: 'PDF', group: 'Document' }];
+ return [];
+ });
+
+ render(
+
+
+
+ );
+
+ // Select a different FROM format
+ const fromDropdown = screen.getByTestId('convert-from-dropdown');
+ fireEvent.click(fromDropdown);
+
+ await waitFor(() => {
+ const docxButton = screen.getByTestId('format-option-docx');
+ fireEvent.click(docxButton);
+ });
+
+ // Should reset TO extension
+ expect(mockOnParameterChange).toHaveBeenCalledWith('fromExtension', 'docx');
+ expect(mockOnParameterChange).toHaveBeenCalledWith('toExtension', '');
+ });
+
+ test('should show placeholder when no FROM format is selected', () => {
+ render(
+
+
+
+ );
+
+ // TO dropdown should show disabled state
+ expect(screen.getByText('Select a source format first')).toBeInTheDocument();
+ });
+ });
+});
\ No newline at end of file
diff --git a/frontend/src/tools/Convert.tsx b/frontend/src/tools/Convert.tsx
index 864fde0d7..d58d2f29e 100644
--- a/frontend/src/tools/Convert.tsx
+++ b/frontend/src/tools/Convert.tsx
@@ -122,6 +122,7 @@ const Convert = ({ selectedFiles = [], onPreviewFile }: ConvertProps) => {
disabled={!convertParams.validateParameters() || !hasFiles || !endpointEnabled}
loadingText={t("convert.converting", "Converting...")}
submitText={t("convert.convertFiles", "Convert Files")}
+ data-testid="convert-button"
/>
)}