-
Notifications
You must be signed in to change notification settings - Fork 164
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add analytics metadata to Select component
- Loading branch information
Francesco Longo
committed
Sep 6, 2024
1 parent
78993c6
commit b5d4211
Showing
6 changed files
with
293 additions
and
1 deletion.
There are no files selected for viewing
12 changes: 12 additions & 0 deletions
12
src/internal/components/button-trigger/analytics-metadata/interfaces.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import { LabelIdentifier } from '@cloudscape-design/component-toolkit/internal/analytics-metadata'; | ||
|
||
export interface GeneratedAnalyticsMetadataButtonTriggerExpand { | ||
action: 'expand'; | ||
detail: { | ||
label: LabelIdentifier; | ||
expanded: string; | ||
}; | ||
} |
8 changes: 8 additions & 0 deletions
8
src/internal/components/button-trigger/analytics-metadata/styles.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/* | ||
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
.button-trigger { | ||
/* used in analytics metadata */ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
import React from 'react'; | ||
import { render } from '@testing-library/react'; | ||
|
||
import { | ||
activateAnalyticsMetadata, | ||
GeneratedAnalyticsMetadataFragment, | ||
} from '@cloudscape-design/component-toolkit/internal/analytics-metadata'; | ||
import { getGeneratedAnalyticsMetadata } from '@cloudscape-design/component-toolkit/internal/analytics-metadata/utils'; | ||
|
||
import FormField from '../../../lib/components/form-field'; | ||
import Select, { SelectProps } from '../../../lib/components/select'; | ||
import InternalSelect from '../../../lib/components/select/internal'; | ||
import createWrapper from '../../../lib/components/test-utils/dom'; | ||
import { validateComponentNameAndLabels } from '../../internal/__tests__/analytics-metadata-test-utils'; | ||
|
||
import buttonTriggerLabels from '../../../lib/components/internal/components/button-trigger/analytics-metadata/styles.css.js'; | ||
import optionLabels from '../../../lib/components/internal/components/option/analytics-metadata/styles.css.js'; | ||
import selectableItemsLabels from '../../../lib/components/internal/components/selectable-item/analytics-metadata/styles.css.js'; | ||
|
||
const labels = { ...selectableItemsLabels, ...optionLabels, ...buttonTriggerLabels }; | ||
|
||
function renderSelect(props: Partial<SelectProps>) { | ||
const renderResult = render( | ||
<Select options={options} selectedOption={null} ariaLabel="select with metadata" onChange={() => {}} {...props} /> | ||
); | ||
return createWrapper(renderResult.container).findSelect()!; | ||
} | ||
|
||
const getMetadataContexts = (label = 'select with metadata', disabled?: boolean) => { | ||
const metadata: GeneratedAnalyticsMetadataFragment = { | ||
contexts: [ | ||
{ | ||
type: 'component', | ||
detail: { | ||
name: 'awsui.Select', | ||
label, | ||
properties: { | ||
disabled: disabled ? 'true' : 'false', | ||
}, | ||
}, | ||
}, | ||
], | ||
}; | ||
return metadata; | ||
}; | ||
|
||
const options: SelectProps['options'] = [ | ||
{ value: 'value1' }, | ||
{ value: 'value2', label: 'label2' }, | ||
{ value: 'value4', label: 'label4', disabled: true }, | ||
]; | ||
const optionsWithGroups: SelectProps['options'] = [ | ||
{ | ||
label: 'group1', | ||
options: [{ value: 'value1', label: 'label1' }, { value: 'value1repeated' }], | ||
}, | ||
{ | ||
label: 'group2', | ||
disabled: true, | ||
options: [{ value: 'value2', label: 'label2' }], | ||
}, | ||
{ | ||
label: 'group3', | ||
options: [{ value: 'value3', label: 'label3' }], | ||
}, | ||
{ | ||
label: 'group4', | ||
options: [ | ||
{ value: 'value4', label: 'label4', disabled: true }, | ||
{ value: 'value5', label: 'label5', disabled: true }, | ||
], | ||
}, | ||
{ | ||
label: 'group5', | ||
options: [ | ||
{ value: 'value6', label: 'label6' }, | ||
{ value: 'value7', label: 'label7' }, | ||
], | ||
}, | ||
]; | ||
|
||
beforeAll(() => { | ||
activateAnalyticsMetadata(true); | ||
}); | ||
describe('Select renders correct analytics metadata', () => { | ||
test('on the trigger button', () => { | ||
const wrapper = renderSelect({}); | ||
let trigger = wrapper.findTrigger()!.getElement(); | ||
validateComponentNameAndLabels(trigger, labels); | ||
expect(getGeneratedAnalyticsMetadata(trigger)).toEqual({ | ||
action: 'expand', | ||
detail: { | ||
label: 'select with metadata', | ||
expanded: 'true', | ||
}, | ||
...getMetadataContexts(), | ||
}); | ||
|
||
wrapper.openDropdown(); | ||
trigger = wrapper.findTrigger()!.getElement(); | ||
validateComponentNameAndLabels(trigger, labels); | ||
expect(getGeneratedAnalyticsMetadata(trigger)).toEqual({ | ||
action: 'expand', | ||
detail: { | ||
label: 'select with metadata', | ||
expanded: 'false', | ||
}, | ||
...getMetadataContexts(), | ||
}); | ||
}); | ||
test('when disabled', () => { | ||
const wrapper = renderSelect({ disabled: true }); | ||
expect(getGeneratedAnalyticsMetadata(wrapper.findTrigger()!.getElement())).toEqual({ | ||
...getMetadataContexts(undefined, true), | ||
}); | ||
}); | ||
|
||
test('with simple items', () => { | ||
const wrapper = renderSelect({}); | ||
wrapper.openDropdown(); | ||
|
||
const simpleEnabledItemWithoutLabel = wrapper.findDropdown().findOptionByValue('value1')!.getElement(); | ||
validateComponentNameAndLabels(simpleEnabledItemWithoutLabel, labels); | ||
expect(getGeneratedAnalyticsMetadata(simpleEnabledItemWithoutLabel)).toEqual({ | ||
action: 'select', | ||
detail: { | ||
label: 'value1', | ||
position: '1', | ||
value: 'value1', | ||
}, | ||
...getMetadataContexts(), | ||
}); | ||
|
||
const simpleEnabledItemWithLabel = wrapper.findDropdown().findOptionByValue('value2')!.getElement(); | ||
validateComponentNameAndLabels(simpleEnabledItemWithLabel, labels); | ||
expect(getGeneratedAnalyticsMetadata(simpleEnabledItemWithLabel)).toEqual({ | ||
action: 'select', | ||
detail: { | ||
label: 'label2', | ||
position: '2', | ||
value: 'value2', | ||
}, | ||
...getMetadataContexts(), | ||
}); | ||
|
||
const disabledItem = wrapper.findDropdown().findOptionByValue('value4')!.getElement(); | ||
validateComponentNameAndLabels(disabledItem, labels); | ||
expect(getGeneratedAnalyticsMetadata(disabledItem)).toEqual({ | ||
...getMetadataContexts(), | ||
}); | ||
}); | ||
test.each([false, true])('with groups and expandToViewport=%s', expandToViewport => { | ||
const wrapper = renderSelect({ options: optionsWithGroups, expandToViewport }); | ||
wrapper.openDropdown(); | ||
|
||
const enabledItemWithoutLabel = wrapper | ||
.findDropdown({ expandToViewport }) | ||
.findOptionByValue('value1repeated')! | ||
.getElement(); | ||
validateComponentNameAndLabels(enabledItemWithoutLabel, labels); | ||
expect(getGeneratedAnalyticsMetadata(enabledItemWithoutLabel)).toEqual({ | ||
action: 'select', | ||
detail: { | ||
label: 'value1repeated', | ||
position: '1,2', | ||
value: 'value1repeated', | ||
groupLabel: 'group1', | ||
}, | ||
...getMetadataContexts(), | ||
}); | ||
|
||
const enabledItemWithLabel = wrapper.findDropdown({ expandToViewport }).findOptionByValue('value3')!.getElement(); | ||
validateComponentNameAndLabels(enabledItemWithLabel, labels); | ||
expect(getGeneratedAnalyticsMetadata(enabledItemWithLabel)).toEqual({ | ||
action: 'select', | ||
detail: { | ||
label: 'label3', | ||
position: '3,1', | ||
value: 'value3', | ||
groupLabel: 'group3', | ||
}, | ||
...getMetadataContexts(), | ||
}); | ||
|
||
const inDisabledGroup = wrapper.findDropdown({ expandToViewport }).findOptionByValue('value2')!.getElement(); | ||
validateComponentNameAndLabels(inDisabledGroup, labels); | ||
expect(getGeneratedAnalyticsMetadata(inDisabledGroup)).toEqual({ | ||
...getMetadataContexts(), | ||
}); | ||
|
||
const disabledItem = wrapper.findDropdown({ expandToViewport }).findOptionByValue('value4')!.getElement(); | ||
validateComponentNameAndLabels(disabledItem, labels); | ||
expect(getGeneratedAnalyticsMetadata(disabledItem)).toEqual({ | ||
...getMetadataContexts(), | ||
}); | ||
}); | ||
test('within a formfield', () => { | ||
const renderResult = render( | ||
<FormField label="formfield label"> | ||
<Select options={options} selectedOption={null} onChange={() => {}} /> | ||
</FormField> | ||
); | ||
const element = createWrapper(renderResult.container).findSelect()!.getElement(); | ||
expect(getGeneratedAnalyticsMetadata(element)).toEqual({ | ||
contexts: [ | ||
...getMetadataContexts('formfield label').contexts!, | ||
{ | ||
type: 'component', | ||
detail: { | ||
name: 'awsui.FormField', | ||
label: 'formfield label', | ||
}, | ||
}, | ||
], | ||
}); | ||
}); | ||
}); | ||
|
||
test('Internal Select does not render "component" metadata', () => { | ||
const renderResult = render( | ||
<InternalSelect options={options} selectedOption={null} ariaLabel="select with metadatada" onChange={() => {}} /> | ||
); | ||
const wrapper = createWrapper(renderResult.container).findSelect()!; | ||
expect(getGeneratedAnalyticsMetadata(wrapper.findTrigger()!.getElement()).contexts).toBeUndefined(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import { GeneratedAnalyticsMetadataButtonTriggerExpand } from '../../internal/components/button-trigger/analytics-metadata/interfaces'; | ||
import { GeneratedAnalyticsMetadataSelectableItemSelect } from '../../internal/components/selectable-item/analytics-metadata/interfaces'; | ||
|
||
export type GeneratedAnalyticsMetadataSelectSelect = GeneratedAnalyticsMetadataSelectableItemSelect; | ||
|
||
export type GeneratedAnalyticsMetadataSelectExpand = GeneratedAnalyticsMetadataButtonTriggerExpand; | ||
|
||
export interface GeneratedAnalyticsMetadataSelectComponent { | ||
name: 'awsui.Select'; | ||
label: string; | ||
properties: { | ||
disabled: string; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters