1+ import React from 'react' ;
2+ import { MemoryRouter } from 'react-router-dom' ;
3+ import Adapter from '@magento/venia-ui/lib/components/Adapter' ;
4+ import { Form } from 'informed' ;
5+ import store from '../store' ;
6+ import '@magento/venia-ui/lib/index.module.css' ;
7+ import 'tailwindcss/tailwind.css' ;
8+
9+ // Mock browser APIs that components might expect
10+ if ( typeof window !== 'undefined' ) {
11+ // Ensure URLSearchParams is available with comprehensive methods
12+ if ( ! window . URLSearchParams ) {
13+ window . URLSearchParams = class URLSearchParams {
14+ constructor ( search = '' ) {
15+ this . params = new Map ( ) ;
16+ if ( typeof search === 'string' ) {
17+ if ( search . startsWith ( '?' ) ) search = search . slice ( 1 ) ;
18+ if ( search ) {
19+ search . split ( '&' ) . forEach ( param => {
20+ const [ key , value ] = param . split ( '=' ) ;
21+ if ( key ) this . params . set ( decodeURIComponent ( key ) , decodeURIComponent ( value || '' ) ) ;
22+ } ) ;
23+ }
24+ }
25+ }
26+ get ( key ) { return this . params . get ( key ) ; }
27+ set ( key , value ) { this . params . set ( key , value ) ; }
28+ delete ( key ) { this . params . delete ( key ) ; }
29+ has ( key ) { return this . params . has ( key ) ; }
30+ append ( key , value ) { this . params . set ( key , value ) ; }
31+ toString ( ) {
32+ const entries = Array . from ( this . params . entries ( ) ) ;
33+ return entries . map ( ( [ k , v ] ) => `${ encodeURIComponent ( k ) } =${ encodeURIComponent ( v ) } ` ) . join ( '&' ) ;
34+ }
35+ forEach ( callback ) { this . params . forEach ( callback ) ; }
36+ keys ( ) { return this . params . keys ( ) ; }
37+ values ( ) { return this . params . values ( ) ; }
38+ entries ( ) { return this . params . entries ( ) ; }
39+ } ;
40+ }
41+
42+ // Create comprehensive URL object mock
43+ if ( ! window . URL ) {
44+ window . URL = class URL {
45+ constructor ( url , base ) {
46+ this . href = url || 'http://localhost:9001/?page=1' ;
47+ this . origin = 'http://localhost:9001' ;
48+ this . protocol = 'http:' ;
49+ this . host = 'localhost:9001' ;
50+ this . hostname = 'localhost' ;
51+ this . port = '9001' ;
52+ this . pathname = '/' ;
53+ this . search = '?page=1' ;
54+ this . hash = '' ;
55+ }
56+ toString ( ) { return this . href ; }
57+ } ;
58+ }
59+
60+ // Mock location.search and other properties that might be undefined
61+ try {
62+ if ( ! window . location . search || window . location . search === '' ) {
63+ Object . defineProperty ( window . location , 'search' , {
64+ value : '?page=1' ,
65+ writable : true ,
66+ configurable : true
67+ } ) ;
68+ }
69+ if ( ! window . location . pathname || window . location . pathname === '' ) {
70+ Object . defineProperty ( window . location , 'pathname' , {
71+ value : '/' ,
72+ writable : true ,
73+ configurable : true
74+ } ) ;
75+ }
76+ } catch ( e ) {
77+ // Some browsers don't allow modifying location
78+ console . warn ( 'Could not mock location properties:' , e ) ;
79+ }
80+
81+ // Global string replacement protection
82+ const originalStringReplace = String . prototype . replace ;
83+ String . prototype . replace = function ( ...args ) {
84+ if ( this == null || this === undefined ) {
85+ console . warn ( 'Attempted to call replace on undefined/null value' ) ;
86+ return '' ;
87+ }
88+ return originalStringReplace . apply ( this , args ) ;
89+ } ;
90+ }
91+
92+ const origin = process . env . MAGENTO_BACKEND_URL || 'https://master-7rqtwti-c5v7sxvquxwl4.eu-4.magentosite.cloud/' ;
93+
94+ // Form wrapper for components that need form context
95+ const FormWrapper = ( { children } ) => {
96+ return (
97+ < Form >
98+ { children }
99+ </ Form >
100+ ) ;
101+ } ;
102+
103+ // Router wrapper for components that need routing context
104+ const RouterWrapper = ( { children } ) => {
105+ // Provide initial location with comprehensive data that components might expect
106+ const initialEntries = [
107+ {
108+ pathname : '/' ,
109+ search : '?page=1' ,
110+ hash : '' ,
111+ state : null ,
112+ key : 'default'
113+ }
114+ ] ;
115+
116+ return (
117+ < MemoryRouter initialEntries = { initialEntries } >
118+ { children }
119+ </ MemoryRouter >
120+ ) ;
121+ } ;
122+
123+ export const decorators = [
124+ ( Story ) => (
125+ < RouterWrapper >
126+ < Adapter origin = { origin } store = { store } >
127+ < FormWrapper >
128+ < Story />
129+ </ FormWrapper >
130+ </ Adapter >
131+ </ RouterWrapper >
132+ ) ,
133+ ] ;
134+
135+ export const parameters = {
136+ actions : { argTypesRegex : "^on[A-Z].*" } ,
137+ controls : {
138+ matchers : {
139+ color : / ( b a c k g r o u n d | c o l o r ) $ / i,
140+ date : / D a t e $ / ,
141+ } ,
142+ } ,
143+ } ;
0 commit comments