@kindly/react-chat 2.39.4 → 2.39.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kindly/react-chat",
3
- "version": "2.39.4",
3
+ "version": "2.39.6",
4
4
  "description": "Kindly Chat react component",
5
5
  "repository": "https://github.com/kindly-ai/kindly-chat/tree/main/packages/react-chat",
6
6
  "main": "dist/index.js",
@@ -126,5 +126,5 @@
126
126
  "silent": true,
127
127
  "webpackConfig": "./webpack.config.js"
128
128
  },
129
- "gitHead": "d7deb45ab7212650f94d159204e63e1d869ec161"
129
+ "gitHead": "904044d23976aa4fe6dd329b97e52929d3811655"
130
130
  }
@@ -1,12 +1,13 @@
1
1
  import { expect } from '@storybook/jest';
2
2
  /* eslint-disable react-hooks/exhaustive-deps */
3
3
  /* eslint-disable react/prop-types */
4
- import { fireEvent, screen, userEvent, waitFor } from '@storybook/testing-library';
4
+ import { fireEvent, screen, userEvent } from '@storybook/testing-library';
5
5
  import React from 'react';
6
6
  import withFetchMock from 'storybook-addon-mock';
7
7
 
8
8
  import { IMAGE_WIDTH } from 'app/constants';
9
9
 
10
+ import { chromaticViewports } from '../../.storybook/preview';
10
11
  import KindlyChatButton from '../../src/features/KindlyChatButton/KindlyChatButton';
11
12
  import settingsJSON from '../assets/settingsJson';
12
13
  import withContainer from '../decorators/withContainer';
@@ -37,8 +38,7 @@ export default {
37
38
  },
38
39
  };
39
40
 
40
- export const Regular = Template.bind({});
41
- Regular.parameters = {
41
+ const defaultParameters = {
42
42
  botSettings: defaultBotSettings,
43
43
  initialStateModifier: {
44
44
  chatbubble: {
@@ -100,12 +100,18 @@ Regular.parameters = {
100
100
  },
101
101
  };
102
102
 
103
+ export const Regular = Template.bind({});
104
+ Regular.parameters = {
105
+ ...defaultParameters,
106
+ chromatic: { viewports: chromaticViewports },
107
+ };
108
+
103
109
  export const Annoucement = Template.bind({});
104
110
  Annoucement.args = {
105
111
  type: 'WARNING',
106
112
  text: 'You seem to be offline, please check your internet connection',
107
113
  initialStateModifierFromArgs: ({ type, text }) => ({
108
- ...Regular.parameters.initialStateModifier,
114
+ ...defaultParameters.initialStateModifier,
109
115
  announcement: {
110
116
  show: true,
111
117
  type,
@@ -218,9 +224,9 @@ const MESSAGES = {
218
224
  };
219
225
  MultilineBotMessage.storyName = 'Multiline Bot & User Messages';
220
226
  MultilineBotMessage.parameters = {
221
- ...Regular.parameters,
227
+ ...defaultParameters,
222
228
  initialStateModifier: {
223
- ...Regular.parameters.initialStateModifier,
229
+ ...defaultParameters.initialStateModifier,
224
230
  messages: {
225
231
  chatMessages: [
226
232
  {
@@ -274,16 +280,19 @@ MultilineBotMessage.play = async () => {
274
280
  await screen.findAllByText('Single-line lonely message');
275
281
  // wait for the auto-scroll to execute
276
282
  await new Promise((resolve) => {
277
- setTimeout(resolve, 10);
283
+ setTimeout(resolve, 50);
278
284
  });
279
285
  fireEvent.scroll(chatBody, { target: { scrollTop: 0 } });
286
+
280
287
  const chatNewMessage = await screen.findByTestId('chat-new-message');
281
- await waitFor(
282
- async () => {
283
- await expect(chatNewMessage).toBeVisible();
284
- },
285
- { timeout: 5000 },
286
- );
288
+
289
+ // TODO: We used to use `waitFor`, but it seems to fail in Chromatic.
290
+ // Wait for the newMessage button to be visible
291
+ await new Promise((resolve) => {
292
+ setTimeout(resolve, 1400);
293
+ });
294
+
295
+ await expect(chatNewMessage).toBeVisible();
287
296
  };
288
297
 
289
298
  export const GroupsOfMessages = Template.bind({});
@@ -378,9 +387,9 @@ HandoverCancelled.play = async () => {
378
387
 
379
388
  export const Checkbox = Template.bind({});
380
389
  Checkbox.parameters = {
381
- ...Regular.parameters,
390
+ ...defaultParameters,
382
391
  initialStateModifier: {
383
- ...Regular.parameters.initialStateModifier,
392
+ ...defaultParameters.initialStateModifier,
384
393
  messages: {
385
394
  chatMessages: [
386
395
  {
@@ -426,9 +435,9 @@ Checkbox.parameters = {
426
435
 
427
436
  export const Fallback = Template.bind({});
428
437
  Fallback.parameters = {
429
- ...Regular.parameters,
438
+ ...defaultParameters,
430
439
  initialStateModifier: {
431
- ...Regular.parameters.initialStateModifier,
440
+ ...defaultParameters.initialStateModifier,
432
441
  messages: {
433
442
  chatMessages: [
434
443
  {
@@ -499,7 +508,7 @@ VideoEmbed.args = {
499
508
  videoSource: videoSources[0][0],
500
509
  videoSourceList: videoSources,
501
510
  initialStateModifierFromArgs: ({ videoSource, videoSourceList }) => ({
502
- ...Regular.parameters.initialStateModifier,
511
+ ...defaultParameters.initialStateModifier,
503
512
  messages: {
504
513
  chatMessages: [
505
514
  {
@@ -554,7 +563,7 @@ ImageGallery.args = {
554
563
  hasLink,
555
564
  newTab,
556
565
  }) => ({
557
- ...Regular.parameters.initialStateModifier,
566
+ ...defaultParameters.initialStateModifier,
558
567
  messages: {
559
568
  chatMessages: [
560
569
  {
@@ -639,9 +648,9 @@ ImageGalleryWithDescription.parameters = ImageGallery.parameters;
639
648
 
640
649
  export const Slider = Template.bind({});
641
650
  Slider.parameters = {
642
- ...Regular.parameters,
651
+ ...defaultParameters,
643
652
  initialStateModifier: {
644
- ...Regular.parameters.initialStateModifier,
653
+ ...defaultParameters.initialStateModifier,
645
654
  messages: {
646
655
  chatMessages: [
647
656
  {
@@ -690,9 +699,9 @@ Slider.parameters = {
690
699
 
691
700
  export const Form = Template.bind({});
692
701
  Form.parameters = {
693
- ...Regular.parameters,
702
+ ...defaultParameters,
694
703
  initialStateModifier: {
695
- ...Regular.parameters.initialStateModifier,
704
+ ...defaultParameters.initialStateModifier,
696
705
  messages: {
697
706
  chatMessages: [
698
707
  {
@@ -704,191 +713,70 @@ Form.parameters = {
704
713
  message_format: 'txt',
705
714
  buttons: [],
706
715
  created: '2022-06-15T19:03:46.186495Z',
707
- title: '',
708
716
  id: '1',
709
717
  form: {
710
- id: 'dddsauhi',
711
- dialogue_id: 'ddda',
712
- slug: 'ddas', // Auto generated by the backend, possibly humanly readable and unique
718
+ submission_id: '1',
719
+ id: '2',
720
+ dialogue_id: '2',
721
+ slug: 'this-is-a-form',
713
722
  submit_dialogue_id: 'c0d685d3-3f11-41b8-9cfd-e35d54df2c95',
714
723
  abandon_dialogue_id: 'b1cde0f3-0715-48eb-8482-a9355fa11ba8',
715
- texts: [
716
- {
717
- id: 'hoho',
718
- languageCode: 'en',
719
- title: 'Form Title',
720
- abandon_dialogue_message: 'Form exited, please ask something else',
721
- unanswered_dialogue_message: 'Form unanswered',
722
- cancel_button_text: 'Cancel',
723
- send_button_text: 'Submit',
724
- },
725
- ],
724
+ languageCode: 'en',
725
+ texts: {
726
+ title: 'This is a form',
727
+ error_text: 'There was an error around here',
728
+ submit_button_text: 'Submit',
729
+ cancel_button_text: 'Exit',
730
+ unanswered_text: 'You failed to answer this form',
731
+ cancel_text: 'You have cancelled/exited this form',
732
+ },
726
733
  fields: [
727
734
  {
728
- type: 'text',
735
+ input_type: 'text',
729
736
  order: 0,
730
- slug: 'gigi', // Auto generated by the backend, possibly humanly readable and unique
731
- texts: [
732
- {
733
- id: 'gfd',
734
- languageCode: 'en',
735
- label: 'Name',
736
- placeholder: 'Your name',
737
- helper_text: 'Please fill in your full name here',
738
- },
739
- ],
737
+ slug: 'first-name-field',
738
+ texts: {
739
+ label: 'First name',
740
+ help_text: 'Please input your name here',
741
+ placeholder_text: 'First name',
742
+ required_text: 'This field is absolutely required',
743
+ },
744
+ required: true,
740
745
  validators: [
741
746
  {
742
- required: true,
743
- texts: [
744
- {
745
- id: 'gruh',
746
- languageCode: 'en',
747
- message: undefined,
748
- },
749
- ],
750
- },
751
- {
752
- maxLength: 30,
753
- texts: [
754
- {
755
- id: 'duh',
756
- languageCode: 'en',
757
- message: 'Maximum number of length is 30',
758
- },
759
- ],
747
+ max_length: 30,
748
+ texts: 'Maximum number of length is 30',
760
749
  },
761
750
  ],
762
751
  },
763
752
  {
764
- type: 'email',
753
+ input_type: 'text',
765
754
  order: 1,
766
- slug: 'bras', // Auto generated by the backend, possibly humanly readable and unique
767
- texts: [
768
- {
769
- id: 'tigg',
770
- languageCode: 'en',
771
- label: 'Email',
772
- placeholder: 'Your email',
773
- helper_text: 'Please fill in your email address here so we can contact you',
774
- },
775
- ],
755
+ slug: 'text-field',
756
+ texts: {
757
+ label: 'Text field',
758
+ placeholder_text: 'Free text',
759
+ required_text: 'This field is required',
760
+ },
761
+ required: true,
776
762
  validators: [
777
763
  {
778
- required: true,
779
- texts: [
780
- {
781
- id: 'gigu',
782
- languageCode: 'en',
783
- message: 'This field is required',
784
- },
785
- ],
764
+ min_length: 5,
765
+ text: 'This field should be at least 5 characters long',
786
766
  },
787
767
  {
788
- pattern: /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/.toString(),
789
- texts: [
790
- {
791
- id: 'dada',
792
- languageCode: 'en',
793
- message: 'Please provide valid email',
794
- },
795
- ],
768
+ max_length: 15,
796
769
  },
797
770
  ],
798
771
  },
799
772
  {
800
- type: 'range',
773
+ input_type: 'email',
801
774
  order: 2,
802
- affix: 'PREFIX',
803
- min: 10,
804
- max: 100,
805
- step: 10,
806
- slug: 'yoyo', // Auto generated by the backend, possibly humanly readable and unique
807
- texts: [
808
- {
809
- id: 'blabla',
810
- languageCode: 'en',
811
- label: 'Please select a value',
812
- helper_text: 'Please fill in your full name here',
813
- affix_value: '$',
814
- },
815
- ],
816
- validators: [],
817
- },
818
- {
819
- type: 'checkbox', // not included in the v1
820
- order: 3,
821
- slug: 'dodo', // Auto generated by the backend, possibly humanly readable and unique
822
- texts: [
823
- {
824
- id: 'gogo',
825
- languageCode: 'en',
826
- label: 'What animals do you like?',
827
- helper_text: '',
828
- },
829
- ],
830
- list: [
831
- {
832
- slug: 'hhh', // Not sure if this needs one
833
- value: 'cows',
834
- order: 0,
835
- texts: [
836
- {
837
- id: 'gras',
838
- languageCode: 'en',
839
- label: 'I like cows',
840
- },
841
- ],
842
- },
843
- {
844
- slug: 'ddsad',
845
- value: 'snakes',
846
- order: 1,
847
- texts: [
848
- {
849
- id: 'grq',
850
- languageCode: 'en',
851
- label: 'I like snakes',
852
- },
853
- ],
854
- },
855
- {
856
- slug: 'abv',
857
- value: 'foxes',
858
- order: 2,
859
- texts: [
860
- {
861
- id: 'abc',
862
- languageCode: 'en',
863
- label: 'I like foxes',
864
- },
865
- ],
866
- },
867
- {
868
- slug: '213',
869
- value: 'owls',
870
- order: 3,
871
- texts: [
872
- {
873
- id: '321',
874
- languageCode: 'en',
875
- label: 'I like owls',
876
- },
877
- ],
878
- },
879
- ],
880
- validators: [
881
- {
882
- required: true,
883
- texts: [
884
- {
885
- id: '432',
886
- languageCode: 'en',
887
- message: 'This field is required',
888
- },
889
- ],
890
- },
891
- ],
775
+ slug: 'email-field',
776
+ texts: {
777
+ label: 'Email',
778
+ placeholder_text: 'Email',
779
+ },
892
780
  },
893
781
  ],
894
782
  },
@@ -897,12 +785,30 @@ Form.parameters = {
897
785
  },
898
786
  },
899
787
  };
788
+ Form.play = async () => {
789
+ await screen.findByText('Please input your name here');
790
+ const textPlaceholderValue = 'Free text';
791
+ const textInput = await screen.findByPlaceholderText(textPlaceholderValue);
792
+ await userEvent.type(textInput, 'This');
793
+ await expect(textInput.value).toBe('This');
794
+ await fireEvent(await screen.getByRole('button', { name: /submit/i }), new MouseEvent('click'));
795
+ await screen.findByText('This field is absolutely required');
796
+ await screen.findByText('This field should be at least 5 characters long');
797
+ const textInputStyle = window.getComputedStyle(textInput);
798
+ expect(textInputStyle.border).not.toContain('#00000000');
799
+ expect(textInputStyle.border).not.toContain('transparent');
800
+ await userEvent.type(textInput, ' is too long');
801
+ await expect(textInput.value).toBe('This is too lon');
802
+ const emailPlaceholderValue = 'Email';
803
+ const emailInput = await screen.findByPlaceholderText(emailPlaceholderValue);
804
+ await userEvent.type(emailInput, 'this@is@not@an@email');
805
+ };
900
806
 
901
807
  export const LeaveContactDetails = Template.bind({});
902
808
  LeaveContactDetails.parameters = {
903
- ...Regular.parameters,
809
+ ...defaultParameters,
904
810
  initialStateModifier: {
905
- ...Regular.parameters.initialStateModifier,
811
+ ...defaultParameters.initialStateModifier,
906
812
  messages: {
907
813
  chatMessages: [
908
814
  {
@@ -2,6 +2,7 @@
2
2
  import React from 'react';
3
3
  import withMock from 'storybook-addon-mock';
4
4
 
5
+ import { chromaticViewports } from '../../.storybook/preview';
5
6
  import KindlyChat from '../../src/KindlyChat';
6
7
  import settings from '../assets/settingsJson';
7
8
 
@@ -39,7 +40,10 @@ export default {
39
40
  };
40
41
 
41
42
  export const Regular = Template.bind({});
42
- Regular.parameters = mockSettings();
43
+ Regular.parameters = {
44
+ ...mockSettings(),
45
+ chromatic: { viewports: chromaticViewports },
46
+ };
43
47
 
44
48
  export const Christmas = Template.bind({});
45
49
  Christmas.parameters = mockSettings({
@@ -5,6 +5,7 @@ import withFetchMock from 'storybook-addon-mock';
5
5
 
6
6
  import { feedbackFormTypes } from 'app/constants';
7
7
 
8
+ import { chromaticViewports } from '../../.storybook/preview';
8
9
  import KindlyChatButton from '../../src/features/KindlyChatButton/KindlyChatButton';
9
10
  import settingsJSON from '../assets/settingsJson';
10
11
  import withContainer from '../decorators/withContainer';
@@ -46,6 +47,7 @@ Emojis.parameters = {
46
47
  feedbackFormOpen: true,
47
48
  },
48
49
  },
50
+ chromatic: { viewports: chromaticViewports },
49
51
  };
50
52
 
51
53
  export const Binary = Template.bind({});
@@ -2,6 +2,7 @@
2
2
  import React from 'react';
3
3
  import withMock from 'storybook-addon-mock';
4
4
 
5
+ import { chromaticViewports } from '../../.storybook/preview';
5
6
  import KindlyChat from '../../src/KindlyChat';
6
7
  import settings from '../assets/settingsJson';
7
8
 
@@ -40,7 +41,7 @@ export default {
40
41
  };
41
42
 
42
43
  export const Product = Template.bind({});
43
- Product.parameters = mockSettings();
44
+ Product.parameters = { ...mockSettings(), chromatic: { viewports: chromaticViewports } };
44
45
  Product.args = {
45
46
  slug: settings.nudges.product_nudges[0].slug,
46
47
  };
@@ -4,6 +4,7 @@ import { screen, userEvent } from '@storybook/testing-library';
4
4
  import React from 'react';
5
5
  import withFetchMock from 'storybook-addon-mock';
6
6
 
7
+ import { chromaticViewports } from '../../.storybook/preview';
7
8
  import KindlyChatButton from '../../src/features/KindlyChatButton/KindlyChatButton';
8
9
  import settingsJSON from '../assets/settingsJson';
9
10
  import withContainer from '../decorators/withContainer';
@@ -27,8 +28,7 @@ export default {
27
28
  decorators: [withFetchMock, withContainer, withMockProvider],
28
29
  };
29
30
 
30
- export const Regular = Template.bind({});
31
- Regular.parameters = {
31
+ const defaultParameters = {
32
32
  botSettings: defaultBotSettings,
33
33
  initialStateModifier: {
34
34
  chatbubble: {
@@ -40,6 +40,12 @@ Regular.parameters = {
40
40
  },
41
41
  };
42
42
 
43
+ export const Regular = Template.bind({});
44
+ Regular.parameters = {
45
+ ...defaultParameters,
46
+ chromatic: { viewports: chromaticViewports },
47
+ };
48
+
43
49
  export const WithLanguageChoice = Template.bind({});
44
50
  WithLanguageChoice.parameters = {
45
51
  botSettings: {
@@ -179,7 +185,7 @@ LanguageChoiceConfirm.play = async () => {
179
185
  };
180
186
 
181
187
  export const DeleteConfirmation = Template.bind({});
182
- DeleteConfirmation.parameters = Regular.parameters;
188
+ DeleteConfirmation.parameters = defaultParameters;
183
189
  DeleteConfirmation.play = async () => {
184
190
  const deleteButton = await screen.findByText(defaultBotSettings.text.delete_button.en);
185
191
  await userEvent.click(deleteButton);
@@ -187,9 +193,9 @@ DeleteConfirmation.play = async () => {
187
193
 
188
194
  export const DeleteSuccess = Template.bind({});
189
195
  DeleteSuccess.parameters = {
190
- ...Regular.parameters,
196
+ ...defaultParameters,
191
197
  initialStateModifier: {
192
- ...Regular.parameters.initialStateModifier,
198
+ ...defaultParameters.initialStateModifier,
193
199
  privacy: {
194
200
  chatDeleted: true,
195
201
  },
@@ -197,7 +203,7 @@ DeleteSuccess.parameters = {
197
203
  };
198
204
 
199
205
  export const DownloadChat = Template.bind({});
200
- DownloadChat.parameters = Regular.parameters;
206
+ DownloadChat.parameters = defaultParameters;
201
207
  DownloadChat.play = async () => {
202
208
  const downloadButton = await screen.findByText(defaultBotSettings.text.download_button.en);
203
209
  await userEvent.click(downloadButton);
@@ -205,7 +211,7 @@ DownloadChat.play = async () => {
205
211
 
206
212
  export const QuitChat = Template.bind({});
207
213
  QuitChat.parameters = {
208
- ...Regular.parameters,
214
+ ...defaultParameters,
209
215
  initialStateModifier: {
210
216
  chatbubble: {
211
217
  active: true,
@@ -3,6 +3,7 @@
3
3
  import React from 'react';
4
4
  import withFetchMock from 'storybook-addon-mock';
5
5
 
6
+ import { chromaticViewports } from '../../.storybook/preview';
6
7
  import KindlyChatButton from '../../src/features/KindlyChatButton/KindlyChatButton';
7
8
  import settingsJSON from '../assets/settingsJson';
8
9
  import withContainer from '../decorators/withContainer';
@@ -39,6 +40,7 @@ Default.parameters = {
39
40
  text: 'This is a push greeting',
40
41
  },
41
42
  },
43
+ chromatic: { viewports: chromaticViewports },
42
44
  };
43
45
 
44
46
  export const NewMessage = Template.bind({});
@@ -2,6 +2,7 @@
2
2
  /* eslint-disable react/prop-types */
3
3
  import React from 'react';
4
4
 
5
+ import { chromaticViewports } from '../../.storybook/preview';
5
6
  import KindlyChatButton from '../../src/features/KindlyChatButton/KindlyChatButton';
6
7
  import settingsJSON from '../assets/settingsJson';
7
8
  import withContainer from '../decorators/withContainer';
@@ -34,6 +35,7 @@ export default {
34
35
  };
35
36
 
36
37
  export const Regular = Template.bind({});
38
+ Regular.parameters = { chromatic: { viewports: chromaticViewports } };
37
39
 
38
40
  export const WithLanguageChoice = Template.bind({});
39
41
  WithLanguageChoice.parameters = {