Agent skill

Implement Widget Tests

by cryptomilk in cryptomilk/hass-eink-dashboard

Write TDD tests for a widget type: structural tests (borders, dividers), alignment tests (icon centering), and scaling tests (proportional sizing).

Apache-2.0Auto-check passedTesting & QA

Install Implement Widget Tests

skills CLI
$ npx skills add cryptomilk/hass-eink-dashboard --skill implement-widget-tests -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install cryptomilk/hass-eink-dashboard implement-widget-tests --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/cryptomilk/hass-eink-dashboard.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/implement-widget-tests .claude/skills/implement-widget-tests && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
implement-widget-tests
GitHub stars
116
Token cost
~4.2k tokens
SKILL.md length
1,157 words
Files
1
Skills in repo
3
Repo updated
First seen
Licence
Apache-2.0

At a glance

Write TDD tests for a widget type: structural tests (borders, dividers), alignment tests (icon centering), and scaling tests (proportional sizing).

  • Works in 6 steps: Structural tests — verify visual… → Alignment tests — verify layout… → Scaling tests — verify proportional sizing → …
  • Tasks that involve Test-driven development
  • SKILL.md covers Before you start, Existing test classes, Current test helper signatures and Current WidgetMetrics sizing…, plus 13 more sections
  • Calls uv

What it does

Implement Widget Tests is an agent skill from cryptomilk/hass-eink-dashboard. Write TDD tests for a widget type: structural tests (borders, dividers), alignment tests (icon centering), and scaling tests (proportional sizing). Uses test helpers from tests/helpers.py.

Its SKILL.md is about 4.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Testing & QA, covering Test-driven development. It works with Home Assistant. The repository describes itself as: This is beta quality, should be mostly stable. The licence is Apache-2.0.

When your agent uses it

  • Tasks that involve Test-driven development

Example prompts

  • “/implement-widget-tests”

Requirements

  • Python 3
  • Pre-approved tools (allowed-tools): Read, Edit, Write, Bash(uv *)

Workflow steps

6 steps, taken from the step headings in SKILL.md.

  1. Structural tests — verify visual elements exist
  2. Alignment tests — verify layout relationships
  3. Scaling tests — verify proportional sizing
  4. Data tests — verify state handling
  5. Locale formatting test — numeric-state widgets only
  6. Auto-sizing tests — row-based widgets only

What it can do on your machine

Read from SKILL.md and the folder at commit 6142841. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Read
    • Edit
    • Write
    • Bash(uv *)

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • uv

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use uv, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Implement Widget Tests loads about 4.2k tokens when it runs. Until then it costs about 53 tokens; SKILL.md has 1,157 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~53
When it runs · the whole SKILL.md, loaded when a task matches
~4.2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from cryptomilk/hass-eink-dashboard at commit 6142841, republished under its Apache-2.0 licence (© cryptomilk). 1,157 words, ~4,167 tokens.

Download SKILL.mdSave it as .claude/skills/implement-widget-tests/SKILL.md (or your agent's skills folder).
name
implement-widget-tests
description
Write TDD tests for a widget type: structural tests (borders, dividers), alignment tests (icon centering), and scaling tests (proportional sizing). Uses test helpers from tests/helpers.py.
allowed-tools
Read, Edit, Write, Bash(uv *)
when_to_use
When writing tests for a new widget type. Always run BEFORE implementing the renderer (TDD red phase).
argument-hint
[widget-type]
arguments
widget-type

Write Widget Tests: $widget-type

Write comprehensive tests for the $widget-type widget. This is the TDD red phase — tests must FAIL until the SVG renderer is implemented.

Before you start

  1. Read the task description / spec doc for the new widget.
  2. Read tests/helpers.py for available test helpers.
  3. Read existing per-widget test files in tests/test_render_*.py for patterns. The SEPARATOR tests (TestRenderSeparator) in tests/test_render_separator.py are the reference for structural/pixel assertions. The weather tests (TestRenderWeather) in tests/test_render_weather.py show the _DEFAULTS + _config() pattern.
  4. Read custom_components/eink_dashboard/templates/_macros.svg.j2 for macro signatures (card_container, card_row, chip) so you know the card container insets to use in pixel region calculations.
  5. Read const.py for COLOR_BLACK=0, COLOR_WHITE=255, COLOR_GRAY=120, PADDING=24.

Existing test classes

!grep -rn "^class Test" tests/test_render_*.py

Current test helper signatures

!grep -n "^def " tests/helpers.py

Current WidgetMetrics sizing ratios

Call _compute_metrics(row_h) in tests to derive expected pixel regions from the same ratios the renderer uses — no hardcoded magic numbers.

!grep -n "def _compute_metrics" -A 12 custom_components/eink_dashboard/render.py

SVG macro signatures (from _macros.svg.j2)

!grep -n "macro card_container\|macro card_row\|macro chip" custom_components/eink_dashboard/templates/_macros.svg.j2

Icon resolver (in render.py)

!grep -n "def _device_class_icon" -A 5 custom_components/eink_dashboard/render.py

SVG renderer registry

!grep -n "_SVG_RENDERERS" -A 12 custom_components/eink_dashboard/svg_render.py

Imports

python
import re

from custom_components.eink_dashboard.const import (
    COLOR_BLACK, COLOR_GRAY, PADDING, DEFAULT_CARD_STYLE,
    DEFAULT_ROW_H,
)
from custom_components.eink_dashboard.render import (
    WidgetMetrics, _compute_metrics, DEFAULT_METRICS,
    _device_class_icon, render_dashboard,
)
from custom_components.eink_dashboard.svg_render import (
    render_widget_svg,
)
from custom_components.eink_dashboard.widgets._helpers import (
    _card_insets, _metrics_context, _auto_row_height,
)
from tests.helpers import (
    assert_all_white, assert_card_border, assert_has_dark_pixels,
    assert_has_gray_pixels,
    assert_scales_proportionally, assert_vertically_centered,
    content_bbox, make_config, pixel, render_to_image,
)

Test structure

Create a test class TestRender{WidgetName} (PascalCase) in a dedicated file tests/test_render_{widget_type}.py. When redesigning an existing widget, replace the old test class in its existing file.

1. Structural tests — verify visual elements exist
  • Card border/container: dark pixels along edges for card_style="border", gray pixels on left edge for card_style="left_bar", all white for "none"

  • Default == none: rendering without card_style must be byte-identical to card_style="none". Add this test for every card-style widget:

    python
    def test_card_style_none_is_default(self) -> None:
        # Omitting card_style must produce the same output as "none".
        base = {"type": "$widget-type", "x": 0, "y": 0, "w": 400,
                "h": 56, "entities": ["sensor.temperature"]}
        with_none = render_dashboard(
            [{**base, "card_style": "none"}], self._config()
        )
        without = render_dashboard([base], self._config())
        assert with_none == without
  • Row dividers: light-gray pixels at row boundaries (between entries) on 16-level displays; the divider color is COLOR_LIGHT_GRAY=180, so pass explicit bounds to the helper: assert_has_gray_pixels(img, ..., low=COLOR_LIGHT_GRAY - 20, high=COLOR_LIGHT_GRAY + 20). On 2-level displays both gray values dither identically, so the 2-level test path is unchanged.

  • Chip shape: rounded corners (corner pixels white, nearby edge pixels dark)

  • Icon circle: dark/gray pixels in the icon area

Use assert_card_border(img, w, h, m) for the four-edge border check (default bottom_margin=1 accommodates PIL stroke rounding). Use assert_has_dark_pixels(), assert_all_white(), assert_has_gray_pixels() for everything else.

2. Alignment tests — verify layout relationships
  • Icon ↔ text vertical centering: icon center Y matches text center Y
  • Right-aligned values: value text near the right edge of the widget

Use assert_vertically_centered(img, icon_region, text_region, tolerance=2.0). Each region is (x1, y1, x2, y2) absolute coordinates.

3. Scaling tests — verify proportional sizing
  • Render at h=56 and h=112, compare content_bbox heights via assert_scales_proportionally(..., expected_ratio=2.0, tolerance=0.25).
4. Data tests — verify state handling
  • Missing entity: widget doesn't crash; missing state is skipped silently
  • Missing attributes: handles absent device_class, friendly_name
  • Edge cases: empty entity list, single entity
5. Locale formatting test — numeric-state widgets only

If the widget displays numeric entity states (via _fmt()), add a test to the existing TestLocaleFormattingInWidgets class in tests/test_render_cross_widget.py. Do NOT create a separate class.

python
def test_{widget_type}_decimal_comma(self) -> None:
    # {WidgetName} secondary text must use comma decimal for
    # German locale.
    widget = {
        "type": "$widget-type",
        "entity": "sensor.humidity",
    }
    config = self._config(
        states={
            "sensor.humidity": {
                "state": "8.41",
                "attributes": {"unit_of_measurement": "g/m³"},
            }
        },
        number_format="decimal_comma",
        language="de",
    )
    svg = render_widget_svg(widget, config)
    assert "8,41" in svg
    assert "8.41" not in svg

Widgets that display only non-numeric states (on/off, binary sensors, labels) do not need this test.

7. Auto-sizing tests — row-based widgets only

For row-based widgets (height derived from content rows), verify the auto-sizing fallback. Use render_widget_svg directly — a full-canvas PNG from render_dashboard cannot reveal the widget's own height attribute.

  • No h, one row: SVG height == DEFAULT_ROW_H
  • No h, N rows: SVG height == N * DEFAULT_ROW_H
  • Explicit h preserved: widget with explicit h produces that exact height regardless of row count
python
def test_{widget}_auto_height_single_row(self) -> None:
    # Without explicit h, one row produces height DEFAULT_ROW_H.
    w = {
        "type": "$widget-type",
        "x": 0, "y": 0, "w": 400,
        "entities": ["sensor.temperature"],
    }
    svg = render_widget_svg(w, self._config())
    m = re.search(r'height="(\d+)"', svg)
    assert m is not None
    assert int(m.group(1)) == DEFAULT_ROW_H

def test_{widget}_explicit_h_preserved(self) -> None:
    # An explicit h overrides auto-sizing.
    w = {
        "type": "$widget-type",
        "x": 0, "y": 0, "w": 400, "h": 200,
        "entities": ["sensor.temperature"],
    }
    svg = render_widget_svg(w, self._config())
    m = re.search(r'height="(\d+)"', svg)
    assert m is not None
    assert int(m.group(1)) == 200

Mock state setup

Define mock states at module level (not pytest fixtures — conftest.py only has HA stubs). Include device_class in attributes (required for icon resolution in redesigned widgets). For binary sensors, define separate entries for on and off states to test state-dependent icon resolution:

python
MOCK_{WIDGET}_STATES = {
    "sensor.temperature": {
        "state": "22.5",
        "attributes": {
            "friendly_name": "Living Room",
            "device_class": "temperature",
            "unit_of_measurement": "°C",
        },
    },
    "binary_sensor.front_door": {
        "state": "off",
        "attributes": {
            "friendly_name": "Front Door",
            "device_class": "door",
        },
    },
}

Lesson from completed cycles: The old MOCK_SENSOR_STATES lacked device_class, which caused icon resolution to fall back to letter labels. Always include device_class in mock attributes.

Widget config shape (redesigned widgets)

Redesigned widgets use w and h instead of font_size. The w parameter defines the card/chip boundary width, and h defines the total widget height. All internal dimensions derive from h.

python
# Card-style widget (tile, waste_schedule, person, alarm)
# "h" is optional: omit it for auto-sizing (height =
# num_rows * DEFAULT_ROW_H).  Include it to test explicit override.
widget = {
    "type": "$widget-type",
    "x": PADDING, "y": 0, "w": 350, "h": 112,
    "entities": ["sensor.temperature", "sensor.humidity"],
    "card_style": "border",  # or "left_bar" or "none"
}

# Chip-style widget (lock)
widget = {
    "type": "$widget-type",
    "x": PADDING, "y": 0, "w": 350, "h": 28,
    "entities": ["binary_sensor.front_door"],
}

Do NOT use font_size in redesigned widget configs. The TEXT widget is the only widget that keeps font_size.

Test class pattern

python
class TestRender{WidgetName}:
    # Verify rendering of $widget-type widgets.
    _DEFAULTS: dict[str, object] = {
        "width": 400,
        "height": 300,
        "states": MOCK_{WIDGET}_STATES,
    }

    def _config(self, **overrides: object) -> dict[str, object]:
        return make_config(self._DEFAULTS, **overrides)

    def test_{widget}_draws_content(self) -> None:
        # Verify that content is rendered in the expected region.
        widgets = [{
            "type": "$widget-type",
            "x": PADDING, "y": 0, "w": 350, "h": 56,
            "entities": ["sensor.temperature"],
        }]
        img = render_to_image(widgets, self._config())
        assert_has_dark_pixels(img, PADDING, 0, 350, 56)

    def test_{widget}_empty_entities_white(self) -> None:
        # Empty entity list produces blank output.
        widgets = [{
            "type": "$widget-type",
            "x": PADDING, "y": 0, "w": 350, "h": 56,
            "entities": [],
        }]
        img = render_to_image(widgets, self._config())
        assert_all_white(img, PADDING, 0, 350, 56)

    def test_{widget}_icon_centered_with_text(self) -> None:
        # Verify icon circle is vertically centered with text block.
        m = _compute_metrics(56)
        widgets = [{
            "type": "$widget-type",
            "x": 0, "y": 0, "w": 400, "h": 56,
            "entities": ["sensor.temperature"],
        }]
        img = render_to_image(widgets, self._config())
        assert_vertically_centered(
            img,
            icon_region=(m.padding, 0, m.padding + m.icon_dia, 56),
            text_region=(
                m.padding + m.icon_dia + m.inner_gap, 0, 380, 56
            ),
        )

Computing expected pixel regions

Derive regions from _compute_metrics(row_h) so tests stay in sync with the renderer's own layout:

python
m = _compute_metrics(56)  # row_h = widget h / number of rows
# Card border:
#   x in [0, m.border] and [w - m.border, w]
# Icon circle:
#   x in [x_off + m.padding, x_off + m.padding + m.icon_dia]
# Icon glyph size (inside the circle):
#   m.icon_inner  (do NOT compute as m.icon_dia * 6 // 10)
# Text start:
#   x = x_off + m.padding + m.icon_dia + m.inner_gap
# Row divider:
#   y = row_y + row_h  (height = m.divider)
# card_container macro passes (x_off, right_inset) to caller:
#   "border"   -> (m.padding, m.padding)
#   "left_bar" -> (bar_w + m.padding, 0)
#   "none"     -> (0, 0)
# Content width (cw):
#   cw = w - x_off - right_inset
# _card_insets(m, card_style, display_levels) returns
# (x_off, r_inset, bar_width). Derive lpad/rpad from the result:
#   x_off, r_inset, _ = _card_insets(m, card_style, display_levels)
#   lpad = m.padding if x_off == 0 else 0
#   rpad = m.padding if r_inset == 0 else 0
# Icon circle left arc lands at x_off + lpad, NOT x_off + m.padding.
# Divider lines span x_off + lpad .. w - r_inset - rpad.
Show full SKILL.md (489 more words)Show less

Lessons from completed TDD cycles

  1. Pixel-level assertions for borders: The SEPARATOR tests use exact pixel() checks (e.g. pixel(img, x, 50) == COLOR_BLACK) for precise structural verification. Use these when the exact position is known.

  2. Region-based assertions for content: Use assert_has_dark_pixels() for areas where content location is approximate (text rendering varies by font backend).

  3. content_bbox() for measuring: Use it to find actual rendered content size for scaling and alignment tests. It returns the tight bounding box of non-white pixels.

  4. 2-level display tests: When the widget uses gray elements (dividers, bars, left_bar), test the display_levels=2 path that widens them. Pass it via config: config = {**self._CONFIG, "display_levels": 2}.

  5. Test each card_style variant: For card-style widgets, test all three styles ("border", "left_bar", "none") in separate test methods. The SEPARATOR tests show this pattern well.

  6. 2-level icon ring bounds: When a helper computes the ring check area inside an icon circle (the region above the glyph), it must account for the wider stroke on 2-level displays. Mirror the context builder's icon_stroke_w formula so the check region stays inside the stroke inner edge:

    python
    icon_stroke_w = (
        m.border * 3 if display_levels <= 2 else m.border
    )
    ring_y1 = icon_cy - icon_r + icon_stroke_w // 2 + 3
    ring_y2 = icon_cy - m.icon_inner // 2 - 1

    Without this adjustment, the wider stroke's antialiased inner edge bleeds into the ring region, producing false gray-pixel hits in the 2-level test path.

  7. Missing entity = no crash: Always include a test that passes a nonexistent entity ID and verifies the widget doesn't crash. Also test empty entity list → all white canvas.

  8. Each test needs a comment: Every test function must start with a short comment explaining what it verifies.

  9. Engine-agnostic tests only: Tests call render_dashboard() and inspect PNG output. Do NOT import or call internal drawing helpers from tests. The entry point (render_dashboard) dispatches transparently to the SVG pipeline in svg_render.py. Exception: auto-sizing tests (§5) call render_widget_svg directly to read the SVG height attribute — it cannot be inferred from a full-canvas PNG.

Font metric tolerance

The SVG pipeline uses resvg for text rendering, which may produce slightly different glyph metrics than PIL. Keep the following in mind:

  • Use region-based assertions (assert_has_dark_pixels, assert_has_gray_pixels) rather than exact pixel checks for text content. Text position may shift by 1-3 pixels between engines.
  • Use tolerance=3.0 (instead of 2.0) for assert_vertically_centered when testing icon-text alignment. resvg's dominant-baseline="central" differs slightly from PIL's ascender-based centering.
  • assert_scales_proportionally tolerance of 0.25 remains sufficient — proportional scaling is engine-agnostic.
  • Exact pixel() checks are fine for geometry (borders, dividers, chip corners) — these are SVG shapes, not text.

Verification

Run tests — they should FAIL at this point (TDD red phase):

bash
uv run --group test pytest \
    tests/test_render_{widget_type}.py::TestRender{WidgetName} -v

The tests define the expected behavior. The renderer implementation (via /implement-widget) makes them pass.

Key references

  • Widget behavior source: task description / spec doc for the new widget
  • Test helpers: tests/helpers.py
  • Reference structural tests: TestRenderSeparator in tests/test_render_separator.py
  • Reference _DEFAULTS + _config() pattern: TestRenderWeather in tests/test_render_weather.py
  • Sizing ratios: _compute_metrics() in render.py
  • SVG macros: templates/_macros.svg.j2
  • Colors: COLOR_BLACK=0, COLOR_WHITE=255, COLOR_GRAY=120 in const.py

© cryptomilk, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/implement-widget-tests of cryptomilk/hass-eink-dashboard.

Open the folder on GitHubat commit 6142841

Compare with similar skills

Implement Widget Tests next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Implement Widget Tests compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Implement Widget Tests this skillcryptomilk/hass-eink-dashboard116—~4.2kAutomated safety check: PassApache-2.0
Jest Testing PatternsChrisWiles/claude-code-showcase6.1k7 repos~1.5kAutomated safety check: PassNone
Rust TDD Workflowrtk-ai/rtk83k—~753Automated safety check: NotesApache-2.0
TDDpietheinstrengholt/rssmonster56430 repos~906Automated safety check: PassMIT
RTK Filter TDD in Rustrtk-ai/rtk83k—~1.9kAutomated safety check: NotesApache-2.0
TDD WorkflowhellangleZ/burn-in-cceverywhere-ralph11211 repos~2.4kAutomated safety check: PassNone

Similar skills

  • Jest Testing Patterns

    ChrisWiles/claude-code-showcase

    Jest patterns for React Native style tests: TDD discipline, mock factory functions, module and GraphQL hook mocking, custom render helpers and anti-patterns to avoid.

    6.1k GitHub starsUsed in 7 repos~1.5k tokens
    Testing & QAAuto-check passed
  • Enforces red-green-refactor for Rust work, with idiomatic test patterns, a naming convention and a pre-commit gate of cargo fmt, clippy and test.

    83k GitHub stars~753 tokensUpdated today
    Testing & QAAuto-check: notes
  • TDD

    pietheinstrengholt/rssmonster

    Test-driven development. An agent skill from pietheinstrengholt/rssmonster.

    564 GitHub starsUsed in 30 repos~906 tokens
    Testing & QAAuto-check passed
  • Enforces red-green-refactor for new RTK output filters in Rust, using real captured fixtures, snapshot tests with insta and token-savings assertions.

    83k GitHub stars~1.9k tokensUpdated today
    Testing & QAAuto-check: notes
  • TDD Workflow

    hellangleZ/burn-in-cceverywhere-ralph

    A skill your agent uses when writing new features, fixing bugs, or refactoring code.

    112 GitHub starsUsed in 11 repos~2.4k tokens
    Testing & QAAuto-check passed
  • Official

    A skill your agent uses when a user asks to wobble ty constraint ordering, check constraint-set or TDD ordering determinism, test reversed constraint/typevar IDs, or investigate nondeterministic ty…

    50k GitHub stars~838 tokensUpdated today
    Testing & QAAuto-check passed

More from cryptomilk/hass-eink-dashboard

  • Implement Widget

    cryptomilk/hass-eink-dashboard

    Implement a widget's SVG template and Python context builder.

    116 GitHub stars~4.8k tokensUpdated yesterday
    Auto-check passed
  • Implement Widget Frontend

    cryptomilk/hass-eink-dashboard

    Add TypeScript types in ha.d.ts and editor schema in eink-dashboard-editor.ts for a new or updated widget type; also handles deprecating an old type (remove from picker, keep schema, add @deprecated…

    116 GitHub stars~3.3k tokensUpdated yesterday
    Auto-check passed

Works with

Categories

Questions about Implement Widget Tests

What does Implement Widget Tests do?

Write TDD tests for a widget type: structural tests (borders, dividers), alignment tests (icon centering), and scaling tests (proportional sizing). Implement Widget Tests is an agent skill from cryptomilk/hass-eink-dashboard. Write TDD tests for a widget type: structural tests (borders, dividers), alignment tests (icon centering), and scaling tests (proportional sizing).

When should I use Implement Widget Tests?

Implement Widget Tests fits situations like: tasks that involve Test-driven development.

How do I install Implement Widget Tests in Claude Code?

Run `npx skills add cryptomilk/hass-eink-dashboard --skill implement-widget-tests -a claude-code`. Or copy the skill folder (.agents/skills/implement-widget-tests in cryptomilk/hass-eink-dashboard) into .claude/skills/implement-widget-tests in your project. Claude Code loads it when a task matches its description.

How do I install Implement Widget Tests in Codex?

Run `npx skills add cryptomilk/hass-eink-dashboard --skill implement-widget-tests -a codex`. Or copy the skill folder (.agents/skills/implement-widget-tests in cryptomilk/hass-eink-dashboard) into .agents/skills/implement-widget-tests in your project. Codex loads it when a task matches its description.

Can I use Implement Widget Tests in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add cryptomilk/hass-eink-dashboard --skill implement-widget-tests -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/implement-widget-tests, .gemini/skills/implement-widget-tests, .github/skills/implement-widget-tests and .opencode/skills/implement-widget-tests in your project.

What does Implement Widget Tests need to run?

Going by SKILL.md and its folder, Implement Widget Tests needs the command-line tools its instructions call (uv). Our summary lists: Python 3. Its frontmatter pre-approves these tools: Read, Edit, Write, Bash(uv *).

Does Implement Widget Tests access the network?

SKILL.md contains no URLs. Its commands use uv, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Implement Widget Tests safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Implement Widget Tests use?

Implement Widget Tests is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Implement Widget Tests use?

About 4.2k tokens (SKILL.md is roughly 17k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Implement Widget Tests?

Skills that share tags, products or a category with Implement Widget Tests: Jest Testing Patterns (ChrisWiles/claude-code-showcase, 6.1k stars), Rust TDD Workflow (rtk-ai/rtk, 83k stars), TDD (pietheinstrengholt/rssmonster, 564 stars) and RTK Filter TDD in Rust (rtk-ai/rtk, 83k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Implement Widget Tests?

cryptomilk (a GitHub user) maintains it in cryptomilk/hass-eink-dashboard, which has 116 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 6, 2026.

Source: cryptomilk/hass-eink-dashboard on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.