feat: Add control/output of selected camera via an entity (#1895)
- Closes #1871
This commit is contained in:
@@ -242,6 +242,7 @@ describe('ReolinkCameraManagerEngine', () => {
|
||||
'favorite-events': false,
|
||||
'favorite-recordings': false,
|
||||
clips: true,
|
||||
'remote-control-entity': true,
|
||||
live: true,
|
||||
menu: true,
|
||||
recordings: false,
|
||||
|
||||
@@ -13,7 +13,7 @@ describe('should handle camera_select action', () => {
|
||||
{
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: 'camera_select',
|
||||
camera: 'camera',
|
||||
camera: 'camera.office',
|
||||
},
|
||||
);
|
||||
|
||||
@@ -23,13 +23,36 @@ describe('should handle camera_select action', () => {
|
||||
expect.objectContaining({
|
||||
params: {
|
||||
view: 'live',
|
||||
camera: 'camera',
|
||||
camera: 'camera.office',
|
||||
},
|
||||
failSafe: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should ignore requests to change to the current camera', async () => {
|
||||
const api = createCardAPI();
|
||||
vi.mocked(api.getViewManager().getView).mockReturnValue(
|
||||
createView({
|
||||
camera: 'camera.office',
|
||||
}),
|
||||
);
|
||||
vi.mocked(api.getViewManager().isViewSupportedByCamera).mockReturnValue(true);
|
||||
|
||||
const action = new CameraSelectAction(
|
||||
{},
|
||||
{
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: 'camera_select',
|
||||
camera: 'camera.office',
|
||||
},
|
||||
);
|
||||
|
||||
await action.execute(api);
|
||||
|
||||
expect(api.getViewManager().setViewByParametersWithNewQuery).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('without config', async () => {
|
||||
const api = createCardAPI();
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(null);
|
||||
@@ -45,7 +68,7 @@ describe('should handle camera_select action', () => {
|
||||
{
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: 'camera_select',
|
||||
camera: 'camera',
|
||||
camera: 'camera.office',
|
||||
},
|
||||
);
|
||||
|
||||
@@ -55,7 +78,7 @@ describe('should handle camera_select action', () => {
|
||||
expect.objectContaining({
|
||||
params: {
|
||||
view: 'timeline',
|
||||
camera: 'camera',
|
||||
camera: 'camera.office',
|
||||
},
|
||||
failSafe: true,
|
||||
}),
|
||||
@@ -84,7 +107,7 @@ describe('should handle camera_select action', () => {
|
||||
{
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: 'camera_select',
|
||||
camera: 'camera',
|
||||
camera: 'camera.office',
|
||||
},
|
||||
);
|
||||
|
||||
@@ -94,7 +117,7 @@ describe('should handle camera_select action', () => {
|
||||
expect.objectContaining({
|
||||
params: {
|
||||
view: 'clips',
|
||||
camera: 'camera',
|
||||
camera: 'camera.office',
|
||||
},
|
||||
failSafe: true,
|
||||
}),
|
||||
@@ -106,7 +129,7 @@ describe('should handle camera_select action', () => {
|
||||
vi.mocked(api.getViewManager().getView).mockReturnValue(createView());
|
||||
vi.mocked(api.getViewManager().isViewSupportedByCamera).mockReturnValue(true);
|
||||
vi.mocked(api.getTriggersManager().getMostRecentlyTriggeredCameraID).mockReturnValue(
|
||||
'camera',
|
||||
'camera.office',
|
||||
);
|
||||
|
||||
const action = new CameraSelectAction(
|
||||
@@ -124,7 +147,7 @@ describe('should handle camera_select action', () => {
|
||||
expect.objectContaining({
|
||||
params: {
|
||||
view: 'live',
|
||||
camera: 'camera',
|
||||
camera: 'camera.office',
|
||||
},
|
||||
failSafe: true,
|
||||
}),
|
||||
@@ -136,7 +159,7 @@ describe('should handle camera_select action', () => {
|
||||
vi.mocked(api.getViewManager().getView).mockReturnValue(createView());
|
||||
vi.mocked(api.getViewManager().isViewSupportedByCamera).mockReturnValue(true);
|
||||
vi.mocked(api.getTriggersManager().getMostRecentlyTriggeredCameraID).mockReturnValue(
|
||||
'camera',
|
||||
'camera.office',
|
||||
);
|
||||
|
||||
const action = new CameraSelectAction(
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { expect, it, vi } from 'vitest';
|
||||
import { InternalCallbackAction } from '../../../../src/card-controller/actions/actions/internal-callback';
|
||||
import { INTERNAL_CALLBACK_ACTION } from '../../../../src/config/types';
|
||||
import { createCardAPI } from '../../../test-utils';
|
||||
|
||||
it('should handle internal callback action', async () => {
|
||||
const api = createCardAPI();
|
||||
const callback = vi.fn();
|
||||
const action = new InternalCallbackAction(
|
||||
{},
|
||||
{
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: INTERNAL_CALLBACK_ACTION,
|
||||
callback: callback,
|
||||
},
|
||||
);
|
||||
|
||||
await action.execute(api);
|
||||
|
||||
expect(callback).toBeCalledWith(api);
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { CameraSelectAction } from '../../../src/card-controller/actions/actions/camera-select';
|
||||
import { CameraUIAction } from '../../../src/card-controller/actions/actions/camera-ui';
|
||||
import { DefaultAction } from '../../../src/card-controller/actions/actions/default';
|
||||
@@ -7,6 +7,7 @@ import { DownloadAction } from '../../../src/card-controller/actions/actions/dow
|
||||
import { ExpandAction } from '../../../src/card-controller/actions/actions/expand';
|
||||
import { FullscreenAction } from '../../../src/card-controller/actions/actions/fullscreen';
|
||||
import { GenericAction } from '../../../src/card-controller/actions/actions/generic';
|
||||
import { InternalCallbackAction } from '../../../src/card-controller/actions/actions/internal-callback';
|
||||
import { LogAction } from '../../../src/card-controller/actions/actions/log';
|
||||
import { MediaPlayerAction } from '../../../src/card-controller/actions/actions/media-player';
|
||||
import { MenuToggleAction } from '../../../src/card-controller/actions/actions/menu-toggle';
|
||||
@@ -30,7 +31,10 @@ import { SubstreamSelectAction } from '../../../src/card-controller/actions/acti
|
||||
import { UnmuteAction } from '../../../src/card-controller/actions/actions/unmute';
|
||||
import { ViewAction } from '../../../src/card-controller/actions/actions/view';
|
||||
import { ActionFactory } from '../../../src/card-controller/actions/factory';
|
||||
import { AdvancedCameraCardCustomAction } from '../../../src/config/types';
|
||||
import {
|
||||
AdvancedCameraCardCustomAction,
|
||||
INTERNAL_CALLBACK_ACTION,
|
||||
} from '../../../src/config/types';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('ActionFactory', () => {
|
||||
@@ -165,6 +169,13 @@ describe('ActionFactory', () => {
|
||||
},
|
||||
StatusBarAction,
|
||||
],
|
||||
[
|
||||
{
|
||||
advanced_camera_card_action: INTERNAL_CALLBACK_ACTION,
|
||||
callback: vi.fn(),
|
||||
},
|
||||
InternalCallbackAction,
|
||||
],
|
||||
])(
|
||||
'advanced_camera_card_action: $advanced_camera_card_action',
|
||||
(action: Partial<AdvancedCameraCardCustomAction>, classObject: object) => {
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { setRemoteControlEntityFromConfig } from '../../../src/card-controller/config/load-control-entities';
|
||||
import { createCardAPI, createConfig, createHASS, createStore } from '../../test-utils';
|
||||
import { INTERNAL_CALLBACK_ACTION } from '../../../src/config/types';
|
||||
|
||||
describe('setRemoteControlEntityFromConfig', () => {
|
||||
it('without control entity', () => {
|
||||
const api = createCardAPI();
|
||||
setRemoteControlEntityFromConfig(api);
|
||||
|
||||
expect(api.getAutomationsManager().deleteAutomations).toBeCalled();
|
||||
expect(api.getAutomationsManager().addAutomations).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('with control entity', () => {
|
||||
const api = createCardAPI();
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(
|
||||
createConfig({
|
||||
remote_control: {
|
||||
entities: {
|
||||
camera: 'input_select.camera',
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
setRemoteControlEntityFromConfig(api);
|
||||
|
||||
expect(api.getAutomationsManager().deleteAutomations).toBeCalled();
|
||||
expect(api.getAutomationsManager().addAutomations).toBeCalledWith([
|
||||
{
|
||||
actions: [
|
||||
{
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: '__INTERNAL_CALLBACK_ACTION__',
|
||||
callback: expect.any(Function),
|
||||
},
|
||||
{
|
||||
action: 'perform-action',
|
||||
data: {
|
||||
option: '{{ advanced_camera_card.camera }}',
|
||||
},
|
||||
perform_action: 'input_select.select_option',
|
||||
target: {
|
||||
entity_id: 'input_select.camera',
|
||||
},
|
||||
},
|
||||
],
|
||||
conditions: [
|
||||
{
|
||||
condition: 'config',
|
||||
paths: ['remote_control.entities.camera'],
|
||||
},
|
||||
],
|
||||
tag: setRemoteControlEntityFromConfig,
|
||||
},
|
||||
{
|
||||
actions: [
|
||||
{
|
||||
action: 'perform-action',
|
||||
data: {
|
||||
option: '{{ advanced_camera_card.trigger.camera.to }}',
|
||||
},
|
||||
perform_action: 'input_select.select_option',
|
||||
target: {
|
||||
entity_id: 'input_select.camera',
|
||||
},
|
||||
},
|
||||
],
|
||||
conditions: [
|
||||
{
|
||||
condition: 'camera',
|
||||
},
|
||||
],
|
||||
tag: setRemoteControlEntityFromConfig,
|
||||
},
|
||||
{
|
||||
actions: [
|
||||
{
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: 'camera_select',
|
||||
camera: '{{ advanced_camera_card.trigger.state.to }}',
|
||||
},
|
||||
],
|
||||
conditions: [
|
||||
{
|
||||
condition: 'state',
|
||||
entity: 'input_select.camera',
|
||||
},
|
||||
],
|
||||
tag: setRemoteControlEntityFromConfig,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('internal action should set options', () => {
|
||||
const hass = createHASS();
|
||||
const api = createCardAPI();
|
||||
vi.mocked(api.getHASSManager().getHASS).mockReturnValue(hass);
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(
|
||||
createConfig({
|
||||
remote_control: {
|
||||
entities: {
|
||||
camera: 'input_select.camera',
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
const store = createStore([
|
||||
{
|
||||
cameraID: 'camera.one',
|
||||
},
|
||||
{
|
||||
cameraID: 'camera.two',
|
||||
},
|
||||
]);
|
||||
vi.mocked(api.getCameraManager().getStore).mockReturnValue(store);
|
||||
|
||||
setRemoteControlEntityFromConfig(api);
|
||||
|
||||
const addOptionsAction = vi.mocked(api.getAutomationsManager().addAutomations).mock
|
||||
.calls[0][0][0].actions[0];
|
||||
expect(addOptionsAction.advanced_camera_card_action).toBe(INTERNAL_CALLBACK_ACTION);
|
||||
|
||||
addOptionsAction.callback(api);
|
||||
expect(hass.callService).toBeCalledWith(
|
||||
'input_select',
|
||||
'set_options',
|
||||
{
|
||||
options: ['camera.one', 'camera.two'],
|
||||
},
|
||||
{
|
||||
entity_id: 'input_select.camera',
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -7,9 +7,11 @@ import { PTZAction } from '../../../src/config/ptz';
|
||||
describe('setKeyboardShortcutsFromConfig', () => {
|
||||
it('without shortcuts', () => {
|
||||
const api = createCardAPI();
|
||||
setKeyboardShortcutsFromConfig(api, 'tag');
|
||||
setKeyboardShortcutsFromConfig(api);
|
||||
|
||||
expect(api.getAutomationsManager().deleteAutomations).toBeCalledWith('tag');
|
||||
expect(api.getAutomationsManager().deleteAutomations).toBeCalledWith(
|
||||
setKeyboardShortcutsFromConfig,
|
||||
);
|
||||
expect(api.getAutomationsManager().addAutomations).not.toBeCalled();
|
||||
});
|
||||
|
||||
@@ -24,9 +26,11 @@ describe('setKeyboardShortcutsFromConfig', () => {
|
||||
},
|
||||
}),
|
||||
);
|
||||
setKeyboardShortcutsFromConfig(api, 'tag');
|
||||
setKeyboardShortcutsFromConfig(api);
|
||||
|
||||
expect(api.getAutomationsManager().deleteAutomations).toBeCalledWith('tag');
|
||||
expect(api.getAutomationsManager().deleteAutomations).toBeCalledWith(
|
||||
setKeyboardShortcutsFromConfig,
|
||||
);
|
||||
expect(api.getAutomationsManager().addAutomations).not.toBeCalled();
|
||||
});
|
||||
|
||||
@@ -59,9 +63,11 @@ describe('setKeyboardShortcutsFromConfig', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
setKeyboardShortcutsFromConfig(api, 'tag');
|
||||
setKeyboardShortcutsFromConfig(api);
|
||||
|
||||
expect(api.getAutomationsManager().deleteAutomations).toBeCalledWith('tag');
|
||||
expect(api.getAutomationsManager().deleteAutomations).toBeCalledWith(
|
||||
setKeyboardShortcutsFromConfig,
|
||||
);
|
||||
expect(api.getAutomationsManager().addAutomations).toBeCalledWith([
|
||||
{
|
||||
actions: [
|
||||
@@ -83,7 +89,7 @@ describe('setKeyboardShortcutsFromConfig', () => {
|
||||
state: 'down',
|
||||
},
|
||||
],
|
||||
tag: 'tag',
|
||||
tag: setKeyboardShortcutsFromConfig,
|
||||
},
|
||||
{
|
||||
actions: [
|
||||
@@ -101,7 +107,7 @@ describe('setKeyboardShortcutsFromConfig', () => {
|
||||
state: 'up',
|
||||
},
|
||||
],
|
||||
tag: 'tag',
|
||||
tag: setKeyboardShortcutsFromConfig,
|
||||
},
|
||||
]);
|
||||
});
|
||||
@@ -110,9 +116,11 @@ describe('setKeyboardShortcutsFromConfig', () => {
|
||||
const api = createCardAPI();
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(createConfig());
|
||||
|
||||
setKeyboardShortcutsFromConfig(api, 'tag');
|
||||
setKeyboardShortcutsFromConfig(api);
|
||||
|
||||
expect(api.getAutomationsManager().deleteAutomations).toBeCalledWith('tag');
|
||||
expect(api.getAutomationsManager().deleteAutomations).toBeCalledWith(
|
||||
setKeyboardShortcutsFromConfig,
|
||||
);
|
||||
expect(api.getAutomationsManager().addAutomations).toBeCalledWith(
|
||||
expect.arrayContaining([
|
||||
{
|
||||
@@ -133,7 +141,7 @@ describe('setKeyboardShortcutsFromConfig', () => {
|
||||
state: 'down',
|
||||
},
|
||||
],
|
||||
tag: 'tag',
|
||||
tag: setKeyboardShortcutsFromConfig,
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
ViewDisplayMode,
|
||||
} from '../../src/config/types';
|
||||
import { AdvancedCameraCardMediaPlayer } from '../../src/types';
|
||||
import { createGeneralAction } from '../../src/utils/action';
|
||||
import { createGeneralAction, createViewAction } from '../../src/utils/action';
|
||||
import { ViewMedia } from '../../src/view/media';
|
||||
import { MediaQueriesResults } from '../../src/view/media-queries-results';
|
||||
import { View } from '../../src/view/view';
|
||||
@@ -94,7 +94,7 @@ describe('MenuButtonController', () => {
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: 'Iris / Default View / Unhide menu',
|
||||
tap_action: createGeneralAction('menu_toggle'),
|
||||
hold_action: createGeneralAction('diagnostics'),
|
||||
hold_action: createViewAction('diagnostics'),
|
||||
});
|
||||
});
|
||||
|
||||
@@ -111,7 +111,7 @@ describe('MenuButtonController', () => {
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: 'Iris / Default View / Unhide menu',
|
||||
tap_action: createGeneralAction('default'),
|
||||
hold_action: createGeneralAction('diagnostics'),
|
||||
hold_action: createViewAction('diagnostics'),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
dimensionsConfigSchema,
|
||||
advancedCameraCardConditionSchema,
|
||||
advancedCameraCardCustomActionsBaseSchema,
|
||||
advancedCameraCardCustomActionSchema,
|
||||
internalAdvancedCameraCardCustomActionSchema,
|
||||
} from '../../src/config/types';
|
||||
import { createConfig } from '../test-utils';
|
||||
|
||||
@@ -641,7 +641,7 @@ describe('should lazy evaluate schemas', () => {
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(advancedCameraCardCustomActionSchema.parse(input)).toEqual(input);
|
||||
expect(internalAdvancedCameraCardCustomActionSchema.parse(input)).toEqual(input);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+6
-7
@@ -19,7 +19,6 @@ import { ActionsManager } from '../src/card-controller/actions/actions-manager';
|
||||
import { AutomationsManager } from '../src/card-controller/automations-manager';
|
||||
import { CameraURLManager } from '../src/card-controller/camera-url-manager';
|
||||
import { CardElementManager } from '../src/card-controller/card-element-manager';
|
||||
import { ConditionStateManager } from '../src/conditions/state-manager';
|
||||
import { ConfigManager } from '../src/card-controller/config/config-manager';
|
||||
import { CardController } from '../src/card-controller/controller';
|
||||
import { DefaultManager } from '../src/card-controller/default-manager';
|
||||
@@ -40,18 +39,17 @@ import { StatusBarItemManager } from '../src/card-controller/status-bar-item-man
|
||||
import { StyleManager } from '../src/card-controller/style-manager';
|
||||
import { TriggersManager } from '../src/card-controller/triggers-manager';
|
||||
import { ViewManager } from '../src/card-controller/view/view-manager';
|
||||
import { ConditionStateManager } from '../src/conditions/state-manager';
|
||||
import {
|
||||
ActionsConfig,
|
||||
AdvancedCameraCardCondition,
|
||||
AdvancedCameraCardConfig,
|
||||
AdvancedCameraCardCustomAction,
|
||||
CameraConfig,
|
||||
InternalAdvancedCameraCardCustomAction,
|
||||
PerformanceConfig,
|
||||
RawAdvancedCameraCardConfig,
|
||||
advancedCameraCardConditionSchema,
|
||||
advancedCameraCardConfigSchema,
|
||||
advancedCameraCardCustomActionSchema,
|
||||
cameraConfigSchema,
|
||||
internalAdvancedCameraCardCustomActionSchema,
|
||||
performanceConfigSchema,
|
||||
} from '../src/config/types';
|
||||
import { CapabilitiesRaw, ExtendedHomeAssistant, MediaLoadedInfo } from '../src/types';
|
||||
@@ -65,8 +63,8 @@ import { View, ViewParameters } from '../src/view/view';
|
||||
|
||||
export const createAction = (
|
||||
action: Record<string, unknown>,
|
||||
): AdvancedCameraCardCustomAction | null => {
|
||||
const result = advancedCameraCardCustomActionSchema.safeParse({
|
||||
): InternalAdvancedCameraCardCustomAction | null => {
|
||||
const result = internalAdvancedCameraCardCustomActionSchema.safeParse({
|
||||
action: 'custom:advanced-camera-card-action',
|
||||
...action,
|
||||
});
|
||||
@@ -260,6 +258,7 @@ export const createCapabilities = (capabilities?: CapabilitiesRaw): Capabilities
|
||||
return new Capabilities({
|
||||
'favorite-events': false,
|
||||
'favorite-recordings': false,
|
||||
'remote-control-entity': true,
|
||||
clips: false,
|
||||
live: false,
|
||||
recordings: false,
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import { hasAction as customCardHasAction } from '@dermotduffy/custom-card-helpers';
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
import { mock } from 'vitest-mock-extended';
|
||||
import { actionSchema } from '../../src/config/types';
|
||||
import { actionSchema, INTERNAL_CALLBACK_ACTION } from '../../src/config/types';
|
||||
import {
|
||||
convertActionToCardCustomAction,
|
||||
createCameraAction,
|
||||
createDisplayModeAction,
|
||||
createGeneralAction,
|
||||
createInternalCallbackAction,
|
||||
createLogAction,
|
||||
createMediaPlayerAction,
|
||||
createPTZAction,
|
||||
createPTZControlsAction,
|
||||
createPTZDigitalAction,
|
||||
createPTZMultiAction,
|
||||
createViewAction,
|
||||
getActionConfigGivenAction,
|
||||
hasAction,
|
||||
stopEventFromActivatingCardWideActions,
|
||||
@@ -45,7 +47,21 @@ describe('convertActionToAdvancedCameraCardCustomAction', () => {
|
||||
describe('createGeneralAction', () => {
|
||||
it('should create general action', () => {
|
||||
expect(
|
||||
createGeneralAction('clips', {
|
||||
createGeneralAction('camera_ui', {
|
||||
cardID: 'card_id',
|
||||
}),
|
||||
).toEqual({
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: 'camera_ui',
|
||||
card_id: 'card_id',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('createViewAction', () => {
|
||||
it('should create view action', () => {
|
||||
expect(
|
||||
createViewAction('clips', {
|
||||
cardID: 'card_id',
|
||||
}),
|
||||
).toEqual({
|
||||
@@ -241,6 +257,22 @@ describe('createLogAction', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('createInternalCallbackAction', () => {
|
||||
it('should create internal callback action', () => {
|
||||
const callback = vi.fn();
|
||||
expect(
|
||||
createInternalCallbackAction(callback, {
|
||||
cardID: 'card_id',
|
||||
}),
|
||||
).toEqual({
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: INTERNAL_CALLBACK_ACTION,
|
||||
callback: callback,
|
||||
card_id: 'card_id',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getActionConfigGivenAction', () => {
|
||||
const action = actionSchema.parse({
|
||||
action: 'fire-dom-event',
|
||||
|
||||
Reference in New Issue
Block a user