test: Add tests for config actions, elements and conditions (#1976)

[skip ci]
This commit is contained in:
Dermot Duffy
2025-03-21 20:14:24 -07:00
committed by GitHub
parent 773b486489
commit 92fc8dd844
6 changed files with 737 additions and 30 deletions
+31 -19
View File
@@ -616,36 +616,48 @@ elements:
advanced_camera_card_action: menu_toggle
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-p-circle
title: Microphone connect
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: microphone_connect
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-q-circle
title: Microphone disconnect
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: microphone_disconnect
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-r-circle
title: Microphone mute
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: microphone_mute
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-q-circle
icon: mdi:alpha-s-circle
title: Microphone unmute
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: microphone_unmute
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-r-circle
icon: mdi:alpha-t-circle
title: Mute
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: mute
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-s-circle
icon: mdi:alpha-u-circle
title: Pause
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: pause
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-t-circle
icon: mdi:alpha-v-circle
title: Play
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: play
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-u-circle
icon: mdi:alpha-x-circle
title: Real PTZ Preset
tap_action:
action: custom:advanced-camera-card-action
@@ -653,14 +665,14 @@ elements:
ptz_action: preset
ptz_preset: doorway
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-v-circle
icon: mdi:alpha-y-circle
title: Show PTZ Controls
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: ptz_controls
enabled: true
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-w-circle
icon: mdi:alpha-z-circle
title: Go to precise digital location
tap_action:
action: custom:advanced-camera-card-action
@@ -671,32 +683,32 @@ elements:
x: 58
y: 14
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-x-circle
icon: mdi:alpha-a-circle-outline
title: Smart select between real and digital PTZ
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: ptz_multi
ptz_action: left
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-y-circle
icon: mdi:alpha-b-circle-outline
title: Show most recent recording
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: recording
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-a-circle-outline
icon: mdi:alpha-c-circle-outline
title: Show recordings
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: recordings
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-b-circle-outline
icon: mdi:alpha-d-circle-outline
title: Screenshot
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: screenshot
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-c-circle-outline
icon: mdi:alpha-e-circle-outline
title: Sleep
tap_action:
action: custom:advanced-camera-card-action
@@ -707,31 +719,31 @@ elements:
s: 56
ms: 422
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-d-circle-outline
icon: mdi:alpha-f-circle-outline
title: Show most recent snapshot
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: snapshot
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-e-circle-outline
icon: mdi:alpha-g-circle-outline
title: Show snapshots
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: snapshots
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-f-circle-outline
icon: mdi:alpha-h-circle-outline
title: Show timeline
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: timeline
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-g-circle-outline
icon: mdi:alpha-i-circle-outline
title: Unmute
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: unmute
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-h-circle-outline
icon: mdi:alpha-j-circle-outline
title: Add status bar contents
tap_action:
- action: custom:advanced-camera-card-action
@@ -760,7 +772,7 @@ elements:
priority: 50
sufficient: false
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-i-circle-outline
icon: mdi:alpha-k-circle-outline
title: Remove status bar contents
tap_action:
- action: custom:advanced-camera-card-action
@@ -789,7 +801,7 @@ elements:
priority: 50
sufficient: false
- type: custom:advanced-camera-card-menu-icon
icon: mdi:alpha-i-circle-outline
icon: mdi:alpha-l-circle-outline
title: Reset status bar contents
tap_action:
- action: custom:advanced-camera-card-action
@@ -117,15 +117,4 @@ elements:
tap_action:
action: fire-dom-event
key: value
- type: icon
icon: mdi:numeric-8-box
title: Perform action
style:
left: 200px
top: 400px
tap_action:
action: perform-action
perform_action: homeassistant.toggle
target:
entity_id: light.office_main_lights
```
+17
View File
@@ -45,6 +45,21 @@ conditions:
| `condition` | Must be `config`. |
| `paths` | An optional array of configuration paths (e.g. `menu.style`). If provided condition matches if _ANY_ of the provided configuration paths has changed. |
## `display_mode`
Matches when card display mode changes (e.g. `single` or `grid` mode). See the display settings for [`live`](live.md?id=display) or [`media_viewer`](media-viewer.md?id=display).
```yaml
conditions:
- condition: display_mode
# [...]
```
| Parameter | Description |
| -------------- | --------------------------- |
| `condition` | Must be `display_mode`. |
| `display_mode` | Must be `single` or `grid`. |
## `expand`
Matches based on whether the card is in "expanded" mode.
@@ -291,6 +306,8 @@ conditions:
- condition: config
paths:
- "menu.style"
- condition: display_mode
display_mode: single
- condition: expand
expand: true
- condition: fullscreen
@@ -245,6 +245,7 @@ elements:
- enabled: true
icon: mdi:google
selected: false
state_color: false
style:
color: white
tap_action:
+1
View File
@@ -121,6 +121,7 @@ export class AdvancedCameraCardSubmenuSelectButton extends LitElement {
icon: this.submenuSelect.icon,
entity: entityID,
fallback: 'mdi:format-list-bulleted',
stateColor: this.submenuSelect.state_color,
};
}
+687
View File
@@ -391,6 +391,693 @@ describe('config defaults', () => {
},
});
});
it('should include all stock elements', () => {
const stockElements = [
{
type: 'icon',
icon: 'mdi:dog',
entity: 'camera.office',
},
{
type: 'custom:element',
data: 'foo',
},
{
type: 'image',
entity: 'camera.office',
image: 'image',
camera_image: 'camera_image',
camera_view: 'camera_view',
state_image: {},
filter: 'filter',
state_filter: { on: '/foo' },
aspect_ratio: '16 / 9',
},
{
type: 'custom:advanced-camera-card-menu-icon',
icon: 'mdi:cat',
entity: 'camera.kitchen',
},
{
type: 'custom:advanced-camera-card-menu-state-icon',
entity: 'camera.kitchen',
icon: 'mdi:sheep',
state_color: false,
},
{
type: 'state-badge',
entity: 'sensor.kitchen_dining_multisensor_air_temperature',
style: {
left: '100px',
top: '50px',
},
title: 'Temperature',
},
{
type: 'state-icon',
entity: 'light.office_main_lights',
icon: 'mdi:lamp',
state_color: true,
style: {
left: '100px',
top: '100px',
},
},
{
type: 'state-label',
entity: 'sensor.kitchen_motion_sensor_battery',
attribute: 'battery_voltage',
prefix: 'Volts',
title: 'Battery Voltage',
style: {
left: '100px',
top: '150px',
},
},
{
type: 'state-label',
entity: 'sensor.kitchen_motion_sensor_battery',
attribute: 'battery_voltage',
prefix: 'Volts: ',
title: 'Battery Voltage',
style: {
backgroundColor: 'black',
left: '100px',
top: '200px',
},
},
{
type: 'service-button',
title: 'Light on',
service: 'homeassistant.turn_on',
service_data: {
entity: 'light.office_main_lights',
},
style: {
left: '100px',
top: '250px',
},
},
{
type: 'icon',
icon: 'mdi:cow',
title: 'Moo',
style: {
left: '100px',
top: '300px',
},
},
{
type: 'image',
entity: 'light.office_main_lights',
title: 'Image',
state_image: {
on: 'https://picsum.photos/id/1003/1181/1772',
off: 'https://picsum.photos/id/102/4320/3240',
},
state_filter: {
on: 'brightness(110%) saturate(1.2)',
off: 'brightness(50%) hue-rotate(45deg)',
},
style: {
left: '100px',
top: '350px',
height: '50px',
width: '100px',
},
},
{
type: 'conditional',
conditions: [
{
condition: 'state',
entity: 'light.office_main_lights',
state: 'on',
state_not: 'off',
},
],
elements: [
{
type: 'icon',
icon: 'mdi:dog',
title: 'Woof',
style: {
left: '100px',
top: '400px',
},
},
],
},
];
expect(
createConfig({
elements: stockElements,
}).elements,
).toEqual(stockElements);
});
it('should include all custom elements', () => {
const customElements = [
{
type: 'custom:advanced-camera-card-menu-icon',
alignment: 'matching',
enabled: true,
entity: 'light.office_main_lights',
icon: 'mdi:car',
permanent: false,
priority: 50,
style: {
color: 'white',
},
title: 'Vroom',
},
{
type: 'custom:advanced-camera-card-menu-state-icon',
alignment: 'matching',
enabled: true,
entity: 'light.office_main_lights',
icon: 'mdi:chair-rolling',
permanent: false,
priority: 50,
state_color: true,
style: {
color: 'white',
},
title: 'Office lights',
},
{
type: 'custom:advanced-camera-card-menu-submenu',
alignment: 'matching',
enabled: true,
entity: 'light.office_main_lights',
icon: 'mdi:menu',
items: [
{
enabled: true,
entity: 'light.office_main_lights',
icon: 'mdi:lightbulb',
selected: false,
state_color: true,
style: {
color: 'white',
},
tap_action: {
action: 'toggle',
},
title: 'Lights',
},
{
enabled: true,
icon: 'mdi:google',
selected: false,
state_color: false,
style: {
color: 'white',
},
tap_action: {
action: 'url',
url_path: 'https://www.google.com',
},
title: 'Google',
},
],
permanent: false,
priority: 50,
style: {
color: 'white',
},
title: 'Office lights',
},
{
type: 'custom:advanced-camera-card-menu-submenu-select',
alignment: 'matching',
enabled: true,
entity: 'input_select.kitchen_scene',
icon: 'mdi:lamps',
options: {
'scene.kitchen_cooking_scene': {
enabled: true,
icon: 'mdi:chef-hat',
selected: false,
state_color: true,
style: {
color: 'white',
},
title: 'Cooking time!',
},
'scene.kitchen_tv_scene': {
icon: 'mdi:television',
title: 'TV!',
},
},
permanent: false,
priority: 50,
state_color: true,
style: {
color: 'white',
},
title: 'Kitchen Scene',
},
{
type: 'custom:advanced-camera-card-conditional',
elements: [
{
type: 'icon',
icon: 'mdi:pig',
title: 'Oink',
style: {
left: '300px',
top: '100px',
},
},
],
conditions: [
{
condition: 'view',
views: ['live'],
},
],
},
{
type: 'custom:advanced-camera-card-status-bar-string',
enabled: true,
exclusive: false,
expand: false,
string: 'Intruder alert!',
priority: 50,
sufficient: false,
},
{
type: 'custom:advanced-camera-card-status-bar-icon',
enabled: true,
exclusive: false,
expand: false,
icon: 'mdi:cow',
priority: 50,
sufficient: false,
},
{
type: 'custom:advanced-camera-card-status-bar-image',
enabled: true,
exclusive: false,
expand: false,
image: 'https://my.site.com/status.png',
priority: 50,
sufficient: false,
},
];
expect(
createConfig({
elements: customElements,
}).elements,
).toEqual(customElements);
});
it('should include all conditions', () => {
const conditions = [
{ condition: 'camera', cameras: ['camera.office'] },
{ condition: 'config', paths: ['menu.style'] },
{ condition: 'display_mode', display_mode: 'single' },
{ condition: 'expand', expand: true },
{ condition: 'fullscreen', fullscreen: true },
{ condition: 'initialized' },
{ condition: 'interaction', interaction: true },
{
condition: 'key',
alt: false,
ctrl: false,
key: 'F',
meta: false,
shift: false,
state: 'down',
},
{ condition: 'media_loaded', media_loaded: true },
{ condition: 'microphone', connected: true, muted: true },
{
condition: 'numeric_state',
entity: 'sensor.office_temperature',
above: 10,
below: 20,
},
{ condition: 'screen', media_query: '(orientation: landscape)' },
{
condition: 'state',
entity: 'climate.office',
state: 'heat',
state_not: 'off',
},
{ condition: 'triggered', triggered: ['camera.office'] },
{ condition: 'user', users: ['581fca7fdc014b8b894519cc531f9a04'] },
{
condition: 'user_agent',
user_agent:
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
user_agent_re: 'Chrome/',
companion: true,
},
{ condition: 'view', views: ['live'] },
];
expect(
createConfig({
elements: [
{
type: 'custom:advanced-camera-card-conditional',
elements: [
{
type: 'icon',
icon: 'mdi:pig',
},
],
conditions: conditions,
},
],
}).elements[0].conditions,
).toEqual(conditions);
});
it('should include all stock actions', () => {
const stockActions = [
{
action: 'more-info',
},
{
action: 'toggle',
},
{
action: 'call-service',
service: 'homeassistant.toggle',
data: {
entity_id: 'light.office_main_lights',
},
},
{
action: 'navigate',
navigation_path: '/lovelace/2',
},
{
action: 'url',
url_path: 'https://www.home-assistant.io/',
},
{
action: 'none',
},
{
action: 'fire-dom-event',
key: 'value',
},
{
action: 'perform-action',
perform_action: 'homeassistant.toggle',
target: {
entity_id: 'light.office_main_lights',
},
},
];
expect(
createConfig({
live: {
actions: {
tap_action: stockActions,
},
},
}).live.actions?.tap_action,
).toEqual(stockActions);
});
it('should include all custom actions', () => {
const customActions = [
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'camera_select',
camera: 'camera.front_door',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'camera_ui',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'clip',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'clips',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'default',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'diagnostics',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'display_mode_select',
display_mode: 'grid',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'download',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'expand',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'fullscreen',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'image',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'live',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'live_substream_off',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'live_substream_on',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'live_substream_select',
camera: 'camera.front_door_hd',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'log',
message: 'Hello, world!',
level: 'debug',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'media_player',
media_player: 'media_player.nesthub50be',
media_player_action: 'play',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'media_player',
media_player: 'media_player.nesthub',
media_player_action: 'stop',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'menu_toggle',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'microphone_connect',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'microphone_disconnect',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'microphone_mute',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'microphone_unmute',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'mute',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'pause',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'play',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'ptz',
ptz_action: 'preset',
ptz_preset: 'doorway',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'ptz_controls',
enabled: true,
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'ptz_digital',
absolute: {
zoom: 5,
pan: {
x: 58,
y: 14,
},
},
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'ptz_multi',
ptz_action: 'left',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'recording',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'recordings',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'screenshot',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'sleep',
duration: {
h: 1,
m: 20,
s: 56,
ms: 422,
},
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'snapshot',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'snapshots',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'timeline',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'unmute',
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'status_bar',
status_bar_action: 'add',
items: [
{
type: 'custom:advanced-camera-card-status-bar-string',
enabled: true,
exclusive: false,
expand: false,
string: 'Intruder alert!',
priority: 50,
sufficient: false,
},
{
type: 'custom:advanced-camera-card-status-bar-icon',
enabled: true,
exclusive: false,
expand: false,
icon: 'mdi:cow',
priority: 50,
sufficient: false,
},
{
type: 'custom:advanced-camera-card-status-bar-image',
enabled: true,
exclusive: false,
expand: false,
image: 'https://my.site.com/status.png',
priority: 50,
sufficient: false,
},
],
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'status_bar',
status_bar_action: 'remove',
items: [
{
type: 'custom:advanced-camera-card-status-bar-string',
enabled: true,
exclusive: false,
expand: false,
string: 'Intruder alert!',
priority: 50,
sufficient: false,
},
{
type: 'custom:advanced-camera-card-status-bar-icon',
enabled: true,
exclusive: false,
expand: false,
icon: 'mdi:cow',
priority: 50,
sufficient: false,
},
{
type: 'custom:advanced-camera-card-status-bar-image',
enabled: true,
exclusive: false,
expand: false,
image: 'https://my.site.com/status.png',
priority: 50,
sufficient: false,
},
],
},
{
action: 'custom:advanced-camera-card-action',
advanced_camera_card_action: 'status_bar',
status_bar_action: 'reset',
},
];
expect(
createConfig({
live: {
actions: {
tap_action: customActions,
},
},
}).live.actions?.tap_action,
).toEqual(
// Action type will be transformed to fire-dom-event.
customActions.map((action) => ({ ...action, action: 'fire-dom-event' })),
);
});
});
it('should transform dimensions.aspect_ratio', () => {