# 📱 Appom
**The Modern Page Object Model Framework for Mobile Test Automation**
[](http://badge.fury.io/rb/appom)
[](https://github.com/hoangtaiki/appom/actions)
[](https://codecov.io/gh/hoangtaiki/appom)
[](https://www.ruby-lang.org/)
[](https://opensource.org/licenses/MIT)
[](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 🎉
login_page.login('[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 login(email, password)
self.email.set(email)
self.password.set(password)
login_btn.tap
end
end
3. Write Tests
RSpec.describe 'Login Flow' do
it 'logs user in successfully' do
login_page = LoginPage.new
login_page.login('[email protected]', 'password')
expect(HomePage.new).to
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
- Complete Documentation - Comprehensive guide with advanced features
- API Reference - Detailed API documentation
- Best Practices - Testing patterns and conventions
- Troubleshooting - Common issues and solutions
**Made with ❤️ by the mobile testing community**
[⬆ Back to top](#-appom)