pickle_parser 1.0.4 copy "pickle_parser: ^1.0.4" to clipboard
pickle_parser: ^1.0.4 copied to clipboard

A Flutter package for parsing pickle files and executing Cucumber steps in widget tests.

Pickle Parser #

A comprehensive Flutter package for parsing pickle/Gherkin files and executing Cucumber steps in widget tests. This package allows you to write human-readable test scenarios using Gherkin syntax and automatically execute them as Flutter widget tests.

πŸ“‹ Table of Contents #

πŸ” Overview #

The Pickle Parser package bridges the gap between business-readable Gherkin scenarios and Flutter widget tests. It automatically parses pickle/feature files and executes corresponding test actions, making it easier to maintain test scenarios and improve collaboration between developers and non-technical stakeholders.

✨ Features #

  • πŸ₯’ Full Gherkin Support: Parse and execute Given/When/Then steps
  • 🎯 Multiple Element Selectors: Find widgets by key, type, text, or icon
  • πŸ” Advanced Text Matching: Supports exact, contains, startsWith, endsWith, and regex patterns
  • πŸ’« Rich Interactions: Tap, long press, double tap, swipe, scroll, and keyboard input
  • ⌨️ Text Input: Support for various text field interactions
  • πŸ•’ Wait Strategies: Time-based waits and conditional waiting
  • πŸ“± Navigation Support: Back navigation and dialog dismissal
  • 🎨 Gesture Support: Swipe, scroll, refresh, and custom gestures
  • πŸ“– Clear Error Messages: Detailed logging and error reporting
  • πŸ› οΈ CLI Tools: Validate feature files and generate test skeletons

πŸ“¦ Installation #

Add pickle_parser to your pubspec.yaml file:

dev_dependencies:
  flutter_test:
    sdk: flutter
  pickle_parser: ^1.0.3

Then run:

flutter pub get

πŸ› οΈ CLI Tools #

The package includes powerful command-line tools for validating feature files and generating test skeletons, making it easier to maintain and debug your Gherkin scenarios.

Installation #

The CLI tools are included with the package. After installing pickle_parser, you can run them directly:

# Run from your project directory
dart run pickle_parser:cli --help

Or run the tool file directly:

# Navigate to the package location and run
dart tool/cli/bin/pickle_parser_cli.dart --help

CLI Commands #

Validate Feature Files

# Validate all feature files in default directory (assets/features)
dart run pickle_parser:cli --validate

# Validate with verbose output
dart run pickle_parser:cli --validate --verbose

# Validate specific directory
dart run pickle_parser:cli --validate --input assets/features

Generate Test Skeletons

# Generate test files from feature files
dart run pickle_parser:cli --generate

# Specify input and output directories
dart run pickle_parser:cli --generate --input assets/features --output test/integration

# Generate with verbose output
dart run pickle_parser:cli --generate --verbose

Combined Operations

# Validate and generate in one command
dart run pickle_parser:cli --validate --generate --verbose

# Full workflow with custom directories
dart run pickle_parser:cli --validate --generate --input assets/scenarios --output test/generated --verbose

CLI Features #

  • βœ… Feature File Validation: Checks syntax and supported step patterns
  • πŸ—οΈ Test Skeleton Generation: Creates ready-to-use test files
  • πŸ“Š Detailed Reporting: Shows validation results and statistics
  • 🎯 Smart Error Detection: Identifies unsupported steps and syntax issues
  • πŸ“ Batch Processing: Handles multiple feature files at once
  • πŸ” Step Pattern Recognition: Validates against all supported Gherkin patterns
  • πŸ“‹ Summary Statistics: Reports total files, steps, and validation status

CLI Usage Examples #

Basic Validation

$ dart run pickle_parser:cli --validate
πŸ” Validating feature files in: assets/features
πŸ“ Found 3 feature file(s)
πŸ“Š Validation Summary:
  βœ… Valid files: 3/3
  πŸ“‹ Total steps: 45
  πŸŽ‰ All feature files are valid!

Validation with Errors

$ dart run pickle_parser:cli --validate --verbose
πŸ” Validating feature files in: assets/features
πŸ“ Found 2 feature file(s)

πŸ“„ Validating: login.feature
  βœ… Valid (12 steps)

πŸ“„ Validating: checkout.feature
  ❌ Invalid:
    - Line 15: Unsupported step - "I click the mysterious button"
    - Line 23: Missing Feature declaration

πŸ“Š Validation Summary:
  βœ… Valid files: 1/2
  πŸ“‹ Total steps: 12
  ❌ Errors found: 2

Test Generation

$ dart run pickle_parser:cli --generate --verbose
πŸ—οΈ Generating test skeletons from: assets/features to: test/generated
πŸ“ Created output directory: test/generated
  βœ… Generated: login_test.dart
  βœ… Generated: checkout_test.dart

πŸ“Š Generation Summary:
  βœ… Generated 2 test file(s)
  πŸ“ Output directory: test/generated

πŸ’‘ Next steps:
  1. Review generated test files
  2. Add imports for your app widgets
  3. Customize the test setup as needed
  4. Run: flutter test test/generated

## πŸ”— Dependencies

### Required Dependencies

- **Flutter SDK**: `>=2.19.5 <4.0.0`
- **flutter**: Core Flutter framework
- **flutter_test**: Flutter testing framework

### What's Included

The package automatically provides:

- Gherkin step parsing and execution
- Widget finding capabilities
- Gesture simulation
- Text input handling
- Wait and timing utilities

### Asset Configuration

To use pickle files, add them to your `pubspec.yaml`:

```yaml
flutter:
  assets:
    - assets/features/
    - test/features/

πŸš€ Quick Start #

1. Create a Feature File #

Create a .feature file in your assets folder:

# assets/features/login.feature
Feature: User Login

  Scenario: Successful login
    When I see Welcome to MyApp
    When I enter john@example.com in field with key:email_field
    When I enter password123 in field with key:password_field
    When I tap key:login_button
    Then I see Dashboard
    Then I do not see Login Failed

2. Create a Test File #

// test/login_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:pickle_parser/pickle_parser.dart';
import 'package:myapp/main.dart'; // Your app

void main() {
  testWidgets('Login flow from pickle file', (WidgetTester tester) async {
    // Build your app
    await tester.pumpWidget(MyApp());

    // Execute the pickle file
    await pickleParser(tester, 'assets/features/login.feature');
  });
}

πŸ“ Supported Gherkin Syntax #

Keywords #

  • Given - Setup steps (currently treated as When steps)
  • When - Action steps
  • Then - Assertion steps
  • # - Comments (ignored)

Step Structure #

When I [action] [element]
Then I [assertion] [element]

🎯 Element Selectors #

The package supports multiple ways to find widgets:

1. By Key #

When I tap key:submit_button
Then I see key:success_message

2. By Widget Type #

When I tap type:ElevatedButton
Then I see type:Text

Supported Widget Types:

  • Text, TextField, TextFormField
  • ElevatedButton, TextButton, OutlinedButton
  • Container, Column, Row, Expanded
  • AppBar, Scaffold, Material
  • Icon, IconButton, FloatingActionButton
  • ListView, GridView, Card
  • Checkbox, Switch, Slider, Radio
  • DropdownButton, AlertDialog, SnackBar
  • Drawer, BottomSheet, Tab, TabBar
  • NavigationBar, BottomNavigationBar
  • RefreshIndicator, CupertinoNavigationBar

3. By Text Content #

# Exact match (default)
When I tap Submit
Then I see Welcome!

# Enhanced text matching
When I tap contains:Submit
Then I see startsWith:Welcome
When I see endsWith:Message
Then I see regex:^Error.*occurred$

Text Selector Formats:

  • text:exact - Exact text match (explicit)
  • contains:partial - Text contains substring
  • startsWith:prefix - Text starts with prefix
  • endsWith:suffix - Text ends with suffix
  • regex:pattern - Text matches regex pattern

4. By Icon #

When I tap icon:add
Then I see icon:check

Supported Icons:

  • add, delete, close, menu

πŸ“š Complete Step Reference #

πŸ‘οΈ Visibility Assertions #

Positive Assertions

# Check if element is visible
When I see [element]
Then I see [element]
When I can see [element]  # Alternative syntax

# Examples
When I see Login Button
Then I see key:welcome_message
When I can see type:AppBar

Negative Assertions

# Check if element is NOT visible
When I do not see [element]
When I don't see [element]
Then I do not see [element]
Then I don't see [element]

# Examples
Then I do not see Error Message
When I don't see key:loading_spinner

πŸ–±οΈ Touch Interactions #

Basic Tap

When I tap [element]

# Examples
When I tap Submit
When I tap key:login_button
When I tap type:ElevatedButton
When I tap icon:add

Long Press

When I long press [element]

# Examples
When I long press Delete Item
When I long press key:context_menu
When I long press type:ListTile

Double Tap

When I double tap [element]

# Examples
When I double tap Favorite
When I double tap key:heart_icon
When I double tap type:Image

⌨️ Text Input #

Enter Text (Multiple Formats)

# Format 1: With field specification
When I enter [text] in field with key:[key]
When I enter [text] in field with type:[type]

# Format 2: Into element
When I enter [text] into [element]

# Examples
When I enter hello@example.com in field with key:email_field
When I enter password123 in field with type:TextField
When I enter Search term into key:search_box
When I enter John Doe into type:TextFormField

Clear Field

When I clear field [element]

# Examples
When I clear field key:username
When I clear field type:TextField

Field Content Validation

When field [element] contains [text]
Then field [element] contains [text]

# Examples
Then field key:email_field contains john@example.com
When field type:TextField contains Expected Text

🎯 Gesture Interactions #

Swipe

# Screen swipe
When I swipe [direction]

# Element-specific swipe
When I swipe [direction] on [element]

# Directions: left, right, up, down
# Examples
When I swipe left
When I swipe right on key:card_widget
When I swipe up on type:ListView

Scroll

# Basic scroll
When I scroll [direction]

# Scroll until element is visible
When I scroll until I see [element]

# Examples
When I scroll up
When I scroll down
When I scroll until I see Load More
When I scroll until I see key:bottom_item

Pull to Refresh

When I refresh

# Example
When I refresh
Then I see Updated Content

⏱️ Wait and Timing #

Time-based Wait

When I wait for [seconds]

# Examples
When I wait for 2
When I wait for 5

Conditional Wait

When I wait until I see [element]

# Examples
When I wait until I see Loading Complete
When I wait until I see key:success_dialog
When I wait until I see type:SnackBar

Manual Pump

When I pump [count]

# Examples
When I pump 1
When I pump 5

Settle Animation

When I settle
Then I settle

# Wait for all animations to complete
When I settle

⌨️ Keyboard Interactions #

Key Press

When I press [key]
When I trigger [key]  # Alternative for enter

# Supported keys: enter, escape, space, tab, backspace
# Examples
When I press enter
When I press escape
When I trigger enter  # Same as pressing enter

🧭 Navigation #

Back Navigation

When I navigate back
When I go back

# Examples
When I navigate back
Then I see Previous Screen

Dismiss Dialogs/Overlays

When I dismiss [element]

# Auto-detects common dismiss buttons: Dismiss, Close, OK
# Examples
When I dismiss dialog
When I dismiss key:popup_menu
When I dismiss type:AlertDialog

πŸ’‘ Usage Examples #

Complete Login Flow #

Feature: User Authentication

  Scenario: Successful login and navigation
    # Setup
    Given I am on the login screen

    # Input credentials
    When I enter test@example.com in field with key:email_input
    When I enter secretpass in field with key:password_input

    # Submit form
    When I tap key:login_submit
    When I settle

    # Verify success
    Then I see Welcome back!
    Then I do not see Invalid credentials
    Then I see type:BottomNavigationBar

    # Navigate to profile
    When I tap Profile
    Then I see My Profile
Feature: Product Search

  Scenario: Search and filter products
    # Search for products
    When I tap key:search_field
    When I enter smartphone into key:search_field
    When I press enter
    When I settle

    # Verify results
    Then I see Search Results
    Then I see type:ListView

    # Apply filters
    When I tap Filters
    When I tap Price: Low to High
    When I tap Apply
    When I settle

    # Verify filtered results
    Then I see Sorted Results
    Then I do not see No results found

Enhanced Text Matching #

Feature: Advanced Text Matching

  Scenario: Using flexible text selectors
    # Exact match (default behavior)
    When I see Login Button

    # Partial text matching
    When I tap contains:Submit
    Then I see contains:Success

    # Prefix matching
    When I see startsWith:Welcome

    # Suffix matching
    Then I see endsWith:completed

    # Regex pattern matching
    When I see regex:^Error.*occurred$
    Then I see regex:\d+ items? found

    # Explicit exact match
    When I tap text:Exact Button Text

Form Validation #

Feature: Contact Form

  Scenario: Form validation and submission
    # Fill form with invalid data
    When I enter invalid-email in field with key:email_field
    When I enter x in field with key:name_field
    When I tap Submit

    # Check validation errors
    Then I see Please enter a valid email
    Then I see Name must be at least 2 characters

    # Fix errors
    When I clear field key:email_field
    When I enter valid@email.com in field with key:email_field
    When I clear field key:name_field
    When I enter John Doe in field with key:name_field

    # Submit successfully
    When I tap Submit
    When I settle
    Then I see Thank you for your message
    Then I do not see Please enter a valid email

⚠️ Limitations #

Current Limitations #

  1. Limited Icon Support: Only supports add, delete, close, menu icons
  2. Single Element Finding: Steps target the first matching element
  3. No Parameter Substitution: Variables/parameters not supported in steps
  4. Asset Loading Only: Feature files must be in app assets (not external files)
  5. No Custom Steps: Cannot define custom step implementations
  6. Flutter Dependencies: Requires Flutter test environment

Widget Support Limitations #

  • Custom widgets require key: or type: selectors
  • Complex widget hierarchies may need specific targeting
  • Some widget states (disabled, loading) not explicitly supported

Timing Limitations #

  • Fixed timeout durations (30 seconds for pumpUntilFound)
  • No dynamic timeout configuration
  • Animation timing depends on Flutter's pumpAndSettle

βœ… Improvements Made #

  • βœ… Enhanced Text Matching: Added support for contains, startsWith, endsWith, and regex patterns
  • βœ… CLI Validation: Feature files can now be validated before testing
  • βœ… Test Generation: Automatic test skeleton generation from feature files
  • βœ… Better Error Messages: More specific error reporting and validation

πŸ“‹ Best Practices #

1. Widget Keys #

Always add keys to important widgets for reliable targeting:

ElevatedButton(
  key: Key('submit_button'),
  onPressed: () => {},
  child: Text('Submit'),
)

2. Descriptive Step Names #

Use clear, descriptive step names:

# Good
When I tap key:submit_order_button
Then I see Order confirmation message

# Avoid
When I tap button
Then I see text

3. Wait Strategies #

Use appropriate wait strategies:

# For loading states
When I wait until I see type:CircularProgressIndicator
When I wait until I see Content loaded

# For animations
When I settle

# For time-based operations
When I wait for 3

4. Error Scenarios #

Test both positive and negative scenarios:

Scenario: Invalid login
  When I enter wrong@email.com in field with key:email
  When I enter wrongpass in field with key:password
  When I tap key:login_button
  Then I see Invalid credentials
  Then I do not see Dashboard

5. Organize Feature Files #

Structure your feature files logically:

assets/features/
β”œβ”€β”€ authentication/
β”‚   β”œβ”€β”€ login.feature
β”‚   β”œβ”€β”€ signup.feature
β”‚   └── password_reset.feature
β”œβ”€β”€ shopping/
β”‚   β”œβ”€β”€ product_search.feature
β”‚   β”œβ”€β”€ cart.feature
β”‚   └── checkout.feature
└── profile/
    β”œβ”€β”€ edit_profile.feature
    └── settings.feature

πŸ› Troubleshooting #

Common Issues #

Element Not Found

Error: No widget found with key:my_button

Solutions:

  • Verify the key exists in your widget
  • Use When I wait until I see key:my_button before interaction
  • Check if widget is in a different screen/state

Timeout Errors

Error: Pump until has timed out

Solutions:

  • Increase wait time: When I wait for 5
  • Use When I settle for animations
  • Check if element actually appears

Text Input Issues

Error: Unable to enter text in field

Solutions:

  • Ensure field is focusable and enabled
  • Use correct selector (key vs type)
  • Clear field before entering new text

Step Not Recognized

Error: Unsupported text: my custom step

Solutions:

  • Check step syntax against documentation
  • Verify spelling and formatting
  • Use supported step patterns only
  • Run dart run pickle_parser:cli --validate to check feature files

Enhanced Text Selector Issues

Error: No widget found with contains:partial text

Solutions:

  • Verify the text actually contains the substring
  • Use exact text matching if partial matching fails
  • Check for case sensitivity in text matching
  • Try different selector types (startsWith, endsWith, regex)

Debugging Tips #

  1. Add Logging Steps:
When I settle
# Add debugging visibility checks
Then I see expected_element
  1. Use Type Selectors for Generic Widgets:
# Instead of relying on text that might change
When I tap type:ElevatedButton
  1. Break Down Complex Scenarios:
# Split complex interactions
When I tap Settings
When I settle
When I tap Profile
When I settle
Then I see Profile Settings
  1. Use Enhanced Text Matching:
# Instead of relying on exact text that might change
When I tap contains:Submit
Then I see startsWith:Success
  1. Use CLI Validation:
# Validate your feature files before running tests
dart run pickle_parser:cli --validate --verbose

# Generate skeleton tests to verify structure
dart run pickle_parser:cli --generate --input assets/features --output test/validation

🀝 Contributing #

We welcome contributions! If you encounter issues or have suggestions:

  1. Issues: Create an issue on the GitHub repository
  2. Pull Requests: Submit PRs for bug fixes or new features
  3. Feature Requests: Suggest new Gherkin step patterns or widget support

Development Setup #

# Clone the repository
git clone https://github.com/robrob-creator/pickle_parser.git

# Install dependencies
flutter pub get

# Run tests
flutter test

β˜• Support This Project #

If you find this package helpful and want to support its development, consider buying me a coffee! Your support helps maintain and improve this open-source project.

Buy Me A Coffee

πŸ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details.


Need help? Check the example directory for complete working examples or create an issue on GitHub.

2
likes
0
points
11
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter package for parsing pickle files and executing Cucumber steps in widget tests.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

args, flutter, flutter_test, path

More

Packages that depend on pickle_parser