diff --git a/libs/core/jest.config.js b/libs/core/jest.config.js new file mode 100644 index 000000000..0d7ae9476 --- /dev/null +++ b/libs/core/jest.config.js @@ -0,0 +1,31 @@ +module.exports = { + // E2E tests timeout configuration + testTimeout: 60000, // 60 seconds for E2E tests that may be slow + + // Setup files for E2E tests + setupFilesAfterEnv: ['/src/test-setup.js'], + + // Test patterns + testMatch: [ + '**/__tests__/**/*.(js|ts|tsx)', + '**/*.(test|spec|e2e).(js|ts|tsx)' + ], + + // Transform configuration + transform: { + '^.+\\.(ts|tsx)$': 'ts-jest' + }, + + // Module file extensions + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'], + + // Coverage settings + collectCoverageFrom: [ + 'src/**/*.{ts,tsx}', + '!src/**/*.d.ts', + '!src/**/*.stories.*', + '!src/**/*.test.*', + '!src/**/*.spec.*', + '!src/**/*.e2e.*' + ] +}; \ No newline at end of file diff --git a/libs/core/src/components/pds-checkbox/test/pds-checkbox.e2e.ts b/libs/core/src/components/pds-checkbox/test/pds-checkbox.e2e.ts index 6721e1601..64c4dfe3f 100644 --- a/libs/core/src/components/pds-checkbox/test/pds-checkbox.e2e.ts +++ b/libs/core/src/components/pds-checkbox/test/pds-checkbox.e2e.ts @@ -5,14 +5,19 @@ describe('pds-checkbox', () => { const page = await newE2EPage(); await page.setContent(''); + // Wait for initial render to complete + await page.waitForChanges(); + const component = await page.find('pds-checkbox'); expect(component).toHaveClass('hydrated'); const checkbox = await page.find('pds-checkbox >>> input'); await checkbox.click(); + await page.waitForChanges(); expect(await checkbox.getProperty('checked')).toBeTruthy(); await checkbox.click(); + await page.waitForChanges(); expect(await checkbox.getProperty('checked')).toBeFalsy(); }); @@ -22,7 +27,7 @@ describe('pds-checkbox', () => { const component = await page.find('pds-checkbox'); expect(component).toHaveClass('hydrated'); - let checkbox = await page.find('pds-checkbox >>> input'); + const checkbox = await page.find('pds-checkbox >>> input'); component.setProperty('disabled', false); await page.waitForChanges(); expect(await checkbox.getProperty('disabled')).toBe(false); diff --git a/libs/core/src/components/pds-dropdown-menu/test/pds-dropdown-menu.e2e.ts b/libs/core/src/components/pds-dropdown-menu/test/pds-dropdown-menu.e2e.ts index 032e9cc54..1a96fa295 100644 --- a/libs/core/src/components/pds-dropdown-menu/test/pds-dropdown-menu.e2e.ts +++ b/libs/core/src/components/pds-dropdown-menu/test/pds-dropdown-menu.e2e.ts @@ -5,6 +5,9 @@ describe('pds-dropdown-menu', () => { const page = await newE2EPage(); await page.setContent(''); + // Wait for initial render to complete + await page.waitForChanges(); + const element = await page.find('pds-dropdown-menu'); expect(element).toHaveClass('hydrated'); }); @@ -21,7 +24,7 @@ describe('pds-dropdown-menu', () => { // Get the trigger button const triggerButton = await page.find('button[slot="trigger"]'); - + // Initial state: dropdown should be closed const isInitiallyHidden = await page.evaluate(() => { const dropdown = document.querySelector('pds-dropdown-menu'); @@ -29,10 +32,10 @@ describe('pds-dropdown-menu', () => { return panel.classList.contains('is-hidden'); }); expect(isInitiallyHidden).toBe(true); - + // Click to open await triggerButton.click(); - + // After click: dropdown should be open const isOpenAfterClick = await page.evaluate(() => { const dropdown = document.querySelector('pds-dropdown-menu'); @@ -40,14 +43,14 @@ describe('pds-dropdown-menu', () => { return !panel.classList.contains('is-hidden'); }); expect(isOpenAfterClick).toBe(true); - + // Check ARIA attributes after opening const ariaExpandedAfterOpen = await triggerButton.getAttribute('aria-expanded'); expect(ariaExpandedAfterOpen).toBe('true'); - + // Click again to close await triggerButton.click(); - + // After second click: dropdown should be closed const isClosedAfterSecondClick = await page.evaluate(() => { const dropdown = document.querySelector('pds-dropdown-menu'); @@ -55,7 +58,7 @@ describe('pds-dropdown-menu', () => { return panel.classList.contains('is-hidden'); }); expect(isClosedAfterSecondClick).toBe(true); - + // Check ARIA attributes after closing const ariaExpandedAfterClose = await triggerButton.getAttribute('aria-expanded'); expect(ariaExpandedAfterClose).toBe('false'); @@ -74,7 +77,7 @@ describe('pds-dropdown-menu', () => { // Open the dropdown const triggerButton = await page.find('button[slot="trigger"]'); await triggerButton.click(); - + // Verify it's open const isOpen = await page.evaluate(() => { const dropdown = document.querySelector('pds-dropdown-menu'); @@ -82,10 +85,10 @@ describe('pds-dropdown-menu', () => { return !panel.classList.contains('is-hidden'); }); expect(isOpen).toBe(true); - + // Press Escape key await page.keyboard.press('Escape'); - + // Verify it's closed const isClosed = await page.evaluate(() => { const dropdown = document.querySelector('pds-dropdown-menu'); @@ -111,32 +114,32 @@ describe('pds-dropdown-menu', () => { // Open the dropdown const triggerButton = await page.find('button[slot="trigger"]'); await triggerButton.click(); - + // Wait for the dropdown to be fully open await page.waitForChanges(); - + // Verify the dropdown is open const ariaExpandedAfterOpen = await triggerButton.getAttribute('aria-expanded'); expect(ariaExpandedAfterOpen).toBe('true'); - + // Find an item and click it const firstItem = await page.find('#item1'); const clickSpy = await page.spyOnEvent('pdsClick'); - + await firstItem.click(); await page.waitForChanges(); - + // Verify the item emitted a click event expect(clickSpy).toHaveReceivedEvent(); - + // The dropdown remains open after clicking an item (this is the actual behavior) const ariaExpandedAfterClick = await triggerButton.getAttribute('aria-expanded'); expect(ariaExpandedAfterClick).toBe('true'); - + // Close the dropdown by pressing Escape await page.keyboard.press('Escape'); await page.waitForChanges(); - + // Verify the dropdown is now closed const ariaExpandedAfterEscape = await triggerButton.getAttribute('aria-expanded'); expect(ariaExpandedAfterEscape).toBe('false'); diff --git a/libs/core/src/components/pds-input/test/pds-input.e2e.ts b/libs/core/src/components/pds-input/test/pds-input.e2e.ts index 7776661e5..8ba918879 100644 --- a/libs/core/src/components/pds-input/test/pds-input.e2e.ts +++ b/libs/core/src/components/pds-input/test/pds-input.e2e.ts @@ -41,8 +41,11 @@ describe('pds-input', () => { await page.waitForChanges(); const inputSpy = await page.spyOnEvent('pdsInput'); - await page.keyboard.type('Hello'); + + // Use direct input typing instead of keyboard events (fixes timeout issues) + await input.type('Hello'); await page.waitForChanges(); + value = await input.getProperty('value'); expect(inputSpy).toHaveReceivedEvent(); }); diff --git a/libs/core/src/components/pds-modal/test/pds-modal.e2e.ts b/libs/core/src/components/pds-modal/test/pds-modal.e2e.ts index f62829a00..bdb54f1fc 100644 --- a/libs/core/src/components/pds-modal/test/pds-modal.e2e.ts +++ b/libs/core/src/components/pds-modal/test/pds-modal.e2e.ts @@ -5,6 +5,9 @@ describe('pds-modal', () => { const page = await newE2EPage(); await page.setContent(''); + // Wait for initial render to complete + await page.waitForChanges(); + const element = await page.find('pds-modal'); expect(element).toHaveClass('hydrated'); }); diff --git a/libs/core/src/components/pds-progress/test/pds-progress.e2e.ts b/libs/core/src/components/pds-progress/test/pds-progress.e2e.ts index c13f9c707..6032872cf 100644 --- a/libs/core/src/components/pds-progress/test/pds-progress.e2e.ts +++ b/libs/core/src/components/pds-progress/test/pds-progress.e2e.ts @@ -5,6 +5,9 @@ describe('pds-progress', () => { const page = await newE2EPage(); await page.setContent(''); + // Wait for initial render to complete + await page.waitForChanges(); + const element = await page.find('pds-progress'); expect(element).toHaveClass('hydrated'); }); diff --git a/libs/core/src/test-setup.js b/libs/core/src/test-setup.js new file mode 100644 index 000000000..2ae2aea3e --- /dev/null +++ b/libs/core/src/test-setup.js @@ -0,0 +1,12 @@ +// E2E Test Setup Configuration +// Increase timeout for all E2E tests globally +jest.setTimeout(60000); // 60 seconds + +// Global test setup if needed +beforeAll(() => { + // Any global setup for E2E tests +}); + +afterAll(() => { + // Any global cleanup for E2E tests +}); \ No newline at end of file diff --git a/libs/core/stencil.config.ts b/libs/core/stencil.config.ts index e4c7e21e3..4918d0366 100644 --- a/libs/core/stencil.config.ts +++ b/libs/core/stencil.config.ts @@ -11,6 +11,14 @@ export const config: Config = { openBrowser: false, port: 7300, }, + testing: { + browserHeadless: "shell", + browserArgs: [ + '--no-sandbox', + '--disable-dev-shm-usage', + '--disable-gpu' + ], + }, outputTargets: [ { type: 'dist',