Agent Skills › readest/readest › koreader-e2e

koreader-e2e

GitHub

用于在真实KOReader设备(Kindle/Android)上验证插件修复,通过自动化UI操作、截图和日志断言进行端到端测试。

apps/readest-app/.claude/skills/koreader-e2e/SKILL.md readest/readest

触发场景

用户报告需在实际设备上复现问题 Busted规范测试通过但设备行为未知 需要验证同步、库或统计功能的修复 排查ANR崩溃或内存问题

安装

npx skills add readest/readest --skill koreader-e2e -g -y
更多选项

非标准路径

npx skills add https://github.com/readest/readest/tree/main/apps/readest-app/.claude/skills/koreader-e2e -g -y

不安装直接使用

npx skills use readest/readest@koreader-e2e

指定 Agent (Claude Code)

npx skills add readest/readest --skill koreader-e2e -a claude-code -g -y

安装 repo 全部 skill

npx skills add readest/readest --all -g -y

预览 repo 内 skill

npx skills add readest/readest --list

SKILL.md

Frontmatter
{
    "name": "koreader-e2e",
    "description": "Use when a readest.koplugin change must be verified on a real KOReader device (Kindle over SSH or Android over adb): reproducing a user report, confirming a sync\/library\/stats fix, driving the KOReader UI, capturing device screenshots or KOReader logs, or when busted specs pass but device behavior is unknown. Also for \"test on Kindle\", \"test on Android\", \"verify on device\", ANR\/crash on KOReader, and KOReader memory measurements.\n",
    "user_invocable": true
}

KOReader end-to-end testing

Busted specs run the plugin against stubs. Real devices differ in ways stubs cannot show: writable paths, tmpfs size, fork behavior, SQLite on /sdcard, the Android ANR watchdog. A plugin fix is verified only after it runs on a device through the real KOReader UI.

All device access goes through ko.sh next to this file:

KO=apps/readest-app/.claude/skills/koreader-e2e/ko.sh   # from the repo root
$KO help

Workflow

  1. Check the device. Run $KO kindle check and/or $KO android check: device, KOReader pid, plugin version, signed in or not, network. If the Kindle times out, it is asleep or its Wi-Fi is off: ask the user to wake it.
  2. Install the code under test. Use $KO <t> deploy [VERSION] for the whole plugin built from this checkout, or $KO <t> push library/syncbooks.lua ... for single files.
  3. Restart KOReader with $KO <t> restart. KOReader loads plugin modules once, so pushed Lua does nothing until a restart. On both platforms a restart closes the book the user has open: say so before doing it.
  4. Drive the UI to just before the action under test. Loop: $KO <t> shot NAME, Read the PNG, pick coordinates from it, $KO <t> tap X Y, and take another screenshot to confirm the tap landed.
  5. Open a log window right before the action with $KO <t> log-reset, then do the action. KOReader and the plugin log on their own: for example, opening the Readest Library starts a sync. A window opened earlier would catch that and give a false pass.
  6. Assert on logs. For a sync, wait for the completion line: $KO <t> wait-log 'runCloudSync\[.*\] done' 90. (pullBooks complete fires before the push half has run.) Then run $KO <t> log 'error|traceback|ANR'.
  7. Report the evidence: the exact log lines, and screenshots that show the end state.

Quick reference

Need Command
Shell on device $KO kindle sh 'free; df /var'
Plugin settings $KO <t> sh 'grep -A25 readest_sync <ko>/settings.reader.lua' (<ko> = /mnt/us/koreader or /sdcard/koreader)
Only the new log lines $KO <t> log 'Readest'
Screenshot directory $KO_OUT (default $TMPDIR/koreader-e2e)
Other Kindle KINDLE_HOST=… KINDLE_PORT=… $KO kindle …
Other Android ANDROID_SERIAL=… $KO android …

Getting around the UI (from screenshots; coordinates depend on the device):

  • KOReader main menu: tap the top edge (the ∨ handle on Kindle), then the tools tab → Readest → Readest library. The menu reopens on the last tab used, so check which tab is selected before tapping.
  • The Readest submenu starts with Log out as when signed in, and $KO <t> check prints readest: signed in|out.
  • Readest Library view menu (Sync now, Rescan library, …): tap the library's title.
  • Android screenshots come back scaled down for display. Multiply by the scale the Read tool reports before tapping; Kindle screenshots are 1:1.

What the logs can and cannot show

  • KOReader logs at INFO by default. The sync client logs failures only at logger.dbg, so a failed RPC shows up as success=false status=nil in ReadestLibrary lines, with no reason given. Look at the caller's INFO lines.
  • A status of nil means the request never got an HTTP response: the worker failed, or the network was down. Rule out the network first: $KO <t> check reports it (Kindle: HTTP 403 Not authenticated from the Readest API = reachable).
  • On Android, $KO android log includes system lines. ANR in org.koreader… followed by Process … exited due to signal 9 means Android killed KOReader because its UI thread was blocked for more than 5 s. That is not a Lua error.
  • Measuring memory of a forked worker: an unrooted Android cannot read another process's smaps. Have the child read /proc/self/smaps and append the totals to a file. Use Private_Dirty, not RSS: RSS counts pages shared with the parent after fork().

Device facts that bite

Fact Consequence
Android /tmp is shell:shell 0771 os.tmpname() throws inside KOReader. Write temp files under DataStorage:getSettingsDir()
Kindle /tmp → /var/tmp, a 64 MB tmpfs filled by fm-out-* metrics files; cleared only by rebooting the Kindle Large writes to /tmp get cut short
koreader.sh keeps only the last 500 KB of crash.log at each launch Never address log lines by line number; log-reset writes a marker line instead
Kindle SSH (KOReader's dropbear) takes a blank password, rejects keys ko.sh handles this; don't add keys
Kindle's busybox ash has no <(...), no arrays Keep sh commands POSIX
FFIUtil.runInSubProcess returns the child's pid, not its results Use Trapper:dismissableRunInSubprocess to get results back
One SQLite commit per row on /sdcard takes several ms Loops of upserts need one transaction, or they can hit the ANR watchdog

Leave the device as you found it

  • If a test needs a user setting changed (e.g. home_dir for Rescan library), edit settings.reader.lua only while KOReader is stopped, and change it back afterwards.
  • Remove probes and instrumentation. Put the real plugin files back with push or deploy.
  • Never type into a login or password field, and never print tokens from settings.reader.lua. If the session is dead, ask the user to sign in on the device.

版本历史

  • 9d642fe 当前 2026-09-23 09:05

同 Skill 集合

apps/readest-app/.claude/skills/i18n-koplugin/SKILL.md
apps/readest-app/.claude/skills/i18n/SKILL.md
apps/readest-app/.claude/skills/nightly-review/SKILL.md
apps/readest-app/.claude/skills/triage-github/SKILL.md
apps/readest-app/.claude/skills/watch-social/SKILL.md

元信息

文件数
0
版本
2d37bbf
Hash
23a3db04
收录时间
2026-09-23 09:05

首页 - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-11-02 07:20
浙ICP备14020137号-1