Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions .github/workflows/storybook-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,22 @@ jobs:
- name: Build Storybook
run: yarn build-storybook

- name: Install test dependencies
run: yarn add --dev http-server wait-on

- name: Run Storybook tests
run: |
# Start Storybook in the background
npx http-server storybook-static --port 6006 --silent &
yarn http-server storybook-static --port 6006 --silent &

# Wait for Storybook to be ready
npx wait-on http://localhost:6006
yarn wait-on http://localhost:6006

# Set environment variable for Storybook URL
export STORYBOOK_URL=http://localhost:6006

# Run the tests using test-runner directly
npx test-storybook --url http://localhost:6006 --browsers chromium
# Run the tests using Vitest
yarn test:storybook

- name: Upload test artifacts on failure
if: failure()
Expand Down
1 change: 1 addition & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const config: StorybookConfig = {
addons: [
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-vitest'
],
framework: {
name: '@storybook/html-vite',
Expand Down
6 changes: 6 additions & 0 deletions .storybook/vitest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { setProjectAnnotations } from '@storybook/html-vite';
import * as projectAnnotations from './preview';

// This is an important step to apply the right configuration when testing your stories.
// More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations
setProjectAnnotations([projectAnnotations]);
4 changes: 3 additions & 1 deletion .windsurf/rules/storybook.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ This is guidance for generation and maintenance of StoryBook stories.

Lots of data tables are generated for StoryBook tests. Do not create them as template text in the story. Generate them as suitably named `.html` files in the `stories` sub-folder.

This make it easier to understand and maintain them.
This make it easier to understand and maintain them.

We will be using Storybook V9 interaction tests, as documented here: https://storybook.js.org/docs/writing-tests/interaction-testing
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,31 @@
"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:storybook": "vitest run --project=storybook",
"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",
"test:e2e:ui": "vite build && playwright test --ui tests/e2e"
},
"devDependencies": {
"@playwright/test": "^1.53.0",
"@storybook/addon-docs": "^9.0.6",
"@storybook/addon-essentials": "^9.0.0-alpha.12",
"@storybook/addon-interactions": "^9.0.0-alpha.10",
"@storybook/addon-vitest": "^9.0.9",
"@storybook/html-vite": "^9.0.6",
"@storybook/test": "^8.6.14",
"@types/fs-extra": "^11.0.4",
"@vitest/browser": "3.2.3",
"@vitest/coverage-v8": "^3.2.3",
"@vitest/ui": "^3.2.3",
"fs-extra": "^11.3.0",
"jsdom": "^26.1.0",
"playwright": "^1.53.0",
"storybook": "^9.0.6",
"terser": "^5.42.0",
"typescript": "~5.8.3",
Expand Down
94 changes: 35 additions & 59 deletions public/demo/index.html → public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,58 +60,34 @@ <h2>Basic Usage</h2>
<div class="table-wrapper">
<h3>Product Inventory</h3>
<table class="inventory-table">
<thead>
<tr>
<th>Product ID</th>
<th>Product Name</th>
<th>Category</th>
<th>Price</th>
<th>In Stock</th>
<th>Last Ordered</th>
</tr>
</thead>
<tbody>
<tr>
<td>P1001</td>
<td>Wireless Mouse</td>
<td>Electronics</td>
<td>29.99</td>
<td>45</td>
<td>2023-05-15</td>
</tr>
<tr>
<td>P1002</td>
<td>Ergonomic Keyboard</td>
<td>Electronics</td>
<td>89.99</td>
<td>23</td>
<td>2023-05-18</td>
</tr>
<tr>
<td>P2001</td>
<td>Desk Lamp</td>
<td>Furniture</td>
<td>45.50</td>
<td>12</td>
<td>2023-05-10</td>
</tr>
<tr>
<td>P2002</td>
<td>Office Chair</td>
<td>Furniture</td>
<td>249.99</td>
<td>5</td>
<td>2023-05-05</td>
</tr>
<tr>
<td>P3001</td>
<td>Notebook Set</td>
<td>Stationery</td>
<td>12.99</td>
<td>87</td>
<td>2023-05-20</td>
</tr>
</tbody>
<tr>
<td>Gear / Revs</td>
<td>5</td>
<td>10</td>
<td>15</td>
<td>20</td>
</tr>
<tr>
<td>Low</td>
<td>10</td>
<td>15</td>
<td>20</td>
<td>25</td>
</tr>
<tr>
<td>Medium</td>
<td>17</td>
<td>22</td>
<td>27</td>
<td>32</td>
</tr>
<tr>
<td>High</td>
<td>27</td>
<td>25</td>
<td>30</td>
<td>35</td>
</tr>
</table>
</div>

Expand All @@ -124,7 +100,7 @@ <h3>Monthly Sales Data</h3>
<th>Revenue</th>
<th>Expenses</th>
<th>Profit</th>
<th>Growth %</th>
<th>Dominant item</th>
</tr>
</thead>
<tbody>
Expand All @@ -133,35 +109,35 @@ <h3>Monthly Sales Data</h3>
<td>12500</td>
<td>9800</td>
<td>2700</td>
<td>5.2</td>
<td>Corded Mouse</td>
</tr>
<tr>
<td>February</td>
<td>11800</td>
<td>9200</td>
<td>2600</td>
<td>-3.7</td>
<td>Wireless Mouse</td>
</tr>
<tr>
<td>March</td>
<td>14200</td>
<td>10100</td>
<td>4100</td>
<td>20.3</td>
<td>Corded Mouse</td>
</tr>
<tr>
<td>April</td>
<td>13800</td>
<td>9900</td>
<td>3900</td>
<td>-2.8</td>
<td>Corded Mouse</td>
</tr>
<tr>
<td>May</td>
<td>15600</td>
<td>10500</td>
<td>5100</td>
<td>13.0</td>
<td>Desk Lamp</td>
</tr>
</tbody>
</table>
Expand All @@ -182,7 +158,7 @@ <h3>Browser Console</h3>
</footer>

<!-- Load Grid-Sight library -->
<script src="grid-sight.iife.js"></script>
<script src="../dist/grid-sight.iife.js"></script>

<script>
// Simple console logger for the demo
Expand Down
2 changes: 1 addition & 1 deletion scripts/copy-demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,34 @@ describe('Heatmap', () => {
const createTestTable = (): HTMLTableElement => {
const table = document.createElement('table');
table.innerHTML = `
<thead>
<tr>
<th>Product</th>
<th>Q1</th>
<th>Q2</th>
<th>Q3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Widget A</td>
<td>10</td>
<td>20</td>
<td>30</td>
</tr>
<tr>
<td>Widget B</td>
<td>15</td>
<td>25</td>
<td>35</td>
</tr>
</tbody>
<tr>
<td>Gear / Revs</td>
<td>5</td>
<td>10</td>
<td>15</td>
<td>20</td>
</tr>
<tr>
<td>Low</td>
<td id='cell-1-1'>10</td>
<td>15</td>
<td>20</td>
<td>25</td>
</tr>
<tr>
<td>Medium</td>
<td>17</td>
<td>22</td>
<td>27</td>
<td>32</td>
</tr>
<tr>
<td>High</td>
<td>27</td>
<td>25</td>
<td>30</td>
<td>35</td>
</tr>
`;
document.body.appendChild(table);
return table;
Expand Down Expand Up @@ -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();
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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('');
Expand All @@ -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');
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down
Loading