@coveo/quantic 3.13.1 → 3.14.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 (50) hide show
  1. package/docs/out/quantic-docs.json +11 -2
  2. package/force-app/main/default/labels/CustomLabels.labels-meta.xml +2 -2
  3. package/force-app/main/default/lwc/quanticBreadcrumbManager/__tests__/quanticBreadcrumbManager.test.js +6 -12
  4. package/force-app/main/default/lwc/quanticGeneratedAnswer/__tests__/quanticGeneratedAnswer.test.js +113 -6
  5. package/force-app/main/default/lwc/quanticGeneratedAnswer/quanticGeneratedAnswer.js +32 -5
  6. package/force-app/main/default/lwc/quanticGeneratedAnswer/templates/generatedAnswer.html +1 -1
  7. package/force-app/main/default/lwc/quanticResultsPerPage/__tests__/quanticResultsPerPage.test.js +404 -0
  8. package/force-app/main/default/lwc/quanticResultsPerPage/e2e/fixture.ts +74 -0
  9. package/force-app/main/default/lwc/quanticResultsPerPage/e2e/pageObject.ts +85 -0
  10. package/force-app/main/default/lwc/quanticResultsPerPage/e2e/quanticResultsPerPage.e2e.ts +97 -0
  11. package/force-app/main/default/lwc/quanticResultsPerPage/quanticResultsPerPage.html +1 -1
  12. package/force-app/main/default/lwc/quanticResultsPerPage/quanticResultsPerPage.js +44 -9
  13. package/force-app/main/default/lwc/quanticSmartSnippet/e2e/data.ts +2 -11
  14. package/force-app/main/default/lwc/quanticSmartSnippet/e2e/fixture.ts +9 -5
  15. package/force-app/main/default/lwc/quanticSmartSnippet/e2e/pageObject.ts +1 -1
  16. package/force-app/main/default/lwc/quanticSmartSnippetAnswer/quanticSmartSnippetAnswer.html +1 -1
  17. package/force-app/main/default/lwc/quanticSmartSnippetSuggestions/__tests__/quanticSmartSnippetSuggestions.test.js +329 -0
  18. package/force-app/main/default/lwc/quanticSmartSnippetSuggestions/e2e/data.ts +31 -0
  19. package/force-app/main/default/lwc/quanticSmartSnippetSuggestions/e2e/fixture.ts +93 -0
  20. package/force-app/main/default/lwc/quanticSmartSnippetSuggestions/e2e/pageObject.ts +160 -0
  21. package/force-app/main/default/lwc/quanticSmartSnippetSuggestions/e2e/quanticSmartSnippetSuggestions.e2e.ts +127 -0
  22. package/force-app/main/default/lwc/quanticSmartSnippetSuggestions/quanticSmartSnippetSuggestions.html +2 -1
  23. package/force-app/main/default/staticresources/coveoheadless/case-assist/headless.js +6 -6
  24. package/force-app/main/default/staticresources/coveoheadless/definitions/api/service/insight/get-interface/get-interface-config-response.d.ts +4 -1
  25. package/force-app/main/default/staticresources/coveoheadless/definitions/commerce.index.d.ts +1 -0
  26. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/context/cart/headless-cart.ssr.d.ts +0 -2
  27. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/context/headless-context.ssr.d.ts +0 -2
  28. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/core/breadcrumb-manager/headless-core-breadcrumb-manager.ssr.d.ts +0 -2
  29. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/core/facets/generator/headless-commerce-facet-generator.ssr.d.ts +0 -2
  30. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/core/pagination/headless-core-commerce-pagination.ssr.d.ts +0 -2
  31. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/core/parameter-manager/headless-core-parameter-manager.ssr.d.ts +0 -2
  32. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/core/sort/headless-core-commerce-sort.ssr.d.ts +0 -2
  33. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/core/summary/headless-core-summary.ssr.d.ts +0 -2
  34. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/field-suggestions/headless-field-suggestions-generator.ssr.d.ts +0 -2
  35. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/instant-products/headless-instant-products.ssr.d.ts +0 -2
  36. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/product-list/headless-product-list.ssr.d.ts +1 -3
  37. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/product-view/headless-product-view.ssr.d.ts +0 -1
  38. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/recent-queries-list/headless-recent-queries-list.ssr.d.ts +0 -2
  39. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/recommendations/headless-recommendations.ssr.d.ts +0 -4
  40. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/search/did-you-mean/headless-did-you-mean.ssr.d.ts +1 -3
  41. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/search-box/headless-search-box.ssr.d.ts +0 -2
  42. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/standalone-search-box/headless-standalone-search-box.ssr.d.ts +0 -2
  43. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/triggers/headless-notify-trigger.ssr.d.ts +0 -2
  44. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/triggers/headless-query-trigger.ssr.d.ts +0 -2
  45. package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/commerce/triggers/headless-redirection-trigger.ssr.d.ts +0 -2
  46. package/force-app/main/default/staticresources/coveoheadless/definitions/features/recent-queries/recent-queries-slice.d.ts +4 -2
  47. package/force-app/main/default/staticresources/coveoheadless/headless.js +8 -8
  48. package/force-app/main/default/staticresources/coveoheadless/insight/headless.js +7 -7
  49. package/force-app/main/default/staticresources/coveoheadless/recommendation/headless.js +6 -6
  50. package/package.json +10 -10
@@ -1021,6 +1021,15 @@
1021
1021
  "required": false,
1022
1022
  "defaultValue": "{false}",
1023
1023
  "type": "boolean"
1024
+ },
1025
+ {
1026
+ "name": "maxCollapsedHeight",
1027
+ "attribute": "max-collapsed-height",
1028
+ "access": "@api",
1029
+ "description": "<p>The maximum height (in px units) of the generated answer when it is collapsed.</p>",
1030
+ "required": false,
1031
+ "defaultValue": "{250}",
1032
+ "type": "number"
1024
1033
  }
1025
1034
  ]
1026
1035
  },
@@ -1894,7 +1903,7 @@
1894
1903
  "access": "@api",
1895
1904
  "description": "<p>The initial selection for the number of result per page. This should be part of the <code>choicesDisplayed</code> option. By default, this is set to the first value in <code>choicesDisplayed</code>.</p>",
1896
1905
  "required": false,
1897
- "defaultValue": "`10`",
1906
+ "defaultValue": "`the first value in 'choicesDisplayed'`",
1898
1907
  "type": "number"
1899
1908
  }
1900
1909
  ]
@@ -5635,7 +5644,7 @@
5635
5644
  "access": "@api",
5636
5645
  "description": "<p>The initial selection for the number of result per page. This should be part of the <code>choicesDisplayed</code> option. By default, this is set to the first value in <code>choicesDisplayed</code>.</p>",
5637
5646
  "required": false,
5638
- "defaultValue": "`10`",
5647
+ "defaultValue": "`the first value in 'choicesDisplayed'`",
5639
5648
  "type": "number"
5640
5649
  }
5641
5650
  ]
@@ -1444,10 +1444,10 @@
1444
1444
  </labels>
1445
1445
  <labels>
1446
1446
  <fullName>quantic_RecentQueryAriaLabel</fullName>
1447
- <value>Recent query,</value>
1447
+ <value>recent query,</value>
1448
1448
  <language>en_US</language>
1449
1449
  <protected>false</protected>
1450
- <shortDescription>Recent query,</shortDescription>
1450
+ <shortDescription>recent query,</shortDescription>
1451
1451
  </labels>
1452
1452
  <labels>
1453
1453
  <fullName>quantic_QuerySuggestionAriaLabel</fullName>
@@ -114,6 +114,12 @@ function cleanup() {
114
114
  }
115
115
 
116
116
  describe('c-quantic-breadcrumb-manager', () => {
117
+ beforeEach(() => {
118
+ mockSuccessfulHeadlessInitialization();
119
+ prepareHeadlessState();
120
+ mockStoreState();
121
+ });
122
+
117
123
  afterEach(() => {
118
124
  breadcrumbManagerState = initialBreadcrumbManagerState;
119
125
  storeState = initialStoreState;
@@ -155,18 +161,6 @@ describe('c-quantic-breadcrumb-manager', () => {
155
161
  });
156
162
  });
157
163
 
158
- beforeEach(() => {
159
- mockSuccessfulHeadlessInitialization();
160
- prepareHeadlessState();
161
- mockStoreState();
162
- });
163
-
164
- afterEach(() => {
165
- breadcrumbManagerState = initialBreadcrumbManagerState;
166
- storeState = initialStoreState;
167
- cleanup();
168
- });
169
-
170
164
  describe('facet breadcrumbs rendering', () => {
171
165
  const exampleFacetBreadcrumbs = [
172
166
  {
@@ -4,7 +4,8 @@ import {createElement} from 'lwc';
4
4
  import QuanticGeneratedAnswer from 'c/quanticGeneratedAnswer';
5
5
  import * as mockHeadlessLoader from 'c/quanticHeadlessLoader';
6
6
 
7
- let mockAnswerHeight = 300;
7
+ let mockAnswerHeight = 250;
8
+ let mockedConsoleWarn;
8
9
 
9
10
  jest.mock('c/quanticHeadlessLoader');
10
11
  jest.mock('c/quanticUtils', () => ({
@@ -31,6 +32,7 @@ const defaultOptions = {
31
32
  answerConfigurationId: undefined,
32
33
  withToggle: false,
33
34
  collapsible: false,
35
+ maxCollapsedHeight: 250,
34
36
  };
35
37
 
36
38
  function createTestComponent(options = defaultOptions) {
@@ -48,6 +50,7 @@ function createTestComponent(options = defaultOptions) {
48
50
  const selectors = {
49
51
  initializationError: 'c-quantic-component-error',
50
52
  generatedAnswerCard: '[data-testid="generated-answer__card"]',
53
+ generatedAnswer: '[data-testid="generated-answer__answer"]',
51
54
  generatedAnswerBadge: '[data-testid="generated-answer__badge"]',
52
55
  generatedAnswerRetryButton: '[data-testid="generated-answer__retry-button"]',
53
56
  generatedAnswerActions: '[data-testid="generated-answer__actions"]',
@@ -101,7 +104,7 @@ const exampleEngine = {
101
104
  id: 'dummy engine',
102
105
  };
103
106
  let isInitialized = false;
104
- const maximumAnswerHeight = 250;
107
+ const defaultAnswerHeight = 250;
105
108
 
106
109
  function prepareHeadlessState() {
107
110
  // @ts-ignore
@@ -142,6 +145,10 @@ function cleanup() {
142
145
  }
143
146
 
144
147
  describe('c-quantic-generated-answer', () => {
148
+ beforeEach(() => {
149
+ mockedConsoleWarn = jest.spyOn(console, 'warn').mockImplementation();
150
+ });
151
+
145
152
  afterEach(() => {
146
153
  cleanup();
147
154
  });
@@ -342,7 +349,7 @@ describe('c-quantic-generated-answer', () => {
342
349
  describe('when the property collapsible is set to true', () => {
343
350
  describe('when the answer is shorter than the maximum answer height', () => {
344
351
  beforeEach(() => {
345
- mockAnswerHeight = maximumAnswerHeight - 100;
352
+ mockAnswerHeight = defaultAnswerHeight - 100;
346
353
  });
347
354
 
348
355
  it('should not display the generating answer message', async () => {
@@ -363,7 +370,7 @@ describe('c-quantic-generated-answer', () => {
363
370
 
364
371
  describe('when the answer is longer than the maximum answer height', () => {
365
372
  beforeEach(() => {
366
- mockAnswerHeight = maximumAnswerHeight + 100;
373
+ mockAnswerHeight = defaultAnswerHeight + 100;
367
374
  });
368
375
 
369
376
  it('should display the generating answer message', async () => {
@@ -489,7 +496,7 @@ describe('c-quantic-generated-answer', () => {
489
496
  describe('when the property collapsible is set to true', () => {
490
497
  describe('when the answer is shorter than the maximum answer height', () => {
491
498
  beforeEach(() => {
492
- mockAnswerHeight = maximumAnswerHeight - 100;
499
+ mockAnswerHeight = defaultAnswerHeight - 100;
493
500
  });
494
501
 
495
502
  it('should not display the generating answer message', async () => {
@@ -525,7 +532,7 @@ describe('c-quantic-generated-answer', () => {
525
532
 
526
533
  describe('when the answer is longer than the maximum answer height', () => {
527
534
  beforeEach(() => {
528
- mockAnswerHeight = maximumAnswerHeight + 100;
535
+ mockAnswerHeight = defaultAnswerHeight + 100;
529
536
  });
530
537
 
531
538
  it('should not display the generating answer message', async () => {
@@ -558,6 +565,106 @@ describe('c-quantic-generated-answer', () => {
558
565
  expect(generatedAnswerCollapseToggle).not.toBeNull();
559
566
  });
560
567
  });
568
+
569
+ describe('when the property maxCollapsedHeight is set to a custom value', () => {
570
+ // The valid range is between 150 and 500 pixels.
571
+ describe('when the maxCollapsedHeight value is within the valid range and the answer exceeds it', () => {
572
+ it('should display the generated answer as collapsed and set the maxHeight of the generated answer to the given custom value', async () => {
573
+ const expectedMaxCollapsibleAnswerHeight = 300;
574
+ mockAnswerHeight = 350;
575
+ const element = createTestComponent({
576
+ ...defaultOptions,
577
+ collapsible: true,
578
+ maxCollapsedHeight: expectedMaxCollapsibleAnswerHeight,
579
+ });
580
+ await flushPromises();
581
+
582
+ const generatedAnswer = element.shadowRoot.querySelector(
583
+ selectors.generatedAnswer
584
+ );
585
+ expect(generatedAnswer).not.toBeNull();
586
+
587
+ const generatedAnswerCollapseToggle =
588
+ element.shadowRoot.querySelector(
589
+ selectors.generatedAnswerCollapseToggle
590
+ );
591
+ expect(generatedAnswerCollapseToggle).not.toBeNull();
592
+
593
+ const maxHeightValue =
594
+ generatedAnswer.style.getPropertyValue('--maxHeight');
595
+ expect(maxHeightValue).toEqual(
596
+ `${expectedMaxCollapsibleAnswerHeight}px`
597
+ );
598
+
599
+ expect(mockedConsoleWarn).not.toHaveBeenCalled();
600
+ });
601
+ });
602
+
603
+ describe('when the maxCollapsedHeight value is greater than the valid range', () => {
604
+ it('should set the generated answer height with the fallback default value and log a warning in the console', async () => {
605
+ const exampleMaxCollapsedHeightValue = 550;
606
+ const element = createTestComponent({
607
+ ...defaultOptions,
608
+ collapsible: true,
609
+ maxCollapsedHeight: exampleMaxCollapsedHeightValue,
610
+ });
611
+ await flushPromises();
612
+
613
+ const generatedAnswer = element.shadowRoot.querySelector(
614
+ selectors.generatedAnswer
615
+ );
616
+ expect(generatedAnswer).not.toBeNull();
617
+
618
+ const generatedAnswerCollapseToggle =
619
+ element.shadowRoot.querySelector(
620
+ selectors.generatedAnswerCollapseToggle
621
+ );
622
+ expect(generatedAnswerCollapseToggle).not.toBeNull();
623
+
624
+ const maxHeightValue =
625
+ generatedAnswer.style.getPropertyValue('--maxHeight');
626
+ expect(maxHeightValue).toEqual(`${defaultAnswerHeight}px`);
627
+
628
+ expect(mockedConsoleWarn).toHaveBeenCalledTimes(1);
629
+ expect(mockedConsoleWarn).toHaveBeenCalledWith(
630
+ `Cannot set max-collapsed-height to (${exampleMaxCollapsedHeightValue}) it accepts a range between 150 and 500. The default value of 250px will be used.`
631
+ );
632
+ });
633
+ });
634
+
635
+ describe('when the maxCollapsedHeight value is smaller than the valid range', () => {
636
+ it('should set the generated answer height with the fallback default value and log a warning in the console', async () => {
637
+ const exampleMaxCollapsedHeightValue = 100;
638
+ const element = createTestComponent({
639
+ ...defaultOptions,
640
+ collapsible: true,
641
+ maxCollapsedHeight: exampleMaxCollapsedHeightValue,
642
+ });
643
+ await flushPromises();
644
+
645
+ const generatedAnswer = element.shadowRoot.querySelector(
646
+ selectors.generatedAnswer
647
+ );
648
+ expect(generatedAnswer).not.toBeNull();
649
+
650
+ const generatedAnswerCollapseToggle =
651
+ element.shadowRoot.querySelector(
652
+ selectors.generatedAnswerCollapseToggle
653
+ );
654
+ expect(generatedAnswerCollapseToggle).not.toBeNull();
655
+
656
+ const maxHeightValue =
657
+ generatedAnswer.style.getPropertyValue('--maxHeight');
658
+
659
+ expect(maxHeightValue).toEqual(`${defaultAnswerHeight}px`);
660
+
661
+ expect(mockedConsoleWarn).toHaveBeenCalledTimes(1);
662
+ expect(mockedConsoleWarn).toHaveBeenCalledWith(
663
+ `Cannot set max-collapsed-height to (${exampleMaxCollapsedHeightValue}) it accepts a range between 150 and 500. The default value of 250px will be used.`
664
+ );
665
+ });
666
+ });
667
+ });
561
668
  });
562
669
 
563
670
  it('should display the generated answer content', async () => {
@@ -44,6 +44,10 @@ const FEEDBACK_LIKED_STATE = 'liked';
44
44
  const FEEDBACK_DISLIKED_STATE = 'disliked';
45
45
  const FEEDBACK_NEUTRAL_STATE = 'neutral';
46
46
 
47
+ const DEFAULT_COLLAPSED_HEIGHT = 250;
48
+ const MAX_VALID_COLLAPSED_HEIGHT = 500;
49
+ const MIN_VALID_COLLAPSED_HEIGHT = 150;
50
+
47
51
  const GENERATED_ANSWER_DATA_KEY = 'coveo-generated-answer-data';
48
52
 
49
53
  /**
@@ -86,6 +90,29 @@ export default class QuanticGeneratedAnswer extends LightningElement {
86
90
  * @type {string}
87
91
  */
88
92
  @api answerConfigurationId;
93
+ /**
94
+ * The maximum height (in px units) of the generated answer when it is collapsed.
95
+ * @api
96
+ * @type {number}
97
+ * @default {250}
98
+ */
99
+ @api
100
+ get maxCollapsedHeight() {
101
+ return this._maxCollapsedHeight;
102
+ }
103
+ set maxCollapsedHeight(value) {
104
+ if (
105
+ value >= MIN_VALID_COLLAPSED_HEIGHT &&
106
+ value <= MAX_VALID_COLLAPSED_HEIGHT
107
+ ) {
108
+ this._maxCollapsedHeight = value;
109
+ } else {
110
+ console.warn(
111
+ `Cannot set max-collapsed-height to (${value}) it accepts a range between ${MIN_VALID_COLLAPSED_HEIGHT} and ${MAX_VALID_COLLAPSED_HEIGHT}. The default value of ${DEFAULT_COLLAPSED_HEIGHT}px will be used.`
112
+ );
113
+ this._maxCollapsedHeight = DEFAULT_COLLAPSED_HEIGHT;
114
+ }
115
+ }
89
116
 
90
117
  labels = {
91
118
  generatedAnswerForYou,
@@ -125,14 +152,14 @@ export default class QuanticGeneratedAnswer extends LightningElement {
125
152
  ariaLiveMessage;
126
153
  /** @type {boolean} */
127
154
  hasInitializationError = false;
128
- /** @type {number} */
129
- _maximumAnswerHeight = 250;
130
155
  /** @type {boolean} */
131
156
  _exceedsMaximumHeight = false;
132
157
  /** @type {boolean} */
133
158
  _liked = false;
134
159
  /** @type {boolean} */
135
160
  _disliked = false;
161
+ /** @type {number} */
162
+ _maxCollapsedHeight = DEFAULT_COLLAPSED_HEIGHT;
136
163
 
137
164
  connectedCallback() {
138
165
  registerComponentForInit(this, this.engineId);
@@ -225,7 +252,7 @@ export default class QuanticGeneratedAnswer extends LightningElement {
225
252
  ? this.generatedAnswerElementHeight + 50
226
253
  : this.generatedAnswerElementHeight;
227
254
 
228
- return answerElementHeight > this._maximumAnswerHeight;
255
+ return answerElementHeight > this.maxCollapsedHeight;
229
256
  }
230
257
 
231
258
  getGeneratedAnswerStatus() {
@@ -397,12 +424,12 @@ export default class QuanticGeneratedAnswer extends LightningElement {
397
424
  }
398
425
 
399
426
  /**
400
- * Sets the the value of the CSS variable "--maxHeight" the value of the _maximumAnswerHeight property.
427
+ * Sets the value of the CSS variable "--maxHeight" to the value of the maxCollapsedHeight property.
401
428
  */
402
429
  updateGeneratedAnswerCSSVariables() {
403
430
  if (this._exceedsMaximumHeight) {
404
431
  const styles = this.generatedAnswerElement?.style;
405
- styles.setProperty('--maxHeight', `${this._maximumAnswerHeight}px`);
432
+ styles?.setProperty('--maxHeight', `${this.maxCollapsedHeight}px`);
406
433
  }
407
434
  }
408
435
 
@@ -48,7 +48,7 @@
48
48
  data-cy="generated-answer__content"
49
49
  class="generated-answer__content slds-var-m-top_medium"
50
50
  >
51
- <div data-cy="generated-answer__answer" class={generatedAnswerClass}>
51
+ <div data-testid="generated-answer__answer" class={generatedAnswerClass}>
52
52
  <c-quantic-generated-answer-content
53
53
  answer-content-format={answerContentFormat}
54
54
  answer={answer}