overdub
FirmwareM-VAVE FM-1

setup-fm1-emulator

DimmKirr/setup-fm1-emulator · ★ 2

GitHub Action that installs the fm1-emu WebAssembly emulator for firmware UI tests in CI, no hardware needed.

README from GitHub, MIT

setup-fm1-emulator

GitHub Action that sets up the fm1-emu synthesizer emulator for E2E firmware UI testing in CI. No hardware needed.

Playing notes on the FM-1 emulator

Test your FM-1 firmware UI in CI: rotate encoders, press buttons, play notes, capture screenshots, and record GIFs. All through Playwright against a WASM emulator, no hardware required.

Usage

jobs:
  test:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-python@v7
        with:
          python-version: '3.12'

      - uses: dimmkirr/setup-fm1-emulator@v1

      - run: fm1-emu --help

Pin a specific emulator version:

- uses: dimmkirr/setup-fm1-emulator@v1
  with:
    version: v0.2.0

Inputs

InputDescriptionDefault
versionfm1-emu release tag (e.g. v0.2.0)baked into action release
github-tokenGitHub token for downloading release assets${{ github.token }}
install-playwrightInstall Playwright, Chromium, and ffmpegtrue

By default the emulator version baked into the action release is used. Override with version to pin a specific upstream release.

Outputs

OutputDescription
versionInstalled fm1-emu version
bin-pathAbsolute path to the fm1-emu binary
web-pathPath to the WASM emulator directory
cache-hitWhether restored from cache
chromium-pathPath to Playwright Chromium (empty if install-playwright is false)

E2E Testing with fm1-playwright

For writing E2E tests against the emulator, install the fm1-playwright package:

pip install fm1-playwright

Then subclass FirmwareUITest in your tests:

from fm1_playwright import FirmwareUITest

class MyFirmwareTest(FirmwareUITest):
    def test_boot(self):
        self._get_page()
        self._screenshot('home')

    def test_change_preset(self):
        self.rotate_encoder('k2', direction=1, steps=1, delay_ms=800)
        self._screenshot('preset-next')

See the fm1-playwright repo for full API docs, examples, and environment variables.

More screenshots
FirmwareHome screen
feluccafelucca home
sloopsloop home
melodeemelodee home

Local usage (Taskfile)

The included Taskfile.yml is a local equivalent of the GitHub Action. Import it into your project:

# Taskfile.yml (your project)
version: '3'

includes:
  fm1-emulator:
    taskfile: https://raw.githubusercontent.com/DimmKirr/setup-fm1-emulator/v1/Taskfile.yml

tasks:
  test:
    deps: [fm1-emulator:download]
    env:
      FM1_WEB_DIR: '{{.HOME}}/.fm1-emulator/web'
    cmds:
      - python3 -m unittest my_tests.e2e_test -v

Commands:

CommandDescription
task fm1-emulator:downloadDownload fm1-emu binary, WASM emulator, and Playwright
task fm1-emulator:download:fm1-emuNative binary only
task fm1-emulator:download:wasmWASM emulator only
task fm1-emulator:download:playwrightPlaywright + Chromium + ffmpeg only
task fm1-emulator:removeRemove ~/.fm1-emulator, results, and Playwright

Installs to ~/.fm1-emulator/ (same location as the GitHub Action). Downloads the pre-built WASM from the vendor-sync mirror first, falls back to building from source if the mirror release doesn't exist.

Credits

This action wraps fm1-emu, the FM1 synthesizer emulator created by Joakim Eriksson. The WASM browser emulator is built from the upstream source and redistributed as a release asset.

License

MIT