Updated

Published

Jevis is a Flutter integration-test agent that only taps what you registered

Jake Gwon released jevis, a Dart package that drives Flutter's integration_test loop with Jev. You register legal actions, write a goal, and set an action budget. Jev picks the next widget action and a Noul checks whether the goal is already on screen.

Jake Gwon posted jevis on September 19. The Dart package is at jaewgwon/jevis and on pub.dev. He is an Android and Flutter engineer at Cybozu.

The loop is Flutter’s integration_test harness, not a desktop accessibility tree and not a browser. You construct a JevisTester with the actions the test is allowed to use, then call test() with a goal, an optional instruction, and an attempts cap.

final agent = JevisTester(
  tester: tester,
  actions: [
    JevisActions.tap(),
    JevisActions.enterText(values: ['Buy milk']),
    JevisActions.scroll(),
    JevisActions.back(),
  ],
);

await agent.test(
  goal: 'A Buy milk todo is completed.',
  instruction: 'Add Buy milk, then mark it complete.',
  attempts: 20,
);

The actions list is a capability set, not a script. Each step observes the current screen, asks a Noul whether the goal is already true, and only then asks a Choice for the next action. The Noul sees {goal, screen}. The Choice sees {actionInstruction, previousActions, screen} and the candidate list. A failed Noul does not lead to a tap.

Typed strings have to be supplied through values or value. Jevis does not invent input. More than 254 available candidates fails on purpose. attempts: 20 means at most 20 widget actions, so creating ten items through open, type, save needs at least 30.

Default goalThreshold is 0.95. The README is blunt: that is a probabilistic model judgment, not a deterministic guarantee. Hidden state and server effects cannot be proved from UI text. Pass a verify callback if you need an assertion after the model says it is done.

The observer reads hit-testable standard Flutter controls: buttons, lists, inputs, Material sliders, dropdowns, some gestures. It does not interpret screenshots, custom canvas, WebViews, or OS permission dialogs. Passwords in the UI stay out of the default collection; ordinary labels still go to the API, so the docs tell you to use test accounts.

The bundled Widget Catalog tests call the real Jev API. flutter test from the package root is mock-backed and does not measure live accuracy. We did not run either suite.

This site's reading

Editorial notes evaluating claims against primary sources, contextualizing findings alongside related implementations, and defining technical terms.

Verify

The September 19 post links the GitHub repository and the pub.dev listing. The README describes JevisTester on Flutter's integration_test framework: register actions (tap, enterText with a supplied values list, scroll, back, and others), then call test() with a goal, an optional instruction, and an attempts budget. Each step is observe, Noul (is the goal already true on this screen), Choice of the next action if not. Input strings must come from values or value; the package does not generate free text. More than 254 candidates fails explicitly. Default goalThreshold is 0.95; bundled catalog tests use 0.6. Completion is a model judgment unless you pass verify. The observer reads hit-testable standard Flutter controls, not screenshots, WebViews, or custom canvas. Local mock tests do not establish live accuracy. We did not run the package against a device.

Compare

Browser Use and Stagehand rank page elements. Jev macOS Loop ranks native window controls after local perception; pixels stay on the Mac. Jevis is the same legal-set pattern inside Flutter's test harness, with a hard rule that typed strings are supplied by the test author. Tetris ranks landings. JevPilot ranks sampled steering paths. None of those are mobile integration tests. The announcement had no published pass rate on a named app.

Terms

Jevis
A Dart package that runs on Flutter integration_test, sends the current screen and a registered action list to Jev, and executes the chosen widget action.
Action budget
The attempts argument on test(). It is a cap on UI actions executed, not on scenario restarts. Goal evaluation also runs before the first action and after the last allowed action.
Model completion
A Noul on the current screen clearing goalThreshold. Reports mark this completionBasis as model unless a verify callback also passes, in which case it is model+assertion.

Sources

  1. Jake Gwon, jevis announcement
  2. jaewgwon/jevis
  3. jevis on pub.dev