@salesforce/retail-react-app 8.1.0 → 8.1.1
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.
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
## v8.1.1 (Oct 1, 2025)
|
|
2
|
+
- International URL Support Message in Shopper Agent chat [#3555](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3355)
|
|
3
|
+
|
|
1
4
|
## v8.1.0 (Sep 25, 2025)
|
|
2
5
|
- Updated search UX - prices, images, suggestions new layout [#3271](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3271)
|
|
3
6
|
- Updated the UI for StoreDisplay component which displays pickup in-store information on different pages. [#3248](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3248)
|
|
@@ -259,6 +259,11 @@ const ShopperAgentWindow = ({commerceAgentConfiguration, domainUrl}) => {
|
|
|
259
259
|
conversationContext
|
|
260
260
|
})
|
|
261
261
|
}
|
|
262
|
+
} else if (event.data.type === 'lwc.getDomainUrl') {
|
|
263
|
+
// Handle domain URL request
|
|
264
|
+
sendConversationContext('conversational.domainUrl', {
|
|
265
|
+
domainUrl
|
|
266
|
+
})
|
|
262
267
|
}
|
|
263
268
|
} catch (error) {
|
|
264
269
|
console.error('Error handling Miaw event:', error)
|
|
@@ -421,7 +426,6 @@ const ShopperAgent = ({commerceAgentConfiguration, basketDoneLoading}) => {
|
|
|
421
426
|
const {enabled} = commerceAgentConfiguration
|
|
422
427
|
|
|
423
428
|
// Get current location and app origin for domain URL
|
|
424
|
-
const location = useLocation()
|
|
425
429
|
const appOrigin = useAppOrigin()
|
|
426
430
|
const {buildUrl} = useMultiSite()
|
|
427
431
|
|
|
@@ -429,7 +433,7 @@ const ShopperAgent = ({commerceAgentConfiguration, basketDoneLoading}) => {
|
|
|
429
433
|
const isShopperAgentEnabled = isEnabled(enabled)
|
|
430
434
|
|
|
431
435
|
// Build the current domain URL
|
|
432
|
-
const domainUrl = `${appOrigin}${buildUrl(
|
|
436
|
+
const domainUrl = `${appOrigin}${buildUrl('')}`
|
|
433
437
|
|
|
434
438
|
// Conditional rendering: only render when all conditions are met
|
|
435
439
|
// 1. Agent is enabled and running on client
|
|
@@ -139,7 +139,7 @@ describe('ShopperAgent Component', () => {
|
|
|
139
139
|
// Mock useMultiSite hook with proper structure
|
|
140
140
|
mockedUseMultiSite.mockReturnValue({
|
|
141
141
|
locale: {id: 'en-US', preferredCurrency: 'USD'},
|
|
142
|
-
buildUrl: jest.fn((
|
|
142
|
+
buildUrl: jest.fn(() => '/us/en-US')
|
|
143
143
|
})
|
|
144
144
|
|
|
145
145
|
// Mock useTheme hook
|
|
@@ -239,7 +239,7 @@ describe('ShopperAgent Component', () => {
|
|
|
239
239
|
RefreshToken: 'test-refresh-token',
|
|
240
240
|
Currency: 'USD',
|
|
241
241
|
Language: 'en_US',
|
|
242
|
-
DomainUrl: 'https://example.com/
|
|
242
|
+
DomainUrl: 'https://example.com/us/en-US'
|
|
243
243
|
})
|
|
244
244
|
})
|
|
245
245
|
|
|
@@ -263,7 +263,7 @@ describe('ShopperAgent Component', () => {
|
|
|
263
263
|
RefreshToken: 'initial-token',
|
|
264
264
|
Currency: 'USD',
|
|
265
265
|
Language: 'en_US',
|
|
266
|
-
DomainUrl: 'https://example.com/
|
|
266
|
+
DomainUrl: 'https://example.com/us/en-US'
|
|
267
267
|
})
|
|
268
268
|
|
|
269
269
|
// Clear mock and change refresh token
|
|
@@ -287,7 +287,7 @@ describe('ShopperAgent Component', () => {
|
|
|
287
287
|
RefreshToken: 'updated-token',
|
|
288
288
|
Currency: 'USD',
|
|
289
289
|
Language: 'en_US',
|
|
290
|
-
DomainUrl: 'https://example.com/
|
|
290
|
+
DomainUrl: 'https://example.com/us/en-US'
|
|
291
291
|
})
|
|
292
292
|
})
|
|
293
293
|
|
|
@@ -310,7 +310,7 @@ describe('ShopperAgent Component', () => {
|
|
|
310
310
|
RefreshToken: null,
|
|
311
311
|
Currency: 'USD',
|
|
312
312
|
Language: 'en_US',
|
|
313
|
-
DomainUrl: 'https://example.com/
|
|
313
|
+
DomainUrl: 'https://example.com/us/en-US'
|
|
314
314
|
})
|
|
315
315
|
})
|
|
316
316
|
|
|
@@ -318,7 +318,7 @@ describe('ShopperAgent Component', () => {
|
|
|
318
318
|
// Mock useMultiSite to return different currency values
|
|
319
319
|
mockedUseMultiSite.mockReturnValue({
|
|
320
320
|
locale: {id: 'en-US', preferredCurrency: 'USD'},
|
|
321
|
-
buildUrl: jest.fn((
|
|
321
|
+
buildUrl: jest.fn(() => '/us/en-US')
|
|
322
322
|
})
|
|
323
323
|
|
|
324
324
|
render(<ShopperAgent {...defaultProps} />)
|
|
@@ -337,14 +337,14 @@ describe('ShopperAgent Component', () => {
|
|
|
337
337
|
RefreshToken: 'test-refresh-token',
|
|
338
338
|
Currency: 'USD',
|
|
339
339
|
Language: 'en_US',
|
|
340
|
-
DomainUrl: 'https://example.com/
|
|
340
|
+
DomainUrl: 'https://example.com/us/en-US'
|
|
341
341
|
})
|
|
342
342
|
|
|
343
343
|
// Clear mock and change currency to EUR
|
|
344
344
|
mockEmbeddedService.prechatAPI.setHiddenPrechatFields.mockClear()
|
|
345
345
|
mockedUseMultiSite.mockReturnValue({
|
|
346
346
|
locale: {id: 'en-US', preferredCurrency: 'EUR'},
|
|
347
|
-
buildUrl: jest.fn((
|
|
347
|
+
buildUrl: jest.fn(() => '/us/en-US')
|
|
348
348
|
})
|
|
349
349
|
|
|
350
350
|
// Re-render with new currency
|
|
@@ -364,7 +364,7 @@ describe('ShopperAgent Component', () => {
|
|
|
364
364
|
RefreshToken: 'test-refresh-token',
|
|
365
365
|
Currency: 'EUR',
|
|
366
366
|
Language: 'en_US',
|
|
367
|
-
DomainUrl: 'https://example.com/
|
|
367
|
+
DomainUrl: 'https://example.com/us/en-US'
|
|
368
368
|
})
|
|
369
369
|
})
|
|
370
370
|
|
|
@@ -372,7 +372,7 @@ describe('ShopperAgent Component', () => {
|
|
|
372
372
|
// Mock useMultiSite to return different locale values
|
|
373
373
|
mockedUseMultiSite.mockReturnValue({
|
|
374
374
|
locale: {id: 'en-US', preferredCurrency: 'USD'},
|
|
375
|
-
buildUrl: jest.fn((
|
|
375
|
+
buildUrl: jest.fn(() => '/us/en-US')
|
|
376
376
|
})
|
|
377
377
|
|
|
378
378
|
render(<ShopperAgent {...defaultProps} />)
|
|
@@ -391,14 +391,14 @@ describe('ShopperAgent Component', () => {
|
|
|
391
391
|
RefreshToken: 'test-refresh-token',
|
|
392
392
|
Currency: 'USD',
|
|
393
393
|
Language: 'en_US',
|
|
394
|
-
DomainUrl: 'https://example.com/
|
|
394
|
+
DomainUrl: 'https://example.com/us/en-US'
|
|
395
395
|
})
|
|
396
396
|
|
|
397
397
|
// Clear mock and change locale to en-GB
|
|
398
398
|
mockEmbeddedService.prechatAPI.setHiddenPrechatFields.mockClear()
|
|
399
399
|
mockedUseMultiSite.mockReturnValue({
|
|
400
400
|
locale: {id: 'en-GB', preferredCurrency: 'GBP'},
|
|
401
|
-
buildUrl: jest.fn((
|
|
401
|
+
buildUrl: jest.fn(() => '/us/en-US')
|
|
402
402
|
})
|
|
403
403
|
|
|
404
404
|
// Re-render with new locale
|
|
@@ -418,7 +418,7 @@ describe('ShopperAgent Component', () => {
|
|
|
418
418
|
RefreshToken: 'test-refresh-token',
|
|
419
419
|
Currency: 'GBP',
|
|
420
420
|
Language: 'en_GB',
|
|
421
|
-
DomainUrl: 'https://example.com/
|
|
421
|
+
DomainUrl: 'https://example.com/us/en-US'
|
|
422
422
|
})
|
|
423
423
|
})
|
|
424
424
|
|
|
@@ -449,7 +449,7 @@ describe('ShopperAgent Component', () => {
|
|
|
449
449
|
RefreshToken: 'test-refresh-token',
|
|
450
450
|
Currency: 'USD',
|
|
451
451
|
Language: 'en_US',
|
|
452
|
-
DomainUrl: 'https://example.com/
|
|
452
|
+
DomainUrl: 'https://example.com/us/en-US'
|
|
453
453
|
})
|
|
454
454
|
})
|
|
455
455
|
|
|
@@ -560,7 +560,7 @@ describe('ShopperAgent Component', () => {
|
|
|
560
560
|
RefreshToken: 'test-refresh-token',
|
|
561
561
|
Currency: 'USD',
|
|
562
562
|
Language: 'en_US',
|
|
563
|
-
DomainUrl: 'https://example.com/
|
|
563
|
+
DomainUrl: 'https://example.com/us/en-US'
|
|
564
564
|
})
|
|
565
565
|
})
|
|
566
566
|
|
|
@@ -585,7 +585,7 @@ describe('ShopperAgent Component', () => {
|
|
|
585
585
|
RefreshToken: 'test-refresh-token',
|
|
586
586
|
Currency: 'USD',
|
|
587
587
|
Language: 'en_US',
|
|
588
|
-
DomainUrl: 'https://example.com/
|
|
588
|
+
DomainUrl: 'https://example.com/us/en-US'
|
|
589
589
|
})
|
|
590
590
|
})
|
|
591
591
|
|
|
@@ -597,39 +597,6 @@ describe('ShopperAgent Component', () => {
|
|
|
597
597
|
render(<ShopperAgent {...props} />)
|
|
598
598
|
expect(screen.queryByTestId('shopper-agent')).toBeInTheDocument()
|
|
599
599
|
})
|
|
600
|
-
|
|
601
|
-
test('should handle complex domainUrl with query parameters and fragments', async () => {
|
|
602
|
-
// Mock complex location data
|
|
603
|
-
mockUseLocation.mockReturnValue({
|
|
604
|
-
pathname: '/products/shoes',
|
|
605
|
-
search: '?color=red&size=10',
|
|
606
|
-
hash: '#reviews'
|
|
607
|
-
})
|
|
608
|
-
mockUseAppOrigin.mockReturnValue('https://test-store.com')
|
|
609
|
-
|
|
610
|
-
const props = {
|
|
611
|
-
...defaultProps
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
render(<ShopperAgent {...props} />)
|
|
615
|
-
|
|
616
|
-
// Trigger the onEmbeddedMessagingReady event
|
|
617
|
-
await act(async () => {
|
|
618
|
-
window.dispatchEvent(new Event('onEmbeddedMessagingReady'))
|
|
619
|
-
})
|
|
620
|
-
|
|
621
|
-
expect(mockEmbeddedService.prechatAPI.setHiddenPrechatFields).toHaveBeenCalledWith({
|
|
622
|
-
SiteId: 'RefArchGlobal',
|
|
623
|
-
Locale: 'en-US',
|
|
624
|
-
OrganizationId: 'test-commerce-org-id',
|
|
625
|
-
UsId: 'test-usid',
|
|
626
|
-
IsCartMgmtSupported: 'true',
|
|
627
|
-
RefreshToken: 'test-refresh-token',
|
|
628
|
-
Currency: 'USD',
|
|
629
|
-
Language: 'en_US',
|
|
630
|
-
DomainUrl: 'https://test-store.com/products/shoes'
|
|
631
|
-
})
|
|
632
|
-
})
|
|
633
600
|
})
|
|
634
601
|
|
|
635
602
|
describe('Conversation Context Functionality', () => {
|
|
@@ -987,4 +954,78 @@ describe('ShopperAgent Component', () => {
|
|
|
987
954
|
expect(() => render(<ShopperAgent {...props} />)).not.toThrow()
|
|
988
955
|
})
|
|
989
956
|
})
|
|
957
|
+
|
|
958
|
+
describe('Domain URL Event Functionality', () => {
|
|
959
|
+
beforeEach(() => {
|
|
960
|
+
// Mock postMessage for iframe communication
|
|
961
|
+
global.postMessage = jest.fn()
|
|
962
|
+
|
|
963
|
+
// Mock document.querySelector for iframe
|
|
964
|
+
const mockIframe = {
|
|
965
|
+
src: 'https://test.salesforce.com/iframe',
|
|
966
|
+
contentWindow: {
|
|
967
|
+
postMessage: jest.fn()
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
jest.spyOn(document, 'querySelector').mockReturnValue(mockIframe)
|
|
971
|
+
})
|
|
972
|
+
|
|
973
|
+
afterEach(() => {
|
|
974
|
+
jest.restoreAllMocks()
|
|
975
|
+
})
|
|
976
|
+
|
|
977
|
+
test('should handle lwc.getDomainUrl event and send domain URL', async () => {
|
|
978
|
+
render(<ShopperAgent {...defaultProps} />)
|
|
979
|
+
|
|
980
|
+
// Mock iframe for postMessage
|
|
981
|
+
const mockIframe = {
|
|
982
|
+
src: 'https://test.salesforce.com/iframe',
|
|
983
|
+
contentWindow: {
|
|
984
|
+
postMessage: jest.fn()
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
jest.spyOn(document, 'querySelector').mockReturnValue(mockIframe)
|
|
988
|
+
|
|
989
|
+
// Simulate MIAW event requesting domain URL
|
|
990
|
+
const mockEvent = {
|
|
991
|
+
source: {postMessage: jest.fn()},
|
|
992
|
+
data: {type: 'lwc.getDomainUrl'}
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
await act(async () => {
|
|
996
|
+
window.dispatchEvent(new MessageEvent('message', mockEvent))
|
|
997
|
+
})
|
|
998
|
+
|
|
999
|
+
// Verify postMessage was called with domain URL
|
|
1000
|
+
expect(mockIframe.contentWindow.postMessage).toHaveBeenCalledWith(
|
|
1001
|
+
{
|
|
1002
|
+
type: 'conversational.domainUrl',
|
|
1003
|
+
payload: {
|
|
1004
|
+
domainUrl: 'https://example.com/us/en-US'
|
|
1005
|
+
}
|
|
1006
|
+
},
|
|
1007
|
+
'https://test.salesforce.com'
|
|
1008
|
+
)
|
|
1009
|
+
})
|
|
1010
|
+
|
|
1011
|
+
test('should handle lwc.getDomainUrl event properly when iframe not found', async () => {
|
|
1012
|
+
render(<ShopperAgent {...defaultProps} />)
|
|
1013
|
+
|
|
1014
|
+
// Mock querySelector to return null (iframe not found)
|
|
1015
|
+
jest.spyOn(document, 'querySelector').mockReturnValue(null)
|
|
1016
|
+
|
|
1017
|
+
// Simulate MIAW event
|
|
1018
|
+
const mockEvent = {
|
|
1019
|
+
source: {postMessage: jest.fn()},
|
|
1020
|
+
data: {type: 'lwc.getDomainUrl'}
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
await act(async () => {
|
|
1024
|
+
window.dispatchEvent(new MessageEvent('message', mockEvent))
|
|
1025
|
+
})
|
|
1026
|
+
|
|
1027
|
+
// Should handle missing iframe gracefully without throwing
|
|
1028
|
+
expect(() => render(<ShopperAgent {...defaultProps} />)).not.toThrow()
|
|
1029
|
+
})
|
|
1030
|
+
})
|
|
990
1031
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/retail-react-app",
|
|
3
|
-
"version": "8.1.
|
|
3
|
+
"version": "8.1.1",
|
|
4
4
|
"license": "See license in LICENSE",
|
|
5
5
|
"author": "cc-pwa-kit@salesforce.com",
|
|
6
6
|
"ccExtensibility": {
|
|
@@ -107,5 +107,5 @@
|
|
|
107
107
|
"maxSize": "335 kB"
|
|
108
108
|
}
|
|
109
109
|
],
|
|
110
|
-
"gitHead": "
|
|
110
|
+
"gitHead": "9ea82a41bc00f5d3e46985b448c3b2c9efc4bf0b"
|
|
111
111
|
}
|