pebble-web 2.25.1 → 2.25.2-alpha.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.
Files changed (82) hide show
  1. package/dist/components/typings/Button.d.ts +1 -0
  2. package/dist/components/typings/Control.d.ts +1 -0
  3. package/dist/components/typings/DateInput.d.ts +1 -0
  4. package/dist/components/typings/Dropdown.d.ts +1 -0
  5. package/dist/components/typings/Input.d.ts +1 -0
  6. package/dist/components/typings/Loader.d.ts +1 -0
  7. package/dist/components/typings/Message.d.ts +1 -0
  8. package/dist/components/typings/OptionGroup.d.ts +1 -0
  9. package/dist/components/typings/OptionGroupCheckBox.d.ts +1 -0
  10. package/dist/components/typings/OptionGroupRadio.d.ts +1 -0
  11. package/dist/components/typings/PhoneNumberInput.d.ts +1 -0
  12. package/dist/components/typings/RadioGroup.d.ts +1 -0
  13. package/dist/components/typings/Search.d.ts +1 -0
  14. package/dist/components/typings/SecondaryInput.d.ts +1 -0
  15. package/dist/components/typings/Select.d.ts +1 -0
  16. package/dist/components/typings/Text.d.ts +1 -0
  17. package/dist/components/typings/Typeahead.d.ts +1 -0
  18. package/dist/index.d.ts +1 -0
  19. package/dist/pebble-web.dev.js +253 -112
  20. package/dist/pebble-web.dev.js.map +1 -1
  21. package/dist/pebble-web.es.dev.js +179 -58
  22. package/dist/pebble-web.es.dev.js.map +1 -1
  23. package/dist/pebble-web.es.js +174 -53
  24. package/dist/pebble-web.es.js.map +1 -1
  25. package/dist/pebble-web.js +248 -107
  26. package/dist/pebble-web.js.map +1 -1
  27. package/dist/pebble-web.module.dev.js +245 -113
  28. package/dist/pebble-web.module.dev.js.map +1 -1
  29. package/dist/pebble-web.module.js +240 -108
  30. package/dist/pebble-web.module.js.map +1 -1
  31. package/dist/pebble-web.umd.dev.js +253 -112
  32. package/dist/pebble-web.umd.dev.js.map +1 -1
  33. package/dist/pebble-web.umd.js +248 -107
  34. package/dist/pebble-web.umd.js.map +1 -1
  35. package/dist/utils/index.d.ts +1 -0
  36. package/dist/utils/testIds.d.ts +53 -0
  37. package/package.json +1 -1
  38. package/src/components/Button.tsx +3 -1
  39. package/src/components/DateInput.tsx +3 -1
  40. package/src/components/DropDown.tsx +3 -1
  41. package/src/components/Input.tsx +13 -3
  42. package/src/components/Loader.tsx +3 -1
  43. package/src/components/Message.tsx +3 -1
  44. package/src/components/NativeDateInput.tsx +2 -1
  45. package/src/components/OptionGroupCheckBox.tsx +14 -2
  46. package/src/components/PhoneNumberInput.tsx +7 -1
  47. package/src/components/RadioGroup.tsx +20 -3
  48. package/src/components/Search.tsx +3 -1
  49. package/src/components/SecondaryInput.tsx +7 -2
  50. package/src/components/Select.tsx +13 -1
  51. package/src/components/Tabs.tsx +1 -1
  52. package/src/components/Text.tsx +7 -2
  53. package/src/components/TimePicker.tsx +2 -2
  54. package/src/components/Toast.tsx +2 -2
  55. package/src/components/TypeAhead.tsx +14 -3
  56. package/src/components/__tests__/__snapshots__/optionGroup.test.tsx.snap +0 -3
  57. package/src/components/__tests__/__snapshots__/select.test.tsx.snap +3 -0
  58. package/src/components/__tests__/__snapshots__/timepicker.test.tsx.snap +18 -18
  59. package/src/components/__tests__/select.test.tsx +19 -30
  60. package/src/components/__tests__/timepicker.test.tsx +4 -14
  61. package/src/components/shared/Control.tsx +3 -1
  62. package/src/components/shared/OptionGroup.tsx +23 -5
  63. package/src/components/typings/Button.ts +1 -0
  64. package/src/components/typings/Control.ts +1 -0
  65. package/src/components/typings/DateInput.ts +1 -0
  66. package/src/components/typings/Dropdown.ts +1 -0
  67. package/src/components/typings/Input.ts +1 -0
  68. package/src/components/typings/Loader.ts +1 -0
  69. package/src/components/typings/Message.ts +1 -0
  70. package/src/components/typings/OptionGroup.ts +1 -0
  71. package/src/components/typings/OptionGroupCheckBox.ts +1 -0
  72. package/src/components/typings/OptionGroupRadio.ts +1 -0
  73. package/src/components/typings/PhoneNumberInput.ts +1 -0
  74. package/src/components/typings/RadioGroup.ts +1 -0
  75. package/src/components/typings/Search.ts +1 -0
  76. package/src/components/typings/SecondaryInput.ts +1 -0
  77. package/src/components/typings/Select.ts +1 -0
  78. package/src/components/typings/Text.ts +1 -0
  79. package/src/components/typings/Typeahead.ts +1 -0
  80. package/src/index.ts +1 -0
  81. package/src/utils/index.ts +1 -0
  82. package/src/utils/testIds.ts +98 -0
@@ -70,7 +70,7 @@ exports[`TimePicker { selectedHour: 1, selectedMinute: 0 } 1`] = `
70
70
  >
71
71
  <div
72
72
  className="emotion-2"
73
- data-test-id="hour-label"
73
+ data-testid="hour-label"
74
74
  onClick={[Function]}
75
75
  >
76
76
  <span
@@ -109,7 +109,7 @@ exports[`TimePicker { selectedHour: 1, selectedMinute: 0 } 1`] = `
109
109
  >
110
110
  <div
111
111
  className="emotion-2"
112
- data-test-id="minute-label"
112
+ data-testid="minute-label"
113
113
  onClick={[Function]}
114
114
  >
115
115
  <span
@@ -201,7 +201,7 @@ exports[`TimePicker { selectedHour: 1, selectedMinute: 15 } 1`] = `
201
201
  >
202
202
  <div
203
203
  className="emotion-2"
204
- data-test-id="hour-label"
204
+ data-testid="hour-label"
205
205
  onClick={[Function]}
206
206
  >
207
207
  <span
@@ -240,7 +240,7 @@ exports[`TimePicker { selectedHour: 1, selectedMinute: 15 } 1`] = `
240
240
  >
241
241
  <div
242
242
  className="emotion-2"
243
- data-test-id="minute-label"
243
+ data-testid="minute-label"
244
244
  onClick={[Function]}
245
245
  >
246
246
  <span
@@ -332,7 +332,7 @@ exports[`TimePicker { selectedHour: 1, selectedMinute: undefined } 1`] = `
332
332
  >
333
333
  <div
334
334
  className="emotion-2"
335
- data-test-id="hour-label"
335
+ data-testid="hour-label"
336
336
  onClick={[Function]}
337
337
  >
338
338
  <span
@@ -371,7 +371,7 @@ exports[`TimePicker { selectedHour: 1, selectedMinute: undefined } 1`] = `
371
371
  >
372
372
  <div
373
373
  className="emotion-2"
374
- data-test-id="minute-label"
374
+ data-testid="minute-label"
375
375
  onClick={[Function]}
376
376
  >
377
377
  <span
@@ -463,7 +463,7 @@ exports[`TimePicker { selectedHour: 12, selectedMinute: 0 } 1`] = `
463
463
  >
464
464
  <div
465
465
  className="emotion-2"
466
- data-test-id="hour-label"
466
+ data-testid="hour-label"
467
467
  onClick={[Function]}
468
468
  >
469
469
  <span
@@ -502,7 +502,7 @@ exports[`TimePicker { selectedHour: 12, selectedMinute: 0 } 1`] = `
502
502
  >
503
503
  <div
504
504
  className="emotion-2"
505
- data-test-id="minute-label"
505
+ data-testid="minute-label"
506
506
  onClick={[Function]}
507
507
  >
508
508
  <span
@@ -594,7 +594,7 @@ exports[`TimePicker { selectedHour: 12, selectedMinute: 15 } 1`] = `
594
594
  >
595
595
  <div
596
596
  className="emotion-2"
597
- data-test-id="hour-label"
597
+ data-testid="hour-label"
598
598
  onClick={[Function]}
599
599
  >
600
600
  <span
@@ -633,7 +633,7 @@ exports[`TimePicker { selectedHour: 12, selectedMinute: 15 } 1`] = `
633
633
  >
634
634
  <div
635
635
  className="emotion-2"
636
- data-test-id="minute-label"
636
+ data-testid="minute-label"
637
637
  onClick={[Function]}
638
638
  >
639
639
  <span
@@ -725,7 +725,7 @@ exports[`TimePicker { selectedHour: 12, selectedMinute: undefined } 1`] = `
725
725
  >
726
726
  <div
727
727
  className="emotion-2"
728
- data-test-id="hour-label"
728
+ data-testid="hour-label"
729
729
  onClick={[Function]}
730
730
  >
731
731
  <span
@@ -764,7 +764,7 @@ exports[`TimePicker { selectedHour: 12, selectedMinute: undefined } 1`] = `
764
764
  >
765
765
  <div
766
766
  className="emotion-2"
767
- data-test-id="minute-label"
767
+ data-testid="minute-label"
768
768
  onClick={[Function]}
769
769
  >
770
770
  <span
@@ -856,7 +856,7 @@ exports[`TimePicker { selectedHour: undefined, selectedMinute: 0 } 1`] = `
856
856
  >
857
857
  <div
858
858
  className="emotion-2"
859
- data-test-id="hour-label"
859
+ data-testid="hour-label"
860
860
  onClick={[Function]}
861
861
  >
862
862
  <span
@@ -895,7 +895,7 @@ exports[`TimePicker { selectedHour: undefined, selectedMinute: 0 } 1`] = `
895
895
  >
896
896
  <div
897
897
  className="emotion-2"
898
- data-test-id="minute-label"
898
+ data-testid="minute-label"
899
899
  onClick={[Function]}
900
900
  >
901
901
  <span
@@ -987,7 +987,7 @@ exports[`TimePicker { selectedHour: undefined, selectedMinute: 15 } 1`] = `
987
987
  >
988
988
  <div
989
989
  className="emotion-2"
990
- data-test-id="hour-label"
990
+ data-testid="hour-label"
991
991
  onClick={[Function]}
992
992
  >
993
993
  <span
@@ -1026,7 +1026,7 @@ exports[`TimePicker { selectedHour: undefined, selectedMinute: 15 } 1`] = `
1026
1026
  >
1027
1027
  <div
1028
1028
  className="emotion-2"
1029
- data-test-id="minute-label"
1029
+ data-testid="minute-label"
1030
1030
  onClick={[Function]}
1031
1031
  >
1032
1032
  <span
@@ -1117,7 +1117,7 @@ exports[`TimePicker { selectedHour: undefined, selectedMinute: undefined } 1`] =
1117
1117
  >
1118
1118
  <div
1119
1119
  className="emotion-2"
1120
- data-test-id="hour-label"
1120
+ data-testid="hour-label"
1121
1121
  onClick={[Function]}
1122
1122
  >
1123
1123
  <span
@@ -1156,7 +1156,7 @@ exports[`TimePicker { selectedHour: undefined, selectedMinute: undefined } 1`] =
1156
1156
  >
1157
1157
  <div
1158
1158
  className="emotion-2"
1159
- data-test-id="minute-label"
1159
+ data-testid="minute-label"
1160
1160
  onClick={[Function]}
1161
1161
  >
1162
1162
  <span
@@ -9,6 +9,7 @@ import Button from "../Button";
9
9
  import Input from "../Input";
10
10
  import Search from "../Search";
11
11
  import "../../../tests/__setup__/matchers";
12
+ import { getSelectInputTestIds } from "../../utils/testIds";
12
13
 
13
14
  const options = new Array(5)
14
15
  .fill(1)
@@ -18,6 +19,9 @@ const options = new Array(5)
18
19
 
19
20
  const noop = () => {};
20
21
 
22
+ const SINGLE_SELECT_TEST_ID = "test-single-select";
23
+ const MULTI_SELECT_TEST_ID = "test-multi-select";
24
+
21
25
  function getComponent(
22
26
  spy = noop,
23
27
  props: Partial<SingleSelectProps<string>> = {}
@@ -28,6 +32,7 @@ function getComponent(
28
32
  placeholder="Choose Option"
29
33
  selected={"option-2"}
30
34
  {...props}
35
+ testId={SINGLE_SELECT_TEST_ID}
31
36
  >
32
37
  {options}
33
38
  </Select>
@@ -44,6 +49,7 @@ function getMultiSelectComponent<T>(
44
49
  placeholder="Choose Option"
45
50
  multiSelect
46
51
  {...props}
52
+ testId={MULTI_SELECT_TEST_ID}
47
53
  >
48
54
  {options}
49
55
  </Select>
@@ -96,18 +102,17 @@ describe("Component: Select", () => {
96
102
  const spy = sinon.spy();
97
103
  const select = mount(getComponent(spy));
98
104
  select.find(Input).simulate("click");
99
- select
100
- .find(Option)
101
- .at(2)
102
- .simulate("click");
105
+ select.find(Option).at(2).simulate("click");
103
106
 
104
107
  expect(spy.calledWith("option-3")).toBeTruthy();
105
108
 
106
109
  // wait for the dropdown animation to get over.
107
110
  clock.tick(1000);
108
111
 
112
+ const { optionGroupId } = getSelectInputTestIds(SINGLE_SELECT_TEST_ID);
113
+
109
114
  // This means that Option is no more rendered in DOM.
110
- expect(select).toNotBeInDOM("[data-test-id='optiongroup']");
115
+ expect(select).toNotBeInDOM(`[data-testid='${optionGroupId}']`);
111
116
  });
112
117
 
113
118
  test("multi select: should trigger onChange with correct onChange", () => {
@@ -124,10 +129,7 @@ describe("Component: Select", () => {
124
129
  })
125
130
  );
126
131
  select.find(Input).simulate("click");
127
- select
128
- .find(Option)
129
- .at(2)
130
- .simulate("click");
132
+ select.find(Option).at(2).simulate("click");
131
133
 
132
134
  expect(spy.calledWith(["option-3"])).toBeTruthy();
133
135
 
@@ -135,10 +137,7 @@ describe("Component: Select", () => {
135
137
  selected: ["option-3"]
136
138
  });
137
139
 
138
- select
139
- .find(Option)
140
- .at(3)
141
- .simulate("click");
140
+ select.find(Option).at(3).simulate("click");
142
141
 
143
142
  expect(spy.calledWith(["option-3", "option-4"])).toBeTruthy();
144
143
 
@@ -146,20 +145,14 @@ describe("Component: Select", () => {
146
145
  selected: ["option-3", "option-4"]
147
146
  });
148
147
 
149
- select
150
- .find(Option)
151
- .at(2)
152
- .simulate("click");
148
+ select.find(Option).at(2).simulate("click");
153
149
 
154
150
  expect(spy.calledWith(["option-4"])).toBeTruthy();
155
151
 
156
152
  expect(select.find(Button)).toHaveLength(2);
157
153
 
158
154
  // test onClear
159
- select
160
- .find(Button)
161
- .at(0)
162
- .simulate("click");
155
+ select.find(Button).at(0).simulate("click");
163
156
  expect(clearSpy.calledOnce).toBeTruthy();
164
157
 
165
158
  // Reopen dropdown and test onApply
@@ -168,16 +161,15 @@ describe("Component: Select", () => {
168
161
  selected: ["option-3"]
169
162
  });
170
163
 
171
- select
172
- .find(Button)
173
- .at(1)
174
- .simulate("click");
164
+ select.find(Button).at(1).simulate("click");
175
165
  expect(applySpy.calledWith(["option-3"])).toBeTruthy();
176
166
 
177
167
  clock.tick(1000);
178
168
 
169
+ const { optionGroupId } = getSelectInputTestIds(MULTI_SELECT_TEST_ID, true);
170
+
179
171
  // ensure the dropdown is closed
180
- expect(select).toNotBeInDOM("[data-test-id='optiongroup']");
172
+ expect(select).toNotBeInDOM(`[data-testid='${optionGroupId}']`);
181
173
  });
182
174
 
183
175
  test("single select: query change triggers onChange", () => {
@@ -222,10 +214,7 @@ describe("Component: Select", () => {
222
214
  );
223
215
  select.find(Input).simulate("click");
224
216
 
225
- select
226
- .find(Search)
227
- .find(".pi-close")
228
- .simulate("click");
217
+ select.find(Search).find(".pi-close").simulate("click");
229
218
  expect(clearQuerySpy.calledWith("")).toBeTruthy();
230
219
  });
231
220
 
@@ -36,30 +36,20 @@ describe("TimePicker: functionality test", () => {
36
36
  const timePicker = mount(
37
37
  <TimePicker onHourChange={spyHour} onMinuteChange={spyMinute} />
38
38
  );
39
- timePicker.find("[data-test-id='hour-label']").simulate("click");
39
+ timePicker.find("[data-testid='hour-label']").simulate("click");
40
40
 
41
41
  clock.tick(10000);
42
42
 
43
- timePicker
44
- .find(DropDown)
45
- .at(0)
46
- .find(Option)
47
- .at(0)
48
- .simulate("click");
43
+ timePicker.find(DropDown).at(0).find(Option).at(0).simulate("click");
49
44
 
50
45
  expect(spyHour.calledOnce).toBeTruthy();
51
46
  expect(spyHour.calledWith(1)).toBeTruthy();
52
47
 
53
- timePicker.find("[data-test-id='minute-label']").simulate("click");
48
+ timePicker.find("[data-testid='minute-label']").simulate("click");
54
49
 
55
50
  clock.tick(10000);
56
51
 
57
- timePicker
58
- .find(DropDown)
59
- .at(1)
60
- .find(Option)
61
- .at(0)
62
- .simulate("click");
52
+ timePicker.find(DropDown).at(1).find(Option).at(0).simulate("click");
63
53
 
64
54
  expect(spyMinute.calledOnce).toBeTruthy();
65
55
  expect(spyMinute.calledWith(0)).toBeTruthy();
@@ -13,7 +13,8 @@ function Control<OptionType>(props: ControlProps<OptionType>) {
13
13
  children = ControlView,
14
14
  type,
15
15
  className,
16
- indeterminate
16
+ indeterminate,
17
+ testId
17
18
  } = props;
18
19
  return (
19
20
  <div
@@ -30,6 +31,7 @@ function Control<OptionType>(props: ControlProps<OptionType>) {
30
31
  onChange && onChange({ value, checked: !checked }, e)
31
32
  : undefined
32
33
  }
34
+ data-testid={testId}
33
35
  >
34
36
  {children(props)}
35
37
  </div>
@@ -12,6 +12,11 @@ import {
12
12
  searchBoxHeight
13
13
  } from "../styles/OptionGroup.styles";
14
14
  import { rowWrapper, advancedActionsWrapper } from "../styles/Options.styles";
15
+ import {
16
+ getOptionGroupTestIds,
17
+ getOptionTestId,
18
+ getTestIds
19
+ } from "../../utils/testIds";
15
20
 
16
21
  class OptionGroup<OptionType> extends React.PureComponent<
17
22
  OptionGroupProps<OptionType>,
@@ -121,10 +126,13 @@ class OptionGroup<OptionType> extends React.PureComponent<
121
126
  className,
122
127
  isSelected,
123
128
  handleChange,
124
- searchBoxProps
129
+ searchBoxProps,
130
+ testId
125
131
  } = this.props;
126
132
  const { isScrolled, highlighted } = this.state;
127
133
 
134
+ const testIds = getTestIds(testId, getOptionGroupTestIds);
135
+
128
136
  const _children = React.Children.map(children, (_option, i) => {
129
137
  // `_option as React.ReactElement<OptionProps>` is a hack
130
138
  // Because React does not allow us to specify what sort of elements
@@ -142,7 +150,10 @@ class OptionGroup<OptionType> extends React.PureComponent<
142
150
  isSelected: isSelected(option.props.value),
143
151
  multiSelect,
144
152
  // @ts-ignore
145
- ref
153
+ ref,
154
+ testId: testIds.optionId
155
+ ? getOptionTestId(testIds.optionId, i)
156
+ : undefined
146
157
  });
147
158
  });
148
159
 
@@ -168,6 +179,7 @@ class OptionGroup<OptionType> extends React.PureComponent<
168
179
  onKeyDown: this.handleKeyPress,
169
180
  autoFocus: true
170
181
  }}
182
+ testId={testIds.searchBoxId}
171
183
  />
172
184
  </div>
173
185
  )}
@@ -179,15 +191,21 @@ class OptionGroup<OptionType> extends React.PureComponent<
179
191
  }}
180
192
  className={cx(optionsWrapper, className)}
181
193
  role={multiSelect ? "group" : "radiogroup"}
182
- data-test-id="optiongroup"
194
+ data-testid={testId}
183
195
  aria-label={searchBoxProps && searchBoxProps.placeholder}
184
196
  >
185
197
  {advancedOptions && advancedOptionsProps && (
186
198
  <div className={_class}>
187
- <div onClick={advancedOptionsProps.selectVisible}>
199
+ <div
200
+ onClick={advancedOptionsProps.selectVisible}
201
+ data-testid={testIds.selectVisibleId}
202
+ >
188
203
  Select Visible
189
204
  </div>
190
- <div onClick={advancedOptionsProps.clearVisible}>
205
+ <div
206
+ onClick={advancedOptionsProps.clearVisible}
207
+ data-testid={testIds.clearVisibleId}
208
+ >
191
209
  Clear Visible
192
210
  </div>
193
211
  </div>
@@ -16,6 +16,7 @@ export interface ButtonProps {
16
16
  loading?: boolean;
17
17
  outline?: boolean;
18
18
  buttonProps?: React.ButtonHTMLAttributes<HTMLButtonElement>;
19
+ testId?: string;
19
20
  }
20
21
 
21
22
  export interface DropDownButtonProps extends ButtonProps {
@@ -14,4 +14,5 @@ export interface ControlProps<OptionType> {
14
14
  className?: string;
15
15
  iconClassName?: string;
16
16
  indeterminate?: boolean;
17
+ testId?: string;
17
18
  }
@@ -18,6 +18,7 @@ export interface DateInputProps {
18
18
  onOutsideClick?: (isOpen: boolean) => void;
19
19
  controlled?: boolean;
20
20
  isOpen?: boolean;
21
+ testId?: string;
21
22
  }
22
23
 
23
24
  export interface DateInputState {
@@ -25,6 +25,7 @@ export interface DropdownProps {
25
25
  modifiers?: Modifiers;
26
26
  controlled?: boolean;
27
27
  isOpen?: boolean;
28
+ testId?: string;
28
29
  }
29
30
 
30
31
  export interface DropdownState {
@@ -20,6 +20,7 @@ export interface CommonInputProps {
20
20
  successMessage?: string;
21
21
  leftElement?: () => React.ReactNode;
22
22
  rightElement?: () => React.ReactNode;
23
+ testId?: string;
23
24
  }
24
25
 
25
26
  export type InputType =
@@ -2,4 +2,5 @@ export interface LoaderProps {
2
2
  color?: string;
3
3
  className?: string;
4
4
  scale?: number;
5
+ testId?: string;
5
6
  }
@@ -4,4 +4,5 @@ export interface AlertProps {
4
4
  intent: "error" | "success";
5
5
  className?: string;
6
6
  text: React.ReactChild;
7
+ testId?: string;
7
8
  }
@@ -13,6 +13,7 @@ export interface CommonProps {
13
13
  selectVisible?: () => void;
14
14
  clearVisible?: () => void;
15
15
  };
16
+ testId?: string;
16
17
  }
17
18
 
18
19
  export interface OptionGroupProps<OptionType> extends CommonProps {
@@ -13,4 +13,5 @@ export interface OptionGroupCheckBoxProps<OptionType> extends CommonProps {
13
13
  props: OptionGroupCheckBoxProps<OptionType>
14
14
  ) => void;
15
15
  onClear?: () => void;
16
+ testId?: string;
16
17
  }
@@ -7,4 +7,5 @@ export interface OptionGroupRadio<OptionType> extends CommonProps {
7
7
  */
8
8
  selected?: OptionType;
9
9
  isSelected?: (value: OptionType) => boolean;
10
+ testId?: string;
10
11
  }
@@ -19,4 +19,5 @@ export interface PhoneNumberInputProps<OptionType = string> {
19
19
  inputProps?: Omit<SimpleInputProps, "value" | "onChange" | "placeholder">;
20
20
  placeholder?: string;
21
21
  required?: boolean;
22
+ testId?: string;
22
23
  }
@@ -7,4 +7,5 @@ export interface RadioGroupProps<OptionType> {
7
7
  className?: string;
8
8
  name: string;
9
9
  disabled?: boolean;
10
+ testId?: string;
10
11
  }
@@ -10,4 +10,5 @@ export interface SearchProps {
10
10
  clearable?: boolean;
11
11
  inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
12
12
  loading?: boolean;
13
+ testId?: string;
13
14
  }
@@ -14,6 +14,7 @@ export interface SecondaryInputProps {
14
14
  message?: string;
15
15
  inputProps?: React.InputHTMLAttributes<HTMLInputElement> &
16
16
  React.RefAttributes<HTMLInputElement>;
17
+ testId?: string;
17
18
  }
18
19
 
19
20
  export interface SecondaryInputState {
@@ -23,6 +23,7 @@ export interface CommonSelectProps<OptionType> {
23
23
  isSelected?: (value: OptionType) => boolean;
24
24
  placement?: Placement;
25
25
  modifiers?: Modifiers;
26
+ testId?: string;
26
27
  }
27
28
 
28
29
  export interface SingleSelectProps<OptionType>
@@ -4,4 +4,5 @@ export interface TextProps {
4
4
  color?: string;
5
5
  className?: string;
6
6
  typography?: TypographyStyle;
7
+ testId?: string;
7
8
  }
@@ -34,6 +34,7 @@ export interface TypeaheadProps<OptionType> {
34
34
  valueExtractor: (value: OptionType) => string;
35
35
  onClear?: () => void;
36
36
  inputProps?: Omit<SimpleInputProps, "onChange" | "value" | "placeholder">;
37
+ testId?: string;
37
38
  }
38
39
 
39
40
  export interface TypeaheadState {
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from "./theme";
2
2
  export * from "./components";
3
3
  export * from "./utils/useragent";
4
+ export * from "./utils/testIds";
4
5
 
5
6
  import * as utils from "./utils";
6
7
  import { colors } from "pebble-shared";
@@ -2,3 +2,4 @@ export * from "./strings/capitalize";
2
2
  export * from "./numbers/format";
3
3
  export * from "./analytics/ga";
4
4
  export * from "./dimensions";
5
+ export * from "./testIds";
@@ -0,0 +1,98 @@
1
+ type TestIdMap = Record<string, string | object>;
2
+
3
+ type BaseSelectIds = {
4
+ inputId: string;
5
+ optionGroupId: string;
6
+ };
7
+
8
+ type OptionGroupCheckBoxIds = ReturnType<typeof getOptionGroupCheckBoxTestIds>;
9
+
10
+ type OptionGroupRadioIds = ReturnType<typeof getOptionGroupRadioTestIds>;
11
+
12
+ export function getTestIds<T extends TestIdMap>(
13
+ id: string | undefined,
14
+ builder: (_id: string) => Partial<T>
15
+ ): Partial<T> {
16
+ return id ? builder(id) : {};
17
+ }
18
+
19
+ export function getOptionTestId(id: string, index: number) {
20
+ return `${id}-${index}`;
21
+ }
22
+
23
+ export function getRadioGroupTestIds(id: string) {
24
+ return {
25
+ optionId: `${id}-option`
26
+ };
27
+ }
28
+
29
+ export function getOptionGroupTestIds(id: string) {
30
+ return {
31
+ searchBoxId: `${id}-search`,
32
+ optionId: `${id}-option`,
33
+ selectVisibleId: `${id}-select-visible`,
34
+ clearVisibleId: `${id}-clear-visible`
35
+ };
36
+ }
37
+
38
+ export const getOptionGroupRadioTestIds = (id: string) =>
39
+ getOptionGroupTestIds(id);
40
+
41
+ export function getOptionGroupCheckBoxTestIds(id: string) {
42
+ return {
43
+ applyButtonId: `${id}-apply-btn`,
44
+ clearButtonId: `${id}-clear-btn`,
45
+ ...getOptionGroupTestIds(id)
46
+ };
47
+ }
48
+
49
+ export function getPhoneNumberInputTestIds(id: string) {
50
+ return {
51
+ phoneId: `${id}-phone`,
52
+ countryId: `${id}-country`,
53
+ countryInputIds: getSelectInputTestIds(`${id}-country`)
54
+ };
55
+ }
56
+
57
+ export function getSelectInputTestIds(
58
+ id: string,
59
+ multiSelect: true
60
+ ): BaseSelectIds & OptionGroupCheckBoxIds;
61
+
62
+ export function getSelectInputTestIds(
63
+ id: string,
64
+ multiSelect?: false
65
+ ): BaseSelectIds & OptionGroupRadioIds;
66
+
67
+ export function getSelectInputTestIds(
68
+ id: string,
69
+ multiSelect?: boolean
70
+ ):
71
+ | (BaseSelectIds & OptionGroupCheckBoxIds)
72
+ | (BaseSelectIds & OptionGroupRadioIds);
73
+
74
+ export function getSelectInputTestIds(
75
+ id: string,
76
+ multiSelect: boolean = false
77
+ ) {
78
+ const optionGroupId = `${id}-option-group`;
79
+
80
+ const baseIds = {
81
+ inputId: `${id}-input`,
82
+ optionGroupId
83
+ };
84
+ return {
85
+ ...(multiSelect
86
+ ? getOptionGroupCheckBoxTestIds(optionGroupId)
87
+ : getOptionGroupRadioTestIds(optionGroupId)),
88
+ ...baseIds
89
+ };
90
+ }
91
+
92
+ export function getTypeaheadTestIds(id: string) {
93
+ const optionGroupId = `${id}-option-group`;
94
+ return {
95
+ optionGroupId,
96
+ ...getOptionGroupRadioTestIds(optionGroupId)
97
+ };
98
+ }