Skip to content

feat: kitten-lynx, a puppeteer like, android emulator based, testing infrastructure#2272

Merged
PupilTong merged 31 commits intolynx-family:mainfrom
PupilTong:p/hw/based-on-emulator-testing
Mar 18, 2026
Merged

feat: kitten-lynx, a puppeteer like, android emulator based, testing infrastructure#2272
PupilTong merged 31 commits intolynx-family:mainfrom
PupilTong:p/hw/based-on-emulator-testing

Conversation

@PupilTong
Copy link
Copy Markdown
Collaborator

@PupilTong PupilTong commented Feb 26, 2026

Summary by CodeRabbit

  • New Features

    • Kitten-Lynx testing framework: connect to app, create pages, navigate, query elements, read styles, perform taps, and consolidated public exports.
  • CI

    • Added Android emulator-based integration job to run end-to-end tests.
  • Tests

    • Added end-to-end test validating navigation, content reading, element querying, style inspection, and interactions.
  • Bug Fixes

    • Improved app launch fallback for more reliable startup.
  • Documentation

    • Added comprehensive guides, examples, and troubleshooting notes.
  • Chores

    • Added release changeset and package metadata for initial publish.

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).
  • Changeset added, and when a BREAKING CHANGE occurs, it needs to be clearly marked (or not required).

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 26, 2026

🦋 Changeset detected

Latest commit: 1f6a24b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@lynx-js/kitten-lynx-test-infra Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@PupilTong PupilTong self-assigned this Feb 26, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 26, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new Kitten-Lynx testing library (ADB + CDP) with source, tests, docs, configs, and exports; introduces a CI emulator job and changeset; and updates Android transport fallback in devtool connector to use dumpsys/am start when monkey output lacks expected markers.

Changes

Cohort / File(s) Summary
Framework Core
packages/testing-library/kitten-lynx/src/Lynx.ts, packages/testing-library/kitten-lynx/src/KittenLynxView.ts, packages/testing-library/kitten-lynx/src/ElementNode.ts, packages/testing-library/kitten-lynx/src/CDPChannel.ts, packages/testing-library/kitten-lynx/src/index.ts
Added public modules: Lynx connect/newPage/close API, KittenLynxView page model (navigation, attach, content), ElementNode interactions (tap, attributes, styles), typed per-session CDPChannel, and barrel exports.
Tests
packages/testing-library/kitten-lynx/tests/lynx.spec.ts
New end-to-end Vitest spec exercising connect, navigation, DOM inspection, computed styles, and tap interaction.
Docs
packages/testing-library/kitten-lynx/README.md, packages/testing-library/kitten-lynx/AGENTS.md
Added usage and architecture docs, prerequisites, gotchas, extension guidance, and developer notes.
Project Configuration
packages/testing-library/kitten-lynx/package.json, packages/testing-library/kitten-lynx/tsconfig.json, packages/testing-library/kitten-lynx/vitest.config.ts
New package manifest with exports and scripts, TypeScript config with path aliases and declaration output, and Vitest config (node env, timeouts).
CI & Release
.github/workflows/test.yml, .changeset/sharp-dragons-search.md
Added kitten-lynx-android-emulator CI job to run emulator-based tests and a changeset declaring a patch release for @lynx-js/kitten-lynx-test-infra.
Transport Fix
packages/mcp-servers/devtool-connector/src/transport/android.ts
Modified openApp() to treat missing "Events injected:" as failure and added a dumpsys + am start fallback before throwing a consolidated error.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • colinaaa
  • upupming
  • hzy

Poem

🐰 I hopped through code and CI light,
pages, channels, docs in sight,
a tap, a dump, an emulator song,
tests and changesets marching along,
tiny paws push builds along 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main addition: a new testing infrastructure called kitten-lynx with Puppeteer-like API and Android emulator support.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 26, 2026

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Feb 27, 2026

Merging this PR will not alter performance

✅ 72 untouched benchmarks
⏩ 3 skipped benchmarks1


Comparing PupilTong:p/hw/based-on-emulator-testing (1f6a24b) with main (6d8e125)

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@relativeci
Copy link
Copy Markdown

relativeci bot commented Feb 27, 2026

Web Explorer

#8207 Bundle Size — 385.21KiB (0%).

1f6a24b(current) vs 6d8e125 main#8200(baseline)

Bundle metrics  no changes
                 Current
#8207
     Baseline
#8200
No change  Initial JS 155.59KiB 155.59KiB
No change  Initial CSS 35.1KiB 35.1KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 8 8
No change  Assets 8 8
No change  Modules 239 239
No change  Duplicate Modules 16 16
No change  Duplicate Code 2.97% 2.97%
No change  Packages 4 4
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#8207
     Baseline
#8200
No change  JS 254.26KiB 254.26KiB
No change  Other 95.85KiB 95.85KiB
No change  CSS 35.1KiB 35.1KiB

Bundle analysis reportBranch PupilTong:p/hw/based-on-emulator...Project dashboard


Generated by RelativeCIDocumentationReport issue

@PupilTong PupilTong force-pushed the p/hw/based-on-emulator-testing branch from f9adc32 to 49d9236 Compare February 27, 2026 08:22
@PupilTong PupilTong force-pushed the p/hw/based-on-emulator-testing branch from 49d9236 to 5ad9602 Compare February 27, 2026 08:39
@PupilTong PupilTong force-pushed the p/hw/based-on-emulator-testing branch 4 times, most recently from c487be1 to c45cd6b Compare March 6, 2026 10:22
@PupilTong PupilTong force-pushed the p/hw/based-on-emulator-testing branch 12 times, most recently from 585c18c to cb21ae0 Compare March 12, 2026 09:04
@PupilTong PupilTong marked this pull request as ready for review March 12, 2026 09:50
…ttenLynx API usage and internal mechanics for agents.
…er for bundles, refining session matching logic, and adding resource cleanup.
…, update TypeScript module resolution to `Bundler`, and remove immediate `DOM.getDocument` call on session attach.
@PupilTong PupilTong force-pushed the p/hw/based-on-emulator-testing branch from c854154 to 1f6a24b Compare March 18, 2026 03:51
@PupilTong PupilTong merged commit 74603cb into lynx-family:main Mar 18, 2026
81 of 83 checks passed
colinaaa pushed a commit that referenced this pull request Mar 24, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @lynx-js/react@0.117.0

### Minor Changes

- feat: export `GlobalPropsProvider`, `GlobalPropsConsumer`,
`useGlobalProps` and `useGlobalPropsChanged` for `__globalProps`
([#2346](#2346))

- `GlobalPropsProvider`: A Provider component that accepts `children`.
It is used to provide the `lynx.__globalProps` context.
- `GlobalPropsConsumer`: A Consumer component that accepts a function as
a child. It is used to consume the `lynx.__globalProps` context.
- `useGlobalProps`: A hook that returns the `lynx.__globalProps` object.
It triggers a re-render when `lynx.__globalProps` changes.
- `useGlobalPropsChanged`: A hook that accepts a callback function. The
callback is invoked when `lynx.__globalProps` changes.

Note: When `globalPropsMode` is not set to `'event'` (default is
`'reactive'`), these APIs will be ineffective (pass-through) and will
log a warning in development mode, as updates are triggered
automatically by full re-render.

- **BREAKING CHANGE**:
([#2319](#2319))

Change preact package from `@hongzhiyuan/preact` to
`@lynx-js/internal-preact`.

Upgrade preact from
[f7693b72](preactjs/preact@f7693b7)
to
[55254ef7](preactjs/preact@55254ef),
see diffs at
[f7693b72...55254ef7](https://github.com/preactjs/preact/compare/f7693b72ecb4a40c66e6e47f54e2d4edc374c9f0...preactjs:preact:55254ef7021e563cc1a86fb816058964a1b6a29a?expand=1).

- feat: add `globalPropsMode` option to `PluginReactLynxOptions`
([#2346](#2346))

- When configured to `"event"`, `updateGlobalProps` will only trigger a
global event and skip the `runWithForce` flow.
- Defaults to `"reactive"`, which means `updateGlobalProps` will trigger
re-render automatically.

### Patch Changes

- Add `__BACKGROUND__` guard on `onBackgroundSnapshotInstanceUpdateId`
event to prevent bundling to main-thread on dev environment.
([#2332](#2332))

- refactor: extract static string in template literal
([#2334](#2334))

- fix: avoid crash when spread undefined ref
([#2333](#2333))

- Avoid registering lifecycle refs for main-thread functions (MTF) that
have not received an `execId` during `renderPage()` first-screen
binding. ([#2320](#2320))

## @lynx-js/react-umd@0.117.0

### Minor Changes

- Add standalone UMD build of the ReactLynx runtime.
([#2331](#2331))

## @lynx-js/react-rsbuild-plugin@0.13.0

### Minor Changes

- **BREAKING CHANGE**:
([#2319](#2319))

Change preact package from `@hongzhiyuan/preact` to
`@lynx-js/internal-preact`.

Upgrade preact from
[f7693b72](preactjs/preact@f7693b7)
to
[55254ef7](preactjs/preact@55254ef),
see diffs at
[f7693b72...55254ef7](https://github.com/preactjs/preact/compare/f7693b72ecb4a40c66e6e47f54e2d4edc374c9f0...preactjs:preact:55254ef7021e563cc1a86fb816058964a1b6a29a?expand=1).

- feat: add `globalPropsMode` option to `PluginReactLynxOptions`
([#2346](#2346))

- When configured to `"event"`, `updateGlobalProps` will only trigger a
global event and skip the `runWithForce` flow.
- Defaults to `"reactive"`, which means `updateGlobalProps` will trigger
re-render automatically.

### Patch Changes

- Updated dependencies
\[[`f1129ea`](f1129ea),
[`27f1cff`](27f1cff),
[`ed566f0`](ed566f0),
[`402ec2b`](402ec2b)]:
    -   @lynx-js/react-webpack-plugin@0.8.0
    -   @lynx-js/react-refresh-webpack-plugin@0.3.5
    -   @lynx-js/react-alias-rsbuild-plugin@0.13.0
    -   @lynx-js/use-sync-external-store@1.5.0
    -   @lynx-js/template-webpack-plugin@0.10.6
    -   @lynx-js/css-extract-webpack-plugin@0.7.0

## @lynx-js/react-webpack-plugin@0.8.0

### Minor Changes

- feat: add `globalPropsMode` option to `PluginReactLynxOptions`
([#2346](#2346))

- When configured to `"event"`, `updateGlobalProps` will only trigger a
global event and skip the `runWithForce` flow.
- Defaults to `"reactive"`, which means `updateGlobalProps` will trigger
re-render automatically.

### Patch Changes

- Fix sourcemap misalignment when wrapping lazy bundle main-thread
chunks. ([#2361](#2361))

The lazy bundle IIFE wrapper is now injected in `processAssets` at
`PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE + 1` by walking chunk groups instead
of patching assets in `beforeEncode`.

- With `experimental_isLazyBundle: true`, the wrapper is applied to
lazy-bundle chunk groups.
- Without lazy bundle mode, the wrapper is applied to async main-thread
chunk groups generated by dynamic import.

Injecting the wrapper in this stage keeps the emitted JS stable after
optimization while still running before `DEV_TOOLING` sourcemap
finalization, so the generated `.js` and `.js.map` stay aligned.

- Set `__DEV__` and `__PROFILE__` to `true` on `NODE_ENV ===
'development'`.
([#2324](#2324))

## @lynx-js/rspeedy@0.13.6

### Patch Changes

- Rename Web Preview label to fix URL alignment
([#2355](#2355))

- Updated dependencies
\[[`799fda8`](799fda8)]:
    -   @lynx-js/cache-events-webpack-plugin@0.0.3
    -   @lynx-js/web-rsbuild-server-middleware@0.19.9

## @lynx-js/lynx-bundle-rslib-config@0.2.3

### Patch Changes

- Fix snapshot not found error when dev with external bundle
([#2316](#2316))

## @lynx-js/external-bundle-rsbuild-plugin@0.0.4

### Patch Changes

- Updated dependencies
\[[`ed566f0`](ed566f0)]:
    -   @lynx-js/externals-loading-webpack-plugin@0.0.5

## @lynx-js/kitten-lynx-test-infra@0.1.1

### Patch Changes

- feat: support page.screenshot()
([#2364](#2364))

- feat: initial commit
([#2272](#2272))

## @lynx-js/testing-environment@0.1.12

### Patch Changes

- Implement `__ElementAnimate` PAPI for web platform animation lifecycle
([#2329](#2329))

## @lynx-js/web-constants@0.19.9

### Patch Changes

- Implement `__ElementAnimate` PAPI for web platform animation lifecycle
([#2329](#2329))

-   Updated dependencies \[]:
    -   @lynx-js/web-worker-rpc@0.19.9

## @lynx-js/web-core@0.19.9

### Patch Changes

- Updated dependencies
\[[`2efecc2`](2efecc2)]:
    -   @lynx-js/web-constants@0.19.9
    -   @lynx-js/web-mainthread-apis@0.19.9
    -   @lynx-js/web-worker-runtime@0.19.9
    -   @lynx-js/web-worker-rpc@0.19.9

## @lynx-js/web-core-wasm@0.0.6

### Patch Changes

- reexports essential utils & types in @lynx-js/web-elements from
@lynx-js/web-core-wasm/client
([#2321](#2321))

-   Updated dependencies \[]:
    -   @lynx-js/web-worker-rpc@0.19.9

## @lynx-js/web-mainthread-apis@0.19.9

### Patch Changes

- Updated dependencies
\[[`2efecc2`](2efecc2)]:
    -   @lynx-js/web-constants@0.19.9

## @lynx-js/web-worker-runtime@0.19.9

### Patch Changes

- Updated dependencies
\[[`2efecc2`](2efecc2)]:
    -   @lynx-js/web-constants@0.19.9
    -   @lynx-js/web-mainthread-apis@0.19.9
    -   @lynx-js/web-worker-rpc@0.19.9

## @lynx-js/cache-events-webpack-plugin@0.0.3

### Patch Changes

- Cache `globalThis.loadDynamicComponent` in the cache events runtime
and add tests covering tt methods, performance events, and globalThis
replay behavior.
([#2343](#2343))

## @lynx-js/externals-loading-webpack-plugin@0.0.5

### Patch Changes

- Fix snapshot not found error when dev with external bundle
([#2316](#2316))

## @lynx-js/react-refresh-webpack-plugin@0.3.5

### Patch Changes

- Fix snapshot not found error when dev with external bundle
([#2316](#2316))

## @lynx-js/template-webpack-plugin@0.10.6

### Patch Changes

- Updated dependencies
\[[`d034dae`](d034dae)]:
    -   @lynx-js/web-core-wasm@0.0.6

## create-rspeedy@0.13.6



## @lynx-js/react-alias-rsbuild-plugin@0.13.0



## upgrade-rspeedy@0.13.6



## @lynx-js/web-core-server@0.19.9



## @lynx-js/web-rsbuild-server-middleware@0.19.9



## @lynx-js/web-worker-rpc@0.19.9

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants