@nice2dev/testing 1.0.10

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.
@@ -0,0 +1,1618 @@
1
+ import { BrowserContext } from '@playwright/test';
2
+ import { default as default_2 } from 'react';
3
+ import { expect } from 'vitest';
4
+ import * as fc from 'fast-check';
5
+ import { JSX as JSX_2 } from 'react/jsx-runtime';
6
+ import { Page } from '@playwright/test';
7
+ import * as React_2 from 'react';
8
+ import { ReactElement } from 'react';
9
+ import { ReactNode } from 'react';
10
+ import { StorybookConfig } from '@storybook/react-vite';
11
+
12
+ export declare interface A11yAuditResult {
13
+ passes: number;
14
+ violations: A11yViolation[];
15
+ incomplete: number;
16
+ inapplicable: number;
17
+ /** WCAG compliance score (%) */
18
+ complianceScore: number;
19
+ }
20
+
21
+ export declare interface A11yViolation {
22
+ ruleId: string;
23
+ impact: 'critical' | 'serious' | 'moderate' | 'minor';
24
+ description: string;
25
+ helpUrl: string;
26
+ nodes: Array<{
27
+ selector: string;
28
+ html: string;
29
+ failureSummary: string;
30
+ }>;
31
+ }
32
+
33
+ export declare interface AccessibilityAuditConfig {
34
+ /** WCAG level */
35
+ level: WcagLevel;
36
+ /** Rules to include/exclude */
37
+ includeRules?: string[];
38
+ excludeRules?: string[];
39
+ /** Components to audit */
40
+ componentSelectors: string[];
41
+ /** Axe-core configuration */
42
+ axeConfig?: Record<string, unknown>;
43
+ }
44
+
45
+ export declare const arbitraries: {
46
+ /** Non-empty string */
47
+ nonEmptyString: () => fc.Arbitrary<string>;
48
+ /** Non-empty array */
49
+ nonEmptyArray: <T>(arb: fc.Arbitrary<T>) => fc.Arbitrary<T[]>;
50
+ /** Unique array (no duplicates) */
51
+ uniqueArray: <T>(arb: fc.Arbitrary<T>) => fc.Arbitrary<T[]>;
52
+ /** Valid CSS color hex (#RGB or #RRGGBB) */
53
+ hexColor: () => fc.Arbitrary<string>;
54
+ /** RGB color */
55
+ rgbColor: () => fc.Arbitrary<{
56
+ r: number;
57
+ g: number;
58
+ b: number;
59
+ }>;
60
+ /** HSL color */
61
+ hslColor: () => fc.Arbitrary<{
62
+ h: number;
63
+ s: number;
64
+ l: number;
65
+ }>;
66
+ /** CSS size value (e.g., '10px', '2rem') */
67
+ cssSize: () => fc.Arbitrary<string>;
68
+ /** CSS spacing (positive values only) */
69
+ cssSpacing: () => fc.Arbitrary<string>;
70
+ /** CSS border-radius */
71
+ borderRadius: () => fc.Arbitrary<string>;
72
+ /** CSS z-index */
73
+ zIndex: () => fc.Arbitrary<number>;
74
+ /** Viewport dimensions */
75
+ viewport: () => fc.Arbitrary<{
76
+ width: number;
77
+ height: number;
78
+ }>;
79
+ /** Grid columns (1-12) */
80
+ gridColumns: () => fc.Arbitrary<number>;
81
+ /** Flex direction */
82
+ flexDirection: () => fc.Arbitrary<string>;
83
+ /** Flex justify content */
84
+ justifyContent: () => fc.Arbitrary<string>;
85
+ /** Flex align items */
86
+ alignItems: () => fc.Arbitrary<string>;
87
+ /** Valid HTML element tag */
88
+ htmlTag: () => fc.Arbitrary<string>;
89
+ /** Valid ARIA role */
90
+ ariaRole: () => fc.Arbitrary<string>;
91
+ /** Event handler name */
92
+ eventHandler: () => fc.Arbitrary<string>;
93
+ /** Email address */
94
+ email: () => fc.Arbitrary<string>;
95
+ /** UUID */
96
+ uuid: () => fc.Arbitrary<string>;
97
+ /** URL */
98
+ url: () => fc.Arbitrary<string>;
99
+ /** ISO date string */
100
+ isoDate: () => fc.Arbitrary<string>;
101
+ /** Timestamp (milliseconds) */
102
+ timestamp: () => fc.Arbitrary<number>;
103
+ /** Phone number (simple format) */
104
+ phone: () => fc.Arbitrary<string>;
105
+ /** Form field value (string, number, or boolean) */
106
+ fieldValue: () => fc.Arbitrary<string | number | boolean>;
107
+ /** Form validation state */
108
+ validationState: () => fc.Arbitrary<{
109
+ valid: boolean;
110
+ error: string | undefined;
111
+ touched: boolean;
112
+ dirty: boolean;
113
+ }>;
114
+ /** Table row */
115
+ tableRow: <T extends Record<string, fc.Arbitrary<unknown>>>(schema: T) => fc.Arbitrary<{
116
+ [x: string]: unknown;
117
+ id: string;
118
+ }>;
119
+ /** Table data */
120
+ tableData: <T extends Record<string, unknown>>(rowArb: fc.Arbitrary<T>, size?: {
121
+ minLength?: number;
122
+ maxLength?: number;
123
+ }) => fc.Arbitrary<T[]>;
124
+ /** Animation duration (ms) */
125
+ duration: () => fc.Arbitrary<number>;
126
+ /** Animation easing */
127
+ easing: () => fc.Arbitrary<string>;
128
+ /** Animation delay (ms) */
129
+ delay: () => fc.Arbitrary<number>;
130
+ };
131
+
132
+ /**
133
+ * Run axe-core accessibility check
134
+ *
135
+ * @example
136
+ * ```ts
137
+ * test('accessibility', async ({ page }) => {
138
+ * await page.goto('/');
139
+ * const results = await axeCheck(page);
140
+ * expect(results.violations).toHaveLength(0);
141
+ * });
142
+ * ```
143
+ */
144
+ export declare function axeCheck(page: Page, options?: {
145
+ include?: string[];
146
+ exclude?: string[];
147
+ rules?: Record<string, {
148
+ enabled: boolean;
149
+ }>;
150
+ tags?: string[];
151
+ }): Promise<{
152
+ violations: AxeViolation[];
153
+ passes: number;
154
+ incomplete: number;
155
+ }>;
156
+
157
+ export declare interface AxeViolation {
158
+ id: string;
159
+ impact: string;
160
+ description: string;
161
+ help: string;
162
+ helpUrl: string;
163
+ nodes: Array<{
164
+ html: string;
165
+ target: string[];
166
+ failureSummary: string;
167
+ }>;
168
+ }
169
+
170
+ export declare interface BenchmarkResult {
171
+ component: string;
172
+ metric: string;
173
+ mean: number;
174
+ median: number;
175
+ p95: number;
176
+ p99: number;
177
+ min: number;
178
+ max: number;
179
+ stdDev: number;
180
+ regressionDetected: boolean;
181
+ }
182
+
183
+ /**
184
+ * Browser configurations for cross-browser testing
185
+ */
186
+ export declare const BROWSER_CONFIGS: {
187
+ readonly chromium: {
188
+ readonly name: "chromium";
189
+ readonly channel: undefined;
190
+ };
191
+ readonly chrome: {
192
+ readonly name: "chromium";
193
+ readonly channel: "chrome";
194
+ };
195
+ readonly firefox: {
196
+ readonly name: "firefox";
197
+ };
198
+ readonly webkit: {
199
+ readonly name: "webkit";
200
+ };
201
+ readonly edge: {
202
+ readonly name: "chromium";
203
+ readonly channel: "msedge";
204
+ };
205
+ };
206
+
207
+ /**
208
+ * Check if element has proper ARIA attributes for a11y compliance.
209
+ * Returns an array of violations (empty = passed).
210
+ */
211
+ export declare function checkAriaCompliance(element: HTMLElement): string[];
212
+
213
+ /**
214
+ * Run property test and collect statistics
215
+ */
216
+ export declare function checkWithStats<T extends unknown[]>(arbitraries: {
217
+ [K in keyof T]: fc.Arbitrary<T[K]>;
218
+ }, predicate: (...args: T) => void, config?: PropertyTestConfig): fc.RunDetails<T>;
219
+
220
+ /**
221
+ * Chromatic CI script configuration
222
+ */
223
+ export declare const chromaticCIConfig: {
224
+ projectToken: string | undefined;
225
+ buildScriptName: string;
226
+ exitZeroOnChanges: boolean;
227
+ exitOnceUploaded: boolean;
228
+ onlyChanged: boolean;
229
+ externals: string[];
230
+ skip: string;
231
+ traceChanged: string;
232
+ modes: {
233
+ light: {
234
+ theme: string;
235
+ };
236
+ dark: {
237
+ theme: string;
238
+ };
239
+ };
240
+ };
241
+
242
+ /**
243
+ * Default Chromatic parameters for stories
244
+ */
245
+ export declare const chromaticDefaults: {
246
+ viewports: number[];
247
+ diffThreshold: number;
248
+ delay: number;
249
+ pauseAnimationAtEnd: boolean;
250
+ };
251
+
252
+ /**
253
+ * Chromatic modes configuration for Storybook
254
+ * Add this to .storybook/preview.tsx
255
+ *
256
+ * @example
257
+ * ```tsx
258
+ * // .storybook/preview.tsx
259
+ * import { chromaticModes } from '@nice2dev/testing';
260
+ *
261
+ * export const parameters = {
262
+ * chromatic: {
263
+ * modes: chromaticModes,
264
+ * },
265
+ * };
266
+ * ```
267
+ */
268
+ export declare const chromaticModes: {
269
+ mobile: {
270
+ viewport: {
271
+ width: number;
272
+ height: number;
273
+ };
274
+ };
275
+ tablet: {
276
+ viewport: {
277
+ width: number;
278
+ height: number;
279
+ };
280
+ };
281
+ desktop: {
282
+ viewport: {
283
+ width: number;
284
+ height: number;
285
+ };
286
+ };
287
+ wide: {
288
+ viewport: {
289
+ width: number;
290
+ height: number;
291
+ };
292
+ };
293
+ light: {
294
+ theme: string;
295
+ backgrounds: {
296
+ value: string;
297
+ };
298
+ };
299
+ dark: {
300
+ theme: string;
301
+ backgrounds: {
302
+ value: string;
303
+ };
304
+ };
305
+ highContrast: {
306
+ theme: string;
307
+ backgrounds: {
308
+ value: string;
309
+ };
310
+ };
311
+ rtl: {
312
+ globals: {
313
+ direction: string;
314
+ };
315
+ };
316
+ };
317
+
318
+ /**
319
+ * Clean up HTML for snapshot testing by removing dynamic attributes.
320
+ */
321
+ export declare function cleanHtmlForSnapshot(html: string): string;
322
+
323
+ /**
324
+ * Command type for model-based testing
325
+ */
326
+ export declare interface Command<Model, Real> {
327
+ check(model: Readonly<Model>): boolean;
328
+ run(model: Model, real: Real): void | Promise<void>;
329
+ toString(): string;
330
+ }
331
+
332
+ export declare interface CrashReportingConfig {
333
+ /** DSN / endpoint */
334
+ dsn: string;
335
+ /** Environment */
336
+ environment: 'development' | 'staging' | 'production';
337
+ /** Release tag */
338
+ release: string;
339
+ /** Source maps */
340
+ enableSourceMaps: boolean;
341
+ /** Breadcrumbs */
342
+ maxBreadcrumbs: number;
343
+ /** User context */
344
+ includeUserContext: boolean;
345
+ /** Attachments (screenshots, logs) */
346
+ includeScreenshot: boolean;
347
+ }
348
+
349
+ /**
350
+ * Create a mock data source for testing data-bound components.
351
+ *
352
+ * @example
353
+ * const ds = createMockDataSource({
354
+ * data: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }],
355
+ * });
356
+ * render(<NiceDataGrid dataSource={ds} columns={[...]} />);
357
+ */
358
+ export declare function createMockDataSource<T extends Record<string, unknown>>(options: MockDataSourceOptions<T>): MockDataSource<T>;
359
+
360
+ /**
361
+ * RTL decorator for Storybook
362
+ */
363
+ export declare function createRTLDecorator(): (Story: React_2.ComponentType, context: {
364
+ globals: {
365
+ direction?: string;
366
+ };
367
+ }) => JSX_2.Element;
368
+
369
+ /**
370
+ * Create test context with common utilities
371
+ */
372
+ export declare function createTestContext(page: Page, context: BrowserContext): {
373
+ page: Page;
374
+ context: BrowserContext;
375
+ helpers: NiceTestHelpers;
376
+ axe: () => Promise<{
377
+ violations: AxeViolation[];
378
+ passes: number;
379
+ incomplete: number;
380
+ }>;
381
+ mockAPI: (mocks: Parameters<typeof mockAPI>[1]) => Promise<void>;
382
+ mockGraphQL: (endpoint: string, mocks: Record<string, unknown>) => Promise<void>;
383
+ performance: () => Promise<{
384
+ fcp: number;
385
+ lcp: number;
386
+ cls: number;
387
+ ttfb: number;
388
+ tti: number;
389
+ }>;
390
+ };
391
+
392
+ /**
393
+ * Theme decorator for Storybook
394
+ * Apply themes via globals
395
+ */
396
+ export declare function createThemeDecorator(): (Story: React_2.ComponentType, context: {
397
+ globals: {
398
+ theme?: string;
399
+ };
400
+ }) => JSX_2.Element;
401
+
402
+ /**
403
+ * Helper to create .storybook/preview.ts content
404
+ */
405
+ export declare function createVisualPreviewConfig(): string;
406
+
407
+ /**
408
+ * Combined decorator for visual testing
409
+ */
410
+ export declare function createVisualTestDecorator(): (Story: React_2.ComponentType, context: {
411
+ globals: {
412
+ theme?: string;
413
+ direction?: string;
414
+ reducedMotion?: boolean;
415
+ };
416
+ }) => JSX_2.Element;
417
+
418
+ export declare const DEFAULT_BREAKPOINTS: [string, number][];
419
+
420
+ /**
421
+ * Default CSS properties to capture in style snapshots
422
+ */
423
+ export declare const DEFAULT_STYLE_PROPERTIES: string[];
424
+
425
+ /**
426
+ * Device configurations for mobile testing
427
+ */
428
+ export declare const DEVICE_CONFIGS: {
429
+ readonly 'iPhone 13': {
430
+ readonly viewport: {
431
+ readonly width: 390;
432
+ readonly height: 844;
433
+ };
434
+ readonly userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1";
435
+ readonly deviceScaleFactor: 3;
436
+ readonly isMobile: true;
437
+ readonly hasTouch: true;
438
+ };
439
+ readonly 'iPhone 14 Pro Max': {
440
+ readonly viewport: {
441
+ readonly width: 430;
442
+ readonly height: 932;
443
+ };
444
+ readonly userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1";
445
+ readonly deviceScaleFactor: 3;
446
+ readonly isMobile: true;
447
+ readonly hasTouch: true;
448
+ };
449
+ readonly 'iPad Pro': {
450
+ readonly viewport: {
451
+ readonly width: 1024;
452
+ readonly height: 1366;
453
+ };
454
+ readonly userAgent: "Mozilla/5.0 (iPad; CPU OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1";
455
+ readonly deviceScaleFactor: 2;
456
+ readonly isMobile: true;
457
+ readonly hasTouch: true;
458
+ };
459
+ readonly 'Pixel 7': {
460
+ readonly viewport: {
461
+ readonly width: 412;
462
+ readonly height: 915;
463
+ };
464
+ readonly userAgent: "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36";
465
+ readonly deviceScaleFactor: 2.625;
466
+ readonly isMobile: true;
467
+ readonly hasTouch: true;
468
+ };
469
+ readonly 'Samsung Galaxy S23': {
470
+ readonly viewport: {
471
+ readonly width: 360;
472
+ readonly height: 780;
473
+ };
474
+ readonly userAgent: "Mozilla/5.0 (Linux; Android 13; SM-S911B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36";
475
+ readonly deviceScaleFactor: 3;
476
+ readonly isMobile: true;
477
+ readonly hasTouch: true;
478
+ };
479
+ };
480
+
481
+ /**
482
+ * Quality & Reliability types (PRO-6.1)
483
+ *
484
+ * E2E tests, visual regression, performance benchmarks, a11y audit,
485
+ * i18n, error boundaries, telemetry, crash reporting, stress/fuzz/load
486
+ * testing, and security scanning configurations.
487
+ *
488
+ * @module @nice2dev/testing/quality
489
+ */
490
+ export declare interface E2eTestConfig {
491
+ /** Test runner */
492
+ runner: 'playwright' | 'cypress' | 'puppeteer';
493
+ /** Base URL */
494
+ baseUrl: string;
495
+ /** Browsers to test */
496
+ browsers: Array<'chromium' | 'firefox' | 'webkit'>;
497
+ /** Coverage target (%) */
498
+ coverageTarget: number;
499
+ /** Parallel workers */
500
+ workers: number;
501
+ /** Timeout per test (ms) */
502
+ testTimeout: number;
503
+ /** Retry count on failure */
504
+ retries: number;
505
+ /** Output directory */
506
+ outputDir: string;
507
+ /** Sharding */
508
+ sharding?: {
509
+ total: number;
510
+ current: number;
511
+ };
512
+ }
513
+
514
+ export declare interface E2eTestResult {
515
+ suiteName: string;
516
+ passed: number;
517
+ failed: number;
518
+ skipped: number;
519
+ duration: number;
520
+ coveragePercent: number;
521
+ failures: Array<{
522
+ testName: string;
523
+ error: string;
524
+ screenshot?: string;
525
+ trace?: string;
526
+ }>;
527
+ }
528
+
529
+ export declare interface ErrorBoundaryConfig {
530
+ /** Fallback UI component key */
531
+ fallbackComponent: string;
532
+ /** Enable recovery */
533
+ enableRecovery: boolean;
534
+ /** Max retries */
535
+ maxRetries: number;
536
+ /** Error reporting endpoint */
537
+ reportingEndpoint?: string;
538
+ /** Ignored errors */
539
+ ignoredErrors: string[];
540
+ /** Scope: per-component or per-page */
541
+ scope: 'component' | 'page' | 'application';
542
+ }
543
+
544
+ export { expect }
545
+
546
+ /**
547
+ * Assert no accessibility violations
548
+ */
549
+ export declare function expectNoA11yViolations(page: Page): Promise<void>;
550
+
551
+ export { fc }
552
+
553
+ /**
554
+ * Assert that a property holds for all values
555
+ */
556
+ export declare function forAll<T extends unknown[]>(arbitraries: {
557
+ [K in keyof T]: fc.Arbitrary<T[K]>;
558
+ }, predicate: (...args: T) => boolean, config?: PropertyTestConfig): void;
559
+
560
+ export declare interface FuzzTestConfig {
561
+ /** Target component */
562
+ component: string;
563
+ /** Props to fuzz */
564
+ propsToFuzz: string[];
565
+ /** Iterations */
566
+ iterations: number;
567
+ /** Seed for reproducibility */
568
+ seed?: number;
569
+ /** Input generators */
570
+ generators: Record<string, 'string' | 'number' | 'boolean' | 'array' | 'object' | 'null'>;
571
+ }
572
+
573
+ export declare interface FuzzTestResult {
574
+ component: string;
575
+ iterations: number;
576
+ crashes: Array<{
577
+ input: Record<string, unknown>;
578
+ error: string;
579
+ seed: number;
580
+ }>;
581
+ passed: boolean;
582
+ }
583
+
584
+ /**
585
+ * Generate chromatic command for CI
586
+ */
587
+ export declare function getChromaticCommand(options?: {
588
+ onlyChanged?: boolean;
589
+ exitZeroOnChanges?: boolean;
590
+ }): string;
591
+
592
+ /**
593
+ * Get all focusable elements within a container.
594
+ */
595
+ export declare function getFocusableElements(container: HTMLElement): HTMLElement[];
596
+
597
+ /**
598
+ * Get computed styles as object for inline snapshot
599
+ */
600
+ export declare function getStylesSnapshot(element: ReactElement, properties?: string[], options?: SnapshotOptions): Record<string, string>;
601
+
602
+ export declare interface I18nTestConfig {
603
+ /** Locales to test */
604
+ locales: string[];
605
+ /** RTL locales */
606
+ rtlLocales: string[];
607
+ /** Check for missing translation keys */
608
+ checkMissingKeys: boolean;
609
+ /** Check for hardcoded strings */
610
+ checkHardcodedStrings: boolean;
611
+ /** Pseudo-localization mode */
612
+ pseudoLocalization: boolean;
613
+ /** Max string expansion (%) for layout testing */
614
+ maxExpansion: number;
615
+ }
616
+
617
+ export declare interface I18nTestResult {
618
+ locale: string;
619
+ missingKeys: string[];
620
+ hardcodedStrings: Array<{
621
+ file: string;
622
+ line: number;
623
+ text: string;
624
+ }>;
625
+ layoutOverflows: Array<{
626
+ component: string;
627
+ text: string;
628
+ }>;
629
+ rtlIssues: string[];
630
+ }
631
+
632
+ /**
633
+ * Check if a checkbox/toggle is checked.
634
+ */
635
+ export declare function isChecked(element: HTMLElement): boolean;
636
+
637
+ /**
638
+ * Check if a component is disabled.
639
+ */
640
+ export declare function isDisabled(element: HTMLElement): boolean;
641
+
642
+ /**
643
+ * Check if a component is expanded.
644
+ */
645
+ export declare function isExpanded(element: HTMLElement): boolean;
646
+
647
+ /**
648
+ * Assert that an element is focusable.
649
+ */
650
+ export declare function isFocusable(element: HTMLElement): boolean;
651
+
652
+ /**
653
+ * Check if a component is in loading state.
654
+ */
655
+ export declare function isLoading(element: HTMLElement): boolean;
656
+
657
+ export declare interface LoadTestConfig {
658
+ /** Concurrent users */
659
+ concurrentUsers: number;
660
+ /** Ramp-up time (s) */
661
+ rampUpSeconds: number;
662
+ /** Duration (s) */
663
+ durationSeconds: number;
664
+ /** Target endpoint / component */
665
+ target: string;
666
+ /** Acceptable response time (ms) */
667
+ maxResponseTime: number;
668
+ /** Error rate threshold (%) */
669
+ maxErrorRate: number;
670
+ }
671
+
672
+ export declare interface LoadTestResult {
673
+ totalRequests: number;
674
+ successful: number;
675
+ failed: number;
676
+ avgResponseTime: number;
677
+ p95ResponseTime: number;
678
+ p99ResponseTime: number;
679
+ requestsPerSecond: number;
680
+ errorRate: number;
681
+ passed: boolean;
682
+ }
683
+
684
+ /**
685
+ * Measure page performance metrics
686
+ */
687
+ export declare function measurePerformance(page: Page): Promise<{
688
+ fcp: number;
689
+ lcp: number;
690
+ cls: number;
691
+ ttfb: number;
692
+ tti: number;
693
+ }>;
694
+
695
+ /**
696
+ * Mock REST API endpoints
697
+ */
698
+ export declare function mockAPI(page: Page, mocks: Array<{
699
+ url: string | RegExp;
700
+ method?: string;
701
+ status?: number;
702
+ body?: unknown;
703
+ delay?: number;
704
+ }>): Promise<void>;
705
+
706
+ export declare interface MockDataSource<T> {
707
+ key: string;
708
+ load: () => Promise<{
709
+ data: T[];
710
+ totalCount: number;
711
+ }>;
712
+ insert: (item: T) => Promise<T>;
713
+ update: (key: unknown, values: Partial<T>) => Promise<void>;
714
+ remove: (key: unknown) => Promise<void>;
715
+ getData: () => T[];
716
+ reset: () => void;
717
+ }
718
+
719
+ export declare interface MockDataSourceOptions<T> {
720
+ data: T[];
721
+ delay?: number;
722
+ keyField?: string;
723
+ }
724
+
725
+ /**
726
+ * Mock GraphQL operations
727
+ */
728
+ export declare function mockGraphQL(page: Page, endpoint: string, mocks: Record<string, unknown>): Promise<void>;
729
+
730
+ /**
731
+ * Mock SignalR connection
732
+ */
733
+ export declare function mockSignalR(page: Page, hubUrl: string, handlers: Record<string, (...args: unknown[]) => void>): Promise<{
734
+ send: (method: string, ...args: unknown[]) => Promise<void>;
735
+ }>;
736
+
737
+ /**
738
+ * Selectors for querying Nice2Dev components in tests.
739
+ * Every nice component renders a data-testid by convention.
740
+ *
741
+ * @example
742
+ * import { niceSelectors } from '@nice2dev/testing';
743
+ * const btn = screen.getByTestId(niceSelectors.button('submit'));
744
+ * const grid = screen.getByTestId(niceSelectors.dataGrid());
745
+ */
746
+ export declare const niceSelectors: {
747
+ button: (id?: string) => string;
748
+ textInput: (id?: string) => string;
749
+ numberInput: (id?: string) => string;
750
+ select: (id?: string) => string;
751
+ checkbox: (id?: string) => string;
752
+ toggle: (id?: string) => string;
753
+ datePicker: (id?: string) => string;
754
+ dataGrid: (id?: string) => string;
755
+ table: (id?: string) => string;
756
+ list: (id?: string) => string;
757
+ treeView: (id?: string) => string;
758
+ modal: (id?: string) => string;
759
+ drawer: (id?: string) => string;
760
+ form: (id?: string) => string;
761
+ tabs: (id?: string) => string;
762
+ menu: (id?: string) => string;
763
+ chart: (id?: string) => string;
764
+ scheduler: (id?: string) => string;
765
+ gantt: (id?: string) => string;
766
+ diagram: (id?: string) => string;
767
+ toast: (id?: string) => string;
768
+ alert: (id?: string) => string;
769
+ badge: (id?: string) => string;
770
+ avatar: (id?: string) => string;
771
+ progress: (id?: string) => string;
772
+ skeleton: (id?: string) => string;
773
+ spinner: (id?: string) => string;
774
+ card: (id?: string) => string;
775
+ accordion: (id?: string) => string;
776
+ breadcrumb: (id?: string) => string;
777
+ pagination: (id?: string) => string;
778
+ toolbar: (id?: string) => string;
779
+ };
780
+
781
+ /**
782
+ * Helper class for testing Nice2Dev components
783
+ */
784
+ export declare class NiceTestHelpers {
785
+ private page;
786
+ constructor(page: Page);
787
+ dataGrid: {
788
+ /**
789
+ * Wait for DataGrid to fully load
790
+ */
791
+ waitForLoad: (selector?: string) => Promise<void>;
792
+ /**
793
+ * Select a row by index
794
+ */
795
+ selectRow: (index: number, selector?: string) => Promise<void>;
796
+ /**
797
+ * Sort by column
798
+ */
799
+ sortByColumn: (columnId: string, selector?: string) => Promise<void>;
800
+ /**
801
+ * Filter by column
802
+ */
803
+ filterColumn: (columnId: string, value: string, selector?: string) => Promise<void>;
804
+ /**
805
+ * Get row count
806
+ */
807
+ getRowCount: (selector?: string) => Promise<number>;
808
+ /**
809
+ * Get cell value
810
+ */
811
+ getCellValue: (rowIndex: number, columnId: string, selector?: string) => Promise<string | null>;
812
+ };
813
+ form: {
814
+ /**
815
+ * Fill form field
816
+ */
817
+ fillField: (fieldName: string, value: string) => Promise<void>;
818
+ /**
819
+ * Submit form
820
+ */
821
+ submit: (selector?: string) => Promise<void>;
822
+ /**
823
+ * Check validation errors
824
+ */
825
+ getErrors: (selector?: string) => Promise<string[]>;
826
+ /**
827
+ * Wait for form to be ready
828
+ */
829
+ waitForReady: (selector?: string) => Promise<void>;
830
+ };
831
+ modal: {
832
+ /**
833
+ * Wait for modal to open
834
+ */
835
+ waitForOpen: (selector?: string) => Promise<void>;
836
+ /**
837
+ * Wait for modal to close
838
+ */
839
+ waitForClose: (selector?: string) => Promise<void>;
840
+ /**
841
+ * Close modal
842
+ */
843
+ close: (selector?: string) => Promise<void>;
844
+ /**
845
+ * Click modal action button
846
+ */
847
+ clickAction: (action: "confirm" | "cancel", selector?: string) => Promise<void>;
848
+ };
849
+ navigation: {
850
+ /**
851
+ * Navigate via sidebar
852
+ */
853
+ navigateToRoute: (route: string) => Promise<void>;
854
+ /**
855
+ * Open navigation menu (mobile)
856
+ */
857
+ openMenu: () => Promise<void>;
858
+ /**
859
+ * Check active route
860
+ */
861
+ getActiveRoute: () => Promise<string | null>;
862
+ };
863
+ keyboard: {
864
+ /**
865
+ * Tab through focusable elements
866
+ */
867
+ tabThrough: (count: number) => Promise<void>;
868
+ /**
869
+ * Shift+Tab through focusable elements
870
+ */
871
+ shiftTabThrough: (count: number) => Promise<void>;
872
+ /**
873
+ * Press Enter on focused element
874
+ */
875
+ activate: () => Promise<void>;
876
+ /**
877
+ * Press Escape
878
+ */
879
+ escape: () => Promise<void>;
880
+ /**
881
+ * Navigate with arrow keys
882
+ */
883
+ arrow: (direction: "Up" | "Down" | "Left" | "Right") => Promise<void>;
884
+ };
885
+ }
886
+
887
+ /**
888
+ * Wraps components with all necessary providers for testing.
889
+ * Creates a clean environment with i18n, theme, and a11y contexts.
890
+ *
891
+ * @example
892
+ * render(<NiceButton>Click</NiceButton>, { wrapper: NiceTestWrapper });
893
+ *
894
+ * // Or with options:
895
+ * const Wrapper = ({ children }) => (
896
+ * <NiceTestWrapper direction="rtl">{children}</NiceTestWrapper>
897
+ * );
898
+ * render(<NiceButton>Click</NiceButton>, { wrapper: Wrapper });
899
+ */
900
+ export declare const NiceTestWrapper: default_2.FC<NiceTestWrapperProps>;
901
+
902
+ export declare interface NiceTestWrapperProps {
903
+ children: default_2.ReactNode;
904
+ /** Optional theme to apply */
905
+ theme?: Record<string, unknown>;
906
+ /** Direction for RTL testing */
907
+ direction?: 'ltr' | 'rtl';
908
+ /** Custom translation function */
909
+ t?: (key: string, defaultValue: string) => string;
910
+ }
911
+
912
+ /**
913
+ * Percy configuration for CI
914
+ * Use with @percy/cli
915
+ *
916
+ * @example
917
+ * ```yaml
918
+ * # .percy.yml
919
+ * version: 2
920
+ * snapshot:
921
+ * widths: [375, 768, 1280, 1920]
922
+ * min-height: 1024
923
+ * ```
924
+ */
925
+ export declare const percyConfig: {
926
+ version: number;
927
+ snapshot: {
928
+ widths: number[];
929
+ minHeight: number;
930
+ percyCSS: string;
931
+ };
932
+ discovery: {
933
+ networkIdleTimeout: number;
934
+ allowedHostnames: string[];
935
+ };
936
+ };
937
+
938
+ /**
939
+ * Percy snapshot helper
940
+ */
941
+ export declare function percySnapshot(name: string, options?: {
942
+ widths?: number[];
943
+ minHeight?: number;
944
+ scope?: string;
945
+ enableJavaScript?: boolean;
946
+ }): {
947
+ widths?: number[];
948
+ minHeight?: number;
949
+ scope?: string;
950
+ enableJavaScript?: boolean;
951
+ name: string;
952
+ };
953
+
954
+ export declare interface PerformanceBenchmarkConfig {
955
+ /** Components to benchmark */
956
+ components: string[];
957
+ /** Metrics to track */
958
+ metrics: Array<'render-time' | 'rerender-time' | 'memory' | 'layout-shift' | 'interaction-delay'>;
959
+ /** Iterations per benchmark */
960
+ iterations: number;
961
+ /** Warm-up runs */
962
+ warmUp: number;
963
+ /** Threshold for regression (%) */
964
+ regressionThreshold: number;
965
+ /** Budget (ms) */
966
+ budgets: Record<string, number>;
967
+ }
968
+
969
+ export declare interface PropertyTestConfig {
970
+ /** Number of test runs (default: 100) */
971
+ numRuns?: number;
972
+ /** Seed for reproducibility */
973
+ seed?: number;
974
+ /** Timeout per run in ms */
975
+ timeout?: number;
976
+ /** Enable verbose logging */
977
+ verbose?: boolean;
978
+ /** Example values to always test */
979
+ examples?: unknown[][];
980
+ }
981
+
982
+ /**
983
+ * Render component and return serialized HTML for inline snapshot
984
+ */
985
+ export declare function renderToSnapshot(element: ReactElement, options?: SnapshotOptions): string;
986
+
987
+ export declare interface ResponsiveSnapshotOptions extends SnapshotOptions {
988
+ /** Breakpoints to test [name, width] */
989
+ breakpoints?: [string, number][];
990
+ }
991
+
992
+ export declare type ScanType = 'sast' | 'dast' | 'sca' | 'secret-scan';
993
+
994
+ export declare interface SecurityFinding {
995
+ id: string;
996
+ type: ScanType;
997
+ severity: 'critical' | 'high' | 'medium' | 'low' | 'info';
998
+ title: string;
999
+ description: string;
1000
+ file?: string;
1001
+ line?: number;
1002
+ cve?: string;
1003
+ cwe?: string;
1004
+ recommendation: string;
1005
+ }
1006
+
1007
+ export declare interface SecurityScanConfig {
1008
+ /** Scan type */
1009
+ scanType: ScanType;
1010
+ /** Target path / URL */
1011
+ target: string;
1012
+ /** Severity threshold */
1013
+ failOnSeverity: 'critical' | 'high' | 'medium' | 'low';
1014
+ /** Ignored CVEs */
1015
+ ignoredCves: string[];
1016
+ /** Report format */
1017
+ reportFormat: 'sarif' | 'json' | 'html';
1018
+ }
1019
+
1020
+ export declare interface SecurityScanResult {
1021
+ scanType: ScanType;
1022
+ target: string;
1023
+ findings: SecurityFinding[];
1024
+ passed: boolean;
1025
+ scanDuration: number;
1026
+ }
1027
+
1028
+ /**
1029
+ * Simulate a click with optional modifier keys.
1030
+ */
1031
+ export declare function simulateClick(element: HTMLElement, options?: {
1032
+ ctrlKey?: boolean;
1033
+ shiftKey?: boolean;
1034
+ altKey?: boolean;
1035
+ metaKey?: boolean;
1036
+ }): void;
1037
+
1038
+ /**
1039
+ * Simulate keyboard events for testing keyboard navigation.
1040
+ *
1041
+ * @example
1042
+ * const el = screen.getByTestId('nice-select');
1043
+ * simulateKeyboard(el, 'ArrowDown');
1044
+ * simulateKeyboard(el, 'Enter');
1045
+ */
1046
+ export declare function simulateKeyboard(element: HTMLElement, key: string, options?: Partial<KeyboardEventInit>): void;
1047
+
1048
+ /**
1049
+ * Simulate typing into an input element.
1050
+ * Dispatches input and change events as @testing-library would.
1051
+ */
1052
+ export declare function simulateType(element: HTMLInputElement | HTMLTextAreaElement, text: string): void;
1053
+
1054
+ /**
1055
+ * Create a snapshot of accessibility-relevant attributes
1056
+ */
1057
+ export declare function snapshotA11y(element: ReactElement, options?: SnapshotOptions): void;
1058
+
1059
+ /**
1060
+ * Create a snapshot test for a component's rendered structure
1061
+ *
1062
+ * @example
1063
+ * ```tsx
1064
+ * describe('Button', () => {
1065
+ * snapshotComponent(<Button variant="primary">Click</Button>);
1066
+ * snapshotComponent(<Button variant="secondary">Click</Button>);
1067
+ * snapshotComponent(<Button disabled>Disabled</Button>);
1068
+ * });
1069
+ * ```
1070
+ */
1071
+ export declare function snapshotComponent(element: ReactElement, options?: SnapshotOptions): void;
1072
+
1073
+ export declare interface SnapshotOptions {
1074
+ /** Test description name */
1075
+ name?: string;
1076
+ /** Wrapper component (e.g., ThemeProvider) */
1077
+ wrapper?: React.ComponentType<{
1078
+ children: ReactNode;
1079
+ }>;
1080
+ /** Additional props to apply to wrapper */
1081
+ wrapperProps?: Record<string, unknown>;
1082
+ }
1083
+
1084
+ /**
1085
+ * Create snapshots at different viewport sizes
1086
+ *
1087
+ * @example
1088
+ * ```tsx
1089
+ * snapshotResponsive(<Navigation />, {
1090
+ * breakpoints: [
1091
+ * ['mobile', 375],
1092
+ * ['tablet', 768],
1093
+ * ['desktop', 1024],
1094
+ * ],
1095
+ * });
1096
+ * ```
1097
+ */
1098
+ export declare function snapshotResponsive(element: ReactElement, options?: ResponsiveSnapshotOptions): void;
1099
+
1100
+ /**
1101
+ * Create snapshots for styles in different states
1102
+ *
1103
+ * @example
1104
+ * ```tsx
1105
+ * snapshotStateStyles(
1106
+ * <Button>Click</Button>,
1107
+ * {
1108
+ * default: {},
1109
+ * hover: { pseudo: ':hover' },
1110
+ * focus: { pseudo: ':focus' },
1111
+ * disabled: { props: { disabled: true } },
1112
+ * }
1113
+ * );
1114
+ * ```
1115
+ */
1116
+ export declare function snapshotStateStyles(Component: React.ComponentType<Record<string, unknown>>, baseProps: Record<string, unknown>, states: Record<string, {
1117
+ props?: Record<string, unknown>;
1118
+ pseudo?: string;
1119
+ }>, options?: StyleSnapshotOptions): void;
1120
+
1121
+ /**
1122
+ * Create a snapshot of computed styles
1123
+ *
1124
+ * @example
1125
+ * ```tsx
1126
+ * snapshotStyles(<Button>Click</Button>, ['background-color', 'color', 'padding']);
1127
+ * ```
1128
+ */
1129
+ export declare function snapshotStyles(element: ReactElement, options?: StyleSnapshotOptions): void;
1130
+
1131
+ /**
1132
+ * Create snapshots for different themes
1133
+ *
1134
+ * @example
1135
+ * ```tsx
1136
+ * snapshotThemes(
1137
+ * <Button>Click</Button>,
1138
+ * ThemeProvider,
1139
+ * [
1140
+ * { name: 'light', theme: lightTheme },
1141
+ * { name: 'dark', theme: darkTheme },
1142
+ * ]
1143
+ * );
1144
+ * ```
1145
+ */
1146
+ export declare function snapshotThemes<T>(element: ReactElement, ThemeProvider: React.ComponentType<{
1147
+ theme: T;
1148
+ children: ReactNode;
1149
+ }>, themes: Array<{
1150
+ name: string;
1151
+ theme: T;
1152
+ }>, options?: StyleSnapshotOptions): void;
1153
+
1154
+ /**
1155
+ * Create multiple snapshot tests for different variants
1156
+ *
1157
+ * @example
1158
+ * ```tsx
1159
+ * snapshotVariants(
1160
+ * Button,
1161
+ * { children: 'Click me' },
1162
+ * { variant: ['primary', 'secondary', 'ghost'] }
1163
+ * );
1164
+ * ```
1165
+ */
1166
+ export declare function snapshotVariants<P extends Record<string, unknown>>(Component: React.ComponentType<P>, baseProps: Partial<P>, variants: Partial<{
1167
+ [K in keyof P]: P[K][];
1168
+ }>, options?: SnapshotOptions): void;
1169
+
1170
+ export declare interface StressTestConfig {
1171
+ /** Test type */
1172
+ type: 'large-file' | 'large-dataset' | 'deep-tree' | 'many-components';
1173
+ /** Scale factor */
1174
+ itemCount: number;
1175
+ /** Duration (ms) */
1176
+ duration: number;
1177
+ /** Memory limit (MB) */
1178
+ memoryLimit: number;
1179
+ /** Acceptable frame drops (%) */
1180
+ maxFrameDropPercent: number;
1181
+ }
1182
+
1183
+ export declare interface StressTestResult {
1184
+ type: string;
1185
+ itemCount: number;
1186
+ duration: number;
1187
+ peakMemoryMb: number;
1188
+ averageFps: number;
1189
+ frameDropPercent: number;
1190
+ passed: boolean;
1191
+ errors: string[];
1192
+ }
1193
+
1194
+ export declare interface StyleSnapshotOptions extends SnapshotOptions {
1195
+ /** CSS properties to capture */
1196
+ properties?: string[];
1197
+ /** Pseudo-element to capture (e.g., '::before') */
1198
+ pseudo?: string;
1199
+ }
1200
+
1201
+ export declare interface TelemetryConfig {
1202
+ /** Opt-in required */
1203
+ optInRequired: boolean;
1204
+ /** Endpoint */
1205
+ endpoint: string;
1206
+ /** Events to track */
1207
+ events: Array<'click' | 'navigation' | 'error' | 'performance' | 'custom'>;
1208
+ /** Sampling rate (0-1) */
1209
+ samplingRate: number;
1210
+ /** Session recording */
1211
+ sessionRecording: boolean;
1212
+ /** PII masking */
1213
+ piiMasking: boolean;
1214
+ /** Batch size */
1215
+ batchSize: number;
1216
+ /** Flush interval (ms) */
1217
+ flushInterval: number;
1218
+ }
1219
+
1220
+ /**
1221
+ * Generate consistent data-testid attributes.
1222
+ *
1223
+ * @example
1224
+ * testId('nice-button', 'submit') // 'nice-button-submit'
1225
+ * testId('nice-datagrid', 'row', 3) // 'nice-datagrid-row-3'
1226
+ */
1227
+ export declare function testId(...parts: (string | number)[]): string;
1228
+
1229
+ /**
1230
+ * Create a model-based test
1231
+ *
1232
+ * @example
1233
+ * ```ts
1234
+ * const counterCommands = fc.commands([
1235
+ * fc.constant({ check: () => true, run: (m, r) => { m.value++; r.increment(); }, toString: () => 'increment' }),
1236
+ * fc.constant({ check: (m) => m.value > 0, run: (m, r) => { m.value--; r.decrement(); }, toString: () => 'decrement' }),
1237
+ * ]);
1238
+ *
1239
+ * testModel('Counter', { value: 0 }, () => new Counter(), counterCommands);
1240
+ * ```
1241
+ */
1242
+ export declare function testModel<Model extends object, Real>(name: string, initialModel: () => Model, initialReal: () => Real, commands: fc.Arbitrary<fc.Command<Model, Real>[]>, config?: PropertyTestConfig): void;
1243
+
1244
+ /**
1245
+ * Run a property-based test with Vitest integration
1246
+ *
1247
+ * @example
1248
+ * ```ts
1249
+ * testProperty(
1250
+ * 'sorting is idempotent',
1251
+ * [fc.array(fc.integer())],
1252
+ * (arr) => {
1253
+ * const sorted = arr.sort((a, b) => a - b);
1254
+ * const sortedAgain = [...sorted].sort((a, b) => a - b);
1255
+ * expect(sorted).toEqual(sortedAgain);
1256
+ * }
1257
+ * );
1258
+ * ```
1259
+ */
1260
+ export declare function testProperty<T extends unknown[]>(name: string, arbitraries: {
1261
+ [K in keyof T]: fc.Arbitrary<T[K]>;
1262
+ }, predicate: (...args: T) => void | Promise<void>, config?: PropertyTestConfig): void;
1263
+
1264
+ /**
1265
+ * Run a synchronous property-based test
1266
+ */
1267
+ export declare function testPropertySync<T extends unknown[]>(name: string, arbitraries: {
1268
+ [K in keyof T]: fc.Arbitrary<T[K]>;
1269
+ }, predicate: (...args: T) => void, config?: PropertyTestConfig): void;
1270
+
1271
+ /**
1272
+ * Standard breakpoints for responsive visual testing
1273
+ */
1274
+ export declare const VISUAL_BREAKPOINTS: {
1275
+ readonly mobile: {
1276
+ readonly width: 375;
1277
+ readonly height: 667;
1278
+ };
1279
+ readonly mobileLarge: {
1280
+ readonly width: 414;
1281
+ readonly height: 896;
1282
+ };
1283
+ readonly tablet: {
1284
+ readonly width: 768;
1285
+ readonly height: 1024;
1286
+ };
1287
+ readonly tabletLandscape: {
1288
+ readonly width: 1024;
1289
+ readonly height: 768;
1290
+ };
1291
+ readonly desktop: {
1292
+ readonly width: 1280;
1293
+ readonly height: 800;
1294
+ };
1295
+ readonly desktopLarge: {
1296
+ readonly width: 1440;
1297
+ readonly height: 900;
1298
+ };
1299
+ readonly ultrawide: {
1300
+ readonly width: 1920;
1301
+ readonly height: 1080;
1302
+ };
1303
+ };
1304
+
1305
+ /**
1306
+ * Theme configurations for visual testing
1307
+ */
1308
+ export declare const VISUAL_THEMES: {
1309
+ readonly light: {
1310
+ readonly name: "light";
1311
+ readonly className: "theme-light";
1312
+ readonly background: "#ffffff";
1313
+ };
1314
+ readonly dark: {
1315
+ readonly name: "dark";
1316
+ readonly className: "theme-dark";
1317
+ readonly background: "#1a1a1a";
1318
+ };
1319
+ readonly highContrast: {
1320
+ readonly name: "high-contrast";
1321
+ readonly className: "theme-high-contrast";
1322
+ readonly background: "#000000";
1323
+ };
1324
+ };
1325
+
1326
+ export declare interface VisualDiffResult {
1327
+ componentName: string;
1328
+ viewport: string;
1329
+ matchPercentage: number;
1330
+ passed: boolean;
1331
+ baselineImage: string;
1332
+ currentImage: string;
1333
+ diffImage?: string;
1334
+ }
1335
+
1336
+ export declare interface VisualRegressionConfig {
1337
+ /** Screenshot directory */
1338
+ snapshotDir: string;
1339
+ /** Diff threshold (0-1) */
1340
+ diffThreshold: number;
1341
+ /** Update baseline on pass */
1342
+ updateBaseline: boolean;
1343
+ /** Viewports */
1344
+ viewports: Array<{
1345
+ width: number;
1346
+ height: number;
1347
+ name: string;
1348
+ }>;
1349
+ /** CSS animations disabled */
1350
+ disableAnimations: boolean;
1351
+ /** Mask dynamic regions */
1352
+ maskSelectors: string[];
1353
+ }
1354
+
1355
+ export declare interface VisualSnapshot {
1356
+ name: string;
1357
+ viewport: {
1358
+ width: number;
1359
+ height: number;
1360
+ };
1361
+ theme: string;
1362
+ direction: 'ltr' | 'rtl';
1363
+ story?: string;
1364
+ }
1365
+
1366
+ export declare interface VisualTestConfig {
1367
+ /** Component name for screenshot naming */
1368
+ component: string;
1369
+ /** Story names to test */
1370
+ stories?: string[];
1371
+ /** Breakpoints to test */
1372
+ breakpoints?: (keyof typeof VISUAL_BREAKPOINTS)[];
1373
+ /** Themes to test */
1374
+ themes?: (keyof typeof VISUAL_THEMES)[];
1375
+ /** Test RTL layout */
1376
+ rtl?: boolean;
1377
+ /** Custom viewport sizes */
1378
+ customViewports?: Array<{
1379
+ name: string;
1380
+ width: number;
1381
+ height: number;
1382
+ }>;
1383
+ /** Wait time before screenshot (ms) */
1384
+ waitTime?: number;
1385
+ /** Tolerance for pixel differences (0-1) */
1386
+ tolerance?: number;
1387
+ }
1388
+
1389
+ /**
1390
+ * Storybook preset with visual testing addons
1391
+ */
1392
+ export declare const visualTestingAddons: string[];
1393
+
1394
+ /**
1395
+ * Global types for Storybook toolbar
1396
+ * Add to .storybook/preview.tsx
1397
+ *
1398
+ * @example
1399
+ * ```tsx
1400
+ * export const globalTypes = {
1401
+ * ...visualTestingGlobalTypes,
1402
+ * };
1403
+ * ```
1404
+ */
1405
+ export declare const visualTestingGlobalTypes: {
1406
+ theme: {
1407
+ name: string;
1408
+ description: string;
1409
+ defaultValue: string;
1410
+ toolbar: {
1411
+ icon: string;
1412
+ items: {
1413
+ value: string;
1414
+ title: string;
1415
+ }[];
1416
+ showName: boolean;
1417
+ };
1418
+ };
1419
+ direction: {
1420
+ name: string;
1421
+ description: string;
1422
+ defaultValue: string;
1423
+ toolbar: {
1424
+ icon: string;
1425
+ items: {
1426
+ value: string;
1427
+ title: string;
1428
+ }[];
1429
+ showName: boolean;
1430
+ };
1431
+ };
1432
+ reducedMotion: {
1433
+ name: string;
1434
+ description: string;
1435
+ defaultValue: boolean;
1436
+ toolbar: {
1437
+ icon: string;
1438
+ items: {
1439
+ value: boolean;
1440
+ title: string;
1441
+ }[];
1442
+ showName: boolean;
1443
+ };
1444
+ };
1445
+ };
1446
+
1447
+ /**
1448
+ * Parameters for visual testing
1449
+ */
1450
+ export declare const visualTestingParameters: {
1451
+ viewport: {
1452
+ viewports: {
1453
+ mobile: {
1454
+ name: string;
1455
+ styles: {
1456
+ width: string;
1457
+ height: string;
1458
+ };
1459
+ type: "mobile";
1460
+ };
1461
+ mobileLarge: {
1462
+ name: string;
1463
+ styles: {
1464
+ width: string;
1465
+ height: string;
1466
+ };
1467
+ type: "mobile";
1468
+ };
1469
+ tablet: {
1470
+ name: string;
1471
+ styles: {
1472
+ width: string;
1473
+ height: string;
1474
+ };
1475
+ type: "tablet";
1476
+ };
1477
+ desktop: {
1478
+ name: string;
1479
+ styles: {
1480
+ width: string;
1481
+ height: string;
1482
+ };
1483
+ type: "desktop";
1484
+ };
1485
+ desktopLarge: {
1486
+ name: string;
1487
+ styles: {
1488
+ width: string;
1489
+ height: string;
1490
+ };
1491
+ type: "desktop";
1492
+ };
1493
+ ultrawide: {
1494
+ name: string;
1495
+ styles: {
1496
+ width: string;
1497
+ height: string;
1498
+ };
1499
+ type: "desktop";
1500
+ };
1501
+ };
1502
+ defaultViewport: string;
1503
+ };
1504
+ chromatic: {
1505
+ viewports: number[];
1506
+ diffThreshold: number;
1507
+ pauseAnimationAtEnd: boolean;
1508
+ delay: number;
1509
+ };
1510
+ a11y: {
1511
+ element: string;
1512
+ config: {};
1513
+ options: {};
1514
+ manual: boolean;
1515
+ };
1516
+ layout: string;
1517
+ };
1518
+
1519
+ /**
1520
+ * Base Storybook configuration with visual testing
1521
+ */
1522
+ export declare const visualTestingPreset: Partial<StorybookConfig>;
1523
+
1524
+ /**
1525
+ * Viewport configuration for Storybook
1526
+ */
1527
+ export declare const visualTestingViewports: {
1528
+ mobile: {
1529
+ name: string;
1530
+ styles: {
1531
+ width: string;
1532
+ height: string;
1533
+ };
1534
+ type: "mobile";
1535
+ };
1536
+ mobileLarge: {
1537
+ name: string;
1538
+ styles: {
1539
+ width: string;
1540
+ height: string;
1541
+ };
1542
+ type: "mobile";
1543
+ };
1544
+ tablet: {
1545
+ name: string;
1546
+ styles: {
1547
+ width: string;
1548
+ height: string;
1549
+ };
1550
+ type: "tablet";
1551
+ };
1552
+ desktop: {
1553
+ name: string;
1554
+ styles: {
1555
+ width: string;
1556
+ height: string;
1557
+ };
1558
+ type: "desktop";
1559
+ };
1560
+ desktopLarge: {
1561
+ name: string;
1562
+ styles: {
1563
+ width: string;
1564
+ height: string;
1565
+ };
1566
+ type: "desktop";
1567
+ };
1568
+ ultrawide: {
1569
+ name: string;
1570
+ styles: {
1571
+ width: string;
1572
+ height: string;
1573
+ };
1574
+ type: "desktop";
1575
+ };
1576
+ };
1577
+
1578
+ /**
1579
+ * Wait for a condition to be true.
1580
+ */
1581
+ export declare function waitFor(condition: () => boolean | Promise<boolean>, timeout?: number): Promise<void>;
1582
+
1583
+ /**
1584
+ * Wait for an element to appear in the DOM.
1585
+ */
1586
+ export declare function waitForElement(selector: string, container?: HTMLElement, timeout?: number): Promise<HTMLElement | null>;
1587
+
1588
+ export declare type WcagLevel = 'A' | 'AA' | 'AAA';
1589
+
1590
+ /**
1591
+ * Full visual test configuration
1592
+ */
1593
+ export declare function withFullVisualTesting<T extends Record<string, unknown>>(story: T, options?: {
1594
+ viewports?: (keyof typeof VISUAL_BREAKPOINTS)[];
1595
+ themes?: (keyof typeof VISUAL_THEMES)[];
1596
+ rtl?: boolean;
1597
+ }): T;
1598
+
1599
+ /**
1600
+ * Configure story for RTL visual testing
1601
+ */
1602
+ export declare function withRTLTesting<T extends Record<string, unknown>>(story: T): T;
1603
+
1604
+ /**
1605
+ * Configure story for visual testing with themes
1606
+ */
1607
+ export declare function withVisualThemes<T extends Record<string, unknown>>(story: T, themes?: (keyof typeof VISUAL_THEMES)[]): T;
1608
+
1609
+ /**
1610
+ * Configure story for visual testing with all viewports
1611
+ */
1612
+ export declare function withVisualViewports<T extends Record<string, unknown>>(story: T, viewports?: (keyof typeof VISUAL_BREAKPOINTS)[]): T & {
1613
+ parameters: {
1614
+ chromatic: typeof chromaticDefaults;
1615
+ };
1616
+ };
1617
+
1618
+ export { }