e2e 0.3.2 → 0.4.1
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/CHANGELOG.md +25 -0
- data/README.md +36 -6
- data/gemfiles/rails_7.0.gemfile.lock +2 -2
- data/gemfiles/rails_7.1.gemfile.lock +2 -2
- data/gemfiles/rails_7.2.gemfile.lock +2 -2
- data/gemfiles/rails_8.0.gemfile.lock +2 -2
- data/lib/e2e/drivers/playwright.rb +20 -1
- data/lib/e2e/matchers.rb +153 -9
- data/lib/e2e/session.rb +1 -1
- data/lib/e2e/version.rb +1 -1
- data/lib/e2e.rb +17 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: becb7a6f79f72c2fd1f2eef674d126cc20a2dc5ee8186c19a7c8501faef0cab3
|
|
4
|
+
data.tar.gz: da62f528c5865a4801c03ba30a3c17f29271b07f61a7d767e61d7edbe98269ac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 30de0ae743db517797420c5074a784c63c6ccad0594695a0d5292c62ad11ff694d9143ae8d4129263a02d8913538f702b463563673ff0dfea60428ca85a5b31d
|
|
7
|
+
data.tar.gz: 45cffa66438a5da357cd4a09e8e4df12785191155889a93482204d97edebbc1dd99bac8955912aa19d4f3828a87a11174c4285d008ee96a05caee1b3c05cb906
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.1] - 2026-02-07
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `have_no_content` / `have_no_text` matchers with auto-waiting support
|
|
15
|
+
- `have_no_current_path` matcher with auto-waiting support
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- `have_current_path` (and its negation) no longer crashes on invalid URIs (e.g., `data:` URLs)
|
|
20
|
+
|
|
21
|
+
## [0.4.0] - 2026-02-06
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **Auto-waiting matchers:** `have_text`, `have_content`, and `have_current_path` now automatically retry until the expected condition is met or the timeout expires, eliminating flaky tests caused by page transitions and async rendering
|
|
26
|
+
- `have_current_path` matcher for asserting the current URL path with auto-waiting (supports exact strings and regexps)
|
|
27
|
+
- `E2E.wait_until` helper method for custom waiting logic in tests
|
|
28
|
+
- `wait_timeout` configuration option (default: 5 seconds) to control how long matchers wait before failing
|
|
29
|
+
- `text` method on page/session for reading visible text content of the page body
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- `fill_in` now matches fields by label, placeholder, id, and name (Capybara-like behavior) instead of only CSS selectors, with fallback to direct CSS selector
|
|
34
|
+
|
|
10
35
|
## [0.3.2] - 2026-02-05
|
|
11
36
|
|
|
12
37
|
### Fixed
|
data/README.md
CHANGED
|
@@ -85,7 +85,8 @@ RSpec.describe "User Login", type: :e2e do
|
|
|
85
85
|
fill_in "Password", with: "password"
|
|
86
86
|
click_button "Sign In"
|
|
87
87
|
|
|
88
|
-
expect(page
|
|
88
|
+
expect(page).to have_current_path("/dashboard")
|
|
89
|
+
expect(page).to have_content("Welcome, User!")
|
|
89
90
|
end
|
|
90
91
|
end
|
|
91
92
|
```
|
|
@@ -159,7 +160,8 @@ click_button "Submit"
|
|
|
159
160
|
click_link "Read more"
|
|
160
161
|
click "#nav-menu" # CSS selector
|
|
161
162
|
|
|
162
|
-
fill_in "Email", with: "test@example.com"
|
|
163
|
+
fill_in "Email", with: "test@example.com" # Matches by label, placeholder, id, or name
|
|
164
|
+
fill_in "#email", with: "test@example.com" # CSS selector fallback
|
|
163
165
|
check "I agree"
|
|
164
166
|
uncheck "Subscribe"
|
|
165
167
|
attach_file "#upload", "path/to/file.png"
|
|
@@ -175,11 +177,18 @@ find("button", text: "Save") # Filter by text
|
|
|
175
177
|
|
|
176
178
|
#### Assertions & Matchers
|
|
177
179
|
|
|
180
|
+
All text and path matchers **automatically wait** for the expected condition to be met (up to `wait_timeout` seconds), making your tests resilient to page transitions and async rendering.
|
|
181
|
+
|
|
178
182
|
```ruby
|
|
179
|
-
# Check for content
|
|
180
|
-
expect(page
|
|
181
|
-
expect(
|
|
182
|
-
expect(find(".alert")).to
|
|
183
|
+
# Check for content (auto-waiting)
|
|
184
|
+
expect(page).to have_text("Success")
|
|
185
|
+
expect(page).to have_content("Success") # Alias for have_text
|
|
186
|
+
expect(find(".alert")).to have_text("Success") # Works on elements too
|
|
187
|
+
expect(page).to have_text(/welcome/i) # Regexp support
|
|
188
|
+
|
|
189
|
+
# Check current path (auto-waiting)
|
|
190
|
+
expect(page).to have_current_path("/dashboard")
|
|
191
|
+
expect(page).to have_current_path(/\/users\/\d+/) # Regexp support
|
|
183
192
|
|
|
184
193
|
# Check for classes
|
|
185
194
|
expect(find(".alert")).to have_class("success")
|
|
@@ -206,6 +215,26 @@ evaluate("document.title") # Execute JS
|
|
|
206
215
|
save_screenshot("tmp/screen.png")
|
|
207
216
|
```
|
|
208
217
|
|
|
218
|
+
### Auto-Waiting
|
|
219
|
+
|
|
220
|
+
The `have_text`, `have_content`, and `have_current_path` matchers automatically retry until the condition is met or the configured `wait_timeout` expires (default: 5 seconds). This eliminates flaky tests caused by page navigations, redirects, and async rendering.
|
|
221
|
+
|
|
222
|
+
```ruby
|
|
223
|
+
click_button "Submit"
|
|
224
|
+
# No need for sleep or manual waiting — the matcher will poll until
|
|
225
|
+
# the page transitions and the expected content appears
|
|
226
|
+
expect(page).to have_current_path("/success")
|
|
227
|
+
expect(page).to have_content("Your order has been placed")
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
For custom waiting logic, use `E2E.wait_until`:
|
|
231
|
+
|
|
232
|
+
```ruby
|
|
233
|
+
E2E.wait_until(timeout: 10) do
|
|
234
|
+
page.current_url.include?("/ready")
|
|
235
|
+
end
|
|
236
|
+
```
|
|
237
|
+
|
|
209
238
|
### 🔓 Native Access (The Escape Hatch)
|
|
210
239
|
|
|
211
240
|
We believe you shouldn't be limited by the wrapper. You can access the underlying `Playwright::Page` object at any time using `.native`.
|
|
@@ -265,6 +294,7 @@ E2E.configure do |config|
|
|
|
265
294
|
config.browser_type = :chromium # Options: :chromium (default), :firefox, :webkit
|
|
266
295
|
config.headless = ENV.fetch("HEADLESS", "true") == "true"
|
|
267
296
|
config.app = Rails.application # Automatic Rack booting
|
|
297
|
+
config.wait_timeout = 5 # Seconds to wait in auto-waiting matchers (default: 5)
|
|
268
298
|
end
|
|
269
299
|
```
|
|
270
300
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
e2e (0.
|
|
4
|
+
e2e (0.4.1)
|
|
5
5
|
playwright-ruby-client (>= 1.40.0)
|
|
6
6
|
rack
|
|
7
7
|
rackup
|
|
@@ -335,7 +335,7 @@ CHECKSUMS
|
|
|
335
335
|
diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
|
|
336
336
|
docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e
|
|
337
337
|
drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
|
|
338
|
-
e2e (0.
|
|
338
|
+
e2e (0.4.1)
|
|
339
339
|
erb (6.0.1) sha256=28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5
|
|
340
340
|
erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9
|
|
341
341
|
globalid (1.3.0) sha256=05c639ad6eb4594522a0b07983022f04aa7254626ab69445a0e493aa3786ff11
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
e2e (0.
|
|
4
|
+
e2e (0.4.1)
|
|
5
5
|
playwright-ruby-client (>= 1.40.0)
|
|
6
6
|
rack
|
|
7
7
|
rackup
|
|
@@ -349,7 +349,7 @@ CHECKSUMS
|
|
|
349
349
|
diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
|
|
350
350
|
docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e
|
|
351
351
|
drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
|
|
352
|
-
e2e (0.
|
|
352
|
+
e2e (0.4.1)
|
|
353
353
|
erb (6.0.1) sha256=28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5
|
|
354
354
|
erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9
|
|
355
355
|
globalid (1.3.0) sha256=05c639ad6eb4594522a0b07983022f04aa7254626ab69445a0e493aa3786ff11
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
e2e (0.
|
|
4
|
+
e2e (0.4.1)
|
|
5
5
|
playwright-ruby-client (>= 1.40.0)
|
|
6
6
|
rack
|
|
7
7
|
rackup
|
|
@@ -343,7 +343,7 @@ CHECKSUMS
|
|
|
343
343
|
diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
|
|
344
344
|
docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e
|
|
345
345
|
drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
|
|
346
|
-
e2e (0.
|
|
346
|
+
e2e (0.4.1)
|
|
347
347
|
erb (6.0.1) sha256=28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5
|
|
348
348
|
erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9
|
|
349
349
|
globalid (1.3.0) sha256=05c639ad6eb4594522a0b07983022f04aa7254626ab69445a0e493aa3786ff11
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
e2e (0.
|
|
4
|
+
e2e (0.4.1)
|
|
5
5
|
playwright-ruby-client (>= 1.40.0)
|
|
6
6
|
rack
|
|
7
7
|
rackup
|
|
@@ -339,7 +339,7 @@ CHECKSUMS
|
|
|
339
339
|
diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
|
|
340
340
|
docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e
|
|
341
341
|
drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
|
|
342
|
-
e2e (0.
|
|
342
|
+
e2e (0.4.1)
|
|
343
343
|
erb (6.0.1) sha256=28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5
|
|
344
344
|
erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9
|
|
345
345
|
globalid (1.3.0) sha256=05c639ad6eb4594522a0b07983022f04aa7254626ab69445a0e493aa3786ff11
|
|
@@ -59,7 +59,21 @@ module E2E
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def fill_in(selector, with:)
|
|
62
|
-
|
|
62
|
+
# Try to match Capybara's behavior: Label, Placeholder, ID, Name
|
|
63
|
+
chain = @page.get_by_label(selector).or(@page.get_by_placeholder(selector))
|
|
64
|
+
|
|
65
|
+
# Only add ID/Name matching if the selector doesn't contain spaces (valid CSS ID/Name assumption-ish)
|
|
66
|
+
if selector.match?(/^[a-zA-Z0-9_-]+$/)
|
|
67
|
+
chain = chain.or(@page.locator("##{selector}"))
|
|
68
|
+
.or(@page.locator("[name='#{selector}']"))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
begin
|
|
72
|
+
chain.first.fill(with)
|
|
73
|
+
rescue
|
|
74
|
+
# Fallback to treating it as a direct CSS selector if the above failed
|
|
75
|
+
@page.fill(selector, with)
|
|
76
|
+
end
|
|
63
77
|
end
|
|
64
78
|
|
|
65
79
|
def check(selector)
|
|
@@ -78,6 +92,11 @@ module E2E
|
|
|
78
92
|
@page.content
|
|
79
93
|
end
|
|
80
94
|
|
|
95
|
+
# Required for have_content matcher on page object
|
|
96
|
+
def text
|
|
97
|
+
@page.inner_text("body")
|
|
98
|
+
end
|
|
99
|
+
|
|
81
100
|
def evaluate(script)
|
|
82
101
|
@page.evaluate(script)
|
|
83
102
|
end
|
data/lib/e2e/matchers.rb
CHANGED
|
@@ -16,25 +16,169 @@ if defined?(RSpec::Matchers)
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
RSpec::Matchers.define :have_text do |expected_text|
|
|
19
|
-
match do |
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
match do |actual|
|
|
20
|
+
@actual_text = nil
|
|
21
|
+
|
|
22
|
+
E2E.wait_until do
|
|
23
|
+
@actual_text = actual.text
|
|
24
|
+
if expected_text.is_a?(Regexp)
|
|
25
|
+
@actual_text.match?(expected_text)
|
|
26
|
+
else
|
|
27
|
+
@actual_text.include?(expected_text)
|
|
28
|
+
end
|
|
24
29
|
end
|
|
25
30
|
end
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
match_when_negated do |actual|
|
|
33
|
+
E2E.wait_until do
|
|
34
|
+
@actual_text = actual.text
|
|
35
|
+
if expected_text.is_a?(Regexp)
|
|
36
|
+
!@actual_text.match?(expected_text)
|
|
37
|
+
else
|
|
38
|
+
!@actual_text.include?(expected_text)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
29
41
|
end
|
|
30
42
|
|
|
31
|
-
|
|
32
|
-
"expected
|
|
43
|
+
failure_message do
|
|
44
|
+
"expected to find text #{expected_text.inspect} in #{@actual_text.inspect}"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
failure_message_when_negated do
|
|
48
|
+
"expected not to find text #{expected_text.inspect} in #{@actual_text.inspect}"
|
|
33
49
|
end
|
|
34
50
|
end
|
|
35
51
|
|
|
36
52
|
RSpec::Matchers.alias_matcher :have_content, :have_text
|
|
37
53
|
|
|
54
|
+
RSpec::Matchers.define :have_no_text do |expected_text|
|
|
55
|
+
match do |actual|
|
|
56
|
+
@actual_text = nil
|
|
57
|
+
|
|
58
|
+
E2E.wait_until do
|
|
59
|
+
@actual_text = actual.text
|
|
60
|
+
if expected_text.is_a?(Regexp)
|
|
61
|
+
!@actual_text.match?(expected_text)
|
|
62
|
+
else
|
|
63
|
+
!@actual_text.include?(expected_text)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
match_when_negated do |actual|
|
|
69
|
+
E2E.wait_until do
|
|
70
|
+
@actual_text = actual.text
|
|
71
|
+
if expected_text.is_a?(Regexp)
|
|
72
|
+
@actual_text.match?(expected_text)
|
|
73
|
+
else
|
|
74
|
+
@actual_text.include?(expected_text)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
failure_message do
|
|
80
|
+
"expected not to find text #{expected_text.inspect} in #{@actual_text.inspect}"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
failure_message_when_negated do
|
|
84
|
+
"expected to find text #{expected_text.inspect} in #{@actual_text.inspect}"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
RSpec::Matchers.alias_matcher :have_no_content, :have_no_text
|
|
89
|
+
|
|
90
|
+
RSpec::Matchers.define :have_current_path do |expected_path|
|
|
91
|
+
match do |session|
|
|
92
|
+
@actual_path = nil
|
|
93
|
+
|
|
94
|
+
E2E.wait_until do
|
|
95
|
+
url = session.current_url
|
|
96
|
+
@actual_path = begin
|
|
97
|
+
URI.parse(url).path
|
|
98
|
+
rescue URI::InvalidURIError
|
|
99
|
+
url
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
if expected_path.is_a?(Regexp)
|
|
103
|
+
@actual_path.match?(expected_path)
|
|
104
|
+
else
|
|
105
|
+
@actual_path == expected_path
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
match_when_negated do |session|
|
|
111
|
+
E2E.wait_until do
|
|
112
|
+
url = session.current_url
|
|
113
|
+
@actual_path = begin
|
|
114
|
+
URI.parse(url).path
|
|
115
|
+
rescue URI::InvalidURIError
|
|
116
|
+
url
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
if expected_path.is_a?(Regexp)
|
|
120
|
+
!@actual_path.match?(expected_path)
|
|
121
|
+
else
|
|
122
|
+
@actual_path != expected_path
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
failure_message do
|
|
128
|
+
"expected current path to be #{expected_path.inspect}, but was #{@actual_path.inspect}"
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
failure_message_when_negated do
|
|
132
|
+
"expected current path not to be #{expected_path.inspect}, but it was"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
RSpec::Matchers.define :have_no_current_path do |expected_path|
|
|
137
|
+
match do |session|
|
|
138
|
+
@actual_path = nil
|
|
139
|
+
|
|
140
|
+
E2E.wait_until do
|
|
141
|
+
url = session.current_url
|
|
142
|
+
@actual_path = begin
|
|
143
|
+
URI.parse(url).path
|
|
144
|
+
rescue URI::InvalidURIError
|
|
145
|
+
url
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
if expected_path.is_a?(Regexp)
|
|
149
|
+
!@actual_path.match?(expected_path)
|
|
150
|
+
else
|
|
151
|
+
@actual_path != expected_path
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
match_when_negated do |session|
|
|
157
|
+
E2E.wait_until do
|
|
158
|
+
url = session.current_url
|
|
159
|
+
@actual_path = begin
|
|
160
|
+
URI.parse(url).path
|
|
161
|
+
rescue URI::InvalidURIError
|
|
162
|
+
url
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
if expected_path.is_a?(Regexp)
|
|
166
|
+
@actual_path.match?(expected_path)
|
|
167
|
+
else
|
|
168
|
+
@actual_path == expected_path
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
failure_message do
|
|
174
|
+
"expected current path not to be #{expected_path.inspect}, but was #{@actual_path.inspect}"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
failure_message_when_negated do
|
|
178
|
+
"expected current path to be #{expected_path.inspect}, but it was"
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
38
182
|
RSpec::Matchers.define :have_value do |expected_value|
|
|
39
183
|
match do |element|
|
|
40
184
|
element.value == expected_value
|
data/lib/e2e/session.rb
CHANGED
|
@@ -8,7 +8,7 @@ module E2E
|
|
|
8
8
|
|
|
9
9
|
attr_reader :driver
|
|
10
10
|
|
|
11
|
-
def_delegators :@driver, :current_url, :click, :click_button, :click_link, :fill_in, :check, :uncheck, :attach_file, :body, :evaluate, :save_screenshot, :native, :pause, :reset!, :quit
|
|
11
|
+
def_delegators :@driver, :current_url, :click, :click_button, :click_link, :fill_in, :check, :uncheck, :attach_file, :body, :text, :evaluate, :save_screenshot, :native, :pause, :reset!, :quit
|
|
12
12
|
|
|
13
13
|
def initialize(driver_name = E2E.config.driver)
|
|
14
14
|
@driver = initialize_driver(driver_name)
|
data/lib/e2e/version.rb
CHANGED
data/lib/e2e.rb
CHANGED
|
@@ -39,14 +39,30 @@ module E2E
|
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
# Retry a block until it returns truthy or timeout is reached
|
|
43
|
+
def self.wait_until(timeout: config.wait_timeout, interval: 0.05)
|
|
44
|
+
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout
|
|
45
|
+
loop do
|
|
46
|
+
result = yield
|
|
47
|
+
return result if result
|
|
48
|
+
|
|
49
|
+
if Process.clock_gettime(Process::CLOCK_MONOTONIC) >= deadline
|
|
50
|
+
return false
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
sleep interval
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
42
57
|
class Config
|
|
43
|
-
attr_accessor :driver, :headless, :app, :browser_type
|
|
58
|
+
attr_accessor :driver, :headless, :app, :browser_type, :wait_timeout
|
|
44
59
|
|
|
45
60
|
def initialize
|
|
46
61
|
@driver = :playwright
|
|
47
62
|
@browser_type = :chromium
|
|
48
63
|
@headless = ENV.fetch("HEADLESS", "true") == "true"
|
|
49
64
|
@app = nil
|
|
65
|
+
@wait_timeout = 5
|
|
50
66
|
end
|
|
51
67
|
end
|
|
52
68
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: e2e
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alexey Poimtsev
|
|
@@ -238,7 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
238
238
|
- !ruby/object:Gem::Version
|
|
239
239
|
version: '0'
|
|
240
240
|
requirements: []
|
|
241
|
-
rubygems_version: 4.0.
|
|
241
|
+
rubygems_version: 4.0.6
|
|
242
242
|
specification_version: 4
|
|
243
243
|
summary: Unified E2E testing framework for Ruby.
|
|
244
244
|
test_files: []
|