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.
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
| Input | Description | Default |
|---|---|---|
version | fm1-emu release tag (e.g. v0.2.0) | baked into action release |
github-token | GitHub token for downloading release assets | ${{ github.token }} |
install-playwright | Install Playwright, Chromium, and ffmpeg | true |
By default the emulator version baked into the action release is used. Override with version to pin a specific upstream release.
Outputs
| Output | Description |
|---|---|
version | Installed fm1-emu version |
bin-path | Absolute path to the fm1-emu binary |
web-path | Path to the WASM emulator directory |
cache-hit | Whether restored from cache |
chromium-path | Path 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
| Firmware | Home screen |
|---|---|
| felucca | ![]() |
| sloop | ![]() |
| melodee | ![]() |
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:
| Command | Description |
|---|---|
task fm1-emulator:download | Download fm1-emu binary, WASM emulator, and Playwright |
task fm1-emulator:download:fm1-emu | Native binary only |
task fm1-emulator:download:wasm | WASM emulator only |
task fm1-emulator:download:playwright | Playwright + Chromium + ffmpeg only |
task fm1-emulator:remove | Remove ~/.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.


