argent-grid 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/.github/workflows/ci.yml +69 -0
  2. package/.github/workflows/pages.yml +6 -12
  3. package/.storybook/main.ts +20 -0
  4. package/.storybook/preview.ts +18 -0
  5. package/.storybook/tsconfig.json +24 -0
  6. package/AGENTS.md +2 -2
  7. package/README.md +51 -34
  8. package/angular.json +66 -0
  9. package/biome.json +66 -0
  10. package/demo-app/e2e/selection-screenshot.spec.ts +20 -0
  11. package/docs/AG-GRID-COMPARISON.md +725 -0
  12. package/docs/CELL-RENDERER-GUIDE.md +241 -0
  13. package/docs/CONTEXT-MENU-GUIDE.md +371 -0
  14. package/docs/LIVE-DATA-OPTIMIZATIONS.md +497 -0
  15. package/docs/PERFORMANCE-OPTIMIZATIONS-PHASE1.md +162 -0
  16. package/docs/PERFORMANCE-REVIEW.md +571 -0
  17. package/docs/RESEARCH-STATUS.md +234 -0
  18. package/docs/STATE-PERSISTENCE-GUIDE.md +370 -0
  19. package/docs/STORYBOOK-REFACTOR.md +215 -0
  20. package/docs/STORYBOOK-STATUS.md +156 -0
  21. package/docs/TEST-COVERAGE-REPORT.md +276 -0
  22. package/docs/THEME-API-GUIDE.md +445 -0
  23. package/docs/THEME-API-PLAN.md +364 -0
  24. package/e2e/advanced.spec.ts +109 -0
  25. package/e2e/argentgrid.spec.ts +65 -0
  26. package/e2e/benchmark.spec.ts +52 -0
  27. package/e2e/screenshots.spec.ts +52 -0
  28. package/e2e/theming.spec.ts +35 -0
  29. package/e2e/visual.spec.ts +91 -0
  30. package/e2e/visual.spec.ts-snapshots/grid-default.png +0 -0
  31. package/e2e/visual.spec.ts-snapshots/grid-empty-state.png +0 -0
  32. package/e2e/visual.spec.ts-snapshots/grid-filter-popup.png +0 -0
  33. package/e2e/visual.spec.ts-snapshots/grid-scroll-borders.png +0 -0
  34. package/e2e/visual.spec.ts-snapshots/grid-sidebar-buttons.png +0 -0
  35. package/e2e/visual.spec.ts-snapshots/grid-text-filter.png +0 -0
  36. package/e2e/visual.spec.ts-snapshots/grid-with-selection.png +0 -0
  37. package/package.json +20 -6
  38. package/plan.md +50 -18
  39. package/playwright.config.ts +38 -0
  40. package/setup-vitest.ts +10 -13
  41. package/src/lib/argent-grid.module.ts +10 -12
  42. package/src/lib/components/argent-grid.component.css +327 -76
  43. package/src/lib/components/argent-grid.component.html +186 -64
  44. package/src/lib/components/argent-grid.component.spec.ts +120 -160
  45. package/src/lib/components/argent-grid.component.ts +642 -189
  46. package/src/lib/components/argent-grid.selection.spec.ts +132 -0
  47. package/src/lib/components/set-filter/set-filter.component.ts +302 -0
  48. package/src/lib/directives/ag-grid-compatibility.directive.ts +16 -26
  49. package/src/lib/directives/click-outside.directive.ts +19 -0
  50. package/src/lib/rendering/canvas-renderer.spec.ts +366 -0
  51. package/src/lib/rendering/canvas-renderer.ts +418 -305
  52. package/src/lib/rendering/live-data-handler.ts +110 -0
  53. package/src/lib/rendering/live-data-optimizations.ts +133 -0
  54. package/src/lib/rendering/render/blit.spec.ts +16 -27
  55. package/src/lib/rendering/render/blit.ts +48 -36
  56. package/src/lib/rendering/render/cells.spec.ts +132 -0
  57. package/src/lib/rendering/render/cells.ts +46 -24
  58. package/src/lib/rendering/render/column-utils.ts +73 -0
  59. package/src/lib/rendering/render/hit-test.ts +55 -0
  60. package/src/lib/rendering/render/index.ts +79 -76
  61. package/src/lib/rendering/render/lines.ts +43 -43
  62. package/src/lib/rendering/render/primitives.ts +161 -0
  63. package/src/lib/rendering/render/theme.spec.ts +8 -12
  64. package/src/lib/rendering/render/theme.ts +7 -10
  65. package/src/lib/rendering/render/types.ts +2 -2
  66. package/src/lib/rendering/render/walk.spec.ts +35 -38
  67. package/src/lib/rendering/render/walk.ts +60 -50
  68. package/src/lib/rendering/utils/damage-tracker.spec.ts +8 -7
  69. package/src/lib/rendering/utils/damage-tracker.ts +6 -18
  70. package/src/lib/rendering/utils/index.ts +1 -1
  71. package/src/lib/services/grid.service.set-filter.spec.ts +219 -0
  72. package/src/lib/services/grid.service.spec.ts +1165 -201
  73. package/src/lib/services/grid.service.ts +819 -187
  74. package/src/lib/themes/parts/color-schemes.ts +132 -0
  75. package/src/lib/themes/parts/icon-sets.ts +258 -0
  76. package/src/lib/themes/theme-builder.ts +347 -0
  77. package/src/lib/themes/theme-quartz.ts +72 -0
  78. package/src/lib/themes/types.ts +238 -0
  79. package/src/lib/types/ag-grid-types.ts +73 -14
  80. package/src/public-api.ts +39 -9
  81. package/src/stories/Advanced.stories.ts +188 -0
  82. package/src/stories/ArgentGrid.stories.ts +277 -0
  83. package/src/stories/Benchmark.stories.ts +74 -0
  84. package/src/stories/CellRenderers.stories.ts +221 -0
  85. package/src/stories/Filtering.stories.ts +252 -0
  86. package/src/stories/Grouping.stories.ts +217 -0
  87. package/src/stories/Theming.stories.ts +124 -0
  88. package/src/stories/benchmark-wrapper.component.ts +315 -0
  89. package/tsconfig.storybook.json +10 -0
  90. package/vitest.config.ts +9 -9
  91. package/demo-app/README.md +0 -70
  92. package/demo-app/angular.json +0 -78
  93. package/demo-app/e2e/benchmark.spec.ts +0 -53
  94. package/demo-app/e2e/demo-page.spec.ts +0 -77
  95. package/demo-app/e2e/grid-features.spec.ts +0 -269
  96. package/demo-app/package-lock.json +0 -14023
  97. package/demo-app/package.json +0 -36
  98. package/demo-app/playwright-test-menu.js +0 -19
  99. package/demo-app/playwright.config.ts +0 -23
  100. package/demo-app/src/app/app.component.ts +0 -10
  101. package/demo-app/src/app/app.config.ts +0 -13
  102. package/demo-app/src/app/app.routes.ts +0 -7
  103. package/demo-app/src/app/demo-page/demo-page.component.css +0 -313
  104. package/demo-app/src/app/demo-page/demo-page.component.html +0 -124
  105. package/demo-app/src/app/demo-page/demo-page.component.ts +0 -366
  106. package/demo-app/src/index.html +0 -19
  107. package/demo-app/src/main.ts +0 -6
  108. package/demo-app/tsconfig.json +0 -31
@@ -0,0 +1,69 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, dirty]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ build-and-test:
11
+ runs-on: ubuntu-latest
12
+
13
+ strategy:
14
+ matrix:
15
+ node-version: [20.x]
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Use Node.js ${{ matrix.node-version }}
21
+ uses: actions/setup-node@v4
22
+ with:
23
+ node-version: ${{ matrix.node-version }}
24
+ cache: 'npm'
25
+
26
+ - name: Install dependencies
27
+ run: npm ci --legacy-peer-deps
28
+
29
+ - name: Build library
30
+ run: npm run build
31
+
32
+ - name: Build Storybook
33
+ run: npm run build-storybook
34
+
35
+ - name: Run unit tests with coverage
36
+ run: npm run test:coverage
37
+
38
+ - name: Run E2E tests
39
+ run: |
40
+ npx playwright install chromium --with-deps
41
+ npm run test:e2e
42
+
43
+ - name: Upload coverage reports
44
+ uses: codecov/codecov-action@v4
45
+ with:
46
+ files: ./coverage/coverage-final.json
47
+ flags: unittests
48
+ name: codecov-umbrella
49
+ fail_ci_if_error: false
50
+ env:
51
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
52
+
53
+ code-quality:
54
+ runs-on: ubuntu-latest
55
+
56
+ steps:
57
+ - uses: actions/checkout@v4
58
+
59
+ - name: Use Node.js 20.x
60
+ uses: actions/setup-node@v4
61
+ with:
62
+ node-version: 20.x
63
+ cache: 'npm'
64
+
65
+ - name: Install dependencies
66
+ run: npm ci --legacy-peer-deps
67
+
68
+ - name: Lint
69
+ run: npm run lint
@@ -7,12 +7,12 @@ on:
7
7
 
8
8
  paths:
9
9
  - 'src/**'
10
- - 'demo-app/**'
11
10
  - '.github/workflows/pages.yml'
12
11
  - 'package.json'
13
12
  - 'package-lock.json'
14
13
  - 'ng-package.json'
15
14
  - 'tsconfig.json'
15
+ - 'tsconfig.storybook.json'
16
16
  workflow_dispatch:
17
17
 
18
18
  permissions:
@@ -39,21 +39,15 @@ jobs:
39
39
  with:
40
40
  node-version: '20'
41
41
  cache: 'npm'
42
- cache-dependency-path: './package-lock.json'
43
42
 
44
43
  - name: Install root dependencies
45
- run: npm ci
44
+ run: npm ci --legacy-peer-deps
46
45
 
47
46
  - name: Build ArgentGrid library
48
47
  run: npm run build
49
48
 
50
- - name: Install demo app dependencies
51
- working-directory: ./demo-app
52
- run: npm install
53
-
54
- - name: Build demo app
55
- working-directory: ./demo-app
56
- run: npm run build:gh-pages
49
+ - name: Build Storybook
50
+ run: npm run build-storybook
57
51
 
58
52
  - name: Setup Pages
59
53
  uses: actions/configure-pages@v5
@@ -61,8 +55,8 @@ jobs:
61
55
  - name: Upload artifact
62
56
  uses: actions/upload-pages-artifact@v3
63
57
  with:
64
- path: './demo-app/dist/argent-grid-demo/browser'
58
+ path: './storybook-static'
65
59
 
66
60
  - name: Deploy to GitHub Pages
67
61
  id: deployment
68
- uses: actions/deploy-pages@v4
62
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,20 @@
1
+ import type { StorybookConfig } from '@storybook/angular';
2
+
3
+ const config: StorybookConfig = {
4
+ stories: ['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
5
+ addons: [
6
+ '@storybook/addon-essentials',
7
+ '@storybook/addon-actions',
8
+ '@storybook/addon-controls',
9
+ '@chromatic-com/storybook',
10
+ ],
11
+ framework: {
12
+ name: '@storybook/angular',
13
+ options: {},
14
+ },
15
+ docs: {
16
+ autodocs: false,
17
+ },
18
+ };
19
+
20
+ export default config;
@@ -0,0 +1,18 @@
1
+ import type { Preview } from '@storybook/angular';
2
+
3
+ const preview: Preview = {
4
+ parameters: {
5
+ controls: {
6
+ matchers: {
7
+ color: /(background|color)$/i,
8
+ date: /Date$/i,
9
+ },
10
+ },
11
+ layout: 'fullscreen',
12
+ docs: {
13
+ disable: true,
14
+ },
15
+ },
16
+ };
17
+
18
+ export default preview;
@@ -0,0 +1,24 @@
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": ".",
4
+ "outDir": "../dist-storybook",
5
+ "target": "ES2022",
6
+ "module": "ES2022",
7
+ "moduleResolution": "node",
8
+ "lib": ["ES2022", "dom"],
9
+ "strict": false,
10
+ "noImplicitAny": false,
11
+ "noImplicitReturns": false,
12
+ "noFallthroughCasesInSwitch": false,
13
+ "experimentalDecorators": true,
14
+ "emitDecoratorMetadata": true,
15
+ "allowSyntheticDefaultImports": true,
16
+ "esModuleInterop": true,
17
+ "skipLibCheck": true,
18
+ "useDefineForClassFields": false,
19
+ "importHelpers": true,
20
+ "paths": {}
21
+ },
22
+ "include": ["../src/**/*.ts", "*.ts"],
23
+ "exclude": ["../node_modules", "../dist", "../dist-storybook", "../src/**/*.spec.ts"]
24
+ }
package/AGENTS.md CHANGED
@@ -125,9 +125,9 @@ api.setGridOption('floatingFilter', true);
125
125
 
126
126
  Agents working on this repository should utilize the following tools for high-quality contributions:
127
127
 
128
- 1. **Playwright Skill**: Used for running the `demo-app` E2E suite (`npm run test:e2e`).
128
+ 1. **Playwright Skill**: Used for running the root-level E2E suite (`npm run test:e2e`) against Storybook stories.
129
129
  2. **Computer Use (Browser Automation)**: Highly recommended for visual verification of Canvas rendering. Always verify menu positioning, scrolling alignment, and interactive states (like editing) in a live browser before concluding a task.
130
- 3. **TS Strict Mode**: The library is verified against the `demo-app`'s strict TypeScript configuration. Ensure all property accesses (especially dynamic ones in tests) are type-safe.
130
+ 3. **TS Strict Mode**: The library is verified against a strict TypeScript configuration. Ensure all property accesses (especially dynamic ones in tests) are type-safe.
131
131
 
132
132
  ## Known Issues / TODOs
133
133
 
package/README.md CHANGED
@@ -141,71 +141,88 @@ npm run test:coverage # With coverage
141
141
  npm run lint
142
142
  ```
143
143
 
144
- ## 🎨 Demo App Development
144
+ ## 🎨 Storybook Development
145
145
 
146
- The repository includes a standalone Angular application for visual testing and performance benchmarking. It is configured to import `argent-grid` directly from the `src/` folder using TypeScript path mapping.
146
+ ArgentGrid uses **Storybook** for component development, documentation, and visual testing. Each feature (Sorting, Grouping, Theming, etc.) is documented as an isolated story.
147
147
 
148
- **Why this is better:**
149
- - **No Build Step:** You don't need to run `npm run build` in the root every time you change the library.
150
- - **HMR / Live Reload:** Changes in `src/` are detected by the Angular dev-server, triggering an immediate browser refresh.
151
- - **Easier Debugging:** Sourcemaps point directly to your original library source code.
148
+ ### Run Storybook
152
149
 
153
- ### Run Demo App
150
+ ```bash
151
+ # Start Storybook dev server
152
+ npm run storybook
153
+ ```
154
+
155
+ Open [http://localhost:6006](http://localhost:6006) to view the stories and interact with the grid.
156
+
157
+ ### Build Storybook
154
158
 
155
159
  ```bash
156
- cd demo-app
157
- npm install
158
- npm start
160
+ # Build static Storybook site
161
+ npm run build-storybook
159
162
  ```
160
163
 
161
- Open [http://localhost:4200](http://localhost:4200) to view the demo.
164
+ Output will be in the `./storybook-static` directory.
162
165
 
163
166
  ### E2E Testing (Playwright)
164
167
 
165
- argent-grid uses Playwright for end-to-end testing of visual and interactive features (like Canvas rendering, dragging, and menu interactions).
166
-
167
- **Prerequisites:**
168
- The demo app must be running (`npm start` inside `demo-app/`).
168
+ ArgentGrid uses Playwright for end-to-end testing against the Storybook stories. These tests verify visual rendering, interactivity (dragging, resizing), and complex logic (filtering, grouping).
169
169
 
170
170
  **Run Tests:**
171
171
  ```bash
172
- cd demo-app
173
- npx playwright test
172
+ # Run all E2E tests
173
+ npm run test:e2e
174
174
  ```
175
175
 
176
176
  This will execute the **Feature Guard Rails** suite which verifies:
177
177
  - Row Grouping & Expansion
178
178
  - Floating Filters
179
- - Cell Editing (Enter/Escape/Tab)
179
+ - Cell Editing
180
180
  - Column Pinning & Scroll Sync
181
181
  - Column Re-ordering (Drag & Drop)
182
182
 
183
+ ### Visual Regression Testing
184
+
185
+ Since ArgentGrid renders its core data area using HTML5 Canvas, we use **Visual Regression Testing** to ensure consistent rendering and catch pixel-level regressions.
186
+
187
+ **Run Visual Tests:**
188
+ ```bash
189
+ npx playwright test e2e/visual.spec.ts
190
+ ```
191
+
192
+ **Updating Snapshots:**
193
+ If you have made intentional UI changes (e.g., changed selection colors, refined border logic, or adjusted header padding) and the visual tests fail, you must update the baseline snapshots:
194
+
195
+ ```bash
196
+ npx playwright test e2e/visual.spec.ts --update-snapshots
197
+ ```
198
+
199
+ *Note: Ensure your local environment is clean and Storybook is correctly built before updating snapshots. Baseline snapshots are committed to the repository to serve as the source of truth for CI.*
200
+
183
201
  ### Performance Benchmarking
184
202
 
185
- ArgentGrid includes a built-in benchmarking suite to measure rendering efficiency, scroll performance, and memory overhead.
203
+ ArgentGrid includes a benchmarking suite to measure rendering efficiency and scroll performance under heavy load (100,000+ rows).
186
204
 
187
205
  **Option 1: Interactive (UI)**
188
- 1. Start the demo app: `cd demo-app && npm start`
189
- 2. Open [http://localhost:4200](http://localhost:4200)
190
- 3. Click the **🚀 Benchmark** button in the header.
191
- 4. View real-time **ms frame** metrics and a detailed report covering initial render, scrolling, and selection updates.
206
+ 1. Start Storybook: `npm run storybook`
207
+ 2. Open [http://localhost:6006](http://localhost:6006)
208
+ 3. Navigate to **ArgentGrid / Benchmark**
209
+ 4. View real-time **ms frame** metrics and a detailed report.
192
210
 
193
211
  **Option 2: Automated (CLI)**
194
- To run the automated performance test and see results in your terminal:
212
+ To run the automated performance test:
195
213
  ```bash
196
- cd demo-app
197
214
  npx playwright test e2e/benchmark.spec.ts --reporter=list
198
215
  ```
199
216
 
200
- ## Performance Targets
201
-
202
- | Metric | Baseline | Target | Status |
203
- | :--- | :--- | :--- | :--- |
204
- | **Initial Render (100k rows)** | ~45ms | < 30ms | 🚀 (Optimizing) |
205
- | **Scroll Frame Time (avg)** | ~3.8ms | < 4ms | ✅ |
206
- | **Selection Update (All)** | ~12ms | < 20ms | ✅ (Damage Tracking) |
207
- | **Memory per 100k rows** | ~45MB | < 30MB | 🚀 (Optimizing) |
208
- | **Max Rows (60fps)** | 1,000,000+ | 1,000,000+ | ✅ |
217
+ -------------------------------------------
218
+ 🚀 ArgentGrid Performance Benchmark Results
219
+ -------------------------------------------
220
+ Initial Render : 2.60ms
221
+ Avg Scroll Frame : 1.55ms
222
+ Selection All : 103.70ms
223
+ Grouping Toggle : 147.10ms
224
+ Total Test Time : 495.60ms
225
+ -------------------------------------------
209
226
 
210
227
  ## License
211
228
 
package/angular.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3
+ "version": 1,
4
+ "newProjectRoot": "projects",
5
+ "projects": {
6
+ "argent-grid": {
7
+ "projectType": "library",
8
+ "root": "",
9
+ "sourceRoot": "src",
10
+ "prefix": "lib",
11
+ "architect": {
12
+ "build": {
13
+ "builder": "ng-packagr:build",
14
+ "options": {
15
+ "project": "ng-package.json"
16
+ },
17
+ "configurations": {
18
+ "production": {
19
+ "tsConfig": "tsconfig.lib.json"
20
+ },
21
+ "development": {
22
+ "tsConfig": "tsconfig.lib.json"
23
+ }
24
+ },
25
+ "defaultConfiguration": "production"
26
+ },
27
+ "test": {
28
+ "builder": "@angular-devkit/build-angular:karma",
29
+ "options": {
30
+ "tsConfig": "tsconfig.spec.json",
31
+ "karmaConfig": "karma.conf.js"
32
+ }
33
+ }
34
+ }
35
+ },
36
+ "argent-grid-storybook": {
37
+ "projectType": "library",
38
+ "root": "",
39
+ "sourceRoot": "src",
40
+ "prefix": "lib",
41
+ "architect": {
42
+ "storybook": {
43
+ "builder": "@storybook/angular:start-storybook",
44
+ "options": {
45
+ "configDir": ".storybook",
46
+ "tsConfig": ".storybook/tsconfig.json",
47
+ "compodoc": false,
48
+ "port": 6006
49
+ }
50
+ },
51
+ "build-storybook": {
52
+ "builder": "@storybook/angular:build-storybook",
53
+ "options": {
54
+ "configDir": ".storybook",
55
+ "tsConfig": ".storybook/tsconfig.json",
56
+ "compodoc": false,
57
+ "outputDir": "storybook-static"
58
+ }
59
+ }
60
+ }
61
+ }
62
+ },
63
+ "cli": {
64
+ "analytics": false
65
+ }
66
+ }
package/biome.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.4.4/schema.json",
3
+ "vcs": {
4
+ "enabled": true,
5
+ "clientKind": "git",
6
+ "useIgnoreFile": true
7
+ },
8
+ "formatter": {
9
+ "enabled": true,
10
+ "indentStyle": "space",
11
+ "indentWidth": 2,
12
+ "lineWidth": 100
13
+ },
14
+ "linter": {
15
+ "enabled": true,
16
+ "rules": {
17
+ "recommended": true,
18
+ "complexity": {
19
+ "noExcessiveCognitiveComplexity": "off",
20
+ "noBannedTypes": "off"
21
+ },
22
+ "suspicious": {
23
+ "noExplicitAny": "off",
24
+ "useIterableCallbackReturn": "off",
25
+ "useAdjacentOverloadSignatures": "off"
26
+ },
27
+ "style": {
28
+ "useImportType": "off",
29
+ "noNonNullAssertion": "off",
30
+ "noParameterProperties": "off"
31
+ },
32
+ "correctness": {
33
+ "noUnusedFunctionParameters": "off"
34
+ }
35
+ }
36
+ },
37
+ "javascript": {
38
+ "formatter": {
39
+ "quoteStyle": "single",
40
+ "trailingCommas": "es5"
41
+ },
42
+ "parser": {
43
+ "unsafeParameterDecoratorsEnabled": true
44
+ }
45
+ },
46
+ "html": {
47
+ "parser": {
48
+ "interpolation": true
49
+ }
50
+ },
51
+ "overrides": [
52
+ {
53
+ "includes": ["**/*.html"],
54
+ "linter": { "enabled": false },
55
+ "formatter": { "enabled": false }
56
+ }
57
+ ],
58
+ "assist": {
59
+ "enabled": true,
60
+ "actions": {
61
+ "source": {
62
+ "organizeImports": "on"
63
+ }
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,20 @@
1
+ import { test, expect } from '@playwright/test';
2
+
3
+ test('Take selection mode screenshot', async ({ page }) => {
4
+ // Start demo app
5
+ await page.goto('http://localhost:4200');
6
+
7
+ // Wait for grid to load
8
+ await page.waitForSelector('argent-grid', { timeout: 30000 });
9
+
10
+ // Enable selection mode (click the selection toggle if available)
11
+ // Or navigate to a story with selection enabled
12
+
13
+ // Take screenshot
14
+ await page.screenshot({
15
+ path: 'e2e/screenshots/selection-mode.png',
16
+ fullPage: true
17
+ });
18
+
19
+ console.log('Screenshot saved to e2e/screenshots/selection-mode.png');
20
+ });