Skip to content

Commit

Permalink
Add example for Selector UI component (#2724)
Browse files Browse the repository at this point in the history
Add example of `<Selector>` component to Interactive UI Snap example.
Also, add `snaps-jest` tests that cover `<Selector>` component
functionality.

Fixes: #2701

![Screenshot 2024-09-13 at 14 58
26](https://github.com/user-attachments/assets/71576f69-5caa-4d2d-b002-78e764bac13e)
![Screenshot 2024-09-13 at 14 58
42](https://github.com/user-attachments/assets/83623456-8094-473b-9ce3-fa725df868c9)
![Screenshot 2024-09-13 at 14 58
54](https://github.com/user-attachments/assets/047798b9-637a-4e2c-895b-26ca19f4529b)
  • Loading branch information
david0xd authored Sep 16, 2024
1 parent 2ff8932 commit bea39ff
Show file tree
Hide file tree
Showing 9 changed files with 371 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/snaps.git"
},
"source": {
"shasum": "uOuMArCEwmOmCl0Bl1WnRRm+DKcq0Y+O+5n8Z1KBMr8=",
"shasum": "WSCjxt5olWIenXrxEpjc90jeiv5odFCZ1PQ67OwzgBk=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import type { SnapComponent } from '@metamask/snaps-sdk/jsx';
import {
Card,
Selector,
SelectorOption,
Radio,
RadioGroup,
Button,
Expand Down Expand Up @@ -36,6 +39,11 @@ export type InteractiveFormState = {
* The value of the example checkbox.
*/
'example-checkbox': boolean;

/**
* The value of the example Selector.
*/
'example-selector': string;
};

export const InteractiveForm: SnapComponent = () => {
Expand Down Expand Up @@ -63,9 +71,28 @@ export const InteractiveForm: SnapComponent = () => {
<Field label="Example Checkbox">
<Checkbox name="example-checkbox" label="Checkbox" />
</Field>
<Button type="submit" name="submit">
Submit
</Button>
<Field label="Example Selector">
<Selector
name="example-selector"
title="Choose an option"
value="option1"
>
<SelectorOption value="option1">
<Card title="Option 1" value="option1" />
</SelectorOption>
<SelectorOption value="option2">
<Card title="Option 2" value="option2" />
</SelectorOption>
<SelectorOption value="option3">
<Card title="Option 3" value="option3" />
</SelectorOption>
</Selector>
</Field>
<Box center>
<Button type="submit" name="submit">
Submit
</Button>
</Box>
</Form>
</Box>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export const Result: SnapComponent<ResultProps> = ({ values }) => {
<Copyable value={value?.toString() ?? ''} />
))}
</Box>
<Button name="back">Back</Button>
<Box center>
<Button name="back">Back</Button>
</Box>
</Box>
);
};
7 changes: 7 additions & 0 deletions packages/examples/packages/interactive-ui/src/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ describe('onRpcRequest', () => {

await formScreen.selectFromRadioGroup('example-radiogroup', 'option3');

await formScreen.selectFromSelector('example-selector', 'option2');

await formScreen.clickElement('example-checkbox');

await formScreen.clickElement('submit');
Expand All @@ -59,6 +61,7 @@ describe('onRpcRequest', () => {
'example-dropdown': 'option3',
'example-radiogroup': 'option3',
'example-checkbox': true,
'example-selector': 'option2',
}}
/>,
);
Expand Down Expand Up @@ -90,6 +93,7 @@ describe('onRpcRequest', () => {
'example-dropdown': 'option1',
'example-radiogroup': 'option1',
'example-checkbox': false,
'example-selector': 'option1',
}}
/>,
);
Expand All @@ -116,6 +120,8 @@ describe('onHomePage', () => {

await formScreen.selectFromRadioGroup('example-radiogroup', 'option3');

await formScreen.selectFromSelector('example-selector', 'option2');

await formScreen.clickElement('submit');

const resultScreen = response.getInterface();
Expand All @@ -127,6 +133,7 @@ describe('onHomePage', () => {
'example-dropdown': 'option3',
'example-radiogroup': 'option3',
'example-checkbox': false,
'example-selector': 'option2',
}}
/>,
);
Expand Down
3 changes: 3 additions & 0 deletions packages/snaps-jest/src/helpers.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ describe('installSnap', () => {
typeInField: expect.any(Function),
selectInDropdown: expect.any(Function),
selectFromRadioGroup: expect.any(Function),
selectFromSelector: expect.any(Function),
uploadFile: expect.any(Function),
ok: expect.any(Function),
cancel: expect.any(Function),
Expand Down Expand Up @@ -470,6 +471,7 @@ describe('installSnap', () => {
typeInField: expect.any(Function),
selectInDropdown: expect.any(Function),
selectFromRadioGroup: expect.any(Function),
selectFromSelector: expect.any(Function),
uploadFile: expect.any(Function),
ok: expect.any(Function),
cancel: expect.any(Function),
Expand Down Expand Up @@ -531,6 +533,7 @@ describe('installSnap', () => {
typeInField: expect.any(Function),
selectInDropdown: expect.any(Function),
selectFromRadioGroup: expect.any(Function),
selectFromSelector: expect.any(Function),
uploadFile: expect.any(Function),
ok: expect.any(Function),
});
Expand Down
69 changes: 68 additions & 1 deletion packages/snaps-jest/src/internals/request.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { SnapInterfaceController } from '@metamask/snaps-controllers';
import type { SnapId } from '@metamask/snaps-sdk';
import { UserInputEventType, button, input, text } from '@metamask/snaps-sdk';
import { Dropdown, Option, Radio, RadioGroup } from '@metamask/snaps-sdk/jsx';
import {
Card,
Dropdown,
Option,
Radio,
RadioGroup,
Selector,
SelectorOption,
} from '@metamask/snaps-sdk/jsx';
import { getJsxElementFromComponent, HandlerType } from '@metamask/snaps-utils';
import { MOCK_SNAP_ID } from '@metamask/snaps-utils/test-utils';

Expand Down Expand Up @@ -273,6 +281,7 @@ describe('getInterfaceApi', () => {
typeInField: expect.any(Function),
selectInDropdown: expect.any(Function),
selectFromRadioGroup: expect.any(Function),
selectFromSelector: expect.any(Function),
uploadFile: expect.any(Function),
});
});
Expand Down Expand Up @@ -305,6 +314,7 @@ describe('getInterfaceApi', () => {
typeInField: expect.any(Function),
selectInDropdown: expect.any(Function),
selectFromRadioGroup: expect.any(Function),
selectFromSelector: expect.any(Function),
uploadFile: expect.any(Function),
});
});
Expand Down Expand Up @@ -517,4 +527,61 @@ describe('getInterfaceApi', () => {
},
);
});

it('sends the request to the snap when using `selectInSelector`', async () => {
const controllerMessenger = getRootControllerMessenger();

jest.spyOn(controllerMessenger, 'call');

// eslint-disable-next-line no-new
new SnapInterfaceController({
messenger:
getRestrictedSnapInterfaceControllerMessenger(controllerMessenger),
});

const content = (
<Selector name="foo" title="Choose an option" value="option1">
<SelectorOption value="option1">
<Card title="Option 1" value="option1" />
</SelectorOption>
<SelectorOption value="option2">
<Card title="Option 2" value="option2" />
</SelectorOption>
</Selector>
);

const getInterface = await getInterfaceApi(
{ content },
MOCK_SNAP_ID,
controllerMessenger,
);

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const snapInterface = getInterface!();

await snapInterface.selectFromSelector('foo', 'option2');

expect(controllerMessenger.call).toHaveBeenNthCalledWith(
6,
'ExecutionService:handleRpcRequest',
MOCK_SNAP_ID,
{
origin: '',
handler: HandlerType.OnUserInput,
request: {
jsonrpc: '2.0',
method: ' ',
params: {
event: {
type: UserInputEventType.InputChangeEvent,
name: 'foo',
value: 'option2',
},
id: expect.any(String),
context: null,
},
},
},
);
});
});
Loading

0 comments on commit bea39ff

Please sign in to comment.