[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7C9C9BAHAFD15B3TSBNTWWB":3,"skill-same:01M7C9C9BAHAFD15B3TSBNTWWB":62},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":26,"commitSha":27,"skillDirectory":28,"forksCount":29,"repositoryHtmlUrl":30,"repositoryHomepageUrl":6,"ownerHtmlUrl":31,"ownerBlogUrl":6,"ownerDescription":32,"updatedAt":33,"install":34,"resources":47},"01M7C9C9BAHAFD15B3TSBNTWWB","desktop-e2e-edho-ferdian",null,"End-to-end tests for Windows desktop apps (WPF, WinForms, Win32, Qt) with pywinauto over UI Automation. Use for \"test aplikasi desktop\", \"pywinauto\", \"WPF\u002FWinForms\u002FQt test\", \"UI Automation\", \"test .exe ini\", or a flaky desktop GUI suite.","edhoferdian\u002FEEF","edhoferdian","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F64404158?v=4","01M7C8538ZVVZWZEN1AW2MQXCV","Edho F","01M7C8539NS56BMJ4GXN8A47TQ",22,"MIT","https:\u002F\u002Fgithub.com\u002Fedhoferdian\u002FEEF\u002Fblob\u002Fmain\u002Fskills\u002Fdesktop-e2e-edho-ferdian\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: desktop-e2e-edho-ferdian\ndescription: >-\n  End-to-end tests for Windows desktop apps (WPF, WinForms, Win32, Qt) with\n  pywinauto over UI Automation. Use for \"test aplikasi desktop\",\n  \"pywinauto\", \"WPF\u002FWinForms\u002FQt test\", \"UI Automation\", \"test .exe ini\", or\n  a flaky desktop GUI suite.\nmetadata:\n  last_reviewed: \"2026-09-09\"\n---\n\n# Desktop E2E (Windows) — Edho Ferdian Mode\n\n## Where this sits\n\n`e2e-testing-edho-ferdian` owns the *process*: Phase 1 journey mapping,\nPhase 2 Page Object Model, Phase 3 flake quarantine, Phase 4 artifact capture.\nAll four are driver-agnostic and apply unchanged here — do not restate or fork\nthem. This skill supplies only what changes when the driver is native Windows\nautomation instead of a browser:\n\n| Concept | Browser (Playwright) | Here (pywinauto + UIA) |\n|---|---|---|\n| Locator | role \u002F `data-testid` \u002F CSS | AutomationId → Name → ClassName+index |\n| Wait | auto-waiting locators | `spec.wait(\"visible\")` \u002F `wait_until(...)` |\n| Artifact | screenshot \u002F video \u002F trace | window capture \u002F ffmpeg `gdigrab` \u002F step trace |\n| Isolation | browser context | fresh process + redirected `APPDATA`\u002F`TEMP` |\n\n**Not for:** web apps (use Playwright), Electron\u002FCEF\u002FWebView2 (the HTML layer\nneeds browser automation, UIA only sees the shell), mobile, or anything that\ndoes not need a running GUI.\n\n## How it works\n\nEverything routes through Windows UI Automation, an accessibility API built\ninto Windows. Each UI framework ships a UIA provider of varying quality:\n\n```\npytest → pywinauto (uia backend) → Windows UI Automation API → app's UIA provider → running .exe\n```\n\n| Framework | AutomationId source | Reliability |\n|---|---|---|\n| WPF | `x:Name` maps directly | Excellent |\n| UWP \u002F WinUI 3 | native | Excellent |\n| Qt 6.x | `setAccessibleName`; accessibility on by default | Excellent |\n| WinForms | `AccessibleName` | Good |\n| Qt 5.15+ | needs `QT_ACCESSIBILITY=1` | Good |\n| Qt 5.7–5.14 | needs `QT_ACCESSIBILITY=1`; manual objectName | Fair |\n| Win32 \u002F MFC | resource control IDs appear as numeric strings | Fair |\n\n## Phase 0′ — Environment check (before anything else)\n\n```bash\npip install pywinauto pytest pytest-html pytest-timeout Pillow\n```\n\n```python\nfrom pywinauto import Desktop\nDesktop(backend=\"uia\").windows()   # must list top-level windows\n```\n\nInstall **Accessibility Insights for Windows** (free, Microsoft) — it is the\nDevTools equivalent for this stack. Inspect the UIA tree there *before*\nwriting a locator; guessing at AutomationIds is the main time sink here.\n\nIf UIA is unreachable, or the target turns out to be Electron\u002FWebView2, stop\nand say so — report `VERIFIED: NO — no usable native automation driver`, the\nsame convention the rest of this ecosystem uses. Never fabricate a run.\n\n## Testability first\n\nThe single highest-leverage action is giving every interactive control a\nstable AutomationId **before** writing tests. Per framework:\n\n- **WPF** — `x:Name=\"btnLogin\"` in XAML; nothing else needed.\n- **WinForms** — `btnLogin.AccessibleName = \"btnLogin\";`\n- **Qt** — set both, via one helper, and centralize the string constants in a\n  header so tests and app cannot drift:\n  ```cpp\n  void setTestId(QWidget* w, const char* id) {\n      w->setObjectName(id);\n      w->setAccessibleName(id);   \u002F\u002F becomes the UIA Name property\n  }\n  ```\n- **Win32 \u002F MFC** — resource IDs surface as numeric AutomationId strings;\n  prefer `SetWindowText` for a readable Name.\n\nA test suite written against `ClassName + index` because the app has no\nAutomationIds will be rewritten within a release. Fixing testability in the app\nis cheaper than the flakiness it prevents — say so when the app owner resists.\n\n## References\n\n- **`references\u002Fpywinauto-harness.md`** — the Page Object base class, locator\n  priority, wait patterns, artifact capture, the opt-in per-step trace, and the\n  flaky-cause table.\n- **`references\u002Fisolation-and-ci.md`** — the three isolation tiers (tmp_path\n  env redirect \u002F Job Object \u002F Windows Sandbox), hang prevention, and the GitHub\n  Actions `windows-latest` workflow.\n- **`references\u002Fqt-and-fallback.md`** — Qt-specific quirks (combo popups,\n  dialogs as top-level windows, table cells, self-drawn widgets) and the\n  screenshot-matching fallback with its DPI rules.\n\n## Language routing (fixed — see skill-authoring-edho-ferdian's canonical contract)\n\nCommunication to the user in Bahasa Indonesia; test code, page-object names,\nand assertions in English — fixed, never ask. Full contract:\n`skill-authoring-edho-ferdian` §7.\n\n## Global rules\n\n1. **AutomationId first, always.** Name second, ClassName+index only when\n   forced, coordinates never as a primary strategy.\n2. **Never `time.sleep()` as synchronization.** `wait_visible` \u002F `wait_gone` \u002F\n   `wait_until` exist for exactly this.\n3. **Fresh process per test.** A session-scoped app fixture leaks state between\n   tests and turns every failure into an archaeology exercise.\n4. **Assert content and state, never pixel geometry.** `lblStatus == \"Logged\n   in\"` is a test; `btn.rectangle().left == 120` is a trap.\n5. **Redact typed text in traces.** Never enable trace text capture on a login\n   or payment flow.\n6. **Quarantine, don't delete** — the protocol in\n   `e2e-testing-edho-ferdian\u002Freferences\u002Fflake-quarantine.md` applies verbatim;\n   the Python spelling is `@pytest.mark.skip(reason=\"...\")` \u002F\n   `@pytest.mark.skipif(os.environ.get(\"CI\") == \"true\", reason=\"...\")`.\n","# Desktop E2E (Windows) — Edho Ferdian Mode\n\n## Where this sits\n\n`e2e-testing-edho-ferdian` owns the *process*: Phase 1 journey mapping,\nPhase 2 Page Object Model, Phase 3 flake quarantine, Phase 4 artifact capture.\nAll four are driver-agnostic and apply unchanged here — do not restate or fork\nthem. This skill supplies only what changes when the driver is native Windows\nautomation instead of a browser:\n\n| Concept | Browser (Playwright) | Here (pywinauto + UIA) |\n|---|---|---|\n| Locator | role \u002F `data-testid` \u002F CSS | AutomationId → Name → ClassName+index |\n| Wait | auto-waiting locators | `spec.wait(\"visible\")` \u002F `wait_until(...)` |\n| Artifact | screenshot \u002F video \u002F trace | window capture \u002F ffmpeg `gdigrab` \u002F step trace |\n| Isolation | browser context | fresh process + redirected `APPDATA`\u002F`TEMP` |\n\n**Not for:** web apps (use Playwright), Electron\u002FCEF\u002FWebView2 (the HTML layer\nneeds browser automation, UIA only sees the shell), mobile, or anything that\ndoes not need a running GUI.\n\n## How it works\n\nEverything routes through Windows UI Automation, an accessibility API built\ninto Windows. Each UI framework ships a UIA provider of varying quality:\n\n```\npytest → pywinauto (uia backend) → Windows UI Automation API → app's UIA provider → running .exe\n```\n\n| Framework | AutomationId source | Reliability |\n|---|---|---|\n| WPF | `x:Name` maps directly | Excellent |\n| UWP \u002F WinUI 3 | native | Excellent |\n| Qt 6.x | `setAccessibleName`; accessibility on by default | Excellent |\n| WinForms | `AccessibleName` | Good |\n| Qt 5.15+ | needs `QT_ACCESSIBILITY=1` | Good |\n| Qt 5.7–5.14 | needs `QT_ACCESSIBILITY=1`; manual objectName | Fair |\n| Win32 \u002F MFC | resource control IDs appear as numeric strings | Fair |\n\n## Phase 0′ — Environment check (before anything else)\n\n```bash\npip install pywinauto pytest pytest-html pytest-timeout Pillow\n```\n\n```python\nfrom pywinauto import Desktop\nDesktop(backend=\"uia\").windows()   # must list top-level windows\n```\n\nInstall **Accessibility Insights for Windows** (free, Microsoft) — it is the\nDevTools equivalent for this stack. Inspect the UIA tree there *before*\nwriting a locator; guessing at AutomationIds is the main time sink here.\n\nIf UIA is unreachable, or the target turns out to be Electron\u002FWebView2, stop\nand say so — report `VERIFIED: NO — no usable native automation driver`, the\nsame convention the rest of this ecosystem uses. Never fabricate a run.\n\n## Testability first\n\nThe single highest-leverage action is giving every interactive control a\nstable AutomationId **before** writing tests. Per framework:\n\n- **WPF** — `x:Name=\"btnLogin\"` in XAML; nothing else needed.\n- **WinForms** — `btnLogin.AccessibleName = \"btnLogin\";`\n- **Qt** — set both, via one helper, and centralize the string constants in a\n  header so tests and app cannot drift:\n  ```cpp\n  void setTestId(QWidget* w, const char* id) {\n      w->setObjectName(id);\n      w->setAccessibleName(id);   \u002F\u002F becomes the UIA Name property\n  }\n  ```\n- **Win32 \u002F MFC** — resource IDs surface as numeric AutomationId strings;\n  prefer `SetWindowText` for a readable Name.\n\nA test suite written against `ClassName + index` because the app has no\nAutomationIds will be rewritten within a release. Fixing testability in the app\nis cheaper than the flakiness it prevents — say so when the app owner resists.\n\n## References\n\n- **`references\u002Fpywinauto-harness.md`** — the Page Object base class, locator\n  priority, wait patterns, artifact capture, the opt-in per-step trace, and the\n  flaky-cause table.\n- **`references\u002Fisolation-and-ci.md`** — the three isolation tiers (tmp_path\n  env redirect \u002F Job Object \u002F Windows Sandbox), hang prevention, and the GitHub\n  Actions `windows-latest` workflow.\n- **`references\u002Fqt-and-fallback.md`** — Qt-specific quirks (combo popups,\n  dialogs as top-level windows, table cells, self-drawn widgets) and the\n  screenshot-matching fallback with its DPI rules.\n\n## Language routing (fixed — see skill-authoring-edho-ferdian's canonical contract)\n\nCommunication to the user in Bahasa Indonesia; test code, page-object names,\nand assertions in English — fixed, never ask. Full contract:\n`skill-authoring-edho-ferdian` §7.\n\n## Global rules\n\n1. **AutomationId first, always.** Name second, ClassName+index only when\n   forced, coordinates never as a primary strategy.\n2. **Never `time.sleep()` as synchronization.** `wait_visible` \u002F `wait_gone` \u002F\n   `wait_until` exist for exactly this.\n3. **Fresh process per test.** A session-scoped app fixture leaks state between\n   tests and turns every failure into an archaeology exercise.\n4. **Assert content and state, never pixel geometry.** `lblStatus == \"Logged\n   in\"` is a test; `btn.rectangle().left == 120` is a trap.\n5. **Redact typed text in traces.** Never enable trace text capture on a login\n   or payment flow.\n6. **Quarantine, don't delete** — the protocol in\n   `e2e-testing-edho-ferdian\u002Freferences\u002Fflake-quarantine.md` applies verbatim;\n   the Python spelling is `@pytest.mark.skip(reason=\"...\")` \u002F\n   `@pytest.mark.skipif(os.environ.get(\"CI\") == \"true\", reason=\"...\")`.\n",{"name":5,"metadata":24,"description":7},{"last_reviewed":25},"2026-09-09","main","533d32ad55c92d40fbabe93cbe21fe048598fe5a","skills\u002Fdesktop-e2e-edho-ferdian",0,"https:\u002F\u002Fgithub.com\u002Fedhoferdian\u002FEEF","https:\u002F\u002Fgithub.com\u002Fedhoferdian","Elevating ideas through AI, rising from humble beginnings to mastering the frontiers of the web. Every line of code is open-sourced on GitHub, inviting you to f","2026-10-30 03:34:17",{"source":8,"skillName":5,"commands":35,"prompt":45,"zipAvailable":46},[36,39,42],{"tool":37,"command":38},"npx","npx skills add edhoferdian\u002FEEF --skill desktop-e2e-edho-ferdian",{"tool":40,"command":41},"bunx","bunx skills add edhoferdian\u002FEEF --skill desktop-e2e-edho-ferdian",{"tool":43,"command":44},"pnpm","pnpm dlx skills add edhoferdian\u002FEEF --skill desktop-e2e-edho-ferdian","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fedhoferdian\u002FEEF\u002Fblob\u002Fmain\u002Fskills\u002Fdesktop-e2e-edho-ferdian\u002FSKILL.md",true,[48,54,58],{"path":49,"resourceType":50,"resourceTypeDesc":51,"sizeBytes":52,"sourceHtmlUrl":53},"references\u002Fisolation-and-ci.md","REFERENCE","参考文档",3829,"https:\u002F\u002Fgithub.com\u002Fedhoferdian\u002FEEF\u002Fblob\u002Fmain\u002Fskills\u002Fdesktop-e2e-edho-ferdian\u002Freferences\u002Fisolation-and-ci.md",{"path":55,"resourceType":50,"resourceTypeDesc":51,"sizeBytes":56,"sourceHtmlUrl":57},"references\u002Fpywinauto-harness.md",5592,"https:\u002F\u002Fgithub.com\u002Fedhoferdian\u002FEEF\u002Fblob\u002Fmain\u002Fskills\u002Fdesktop-e2e-edho-ferdian\u002Freferences\u002Fpywinauto-harness.md",{"path":59,"resourceType":50,"resourceTypeDesc":51,"sizeBytes":60,"sourceHtmlUrl":61},"references\u002Fqt-and-fallback.md",2892,"https:\u002F\u002Fgithub.com\u002Fedhoferdian\u002FEEF\u002Fblob\u002Fmain\u002Fskills\u002Fdesktop-e2e-edho-ferdian\u002Freferences\u002Fqt-and-fallback.md",[63,70,77,84,91,98],{"skillNo":64,"name":65,"nameZh":6,"description":66,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":67,"categories":68,"keywords":69,"publishedAt":19},"01M7C9FY2EWE5NB7M3YW0KJX62","video-style-edho-ferdian","Measure a reference video's look and pacing (colour grade as a 3D LUT, cut rhythm, overlays) and reproduce it: grade, cut and composite new footage, verify numerically, hand off an NLE timeline. Use for \"tiru look video ini\", \"samakan grading\", \"bikin video dengan gaya referensi\", \"LUT dari referensi\", \"cut rhythm\".","https:\u002F\u002Fgithub.com\u002Fedhoferdian\u002FEEF\u002Fblob\u002Fmain\u002Fskills\u002Fvideo-style-edho-ferdian\u002FSKILL.md",[],[],{"skillNo":71,"name":72,"nameZh":6,"description":73,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":76,"publishedAt":19},"01M7C9FT74P7JXGQ73116B9WS1","test-authoring-edho-ferdian","Write unit and component tests well: React Testing Library, pytest, Go and Vue, plus regression-test patterns. Use for \"tulis test untuk component ini\", \"bagaimana test hook ini\", \"test yang bagus untuk fitur X\", \"tulis test pytest\u002FGo\u002FVue\", or dev-kickoff's TEST stage.","https:\u002F\u002Fgithub.com\u002Fedhoferdian\u002FEEF\u002Fblob\u002Fmain\u002Fskills\u002Ftest-authoring-edho-ferdian\u002FSKILL.md",[],[],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":19},"01M7C9FMPE9W76FS7S8ZZ48ARE","system-design-edho-ferdian","Mid-project architecture decisions: ADRs, trade-off analysis, non-functional requirements, scaling tiers and blast radius. Use for \"desain arsitektur\", \"keputusan teknis besar\", \"bikin ADR\", \"trade-off antara X dan Y\", \"microservices atau monolith\", \"apa yang rusak kalau X diubah\", or a capacity question.","https:\u002F\u002Fgithub.com\u002Fedhoferdian\u002FEEF\u002Fblob\u002Fmain\u002Fskills\u002Fsystem-design-edho-ferdian\u002FSKILL.md",[],[],{"skillNo":85,"name":86,"nameZh":6,"description":87,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":90,"publishedAt":19},"01M7C9FETATAHKG5WKPT4AP1A2","spec-mining-edho-ferdian","Extract behavioural specs from a codebase with none: WHEN\u002FTHEN requirements and invariants, each anchored to the code that enforces it, unclear behaviour recorded as uncertainty. Use for \"ekstrak spec\", \"buat spec dari kode\", \"reverse-engineer the spec\", \"repo ini tidak ada dokumentasi\", or a missing BEHAVIOR_SPEC in dev-kickoff.","https:\u002F\u002Fgithub.com\u002Fedhoferdian\u002FEEF\u002Fblob\u002Fmain\u002Fskills\u002Fspec-mining-edho-ferdian\u002FSKILL.md",[],[],{"skillNo":92,"name":93,"nameZh":6,"description":94,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":97,"publishedAt":19},"01M7C9F93YCXFCVRDG4S5QFAH4","skill-authoring-edho-ferdian","Create and govern this ecosystem's skills: search before building, a quality bar, compliance checks, promoting repeated principles to rules, and packaging dist\u002F*.skill. Use for \"bikin skill baru\", \"ada skill buat X gak\", \"fork skill ini\", \"skill gue kepake gak sih\", \"package skill ini\", \"buatkan .skill-nya\".","https:\u002F\u002Fgithub.com\u002Fedhoferdian\u002FEEF\u002Fblob\u002Fmain\u002Fskills\u002Fskill-authoring-edho-ferdian\u002FSKILL.md",[],[],{"skillNo":99,"name":100,"nameZh":6,"description":101,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":102,"categories":103,"keywords":104,"publishedAt":19},"01M7C9F4XZJ59R0GS4YEP4E1RD","skill-audit-edho-ferdian","Audit this repo's skills\u002F for staleness, redundancy, broken cross-references and weak descriptions (not the ~\u002F.claude setup: that is config-hygiene). Use for \"audit skill saya\", \"cek skill yang sudah dibuat\", \"ada yang redundan gak\", \"skill mana yang basi\".","https:\u002F\u002Fgithub.com\u002Fedhoferdian\u002FEEF\u002Fblob\u002Fmain\u002Fskills\u002Fskill-audit-edho-ferdian\u002FSKILL.md",[],[]]