From b53411f026f6af25a96aabcc5e12e57e1ca145d5 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 09:58:29 +0100 Subject: [PATCH 01/22] pull in changes --- src/enrichments/heatmap.ts | 14 +++-- src/ui/toggle-injector.ts | 6 +- tests/e2e/heatmap.spec.ts | 121 +++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 tests/e2e/heatmap.spec.ts diff --git a/src/enrichments/heatmap.ts b/src/enrichments/heatmap.ts index 0574c0b..af2d47d 100644 --- a/src/enrichments/heatmap.ts +++ b/src/enrichments/heatmap.ts @@ -504,13 +504,19 @@ export function toggleHeatmap( } // Check if this specific heatmap is already active - const isActive = isHeatmapActive(table, index, type); + const isActive = isHeatmapActive(table, type === 'table' ? -1 : index, type); + if (isActive) { // If it's active, remove just this specific heatmap - removeHeatmap(table, index, type); + removeHeatmap(table, type === 'table' ? -1 : index, type); } else { - // If not active, apply the new heatmap (can have multiple heatmaps on different rows/columns) - applyHeatmap(table, index, type, options); + // If not active, apply the new heatmap + if (type === 'table') { + applyTableHeatmap(table, options); + } else { + // For row/column, apply the new heatmap + applyHeatmap(table, index, type, options); + } } } diff --git a/src/ui/toggle-injector.ts b/src/ui/toggle-injector.ts index 1eae54c..7a5685e 100644 --- a/src/ui/toggle-injector.ts +++ b/src/ui/toggle-injector.ts @@ -2,7 +2,7 @@ import { injectPlusIcons, removePlusIcons, plusIconStyles } from './header-utils import type { HeaderType } from './header-utils'; import { removeAllMenus } from './enrichment-menu'; import { analyzeTable } from '../core/table-detection'; -import { toggleHeatmap, applyTableHeatmap } from '../enrichments/heatmap'; +import { toggleHeatmap } from '../enrichments/heatmap'; import { calculateStatistics } from '../enrichments/statistics'; import { analyzeFrequencies } from '../utils/frequency'; import { cleanNumericCell } from '../core/type-detection'; @@ -134,8 +134,8 @@ function handleEnrichmentSelected(event: Event) { toggleHeatmap(table, rowIndex + 1, 'row'); } } else if (type === 'table') { - // Apply heatmap to all numeric cells in the table - applyTableHeatmap(table); + // Toggle heatmap on all numeric cells in the table + toggleHeatmap(table, -1, 'table'); } } else if (enrichmentType === 'statistics' && type === 'column') { // Type assertion for table header cell diff --git a/tests/e2e/heatmap.spec.ts b/tests/e2e/heatmap.spec.ts new file mode 100644 index 0000000..3d1c1d7 --- /dev/null +++ b/tests/e2e/heatmap.spec.ts @@ -0,0 +1,121 @@ +import { test, expect } from '@playwright/test' + +/** + * End-to-end tests for Grid-Sight heatmap functionality + * + * These tests verify that heatmap enrichments can be applied and removed correctly + */ + +test.describe('Grid-Sight Heatmap', () => { + // Test setup - start server and navigate to demo page + test.beforeEach(async ({ page }) => { + // Start the preview server + const { preview } = await import('vite') + const server = await preview({ + preview: { + port: 3001, + open: false, + }, + build: { + outDir: 'dist' + } + }) + + // Store the server in the test info + test.info().attachments.push({ + name: 'server', + body: Buffer.from(JSON.stringify(server as unknown as Record)), + contentType: 'application/json' + }) + + // Navigate to the demo page + await page.goto('http://localhost:3001/demo/') + + // Wait for the page to load completely + await page.waitForLoadState('domcontentloaded') + + // Wait for Grid-Sight to initialize + await page.waitForFunction(() => { + const consoleEl = document.getElementById('console') + return consoleEl && consoleEl.textContent && + consoleEl.textContent.includes('GridSight loaded successfully') + }, { timeout: 5000 }) + }) + + // Close the server after each test + test.afterEach(async ({ page: _page }, testInfo) => { + // Get the server from the test info + const serverAttachment = testInfo.attachments.find(a => a.name === 'server') + if (serverAttachment && serverAttachment.body) { + const server = JSON.parse(serverAttachment.body.toString()) + // Close the preview server + await new Promise(resolve => server.httpServer.close(resolve)) + } + }) + + // Test table-wide heatmap toggle functionality + test('should toggle table-wide heatmap on and off correctly', async ({ page }) => { + // Get the first table + const table = page.locator('table').first() + + // Open the table menu + await page.click('.gs-table-header-menu-button') + + // Wait for the menu to appear + await page.waitForSelector('.gs-menu-container') + + // Click on the heatmap option + await page.getByText('Heatmap').click() + + // Wait for the heatmap to be applied + await page.waitForFunction(() => { + const table = document.querySelector('table') + return table && table.classList.contains('gs-heatmap') + }, { timeout: 5000 }) + + // Verify that the table has the heatmap class + await expect(table).toHaveClass(/gs-heatmap/) + + // Verify that cells have background colors (indicating heatmap is applied) + const cellsWithColor = await page.evaluate(() => { + const cells = Array.from(document.querySelectorAll('table td')) + return cells.filter(cell => { + const style = window.getComputedStyle(cell) + return style.backgroundColor !== 'rgba(0, 0, 0, 0)' && + style.backgroundColor !== 'rgb(255, 255, 255)' && + style.backgroundColor !== 'transparent' + }).length + }) + + // Ensure we have cells with background color + expect(cellsWithColor).toBeGreaterThan(0) + + // Toggle the heatmap off by clicking the menu option again + await page.click('.gs-table-header-menu-button') + await page.waitForSelector('.gs-menu-container') + await page.getByText('Heatmap').click() + + // Wait for the heatmap to be removed + await page.waitForFunction(() => { + const table = document.querySelector('table') + return table && !table.classList.contains('gs-heatmap') + }, { timeout: 5000 }) + + // Verify that the table no longer has the heatmap class + await expect(table).not.toHaveClass(/gs-heatmap/) + + // Verify that cells no longer have background colors + const cellsWithColorAfterToggle = await page.evaluate(() => { + const cells = Array.from(document.querySelectorAll('table td')) + return cells.filter(cell => { + const style = window.getComputedStyle(cell) + return style.backgroundColor !== 'rgba(0, 0, 0, 0)' && + style.backgroundColor !== 'rgb(255, 255, 255)' && + style.backgroundColor !== 'transparent' + }).length + }) + + // Ensure no cells have background color + expect(cellsWithColorAfterToggle).toBe(0) + }) +}) \ No newline at end of file From 7746baee45e3c3a5a22e39872debafaeff74623b Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 10:03:06 +0100 Subject: [PATCH 02/22] allow table level heatmap to be removed --- src/enrichments/heatmap.ts | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/enrichments/heatmap.ts b/src/enrichments/heatmap.ts index af2d47d..f884224 100644 --- a/src/enrichments/heatmap.ts +++ b/src/enrichments/heatmap.ts @@ -497,26 +497,21 @@ export function toggleHeatmap( type: HeatmapType = 'column', options: HeatmapOptions = {} ): void { - if (type === 'table') { - // For table-wide heatmap, delegate to applyTableHeatmap - applyTableHeatmap(table, options); - return; - } - // Check if this specific heatmap is already active - const isActive = isHeatmapActive(table, type === 'table' ? -1 : index, type); + // For table type, use index -1 + const effectiveIndex = type === 'table' ? -1 : index + const isActive = isHeatmapActive(table, effectiveIndex, type) - if (isActive) { // If it's active, remove just this specific heatmap - removeHeatmap(table, type === 'table' ? -1 : index, type); + removeHeatmap(table, effectiveIndex, type) } else { // If not active, apply the new heatmap if (type === 'table') { - applyTableHeatmap(table, options); + applyTableHeatmap(table, options) } else { // For row/column, apply the new heatmap - applyHeatmap(table, index, type, options); + applyHeatmap(table, index, type, options) } } } From c99a0149aa47998c12a3075e53d61fddb8737e40 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 12:37:26 +0100 Subject: [PATCH 03/22] make vite ignore playwright tests --- vitest.config.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vitest.config.ts b/vitest.config.ts index 3e17b8b..b9a30a8 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -6,6 +6,8 @@ export default defineConfig({ globals: true, environment: 'jsdom', setupFiles: ['./src/test-setup.ts'], + include: ['tests/unit/**/*.test.ts', 'src/**/*.test.ts'], + exclude: ['node_modules/**', 'dist/**', '.git/**', 'coverage/**', 'tests/e2e/**'], coverage: { reporter: ['text', 'json', 'html'], exclude: [ From f98f69de64a9a466f6f4e4db8d7ec6d08e08a35d Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 12:37:45 +0100 Subject: [PATCH 04/22] progress on heatmap test --- tests/unit/heatmap.test.ts | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 tests/unit/heatmap.test.ts diff --git a/tests/unit/heatmap.test.ts b/tests/unit/heatmap.test.ts new file mode 100644 index 0000000..b8d2f2f --- /dev/null +++ b/tests/unit/heatmap.test.ts @@ -0,0 +1,48 @@ +import { describe, it, expect, beforeEach, vi } from 'vitest' + +import * as HeatmapModule from '../../src/enrichments/heatmap.ts' +const { toggleHeatmap } = HeatmapModule + +describe('Heatmap Toggle', () => { + let mockTable: HTMLTableElement + + beforeEach(() => { + // Create a mock table element + mockTable = document.createElement('table') as HTMLTableElement + + // Create spies on actual functions + const mockIsHeatmapActive = vi.spyOn(HeatmapModule, 'isHeatmapActive') + const mockApplyTableHeatmap = vi.spyOn(HeatmapModule, 'applyTableHeatmap') + const mockRemoveHeatmap = vi.spyOn(HeatmapModule, 'removeHeatmap') + + mockIsHeatmapActive.mockReset() + mockApplyTableHeatmap.mockReset() + mockRemoveHeatmap.mockReset() + }) + + it('should apply table heatmap when not active', () => { + // Setup: heatmap is not active + vi.spyOn(HeatmapModule, 'isHeatmapActive').mockReturnValue(false) + + // Execute + toggleHeatmap(mockTable, -1, 'table') + + // Verify + expect(HeatmapModule.isHeatmapActive).toHaveBeenCalledWith(mockTable, -1, 'table') + expect(HeatmapModule.applyTableHeatmap).toHaveBeenCalledWith(mockTable, {}) + expect(HeatmapModule.removeHeatmap).not.toHaveBeenCalled() + }) + + it('should remove table heatmap when already active', () => { + // Setup: heatmap is active + vi.spyOn(HeatmapModule, 'isHeatmapActive').mockReturnValue(true) + + // Execute + toggleHeatmap(mockTable, -1, 'table') + + // Verify + expect(HeatmapModule.isHeatmapActive).toHaveBeenCalledWith(mockTable, -1, 'table') + expect(HeatmapModule.removeHeatmap).toHaveBeenCalledWith(mockTable, -1, 'table') + expect(HeatmapModule.applyTableHeatmap).not.toHaveBeenCalled() + }) +}) From abcae9cfd3c1d80eb411932507080b482ac31802 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 13:07:11 +0100 Subject: [PATCH 05/22] update tests --- ...test.ts => frequency.test-interactions.ts} | 0 ...quency.test.ts => frequency-calcs.test.ts} | 0 ...p.test.ts => heatmap-interactions.test.ts} | 79 ++++++++++--------- src/utils/frequency.ts | 2 +- tests/unit/heatmap.test.ts | 48 ----------- 5 files changed, 43 insertions(+), 86 deletions(-) rename src/__tests__/enrichments/{frequency.test.ts => frequency.test-interactions.ts} (100%) rename src/__tests__/utils/{frequency.test.ts => frequency-calcs.test.ts} (100%) rename src/enrichments/__tests__/{heatmap.test.ts => heatmap-interactions.test.ts} (89%) delete mode 100644 tests/unit/heatmap.test.ts diff --git a/src/__tests__/enrichments/frequency.test.ts b/src/__tests__/enrichments/frequency.test-interactions.ts similarity index 100% rename from src/__tests__/enrichments/frequency.test.ts rename to src/__tests__/enrichments/frequency.test-interactions.ts diff --git a/src/__tests__/utils/frequency.test.ts b/src/__tests__/utils/frequency-calcs.test.ts similarity index 100% rename from src/__tests__/utils/frequency.test.ts rename to src/__tests__/utils/frequency-calcs.test.ts diff --git a/src/enrichments/__tests__/heatmap.test.ts b/src/enrichments/__tests__/heatmap-interactions.test.ts similarity index 89% rename from src/enrichments/__tests__/heatmap.test.ts rename to src/enrichments/__tests__/heatmap-interactions.test.ts index 2e94296..8c65e54 100644 --- a/src/enrichments/__tests__/heatmap.test.ts +++ b/src/enrichments/__tests__/heatmap-interactions.test.ts @@ -6,28 +6,34 @@ describe('Heatmap', () => { const createTestTable = (): HTMLTableElement => { const table = document.createElement('table'); table.innerHTML = ` - - - Product - Q1 - Q2 - Q3 - - - - - Widget A - 10 - 20 - 30 - - - Widget B - 15 - 25 - 35 - - + + Gear / Revs + 5 + 10 + 15 + 20 + + + Low + 10 + 15 + 20 + 25 + + + Medium + 17 + 22 + 27 + 32 + + + High + 27 + 25 + 30 + 35 + `; document.body.appendChild(table); return table; @@ -124,7 +130,7 @@ describe('Heatmap', () => { toggleHeatmap(table, columnIndex, 'column'); // Get a reference to a cell that should be colored - const cell = table.querySelector('td') as HTMLElement; + const cell = table.querySelector('#cell-1-1') as HTMLElement; expect(cell).toBeTruthy(); const initialColor = cell.style.backgroundColor; expect(initialColor).toBeTruthy(); @@ -144,11 +150,11 @@ describe('Heatmap', () => { toggleHeatmap(table, 1, 'column'); // Get the cell that will be split - const cell = table.querySelector('tbody tr:nth-child(1) td:nth-child(1)') as HTMLElement; + const cell = table.querySelector('#cell-1-1') as HTMLElement; const initialColor = cell.style.backgroundColor; - + // Apply row heatmap that will overlap with the column - toggleHeatmap(table, 0, 'row'); + toggleHeatmap(table, 2, 'row'); // Should have the split class and custom properties expect(cell.classList.contains('gs-heatmap-split')).toBe(true); @@ -159,8 +165,8 @@ describe('Heatmap', () => { expect(cell.style.backgroundColor).toBe(''); // Remove the row heatmap - removeHeatmap(table, 0, 'row'); - + removeHeatmap(table, 2, 'row'); + // Should remove the split and restore column heatmap expect(cell.classList.contains('gs-heatmap-split')).toBe(false); expect(cell.style.backgroundColor).toBe(initialColor); @@ -175,14 +181,14 @@ describe('Heatmap', () => { // Apply both row and column heatmaps toggleHeatmap(table, 1, 'column'); - toggleHeatmap(table, 0, 'row'); + toggleHeatmap(table, 2, 'row'); // Get the cell at the intersection - const cell = table.querySelector('tbody tr:nth-child(1) td:nth-child(2)') as HTMLElement; - + const cell = table.querySelector('#cell-1-1') as HTMLElement; + // Remove the column heatmap removeHeatmap(table, 1, 'column'); - + // Should remove the split and restore row heatmap expect(cell.classList.contains('gs-heatmap-split')).toBe(false); expect(cell.style.getPropertyValue('--split-color-1')).toBe(''); @@ -198,7 +204,7 @@ describe('Heatmap', () => { it('should apply heatmap to a numeric row', () => { // Arrange const table = createTestTable(); - const rowIndex = 1; // First data row + const rowIndex = 2; // First data row // Act - apply heatmap to the first data row toggleHeatmap(table, rowIndex, 'row'); @@ -208,7 +214,7 @@ describe('Heatmap', () => { expect(table.classList.contains('gs-heatmap')).toBe(true); // 2. Check if cells in the row have background colors - const row = table.rows[rowIndex]; + const row = table.rows[rowIndex - 1]; expect(row).toBeTruthy(); // Skip the first cell (text label) and check the rest @@ -245,7 +251,7 @@ describe('Heatmap', () => { // Apply both row and column heatmaps to create a split cell applyHeatmap(table, 1, 'column'); - applyHeatmap(table, 1, 'row'); + applyHeatmap(table, 2, 'row'); // Get the cell at the intersection const cell = getCell(table, 1, 1); @@ -262,9 +268,8 @@ describe('Heatmap', () => { expect(cell.classList.contains('gs-heatmap-split')).toBe(false); expect(cell.style.getPropertyValue('--split-color-1')).toBe(''); expect(cell.style.getPropertyValue('--split-color-2')).toBe(''); - + // The other heatmap should still be active - expect(cell.classList.contains('gs-heatmap-cell')).toBe(true); expect(cell.style.backgroundColor).toBeTruthy(); // Clean up diff --git a/src/utils/frequency.ts b/src/utils/frequency.ts index 691a5b5..2cb3b19 100644 --- a/src/utils/frequency.ts +++ b/src/utils/frequency.ts @@ -59,7 +59,7 @@ function analyzeFrequencies(values: unknown[]): FrequencyResult[] { return sortedFrequencies.map(([value, count]) => [ value, count, - (count / total) * 100 + Number(((count / total) * 100).toFixed(1)) ]) } diff --git a/tests/unit/heatmap.test.ts b/tests/unit/heatmap.test.ts deleted file mode 100644 index b8d2f2f..0000000 --- a/tests/unit/heatmap.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { describe, it, expect, beforeEach, vi } from 'vitest' - -import * as HeatmapModule from '../../src/enrichments/heatmap.ts' -const { toggleHeatmap } = HeatmapModule - -describe('Heatmap Toggle', () => { - let mockTable: HTMLTableElement - - beforeEach(() => { - // Create a mock table element - mockTable = document.createElement('table') as HTMLTableElement - - // Create spies on actual functions - const mockIsHeatmapActive = vi.spyOn(HeatmapModule, 'isHeatmapActive') - const mockApplyTableHeatmap = vi.spyOn(HeatmapModule, 'applyTableHeatmap') - const mockRemoveHeatmap = vi.spyOn(HeatmapModule, 'removeHeatmap') - - mockIsHeatmapActive.mockReset() - mockApplyTableHeatmap.mockReset() - mockRemoveHeatmap.mockReset() - }) - - it('should apply table heatmap when not active', () => { - // Setup: heatmap is not active - vi.spyOn(HeatmapModule, 'isHeatmapActive').mockReturnValue(false) - - // Execute - toggleHeatmap(mockTable, -1, 'table') - - // Verify - expect(HeatmapModule.isHeatmapActive).toHaveBeenCalledWith(mockTable, -1, 'table') - expect(HeatmapModule.applyTableHeatmap).toHaveBeenCalledWith(mockTable, {}) - expect(HeatmapModule.removeHeatmap).not.toHaveBeenCalled() - }) - - it('should remove table heatmap when already active', () => { - // Setup: heatmap is active - vi.spyOn(HeatmapModule, 'isHeatmapActive').mockReturnValue(true) - - // Execute - toggleHeatmap(mockTable, -1, 'table') - - // Verify - expect(HeatmapModule.isHeatmapActive).toHaveBeenCalledWith(mockTable, -1, 'table') - expect(HeatmapModule.removeHeatmap).toHaveBeenCalledWith(mockTable, -1, 'table') - expect(HeatmapModule.applyTableHeatmap).not.toHaveBeenCalled() - }) -}) From e2d2ab6058a9c98aeaac426799a9554074dea3a1 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 13:34:26 +0100 Subject: [PATCH 06/22] simplify demo structure, reflect in tests --- public/{demo => }/index.html | 0 scripts/copy-demo.js | 2 +- tests/e2e/demo.spec.ts | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename public/{demo => }/index.html (100%) diff --git a/public/demo/index.html b/public/index.html similarity index 100% rename from public/demo/index.html rename to public/index.html diff --git a/scripts/copy-demo.js b/scripts/copy-demo.js index 4945427..91fae89 100644 --- a/scripts/copy-demo.js +++ b/scripts/copy-demo.js @@ -12,7 +12,7 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const rootDir = path.resolve(__dirname, '..'); -const sourceDir = path.join(rootDir, 'public', 'demo'); +const sourceDir = path.join(rootDir, 'public'); const targetDir = path.join(rootDir, 'dist'); async function copyDemoFiles() { diff --git a/tests/e2e/demo.spec.ts b/tests/e2e/demo.spec.ts index f5af548..6db7406 100644 --- a/tests/e2e/demo.spec.ts +++ b/tests/e2e/demo.spec.ts @@ -24,7 +24,7 @@ test.describe('Grid-Sight Demo', () => { try { // Navigate to the demo page - await page.goto('http://localhost:3001/demo/'); + await page.goto('http://localhost:3001/'); // Wait for the page to load completely await page.waitForLoadState('domcontentloaded'); @@ -75,7 +75,7 @@ test.describe('Grid-Sight Demo', () => { test.skip(!!process.env.CI, 'Skipping file:// test in CI environment'); // Navigate to the demo page directly - await page.goto(`file://${process.cwd()}/dist/demo/index.html`); + await page.goto(`file://${process.cwd()}/dist/index.html`); // Wait for the page to load completely await page.waitForLoadState('domcontentloaded'); From 0f8a3704bb87ff3f46304a804fc5e99d7616e098 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 13:35:23 +0100 Subject: [PATCH 07/22] improve e2e --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 82a9695..78c585c 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,8 @@ "test": "vitest run", "test:watch": "vitest", "test:coverage": "vitest run --coverage", - "test:e2e": "playwright test tests/e2e/demo.spec.ts", - "test:e2e:ui": "playwright test --ui tests/e2e/demo.spec.ts" + "test:e2e": "vite build && playwright test tests/e2e/demo.spec.ts", + "test:e2e:ui": "vite build && playwright test --ui tests/e2e/demo.spec.ts" }, "devDependencies": { "@playwright/test": "^1.53.0", From 16fc5b88f24afe3d0ea7b64023d66f5c30f8cf3e Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 13:35:36 +0100 Subject: [PATCH 08/22] drop unnecessary code --- vite.config.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index 702c711..94d3d12 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,17 +5,6 @@ import { dirname } from 'path'; const __dirname = dirname(fileURLToPath(import.meta.url)); -// Simple plugin to copy the demo folder from public to dist -function copyDemoFolder() { - return { - name: 'copy-demo-folder', - writeBundle() { - // This will be implemented in the build script - console.log('Demo files will be copied to the dist root in the build script'); - }, - }; -} - export default defineConfig({ // Configure how Vite handles different file types assetsInclude: ['**/*.html'], @@ -68,7 +57,6 @@ export default defineConfig({ // Configure plugins plugins: [ - copyDemoFolder(), // Add any other Vite plugins here ], From 8a59ec9bddd0dea042f5d0454507687e465131a6 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 13:50:38 +0100 Subject: [PATCH 09/22] fix preview --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 78c585c..07e418f 100644 --- a/package.json +++ b/package.json @@ -7,15 +7,15 @@ "dev": "vite", "build": "tsc && vite build && node scripts/copy-demo.js", "preview": "vite preview", - "preview:demo": "vite preview --port 3000 --open /demo", + "preview:demo": "vite preview --port 3000 --open grid-sight", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", "test:storybook": "test-storybook", "test": "vitest run", "test:watch": "vitest", "test:coverage": "vitest run --coverage", - "test:e2e": "vite build && playwright test tests/e2e/demo.spec.ts", - "test:e2e:ui": "vite build && playwright test --ui tests/e2e/demo.spec.ts" + "test:e2e": "vite build && playwright test tests/e2e", + "test:e2e:ui": "vite build && playwright test --ui tests/e2e" }, "devDependencies": { "@playwright/test": "^1.53.0", From 226b9d6f8c82ebfb98a69bfc89485a299717e78e Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 14:03:00 +0100 Subject: [PATCH 10/22] test fixed --- tests/e2e/heatmap.spec.ts | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/tests/e2e/heatmap.spec.ts b/tests/e2e/heatmap.spec.ts index 3d1c1d7..308ed3b 100644 --- a/tests/e2e/heatmap.spec.ts +++ b/tests/e2e/heatmap.spec.ts @@ -29,7 +29,7 @@ test.describe('Grid-Sight Heatmap', () => { }) // Navigate to the demo page - await page.goto('http://localhost:3001/demo/') + await page.goto('http://localhost:3001/') // Wait for the page to load completely await page.waitForLoadState('domcontentloaded') @@ -48,8 +48,12 @@ test.describe('Grid-Sight Heatmap', () => { const serverAttachment = testInfo.attachments.find(a => a.name === 'server') if (serverAttachment && serverAttachment.body) { const server = JSON.parse(serverAttachment.body.toString()) - // Close the preview server - await new Promise(resolve => server.httpServer.close(resolve)) + // Close the preview server - safely handle different server structures + if (server.httpServer && typeof server.httpServer.close === 'function') { + await new Promise(resolve => server.httpServer.close(resolve)) + } else if (server.close && typeof server.close === 'function') { + await new Promise(resolve => server.close(resolve)) + } } }) @@ -58,11 +62,20 @@ test.describe('Grid-Sight Heatmap', () => { // Get the first table const table = page.locator('table').first() - // Open the table menu - await page.click('.gs-table-header-menu-button') + // Find the Grid-Sight toggle button + await page.waitForSelector('.grid-sight-toggle') + + // Click on the Grid-Sight toggle + await page.click('.grid-sight-toggle') + // await for the table plus to appear + await page.waitForSelector('.gs-table-plus', { timeout: 500 }) + + // Click on the table plus + await page.click('.gs-table-plus') + // Wait for the menu to appear - await page.waitForSelector('.gs-menu-container') + await page.waitForSelector('.gs-enrichment-menu', { timeout: 500 }) // Click on the heatmap option await page.getByText('Heatmap').click() @@ -91,8 +104,8 @@ test.describe('Grid-Sight Heatmap', () => { expect(cellsWithColor).toBeGreaterThan(0) // Toggle the heatmap off by clicking the menu option again - await page.click('.gs-table-header-menu-button') - await page.waitForSelector('.gs-menu-container') + await page.click('.gs-plus-icon') + await page.waitForSelector('.gs-enrichment-menu', { timeout: 5000 }) await page.getByText('Heatmap').click() // Wait for the heatmap to be removed From 5e7bf97279b590585093c3b0ce45dfe38bfb0fc3 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 14:03:05 +0100 Subject: [PATCH 11/22] introduce 2d data --- public/index.html | 80 +++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 52 deletions(-) diff --git a/public/index.html b/public/index.html index 5ac46f0..c8134eb 100644 --- a/public/index.html +++ b/public/index.html @@ -60,58 +60,34 @@

Basic Usage

Product Inventory

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Product IDProduct NameCategoryPriceIn StockLast Ordered
P1001Wireless MouseElectronics29.99452023-05-15
P1002Ergonomic KeyboardElectronics89.99232023-05-18
P2001Desk LampFurniture45.50122023-05-10
P2002Office ChairFurniture249.9952023-05-05
P3001Notebook SetStationery12.99872023-05-20
Gear / Revs5101520
Low10152025
Medium17222732
High27253035
From 40b5ca7bb0285241f4dc5428df0d8505296e1576 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 14:04:56 +0100 Subject: [PATCH 12/22] improved category data in demo --- public/index.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/public/index.html b/public/index.html index c8134eb..7462160 100644 --- a/public/index.html +++ b/public/index.html @@ -100,7 +100,7 @@

Monthly Sales Data

Revenue Expenses Profit - Growth % + Dominant item @@ -109,35 +109,35 @@

Monthly Sales Data

12500 9800 2700 - 5.2 + Corded Mouse February 11800 9200 2600 - -3.7 + Wireless Mouse March 14200 10100 4100 - 20.3 + Corded Mouse April 13800 9900 3900 - -2.8 + Corded Mouse May 15600 10500 5100 - 13.0 + Desk Lamp From 526445bc02962be3c2b19ab844dac582c247e5c0 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 14:12:11 +0100 Subject: [PATCH 13/22] colored bars --- src/ui/frequency-chart-dialog.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ui/frequency-chart-dialog.ts b/src/ui/frequency-chart-dialog.ts index 1974aea..6d24958 100644 --- a/src/ui/frequency-chart-dialog.ts +++ b/src/ui/frequency-chart-dialog.ts @@ -1,5 +1,11 @@ import type { FrequencyResult } from '../utils/frequency'; +// Color palette for frequency chart bars +const BAR_COLORS = [ + '#4e79a7', '#f28e2c', '#e15759', '#76b7b2', '#59a14f', + '#edc949', '#af7aa1', '#ff9da7', '#9c755f', '#bab0ab' +]; + // CSS class names const DIALOG_CLASS = 'gs-frequency-chart-dialog'; const DIALOG_VISIBLE_CLASS = 'gs-frequency-chart-dialog--visible'; @@ -97,12 +103,11 @@ const DIALOG_STYLES = ` } .${DIALOG_SVG_BAR_CLASS} { - fill: #0066cc; transition: fill 0.2s ease; } .${DIALOG_SVG_BAR_CLASS}:hover { - fill: #004c99; + opacity: 0.8; } .${DIALOG_SVG_LABEL_CLASS} { @@ -347,6 +352,10 @@ export class FrequencyChartDialog { bar.setAttribute('height', barHeight.toString()); bar.setAttribute('class', DIALOG_SVG_BAR_CLASS); + // Assign different colors to each bar + const colorIndex = index % BAR_COLORS.length; + bar.setAttribute('fill', BAR_COLORS[colorIndex]); + // Add tooltip with data bar.setAttribute('data-value', value); bar.setAttribute('data-count', count.toString()); From b49f0da525b541686a13c5e9dff689e1dbcf53e8 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 13 Jun 2025 14:18:06 +0100 Subject: [PATCH 14/22] fix path to sources --- public/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index 7462160..299eb74 100644 --- a/public/index.html +++ b/public/index.html @@ -158,7 +158,7 @@

Browser Console

- +