{"id":47178609,"url":"https://github.com/openshot/openshot-replay","last_synced_at":"2026-03-13T07:02:46.541Z","repository":{"id":342698749,"uuid":"1174823646","full_name":"OpenShot/openshot-replay","owner":"OpenShot","description":"Record it once. Replay it anytime. Catch UI regressions before users do.","archived":false,"fork":false,"pushed_at":"2026-03-06T22:19:32.000Z","size":835,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-07T02:27:02.114Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenShot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-06T22:06:21.000Z","updated_at":"2026-03-06T22:19:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/OpenShot/openshot-replay","commit_stats":null,"previous_names":["openshot/openshot-replay"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/OpenShot/openshot-replay","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenShot%2Fopenshot-replay","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenShot%2Fopenshot-replay/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenShot%2Fopenshot-replay/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenShot%2Fopenshot-replay/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenShot","download_url":"https://codeload.github.com/OpenShot/openshot-replay/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenShot%2Fopenshot-replay/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30460818,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-13T06:34:02.089Z","status":"ssl_error","status_checked_at":"2026-03-13T06:33:49.182Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-03-13T07:02:45.783Z","updated_at":"2026-03-13T07:02:46.536Z","avatar_url":"https://github.com/OpenShot.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OpenShot Replay Suite\n\n## Record it once. Replay it anytime. Catch UI regressions before users do.\n\nUI behavior can drift over time, and manual re-testing is slow and inconsistent. This suite gives you a repeatable way to capture real user flows, replay them quickly, and verify that OpenShot still behaves the same.\n\nIt helps you:\n- Reproducing UI behavior quickly\n- Catching regressions in repeatable user flows\n- Comparing trace output against known-good baselines\n\n1. `record.py` captures your input actions and writes `*.actions.json`.\n2. OpenShot writes trace files (`events`, `updates`, `selections`) during recording.\n3. `replay.py` replays a single action file against OpenShot.\n4. `tests.py` discovers all cases, replays each one, and asserts actual traces match expected traces.\n\n## Repository Layout\n\n```text\nsuite/\n  record.py        # Record UI actions to *.actions.json\n  replay.py        # Replay one recorded action file\n  tests.py         # Discover and run all replay test cases\n  init_replay.py   # Create baseline .osp project via replay\n  assertions.py    # Baseline/state assertion helpers\n  cases/           # *.actions.json test cases\n  artifacts/\n    home/          # Isolated OpenShot HOME profile\n    traces/        # Expected recording traces (*.jsonl)\n    runs/          # Actual traces captured during suite runs\n```\n\nBy default, scripts target `../openshot-qt`. Override with:\n- `--openshot-root /path/to/openshot-qt`\n- or `OPENSHOT_QT_ROOT=/path/to/openshot-qt`\n\n## Requirements\n\n- Ubuntu + X11 session\n- Python 3.10+ and the system packages below.\n\nInstall:\n\n```bash\nsudo apt update\nsudo apt install -y xdotool wmctrl curl unzip python3 python3-pynput\n```\n\n## Test Media Setup\n\nRecordings in this repo expect test media at:\n\n`suite/artifacts/home/openshot-testing`\n\nDownload and extract it:\n\n```bash\nmkdir -p suite/artifacts/home\ncurl -L -o /tmp/openshot-testing.zip https://s3.amazonaws.com/releases.openshot.org/testing/openshot-testing.zip\nrm -rf suite/artifacts/home/openshot-testing\nmkdir -p suite/artifacts/home/openshot-testing\nunzip -q /tmp/openshot-testing.zip -d suite/artifacts/home/openshot-testing\n```\n\n## Standard Procedure\n\n1. Record one case per file.\n2. Do not record clicking the window close button at the end of the case.\n3. Let `replay.py` / `tests.py` launch and close OpenShot.\n\n## Record New Case\n\nExample case name: `trim_clip`\n\n```bash\npython3 suite/record.py \\\n  --output suite/cases/trim_clip.actions.json \\\n  --lang es_ES.UTF-8 \\\n  --env QT_SCALE_FACTOR=1 \\\n  --openshot-arg=--web-backend=webengine \\\n  --openshot-root ../openshot-qt\n```\n\nPress `Esc` to stop recording.\n\nThis writes:\n- `suite/cases/trim_clip.actions.json`\n- `suite/artifacts/traces/trim_clip.events.jsonl`\n- `suite/artifacts/traces/trim_clip.updates.jsonl`\n- `suite/artifacts/traces/trim_clip.selections.jsonl`\n\nNotes:\n- By default, updates with `ignore_history=True` are excluded.\n- Use `--include-ignored-updates` if you want all update noise captured.\n- Cache-progress trace events are opt-in (`OPENSHOT_UI_TRACE_CACHE=1`) to avoid timing noise.\n- Mouse wheel scroll is recorded/replayed (including modifier combos like `Ctrl+Scroll`).\n- `--env KEY=VALUE` is repeatable for launch-time env overrides.\n- `--lang` sets both `LANG` and `LC_ALL`.\n- `--openshot-arg ARG` is repeatable for launch-time OpenShot args.\n- Env passed via `--env/--lang` is saved into `meta.env` in the actions file.\n- OpenShot args passed via `--openshot-arg` are saved into `meta.openshot_args`.\n\n## Replay One Case\n\n```bash\npython3 suite/replay.py \\\n  --actions suite/cases/trim_clip.actions.json \\\n  --openshot-root ../openshot-qt\n```\n\nUseful options:\n- `--speed 2.0` (faster replay)\n- `--pointer-margin 56` (more tolerant window-edge clicks)\n- `--debug` (verbose replay logging)\n- `--env KEY=VALUE` / `--lang ...` (override recorded launch env)\n- `--openshot-arg ARG` (append/override recorded OpenShot launch args)\n\nEmergency stop: press physical `Esc`.\n\nReplay automatically applies `meta.env` from the actions file when launching OpenShot.\nReplay also automatically applies `meta.openshot_args` from the actions file.\n\nBackend-specific examples:\n\n```bash\n# Record for webengine\npython3 suite/record.py --output suite/cases/preview_webengine.actions.json --openshot-arg=--web-backend=webengine\n\n# Record for qwidget\npython3 suite/record.py --output suite/cases/preview_qwidget.actions.json --openshot-arg=--web-backend=qwidget\n```\n\n## Run All Cases\n\n```bash\npython3 suite/tests.py --cases suite/cases --openshot-root ../openshot-qt\n```\n\nRun one or more specific cases:\n\n```bash\npython3 suite/tests.py --cases suite/cases --case clips_qwidget\npython3 suite/tests.py --cases suite/cases --case clips_qwidget.actions.json --case files_qwidget\n```\n\nFaster run:\n\n```bash\npython3 suite/tests.py --cases suite/cases --speed 2.0\n```\n\nFloat-tolerant assertions (useful for minor timing/pixel drift):\n\n```bash\npython3 suite/tests.py --cases suite/cases --float-tol 0.10\n```\n\nLocale/env across all cases:\n\n```bash\npython3 suite/tests.py --cases suite/cases --lang es_ES.UTF-8 --env QT_SCALE_FACTOR=1\n```\n\nOpenShot args across all cases:\n\n```bash\npython3 suite/tests.py --cases suite/cases --openshot-arg=--web-backend=webengine\n```\n\n`tests.py` behavior:\n- Launches OpenShot per case\n- Replays case actions\n- Captures actual traces\n- Strictly compares expected vs actual unified `events` trace (if present)\n- Also compares expected vs actual `updates` / `selections` traces (unless disabled per case)\n- Prints end summary\n\nUnified `events` currently includes:\n- `update`\n- `selection`\n- `action_triggered`\n- `dialog_lifecycle`\n- `dock_visibility`\n- `cache_progress` (only when `OPENSHOT_UI_TRACE_CACHE=1`)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenshot%2Fopenshot-replay","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenshot%2Fopenshot-replay","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenshot%2Fopenshot-replay/lists"}