본문으로 건너뛰기
cccskills
무료GitHub에 공개

patrol-e2e-testing

Use when writing E2E/integration tests, testing native interactions like permissions or system dialogs, capturing UI regressions, or validating cross-platform behavior (Patrol 4.x).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md5.5 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Patrol E2E Testing Skill

Design, implement, and run end-to-end (E2E) tests using Patrol 4.x in Flutter projects.

When to Use

Use this skill when:

  • A new screen or user flow needs E2E test coverage.
  • A feature interacts with native components (permissions, notifications, system dialogs, deep links).
  • A UI bug should be captured as a regression test.
  • Cross-platform behavior (Android / iOS / Web) must be validated.
  • Setting up Patrol in a new or existing Flutter project.

Setup

Follow the official Patrol documentation for installation and project initialization: https://patrol.leancode.co/documentation#setup

Key Patrol conventions:

  • Add patrol as a dev dependency.
  • Place tests in patrol_test/.
  • Name test files with a _test.dart suffix.
  • Execute tests with patrol test.

Workflow

Follow these steps when implementing or updating Patrol tests.

1. Identify the user journey

Break the feature into:

  • Actions: taps, scrolls, input, navigation, deep links.
  • Observable outcomes: visible text, screen changes, enabled buttons, dialogs.

Rules:

  • One test per primary (happy-path) journey.
  • Separate tests for critical edge cases.
  • Avoid combining unrelated flows in a single test.

2. Structure the Patrol test

Basic Patrol structure:

import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';

void main() {
  patrolTest(
    'user can log in successfully',
    ($) async {
      await $.pumpWidgetAndSettle(const MyApp());

      const email = String.fromEnvironment('E2E_EMAIL');
      const password = String.fromEnvironment('E2E_PASSWORD');

      await $(#emailField).enterText(email);
      await $(#passwordField).enterText(password);
      await $(#loginButton).tap();

      await $.waitUntilVisible($(#homeScreenTitle));

      expect($(#homeScreenTitle).text, equals('Welcome'));
    },
  );
}

Key concepts:

  • Use patrolTest() instead of testWidgets().
  • $ is the Patrol tester.
  • Use $(#keyName) to find widgets by Key.
  • Use explicit wait conditions (e.g., waitUntilVisible).

3. Handle native dialogs

For OS-level permission dialogs:

patrolTest('grants camera permission', ($) async {
  await $.pumpWidgetAndSettle(const MyApp());

  await $(#openCameraButton).tap();

  if (await $.native.isPermissionDialogVisible()) {
    await $.native.grantPermission();
  }

  await $.waitUntilVisible($(#cameraPreview));
});

Use native automation only when required by the feature.

4. Selector & interaction quick reference

Finding widgets:

$('some text')        // by text
$(TextField)          // by type
$(Icons.arrow_back)   // by icon

Tapping:

// Tap a widget containing a specific text label
await $(Container).$('click').tap();

// Tap a container that contains an ElevatedButton
await $(Container).containing(ElevatedButton).tap();

// Tap only the enabled ElevatedButton
await $(ElevatedButton)
    .which<ElevatedButton>(
      (b) => b.enabled,
    )
    .tap();

Entering text:

// Enter text into the second TextField on screen
await $(TextField).at(1).enterText('your input');

Scrolling:

await $(widget_you_want_to_scroll_to).scrollTo();

Native interactions:

// Grant permission while app is in use
await $.native.grantPermissionWhenInUse();

// Open notification shade and tap a notification by text
await $.native.openNotifications();
await $.native.tapOnNotificationBySelector(
  Selector(textContains: 'text'),
);

5. Running Patrol tests

Run all tests:

patrol test

Run a specific file with live reload (development mode):

patrol develop -t integration_test/my_test.dart

Run a specific file:

patrol test --target patrol_test/login_test.dart

Run on web:

patrol test --device chrome

Headless web (CI):

patrol test --device chrome --web-headless true

Filter by tags:

patrol test --tags android

6. Stabilization patterns

Flaky tests undermine confidence. Apply these patterns:

// AVOID — arbitrary delay
await Future.delayed(Duration(seconds: 3));

// PREFER — explicit wait condition
await $.waitUntilVisible($(#targetWidget));

// For animations, pump until settled
await $.pumpAndSettle();
  • Never use Future.delayed as a synchronization mechanism.
  • Use waitUntilVisible or waitUntilExists to wait for UI state.
  • Set settleTimeout in PatrolTesterConfig for slow CI environments.

Output requirements

When applied, this skill produces:

  1. Patrol test(s) covering the specified feature.
  2. Any required widget Key additions to production code.
  3. Exact patrol test command(s) to execute locally.
  4. Notes explaining stabilization or timing decisions.

Checkpoint: Run patrol test --target <file> locally to confirm the test passes before committing.

Quality bar

A valid Patrol test must be:

  • Deterministic — no arbitrary delays; uses explicit wait conditions.
  • Readable — clear test name describing the user journey.
  • Minimal but complete — one assertion chain per journey.
  • Secret-safe — credentials loaded from String.fromEnvironment, never hardcoded.
  • CI-ready — passes headless with --web-headless true or on emulator.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Use when working on accessibility, a11y, WCAG, ARIA, screen readers, keyboard nav, focus order, contrast, alt text, captions, reduced motion, or target sizes; not language/culture/device (see inclusive-design).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

evanca/flutter-ai-rules6532026년 10월 10일 업데이트

Use when creating a feature, designing folder structure, adding repositories/services/view models, wiring dependency injection, or deciding which layer owns logic.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

evanca/flutter-ai-rules6532026년 10월 10일 업데이트

bloc

무료

Use when creating a Cubit or Bloc, modeling state with sealed classes or status enums, wiring BlocBuilder/BlocListener/BlocProvider, writing bloc tests, or choosing between Cubit and Bloc.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

evanca/flutter-ai-rules6532026년 10월 10일 업데이트

Use when asked to review a PR, MR, branch, or diff, audit changed files, or check code quality.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

evanca/flutter-ai-rules6532026년 10월 10일 업데이트

Use when writing switch statements, refactoring if-else chains, creating data classes, choosing records vs classes, destructuring values, or modernizing pre-Dart-3 code.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

evanca/flutter-ai-rules6532026년 10월 10일 업데이트

Use when building AI agents in Dart, implementing Genkit flows or tools, integrating LLMs into Dart or Flutter applications, or using Genkit Dart plugins.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

evanca/flutter-ai-rules6532026년 10월 10일 업데이트

evanca의 스킬 모두 보기

이 스킬의 문제 신고