appom 1.4.0 β 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +170 -42
- data/lib/appom/configuration.rb +490 -0
- data/lib/appom/element_cache.rb +372 -0
- data/lib/appom/element_container.rb +257 -244
- data/lib/appom/element_finder.rb +142 -138
- data/lib/appom/element_state.rb +458 -0
- data/lib/appom/element_validation.rb +138 -0
- data/lib/appom/exceptions.rb +130 -0
- data/lib/appom/helpers.rb +328 -0
- data/lib/appom/logging.rb +106 -0
- data/lib/appom/page.rb +19 -10
- data/lib/appom/performance.rb +394 -0
- data/lib/appom/retry.rb +178 -0
- data/lib/appom/screenshot.rb +371 -0
- data/lib/appom/section.rb +24 -21
- data/lib/appom/smart_wait.rb +455 -0
- data/lib/appom/version.rb +4 -1
- data/lib/appom/visual.rb +600 -0
- data/lib/appom/wait.rb +96 -35
- data/lib/appom.rb +191 -20
- metadata +35 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 956c68b448dee7fd7611256fe182aa80a75a8b9f28c30a09c9b83dee021c53dd
|
|
4
|
+
data.tar.gz: 979e09f836332c000a83804062f9df27599df7539e10e11b615de5647b44ac47
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f7ab4bd8d0501a5022ef64261dd02422b9f73ab3c56195188c83fe14b847071fc201155474063442e5369c96b2e95c498b972d2c911ac5e1009174717645016d
|
|
7
|
+
data.tar.gz: 98d760be575c99b151d2b730d01d5c862d8b8238af4fb3204e7ded4e6b6c850e01e181a2f4e59f3cab106bc011f89d7df8ad92a1ee2d70c37823b327517c8250
|
data/README.md
CHANGED
|
@@ -1,81 +1,209 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# π± Appom
|
|
4
|
+
|
|
5
|
+
**The Modern Page Object Model Framework for Mobile Test Automation**
|
|
6
|
+
|
|
2
7
|
[](http://badge.fury.io/rb/appom)
|
|
8
|
+
[](https://github.com/hoangtaiki/appom/actions)
|
|
9
|
+
[](https://codecov.io/gh/hoangtaiki/appom)
|
|
10
|
+
[](https://www.ruby-lang.org/)
|
|
11
|
+
[](https://opensource.org/licenses/MIT)
|
|
12
|
+
[](https://rubygems.org/gems/appom)
|
|
13
|
+
|
|
14
|
+
*Write mobile tests that are maintainable, readable, and reliable*
|
|
3
15
|
|
|
4
|
-
|
|
16
|
+
[Quick Start](#-quick-start) β’ [Documentation](Documentation.md) β’ [Examples](#-examples) β’ [Contributing](#-contributing)
|
|
5
17
|
|
|
6
|
-
|
|
18
|
+
</div>
|
|
7
19
|
|
|
8
|
-
|
|
9
|
-
If you have used the [Page Object Model](https://medium.com/tech-tajawal/page-object-model-pom-design-pattern-f9588630800b) (POM) with Appium you will probably know about [Capybara](https://github.com/teamcapybara/capybara) and [SitePrism](https://github.com/natritmeyer/site_prism). But CapyBara and SitePrism are designed for the web rather than the mobile.
|
|
20
|
+
---
|
|
10
21
|
|
|
11
|
-
|
|
22
|
+
## β¨ Why Appom?
|
|
12
23
|
|
|
13
|
-
|
|
24
|
+
Tired of flaky mobile tests that break every release? **Appom** transforms mobile test automation with:
|
|
14
25
|
|
|
15
|
-
|
|
26
|
+
```ruby
|
|
27
|
+
# Traditional approach π’
|
|
28
|
+
driver.find_element(:id, 'login_btn').click
|
|
29
|
+
sleep(2) # Hope the page loads...
|
|
30
|
+
driver.find_element(:xpath, '//input[@type="email"]').send_keys('user@test.com')
|
|
31
|
+
|
|
32
|
+
# Appom way π
|
|
33
|
+
login_page.login('user@test.com', 'password')
|
|
34
|
+
expect(home_page).to have_dashboard
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## π Key Features
|
|
38
|
+
|
|
39
|
+
<table>
|
|
40
|
+
<tr>
|
|
41
|
+
<td>π― <strong>Smart Page Objects</strong></td>
|
|
42
|
+
<td>Semantic DSL that reads like natural language</td>
|
|
43
|
+
</tr>
|
|
44
|
+
<tr>
|
|
45
|
+
<td>π <strong>Intelligent Retry</strong></td>
|
|
46
|
+
<td>Auto-retry with exponential backoff for flaky elements</td>
|
|
47
|
+
</tr>
|
|
48
|
+
<tr>
|
|
49
|
+
<td>π <strong>Performance Monitoring</strong></td>
|
|
50
|
+
<td>Track test performance and identify bottlenecks</td>
|
|
51
|
+
</tr>
|
|
52
|
+
<tr>
|
|
53
|
+
<td>π¨ <strong>Visual Testing</strong></td>
|
|
54
|
+
<td>Automated visual regression testing built-in</td>
|
|
55
|
+
</tr>
|
|
56
|
+
<tr>
|
|
57
|
+
<td>π‘οΈ <strong>Robust Error Handling</strong></td>
|
|
58
|
+
<td>Detailed diagnostics with screenshots and context</td>
|
|
59
|
+
</tr>
|
|
60
|
+
<tr>
|
|
61
|
+
<td>π± <strong>Cross-Platform</strong></td>
|
|
62
|
+
<td>Single codebase for iOS and Android</td>
|
|
63
|
+
</tr>
|
|
64
|
+
</table>
|
|
65
|
+
|
|
66
|
+
## π¦ Installation
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
gem install appom
|
|
70
|
+
```
|
|
16
71
|
|
|
17
|
-
|
|
72
|
+
Or add to your `Gemfile`:
|
|
18
73
|
|
|
19
74
|
```ruby
|
|
20
75
|
gem 'appom'
|
|
21
76
|
```
|
|
22
77
|
|
|
23
|
-
|
|
78
|
+
## β‘ Quick Start
|
|
24
79
|
|
|
25
|
-
|
|
80
|
+
### 1. Initialize Appom
|
|
26
81
|
|
|
27
|
-
|
|
82
|
+
```ruby
|
|
83
|
+
require 'appom'
|
|
28
84
|
|
|
29
|
-
|
|
85
|
+
Appom.register_driver do
|
|
86
|
+
Appium::Driver.new({
|
|
87
|
+
caps: {
|
|
88
|
+
platformName: 'iOS',
|
|
89
|
+
deviceName: 'iPhone 15',
|
|
90
|
+
app: '/path/to/your/app.ipa'
|
|
91
|
+
},
|
|
92
|
+
appium_lib: { server_url: 'http://localhost:4723/wd/hub' }
|
|
93
|
+
})
|
|
94
|
+
end
|
|
95
|
+
```
|
|
30
96
|
|
|
31
|
-
|
|
97
|
+
### 2. Create Page Objects
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
class LoginPage < Appom::Page
|
|
101
|
+
element :email, :accessibility_id, 'email_field'
|
|
102
|
+
element :password, :accessibility_id, 'password_field'
|
|
103
|
+
element :login_btn, :accessibility_id, 'login_button'
|
|
104
|
+
|
|
105
|
+
def login(email, password)
|
|
106
|
+
self.email.set(email)
|
|
107
|
+
self.password.set(password)
|
|
108
|
+
login_btn.tap
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
```
|
|
32
112
|
|
|
33
|
-
|
|
113
|
+
### 3. Write Tests
|
|
34
114
|
|
|
35
|
-
### Register Appium Driver
|
|
36
|
-
Appium use appium directly to find elements. So that to use Appom you must register Appium Driver for Appom
|
|
37
115
|
```ruby
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
116
|
+
RSpec.describe 'Login Flow' do
|
|
117
|
+
it 'logs user in successfully' do
|
|
118
|
+
login_page = LoginPage.new
|
|
119
|
+
login_page.login('test@example.com', 'password')
|
|
120
|
+
|
|
121
|
+
expect(HomePage.new).to have_welcome_message
|
|
122
|
+
end
|
|
44
123
|
end
|
|
45
124
|
```
|
|
46
|
-
`appium_lib_options` and `caps` are options to initiate a appium driver. You can follow [Appium Ruby Client](https://github.com/appium/ruby_lib)
|
|
47
125
|
|
|
48
|
-
|
|
126
|
+
**That's it!** No more `sleep()`, no more flaky selectors, no more mysterious failures.
|
|
127
|
+
|
|
128
|
+
## π― Examples
|
|
129
|
+
|
|
130
|
+
<details>
|
|
131
|
+
<summary><strong>Advanced Page Object with Sections</strong></summary>
|
|
132
|
+
|
|
49
133
|
```ruby
|
|
50
|
-
|
|
51
|
-
|
|
134
|
+
class ShoppingPage < Appom::Page
|
|
135
|
+
section :header, HeaderSection, :id, 'header'
|
|
136
|
+
sections :products, ProductSection, :class, 'product-card'
|
|
137
|
+
|
|
138
|
+
def add_product_to_cart(product_name)
|
|
139
|
+
product = products.find { |p| p.name.text == product_name }
|
|
140
|
+
product.add_to_cart
|
|
141
|
+
wait_for_cart_update
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
class ProductSection < Appom::Section
|
|
146
|
+
element :name, :class, 'product-name'
|
|
147
|
+
element :price, :class, 'product-price'
|
|
148
|
+
element :add_btn, :class, 'add-to-cart-btn'
|
|
149
|
+
|
|
150
|
+
def add_to_cart
|
|
151
|
+
scroll_to_and_tap(:add_btn)
|
|
152
|
+
end
|
|
52
153
|
end
|
|
53
154
|
```
|
|
54
155
|
|
|
55
|
-
|
|
156
|
+
</details>
|
|
157
|
+
|
|
158
|
+
<details>
|
|
159
|
+
<summary><strong>Smart Waiting & Retry Logic</strong></summary>
|
|
160
|
+
|
|
56
161
|
```ruby
|
|
57
|
-
class
|
|
58
|
-
element :
|
|
59
|
-
element :
|
|
60
|
-
|
|
162
|
+
class PaymentPage < Appom::Page
|
|
163
|
+
element :card_field, :id, 'card_number'
|
|
164
|
+
element :submit_btn, :id, 'submit_payment'
|
|
165
|
+
|
|
166
|
+
def process_payment(card_number)
|
|
167
|
+
# Auto-retry for flaky elements
|
|
168
|
+
interact_with_retry(:card_field, :send_keys, text: card_number)
|
|
169
|
+
|
|
170
|
+
# Wait for specific conditions
|
|
171
|
+
tap_and_wait(:submit_btn)
|
|
172
|
+
wait_for_any(:success_message, :error_message, timeout: 30)
|
|
173
|
+
end
|
|
61
174
|
end
|
|
62
175
|
```
|
|
63
176
|
|
|
64
|
-
|
|
65
|
-
|
|
177
|
+
</details>
|
|
178
|
+
|
|
179
|
+
<details>
|
|
180
|
+
<summary><strong>Visual Testing Integration</strong></summary>
|
|
66
181
|
|
|
67
|
-
|
|
68
|
-
|
|
182
|
+
```ruby
|
|
183
|
+
class ProductPage < Appom::Page
|
|
184
|
+
def verify_product_display
|
|
185
|
+
# Automatic visual regression testing
|
|
186
|
+
take_visual_snapshot('product_page')
|
|
187
|
+
compare_visual_baseline('product_page', threshold: 0.95)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
```
|
|
69
191
|
|
|
192
|
+
</details>
|
|
70
193
|
|
|
71
|
-
##
|
|
194
|
+
## π Documentation
|
|
72
195
|
|
|
73
|
-
|
|
196
|
+
- **[Complete Documentation](Documentation.md)** - Comprehensive guide with advanced features
|
|
197
|
+
- **[API Reference](https://rubydoc.info/gems/appom)** - Detailed API documentation
|
|
198
|
+
- **[Best Practices](Documentation.md#best-practices)** - Testing patterns and conventions
|
|
199
|
+
- **[Troubleshooting](Documentation.md#troubleshooting)** - Common issues and solutions
|
|
74
200
|
|
|
75
|
-
|
|
201
|
+
---
|
|
76
202
|
|
|
77
|
-
|
|
203
|
+
<div align="center">
|
|
204
|
+
|
|
205
|
+
**Made with β€οΈ by the mobile testing community**
|
|
78
206
|
|
|
79
|
-
|
|
207
|
+
[β¬ Back to top](#-appom)
|
|
80
208
|
|
|
81
|
-
|
|
209
|
+
</div>
|