# 📱 Appom **The Modern Page Object Model Framework for Mobile Test Automation** [![Gem Version](https://badge.fury.io/rb/appom.svg)](http://badge.fury.io/rb/appom) [![Build Status](https://github.com/hoangtaiki/appom/workflows/CI/badge.svg)](https://github.com/hoangtaiki/appom/actions) [![Coverage](https://codecov.io/gh/hoangtaiki/appom/branch/master/graph/badge.svg)](https://codecov.io/gh/hoangtaiki/appom) [![Ruby Version](https://img.shields.io/badge/Ruby-3.2.2-red)](https://www.ruby-lang.org/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Downloads](https://img.shields.io/gem/dt/appom.svg)](https://rubygems.org/gems/appom) *Write mobile tests that are maintainable, readable, and reliable* [Quick Start](#-quick-start) • [Documentation](Documentation.md) • [Examples](#-examples) • [Contributing](#-contributing)

✨ Why Appom?

Tired of flaky mobile tests that break every release? Appom transforms mobile test automation with:

# Traditional approach 😢
driver.find_element(:id, 'login_btn').click
sleep(2) # Hope the page loads...
driver.find_element(:xpath, '//input[@type="email"]').send_keys('[email protected]')

# Appom way 🎉
.('[email protected]', 'password')
expect(home_page).to have_dashboard

🚀 Key Features

🎯 Smart Page Objects Semantic DSL that reads like natural language
🔄 Intelligent Retry Auto-retry with exponential backoff for flaky elements
📊 Performance Monitoring Track test performance and identify bottlenecks
🎨 Visual Testing Automated visual regression testing built-in
🛡️ Robust Error Handling Detailed diagnostics with screenshots and context
📱 Cross-Platform Single codebase for iOS and Android

📦 Installation

gem install appom

Or add to your Gemfile:

gem 'appom'

⚡ Quick Start

1. Initialize Appom

require 'appom'

Appom.register_driver do
  Appium::Driver.new({
    caps: {
      platformName: 'iOS',
      deviceName: 'iPhone 15',
      app: '/path/to/your/app.ipa'
    },
    appium_lib: { server_url: 'http://localhost:4723/wd/hub' }
  })
end

2. Create Page Objects

class LoginPage < Appom::Page
  element :email, :accessibility_id, 'email_field'
  element :password, :accessibility_id, 'password_field'
  element :login_btn, :accessibility_id, 'login_button'

  def (email, password)
    self.email.set(email)
    self.password.set(password)
    .tap
  end
end

3. Write Tests

RSpec.describe 'Login Flow' do
  it 'logs user in successfully' do
     = LoginPage.new
    .('[email protected]', 'password')

    expect(HomePage.new).to have_welcome_message
  end
end

That's it! No more sleep(), no more flaky selectors, no more mysterious failures.

🎯 Examples

Advanced Page Object with Sections ```ruby class ShoppingPage < Appom::Page section :header, HeaderSection, :id, 'header' sections :products, ProductSection, :class, 'product-card' def add_product_to_cart(product_name) product = products.find { |p| p.name.text == product_name } product.add_to_cart wait_for_cart_update end end class ProductSection < Appom::Section element :name, :class, 'product-name' element :price, :class, 'product-price' element :add_btn, :class, 'add-to-cart-btn' def add_to_cart scroll_to_and_tap(:add_btn) end end ```
Smart Waiting & Retry Logic ```ruby class PaymentPage < Appom::Page element :card_field, :id, 'card_number' element :submit_btn, :id, 'submit_payment' def process_payment(card_number) # Auto-retry for flaky elements interact_with_retry(:card_field, :send_keys, text: card_number) # Wait for specific conditions tap_and_wait(:submit_btn) wait_for_any(:success_message, :error_message, timeout: 30) end end ```
Visual Testing Integration ```ruby class ProductPage < Appom::Page def verify_product_display # Automatic visual regression testing take_visual_snapshot('product_page') compare_visual_baseline('product_page', threshold: 0.95) end end ```

📚 Documentation


**Made with ❤️ by the mobile testing community** [⬆ Back to top](#-appom)