dommy-rack 0.8.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 +7 -0
- data/CHANGELOG.md +16 -0
- data/LICENSE.txt +21 -0
- data/README.md +230 -0
- data/Rakefile +8 -0
- data/lib/dommy/rack/cookie_jar.rb +166 -0
- data/lib/dommy/rack/errors.rb +34 -0
- data/lib/dommy/rack/field_interactor.rb +81 -0
- data/lib/dommy/rack/file_upload.rb +73 -0
- data/lib/dommy/rack/form_submission.rb +273 -0
- data/lib/dommy/rack/header_store.rb +58 -0
- data/lib/dommy/rack/history.rb +45 -0
- data/lib/dommy/rack/locator.rb +115 -0
- data/lib/dommy/rack/navigation.rb +176 -0
- data/lib/dommy/rack/request_builder.rb +134 -0
- data/lib/dommy/rack/response.rb +153 -0
- data/lib/dommy/rack/session.rb +525 -0
- data/lib/dommy/rack/version.rb +7 -0
- data/lib/dommy/rack/visibility.rb +47 -0
- data/lib/dommy/rack.rb +24 -0
- data/sig/dommy/rack.rbs +232 -0
- metadata +94 -0
data/sig/dommy/rack.rbs
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
module Dommy
|
|
2
|
+
module Rack
|
|
3
|
+
VERSION: String
|
|
4
|
+
|
|
5
|
+
# --- Errors ---
|
|
6
|
+
class Error < StandardError
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class ElementNotFoundError < Error
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class ElementNotClickableError < Error
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class AmbiguousElementError < Error
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class UnsupportedURLError < Error
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class CrossOriginError < Error
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class TooManyRedirectsError < Error
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class UnsupportedContentTypeError < Error
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class InvalidFormError < Error
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class FileNotFoundError < Error
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
type headers = Hash[String, untyped]
|
|
37
|
+
type params = Hash[untyped, untyped]
|
|
38
|
+
type redirect_mode = :follow | :manual | :error
|
|
39
|
+
type redirect_entry = { status: Integer, url: String, location: String? }
|
|
40
|
+
|
|
41
|
+
# A single completed Rack response plus the URL it was fetched at.
|
|
42
|
+
class Response
|
|
43
|
+
HTML_CONTENT_TYPES: Array[String]
|
|
44
|
+
REDIRECT_STATUSES: Array[Integer]
|
|
45
|
+
|
|
46
|
+
attr_reader status: Integer
|
|
47
|
+
attr_reader headers: headers
|
|
48
|
+
attr_reader url: String?
|
|
49
|
+
attr_accessor redirects: Array[redirect_entry]
|
|
50
|
+
|
|
51
|
+
def initialize: (untyped status, headers? headers, untyped body, url: String?) -> void
|
|
52
|
+
def body: () -> String
|
|
53
|
+
def content_type: () -> String?
|
|
54
|
+
def html?: () -> bool
|
|
55
|
+
def json?: () -> bool
|
|
56
|
+
def json: (?symbolize_names: bool) -> untyped
|
|
57
|
+
def redirect?: () -> bool
|
|
58
|
+
def success?: () -> bool
|
|
59
|
+
def client_error?: () -> bool
|
|
60
|
+
def server_error?: () -> bool
|
|
61
|
+
def error?: () -> bool
|
|
62
|
+
def not_found?: () -> bool
|
|
63
|
+
def location_header: () -> String?
|
|
64
|
+
def meta_refresh_url: () -> String?
|
|
65
|
+
def set_cookie_strings: () -> Array[String]
|
|
66
|
+
def window: () -> untyped
|
|
67
|
+
def document: () -> untyped
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# A simplified, same-origin cookie store.
|
|
71
|
+
class CookieJar
|
|
72
|
+
class CookieEntry < Struct[untyped]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def initialize: () -> void
|
|
76
|
+
def store_from_header: (String set_cookie_string, String request_url) -> void
|
|
77
|
+
def set!: (untyped name, untyped value, ?domain: String?, ?path: String?, ?expires: untyped, ?secure: bool, ?http_only: bool) -> untyped
|
|
78
|
+
def get: (untyped name) -> String?
|
|
79
|
+
def clear: () -> void
|
|
80
|
+
def all: () -> Array[untyped]
|
|
81
|
+
def cookies_for: (String request_url) -> String
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Browser-tab-style history stack.
|
|
85
|
+
class History
|
|
86
|
+
def initialize: () -> void
|
|
87
|
+
def push: (String url) -> void
|
|
88
|
+
def back: () -> String?
|
|
89
|
+
def forward: () -> String?
|
|
90
|
+
def current: () -> String?
|
|
91
|
+
def entries: () -> Array[String]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Finds DOM elements within a document/element by Capybara-style locators.
|
|
95
|
+
class Locator
|
|
96
|
+
def initialize: (untyped document) -> void
|
|
97
|
+
def find_field: (untyped locator) -> untyped
|
|
98
|
+
def find_link: (untyped locator) -> untyped
|
|
99
|
+
def find_button: (untyped locator) -> untyped
|
|
100
|
+
def find_option: (untyped select_el, untyped value) -> untyped
|
|
101
|
+
def form_for: (untyped element) -> untyped
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# URL resolution, redirect following, same-origin enforcement, meta refresh.
|
|
105
|
+
class Navigation
|
|
106
|
+
def initialize: (Session session) -> void
|
|
107
|
+
def resolve_url: (untyped url_or_path, String? base_url) -> String
|
|
108
|
+
def check_same_origin!: (String url) -> void
|
|
109
|
+
def navigate: (method: untyped, url: untyped, ?params: params?, ?body: untyped, ?headers: headers) -> Response
|
|
110
|
+
def fetch: (untyped url, ?method: untyped, ?params: params?, ?body: untyped, ?headers: headers, ?redirect: redirect_mode) -> Response
|
|
111
|
+
def revisit: (String url) -> Response
|
|
112
|
+
def run: (method: untyped, url: untyped, ?params: params?, ?body: untyped, ?headers: headers, ?follow: bool) -> [ Response, String ]
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# A single browser-like session over a Rack application.
|
|
116
|
+
class Session
|
|
117
|
+
DEFAULT_ACCEPT: String
|
|
118
|
+
|
|
119
|
+
class Config < Struct[untyped]
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
attr_reader last_request: untyped
|
|
123
|
+
attr_reader last_response: Response?
|
|
124
|
+
attr_reader history: History
|
|
125
|
+
|
|
126
|
+
def initialize: (untyped app, ?default_host: String, ?follow_redirects: bool, ?max_redirects: Integer, ?respect_method_override: bool, ?method_override_param: String, ?user_agent: String, ?accept: String, ?enforce_same_origin: bool, ?follow_meta_refresh: bool) -> void
|
|
127
|
+
|
|
128
|
+
# config readers
|
|
129
|
+
def default_host: () -> String
|
|
130
|
+
def follow_redirects?: () -> bool
|
|
131
|
+
def max_redirects: () -> Integer
|
|
132
|
+
def enforce_same_origin?: () -> bool
|
|
133
|
+
def follow_meta_refresh?: () -> bool
|
|
134
|
+
def config: () -> untyped
|
|
135
|
+
|
|
136
|
+
# navigation
|
|
137
|
+
def visit: (untyped path) -> Response
|
|
138
|
+
def navigate: (method: untyped, url: untyped, ?params: params?, ?body: untyped, ?headers: headers) -> Response
|
|
139
|
+
def reload: () -> Response
|
|
140
|
+
def back: () -> Response?
|
|
141
|
+
def forward: () -> Response?
|
|
142
|
+
def get: (untyped path, ?headers: headers) -> Response
|
|
143
|
+
def post: (untyped path, ?params: params?, ?body: untyped, ?headers: headers) -> Response
|
|
144
|
+
def put: (untyped path, ?params: params?, ?body: untyped, ?headers: headers) -> Response
|
|
145
|
+
def patch: (untyped path, ?params: params?, ?body: untyped, ?headers: headers) -> Response
|
|
146
|
+
def delete: (untyped path, ?params: params?, ?body: untyped, ?headers: headers) -> Response
|
|
147
|
+
def request: (untyped method, untyped path, ?params: params?, ?body: untyped, ?headers: headers) -> Response
|
|
148
|
+
def fetch: (untyped url, ?method: untyped, ?headers: headers, ?body: untyped, ?params: params?, ?redirect: redirect_mode) -> Response
|
|
149
|
+
|
|
150
|
+
# JSON
|
|
151
|
+
def post_json: (untyped path, untyped data, ?headers: headers) -> Response
|
|
152
|
+
def put_json: (untyped path, untyped data, ?headers: headers) -> Response
|
|
153
|
+
def patch_json: (untyped path, untyped data, ?headers: headers) -> Response
|
|
154
|
+
def delete_json: (untyped path, untyped data, ?headers: headers) -> Response
|
|
155
|
+
def json: (?symbolize_names: bool) -> untyped
|
|
156
|
+
|
|
157
|
+
# persistent headers / auth
|
|
158
|
+
def default_headers: () -> headers
|
|
159
|
+
def set_header: (untyped name, untyped value) -> self
|
|
160
|
+
def delete_header: (untyped name) -> self
|
|
161
|
+
def basic_auth: (untyped user, untyped password) -> self
|
|
162
|
+
def authorization_bearer: (untyped token) -> self
|
|
163
|
+
|
|
164
|
+
# current page state
|
|
165
|
+
def current_url: () -> String?
|
|
166
|
+
def current_path: () -> String?
|
|
167
|
+
def current_host: () -> String?
|
|
168
|
+
def status: () -> Integer?
|
|
169
|
+
def headers: () -> headers?
|
|
170
|
+
def body: () -> String?
|
|
171
|
+
def document: () -> untyped
|
|
172
|
+
def html: () -> String?
|
|
173
|
+
def text: () -> String?
|
|
174
|
+
def save_page: (?String? path) -> String
|
|
175
|
+
|
|
176
|
+
# status predicates
|
|
177
|
+
def success?: () -> bool
|
|
178
|
+
def client_error?: () -> bool
|
|
179
|
+
def server_error?: () -> bool
|
|
180
|
+
def not_found?: () -> bool
|
|
181
|
+
|
|
182
|
+
# redirect chain
|
|
183
|
+
def redirects: () -> Array[redirect_entry]
|
|
184
|
+
def redirected?: () -> bool
|
|
185
|
+
|
|
186
|
+
# instrumentation
|
|
187
|
+
def on_request: () { (untyped env) -> void } -> self
|
|
188
|
+
def on_response: () { (Response response) -> void } -> self
|
|
189
|
+
|
|
190
|
+
# DOM queries
|
|
191
|
+
def at_css: (String selector) -> untyped
|
|
192
|
+
def all_css: (String selector) -> untyped
|
|
193
|
+
def at_xpath: (String xpath) -> untyped
|
|
194
|
+
def all_xpath: (String xpath) -> untyped
|
|
195
|
+
|
|
196
|
+
# scoping and matchers
|
|
197
|
+
def within: (String selector) ?{ (Session) -> void } -> untyped
|
|
198
|
+
def within_frame: (?untyped locator) ?{ (Session) -> void } -> untyped
|
|
199
|
+
def has_css?: (String selector, ?count: Integer?) -> bool
|
|
200
|
+
def has_no_css?: (String selector, ?count: Integer?) -> bool
|
|
201
|
+
def has_text?: (untyped string) -> bool
|
|
202
|
+
def has_no_text?: (untyped string) -> bool
|
|
203
|
+
def has_link?: (untyped locator) -> bool
|
|
204
|
+
def has_button?: (untyped locator) -> bool
|
|
205
|
+
def has_field?: (untyped locator) -> bool
|
|
206
|
+
|
|
207
|
+
# links and forms
|
|
208
|
+
def click_link: (untyped locator) -> untyped
|
|
209
|
+
def click_link_element: (untyped element) -> untyped
|
|
210
|
+
def fill_in: (untyped locator, with: untyped) -> untyped
|
|
211
|
+
def choose: (untyped locator) -> untyped
|
|
212
|
+
def check: (untyped locator) -> untyped
|
|
213
|
+
def uncheck: (untyped locator) -> untyped
|
|
214
|
+
def attach_file: (untyped locator, untyped path) -> untyped
|
|
215
|
+
def select: (untyped value, from: untyped) -> untyped
|
|
216
|
+
def unselect: (untyped value, from: untyped) -> untyped
|
|
217
|
+
def click_button: (untyped locator) -> untyped
|
|
218
|
+
def submit_form: (untyped form, ?submitter: untyped) -> Response
|
|
219
|
+
def submit: (untyped form, ?submitter: untyped) -> Response
|
|
220
|
+
|
|
221
|
+
# cookies
|
|
222
|
+
def cookies: () -> Array[untyped]
|
|
223
|
+
def set_cookie: (untyped name, untyped value, ?path: String, ?domain: String?, **untyped opts) -> untyped
|
|
224
|
+
def get_cookie: (untyped name) -> String?
|
|
225
|
+
def clear_cookies: () -> void
|
|
226
|
+
|
|
227
|
+
# collaboration API used by Navigation
|
|
228
|
+
def raw_request: (untyped method, String absolute_url, ?params: params?, ?body: untyped, ?headers: headers) -> Response
|
|
229
|
+
def apply_navigation_response: (Response response, String final_url, ?push_history: bool) -> void
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: dommy-rack
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.8.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- takahashim
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-05-31 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: dommy
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 0.8.0
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 0.8.0
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: rack
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2.0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '2.0'
|
|
40
|
+
description: |
|
|
41
|
+
dommy-rack lets a Rack application (including Rails) be visited and manipulated
|
|
42
|
+
as a Dommy::Document without launching a real browser. It provides a small,
|
|
43
|
+
synchronous, browser-like session API with navigation, cookies, redirects,
|
|
44
|
+
link clicking, and form submission.
|
|
45
|
+
email:
|
|
46
|
+
- takahashimm@gmail.com
|
|
47
|
+
executables: []
|
|
48
|
+
extensions: []
|
|
49
|
+
extra_rdoc_files: []
|
|
50
|
+
files:
|
|
51
|
+
- CHANGELOG.md
|
|
52
|
+
- LICENSE.txt
|
|
53
|
+
- README.md
|
|
54
|
+
- Rakefile
|
|
55
|
+
- lib/dommy/rack.rb
|
|
56
|
+
- lib/dommy/rack/cookie_jar.rb
|
|
57
|
+
- lib/dommy/rack/errors.rb
|
|
58
|
+
- lib/dommy/rack/field_interactor.rb
|
|
59
|
+
- lib/dommy/rack/file_upload.rb
|
|
60
|
+
- lib/dommy/rack/form_submission.rb
|
|
61
|
+
- lib/dommy/rack/header_store.rb
|
|
62
|
+
- lib/dommy/rack/history.rb
|
|
63
|
+
- lib/dommy/rack/locator.rb
|
|
64
|
+
- lib/dommy/rack/navigation.rb
|
|
65
|
+
- lib/dommy/rack/request_builder.rb
|
|
66
|
+
- lib/dommy/rack/response.rb
|
|
67
|
+
- lib/dommy/rack/session.rb
|
|
68
|
+
- lib/dommy/rack/version.rb
|
|
69
|
+
- lib/dommy/rack/visibility.rb
|
|
70
|
+
- sig/dommy/rack.rbs
|
|
71
|
+
homepage: https://github.com/takahashim/dommy
|
|
72
|
+
licenses:
|
|
73
|
+
- MIT
|
|
74
|
+
metadata:
|
|
75
|
+
homepage_uri: https://github.com/takahashim/dommy
|
|
76
|
+
source_code_uri: https://github.com/takahashim/dommy/tree/main/gems/dommy-rack
|
|
77
|
+
rdoc_options: []
|
|
78
|
+
require_paths:
|
|
79
|
+
- lib
|
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
81
|
+
requirements:
|
|
82
|
+
- - ">="
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
version: '3.2'
|
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
requirements: []
|
|
91
|
+
rubygems_version: 3.6.2
|
|
92
|
+
specification_version: 4
|
|
93
|
+
summary: Rack-backed browser session layer for Dommy
|
|
94
|
+
test_files: []
|