webaccount 0.3.1 → 0.5.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/CHANGELOG +115 -0
- data/Gemfile +2 -0
- data/LICENSE +21 -0
- data/README.md +198 -0
- data/Rakefile +9 -0
- data/lib/Thoran/Selenium/WebDriver/Driver/Attempt/attempt.rb +29 -19
- data/lib/Thoran/Selenium/WebDriver/Driver/ElementPresentQ/element_presentQ.rb +37 -0
- data/lib/Thoran/Selenium.rb +9 -6
- data/lib/web_account.rb +1 -1
- data/lib/webaccount/VERSION.rb +6 -0
- data/lib/{WebAccount.rb → webaccount.rb} +69 -39
- data/test/Thoran/Selenium/WebDriver/Driver/Attempt_test.rb +169 -0
- data/test/webaccount_test.rb +45 -0
- data/webaccount.gemspec +48 -0
- metadata +60 -19
- data/lib/Thoran/Array/AllButFirst/all_but_first.rb +0 -28
- data/lib/Thoran/Array/FirstX/firstX.rb +0 -21
- data/lib/Thoran/Selenium/WebDriver/Remote/W3C/Bridge/ConvertLocators/convert_locators.rb +0 -51
- data/lib/Thoran/Selenium/WebDriver/SearchContext/ElementPresentQ/element_presentQ.rb +0 -39
- data/lib/Thoran/Selenium/WebDriver/SearchContext/ElementsPresentQ/elements_presentQ.rb +0 -39
- data/lib/Thoran/Selenium/WebDriver/Setup/setup.rb +0 -66
- data/lib/Thoran/String/ToConst/to_const.rb +0 -47
- data/lib/WebAccount/VERSION.rb +0 -5
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# webaccount.rb
|
|
2
2
|
# WebAccount
|
|
3
3
|
|
|
4
4
|
require 'selenium-webdriver'
|
|
5
|
-
|
|
5
|
+
require_relative './Thoran/Selenium'
|
|
6
|
+
require_relative './WebAccount/VERSION'
|
|
6
7
|
|
|
7
8
|
class WebAccount
|
|
8
|
-
|
|
9
9
|
attr_accessor :username
|
|
10
10
|
attr_accessor :password
|
|
11
|
-
attr_writer :user_agent_alias
|
|
12
11
|
|
|
13
12
|
def initialize(
|
|
14
13
|
username: nil, password: nil,
|
|
14
|
+
browser: nil, driver_options: nil,
|
|
15
15
|
login_page_url: nil,
|
|
16
16
|
login_page_username_field_selector: nil, login_page_password_field_selector: nil,
|
|
17
17
|
login_page_submit_button_selector: nil,
|
|
@@ -19,6 +19,7 @@ class WebAccount
|
|
|
19
19
|
logged_out_xpath: nil
|
|
20
20
|
)
|
|
21
21
|
@username, @password = username, password
|
|
22
|
+
@browser, @driver_options = browser, driver_options
|
|
22
23
|
@login_page_url = login_page_url
|
|
23
24
|
@login_page_username_field_selector, @login_page_password_field_selector = login_page_username_field_selector, login_page_password_field_selector
|
|
24
25
|
@login_page_submit_button_selector = login_page_submit_button_selector
|
|
@@ -30,7 +31,6 @@ class WebAccount
|
|
|
30
31
|
@logged_in = false
|
|
31
32
|
username ||= self.username
|
|
32
33
|
password ||= self.password
|
|
33
|
-
attempts = 0
|
|
34
34
|
driver.attempt do
|
|
35
35
|
get_login_page
|
|
36
36
|
enter_username(username)
|
|
@@ -38,7 +38,7 @@ class WebAccount
|
|
|
38
38
|
login_page_submit_button.click
|
|
39
39
|
end
|
|
40
40
|
@logged_in = driver_wait.until do
|
|
41
|
-
driver.element_present?(
|
|
41
|
+
driver.element_present?(logout_button_selector.keys.first, logout_button_selector.values.first)
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
alias_method :logon, :login
|
|
@@ -56,6 +56,10 @@ class WebAccount
|
|
|
56
56
|
driver.quit
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
+
def driver
|
|
60
|
+
@driver ||= Selenium::WebDriver.for(browser, options: driver_options)
|
|
61
|
+
end
|
|
62
|
+
|
|
59
63
|
# predicate methods
|
|
60
64
|
|
|
61
65
|
def logged_in?
|
|
@@ -70,20 +74,46 @@ class WebAccount
|
|
|
70
74
|
|
|
71
75
|
private
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
# driver construction
|
|
78
|
+
|
|
79
|
+
def default_browser
|
|
80
|
+
:chrome
|
|
75
81
|
end
|
|
76
82
|
|
|
77
|
-
def
|
|
78
|
-
@
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
def browser
|
|
84
|
+
(@browser || default_browser).to_sym.downcase
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def default_driver_options
|
|
88
|
+
nil
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def driver_options
|
|
92
|
+
@driver_options || default_driver_options
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# waiting
|
|
96
|
+
|
|
97
|
+
# For navigation: a submit, the authentication behind it, and the redirect.
|
|
98
|
+
def default_wait_timeout
|
|
99
|
+
30
|
|
83
100
|
end
|
|
84
101
|
|
|
85
102
|
def driver_wait
|
|
86
|
-
@driver_wait ||= Selenium::WebDriver::Wait.new(timeout:
|
|
103
|
+
@driver_wait ||= Selenium::WebDriver::Wait.new(timeout: default_wait_timeout)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# For lookups: the element should already be on a page which has loaded.
|
|
107
|
+
def default_find_timeout
|
|
108
|
+
5
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def find_wait
|
|
112
|
+
@find_wait ||= Selenium::WebDriver::Wait.new(timeout: default_find_timeout)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def find(selector)
|
|
116
|
+
find_wait.until{driver.find_element(selector.keys.first, selector.values.first)}
|
|
87
117
|
end
|
|
88
118
|
|
|
89
119
|
# logging in
|
|
@@ -98,16 +128,16 @@ class WebAccount
|
|
|
98
128
|
username_field.send_keys(username)
|
|
99
129
|
end
|
|
100
130
|
|
|
101
|
-
def
|
|
102
|
-
{name:
|
|
131
|
+
def default_username_field_selector
|
|
132
|
+
{name: 'username'}
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def username_field_selector
|
|
136
|
+
@login_page_username_field_selector || default_username_field_selector
|
|
103
137
|
end
|
|
104
138
|
|
|
105
139
|
def username_field
|
|
106
|
-
|
|
107
|
-
driver.find_element(@login_page_username_field_selector.keys.first, @login_page_username_field_selector.values.first)
|
|
108
|
-
else
|
|
109
|
-
driver.find_element(default_username_field.keys.first, default_username_field.values.first)
|
|
110
|
-
end
|
|
140
|
+
find(username_field_selector)
|
|
111
141
|
end
|
|
112
142
|
|
|
113
143
|
def enter_password(password = nil)
|
|
@@ -115,28 +145,28 @@ class WebAccount
|
|
|
115
145
|
password_field.send_keys(password)
|
|
116
146
|
end
|
|
117
147
|
|
|
118
|
-
def
|
|
119
|
-
{name:
|
|
148
|
+
def default_password_field_selector
|
|
149
|
+
{name: 'password'}
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def password_field_selector
|
|
153
|
+
@login_page_password_field_selector || default_password_field_selector
|
|
120
154
|
end
|
|
121
155
|
|
|
122
156
|
def password_field
|
|
123
|
-
|
|
124
|
-
driver.find_element(@login_page_password_field_selector.keys.first, @login_page_password_field_selector.values.first)
|
|
125
|
-
else
|
|
126
|
-
driver.find_element(default_password_field.keys.first, default_password_field.values.first)
|
|
127
|
-
end
|
|
157
|
+
find(password_field_selector)
|
|
128
158
|
end
|
|
129
159
|
|
|
130
160
|
def default_login_page_submit_button_selector
|
|
131
161
|
{xpath: '//input[@type="submit" and @value="Login"]'}
|
|
132
162
|
end
|
|
133
163
|
|
|
164
|
+
def login_page_submit_button_selector
|
|
165
|
+
@login_page_submit_button_selector || default_login_page_submit_button_selector
|
|
166
|
+
end
|
|
167
|
+
|
|
134
168
|
def login_page_submit_button
|
|
135
|
-
|
|
136
|
-
driver.find_element(@login_page_submit_button_selector.keys.first, @login_page_submit_button_selector.values.first)
|
|
137
|
-
else
|
|
138
|
-
driver.find_element(default_login_page_submit_button_selector.keys.first, default_login_page_submit_button_selector.values.first)
|
|
139
|
-
end
|
|
169
|
+
find(login_page_submit_button_selector)
|
|
140
170
|
end
|
|
141
171
|
|
|
142
172
|
# logging out
|
|
@@ -145,11 +175,11 @@ class WebAccount
|
|
|
145
175
|
{xpath: '//input[@type="submit" and @value="Logout"]'}
|
|
146
176
|
end
|
|
147
177
|
|
|
178
|
+
def logout_button_selector
|
|
179
|
+
@logout_button_selector || default_logout_button_selector
|
|
180
|
+
end
|
|
181
|
+
|
|
148
182
|
def logout_button
|
|
149
|
-
|
|
150
|
-
driver.find_element(@logout_button_selector.keys.first, @logout_button_selector.values.first)
|
|
151
|
-
else
|
|
152
|
-
driver.find_element(default_logout_button_selector.keys.first, default_logout_button_selector.values.first)
|
|
153
|
-
end
|
|
183
|
+
find(logout_button_selector)
|
|
154
184
|
end
|
|
155
185
|
end
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# test/Thoran/Selenium/WebDriver/Driver/Attempt_test.rb
|
|
2
|
+
|
|
3
|
+
# Notes:
|
|
4
|
+
# 1. selenium-webdriver is required first because attempt.rb resolves the Selenium error
|
|
5
|
+
# classes at load time, in TRANSIENT_ERRORS, but does not require them itself.
|
|
6
|
+
# 2. The transient and non-transient errors are listed here rather than read from
|
|
7
|
+
# TRANSIENT_ERRORS, so that these tests state which errors are meant to be retried rather
|
|
8
|
+
# than agreeing with whatever the implementation happens to say.
|
|
9
|
+
# 3. No driver, no browser: the errors are raised directly at a dummy including the module.
|
|
10
|
+
|
|
11
|
+
require 'selenium-webdriver'
|
|
12
|
+
require_relative '../../../../../lib/Thoran/Selenium/WebDriver/Driver/Attempt/attempt'
|
|
13
|
+
|
|
14
|
+
require 'minitest/autorun'
|
|
15
|
+
require 'minitest-spec-context'
|
|
16
|
+
|
|
17
|
+
class AttemptDummy
|
|
18
|
+
include Thoran::Selenium::WebDriver::Driver::Attempt
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe Thoran::Selenium::WebDriver::Driver::Attempt do
|
|
22
|
+
TRANSIENT = [
|
|
23
|
+
Selenium::WebDriver::Error::ElementClickInterceptedError,
|
|
24
|
+
Selenium::WebDriver::Error::ElementNotInteractableError,
|
|
25
|
+
Selenium::WebDriver::Error::NoSuchElementError,
|
|
26
|
+
Selenium::WebDriver::Error::StaleElementReferenceError,
|
|
27
|
+
Selenium::WebDriver::Error::TimeoutError,
|
|
28
|
+
Selenium::WebDriver::Error::UnexpectedAlertOpenError,
|
|
29
|
+
Selenium::WebDriver::Error::UnknownError,
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
NON_TRANSIENT = [
|
|
33
|
+
Selenium::WebDriver::Error::InvalidSelectorError,
|
|
34
|
+
Selenium::WebDriver::Error::NoSuchDriverError,
|
|
35
|
+
ArgumentError,
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
before do
|
|
39
|
+
@dummy = AttemptDummy.new
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context "when the block succeeds" do
|
|
43
|
+
it "returns the value of the block" do
|
|
44
|
+
expect(@dummy.attempt{42}).must_equal(42)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "yields itself, so that the documented block argument is the receiver" do
|
|
48
|
+
yielded = nil
|
|
49
|
+
@dummy.attempt{|driver| yielded = driver}
|
|
50
|
+
expect(yielded).must_be_same_as(@dummy)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "calls the block once" do
|
|
54
|
+
calls = 0
|
|
55
|
+
@dummy.attempt{calls += 1}
|
|
56
|
+
expect(calls).must_equal(1)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "says nothing" do
|
|
60
|
+
_out, err = capture_io{@dummy.attempt{42}}
|
|
61
|
+
expect(err).must_be_empty
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "when the block raises a transient error" do
|
|
66
|
+
TRANSIENT.each do |error_class|
|
|
67
|
+
it "retries #{error_class}" do
|
|
68
|
+
calls = 0
|
|
69
|
+
capture_io do
|
|
70
|
+
@dummy.attempt(3) do
|
|
71
|
+
calls += 1
|
|
72
|
+
raise error_class if calls < 3
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
expect(calls).must_equal(3)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "returns the value of the attempt which succeeds" do
|
|
80
|
+
calls = 0
|
|
81
|
+
value = nil
|
|
82
|
+
capture_io do
|
|
83
|
+
value = @dummy.attempt(3) do
|
|
84
|
+
calls += 1
|
|
85
|
+
raise Selenium::WebDriver::Error::StaleElementReferenceError if calls < 2
|
|
86
|
+
:recovered
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
expect(value).must_equal(:recovered)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "re-raises once max_attempts is reached" do
|
|
93
|
+
capture_io do
|
|
94
|
+
expect do
|
|
95
|
+
@dummy.attempt(3){raise Selenium::WebDriver::Error::UnknownError}
|
|
96
|
+
end.must_raise(Selenium::WebDriver::Error::UnknownError)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "makes exactly max_attempts attempts before re-raising" do
|
|
101
|
+
calls = 0
|
|
102
|
+
capture_io do
|
|
103
|
+
begin
|
|
104
|
+
@dummy.attempt(3){calls += 1; raise Selenium::WebDriver::Error::UnknownError}
|
|
105
|
+
rescue Selenium::WebDriver::Error::UnknownError
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
expect(calls).must_equal(3)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "honours a supplied max_attempts" do
|
|
112
|
+
calls = 0
|
|
113
|
+
capture_io do
|
|
114
|
+
begin
|
|
115
|
+
@dummy.attempt(5){calls += 1; raise Selenium::WebDriver::Error::UnknownError}
|
|
116
|
+
rescue Selenium::WebDriver::Error::UnknownError
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
expect(calls).must_equal(5)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "defaults to three attempts" do
|
|
123
|
+
calls = 0
|
|
124
|
+
capture_io do
|
|
125
|
+
begin
|
|
126
|
+
@dummy.attempt{calls += 1; raise Selenium::WebDriver::Error::UnknownError}
|
|
127
|
+
rescue Selenium::WebDriver::Error::UnknownError
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
expect(calls).must_equal(3)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "warns once per failed attempt, naming the error" do
|
|
134
|
+
_out, err = capture_io do
|
|
135
|
+
begin
|
|
136
|
+
@dummy.attempt(2){raise Selenium::WebDriver::Error::StaleElementReferenceError}
|
|
137
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
expect(err.lines.size).must_equal(2)
|
|
141
|
+
expect(err).must_match(/Attempt 1 of 2 failed: Selenium::WebDriver::Error::StaleElementReferenceError/)
|
|
142
|
+
expect(err).must_match(/Attempt 2 of 2 failed: Selenium::WebDriver::Error::StaleElementReferenceError/)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
context "when the block raises a non-transient error" do
|
|
147
|
+
NON_TRANSIENT.each do |error_class|
|
|
148
|
+
it "does not retry #{error_class}" do
|
|
149
|
+
calls = 0
|
|
150
|
+
capture_io do
|
|
151
|
+
expect do
|
|
152
|
+
@dummy.attempt(3){calls += 1; raise error_class}
|
|
153
|
+
end.must_raise(error_class)
|
|
154
|
+
end
|
|
155
|
+
expect(calls).must_equal(1)
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "says nothing, since it did not retry" do
|
|
160
|
+
_out, err = capture_io do
|
|
161
|
+
begin
|
|
162
|
+
@dummy.attempt(3){raise Selenium::WebDriver::Error::InvalidSelectorError}
|
|
163
|
+
rescue Selenium::WebDriver::Error::InvalidSelectorError
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
expect(err).must_be_empty
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# test/webaccount_test.rb
|
|
2
|
+
|
|
3
|
+
# Notes:
|
|
4
|
+
# 1. No browser: Selenium::WebDriver.for is swapped for a stand-in for the length of
|
|
5
|
+
# each example and put back afterwards, so what is asserted is what WebAccount asks
|
|
6
|
+
# of Selenium and what it hands back.
|
|
7
|
+
|
|
8
|
+
require_relative '../lib/webaccount'
|
|
9
|
+
|
|
10
|
+
require 'minitest/autorun'
|
|
11
|
+
require 'minitest-spec-context'
|
|
12
|
+
|
|
13
|
+
describe WebAccount do
|
|
14
|
+
def with_driver_factory(&block)
|
|
15
|
+
calls = []
|
|
16
|
+
stand_in = Object.new
|
|
17
|
+
original = Selenium::WebDriver.method(:for)
|
|
18
|
+
Selenium::WebDriver.define_singleton_method(:for){|browser, options: nil| calls << [browser, options]; stand_in}
|
|
19
|
+
block.call(stand_in, calls)
|
|
20
|
+
ensure
|
|
21
|
+
Selenium::WebDriver.define_singleton_method(:for, original)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "#driver" do
|
|
25
|
+
it "is public, so that the logged-in browser can be driven from outside" do
|
|
26
|
+
_(WebAccount.public_method_defined?(:driver)).must_equal(true)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "is the browser Selenium made, made once" do
|
|
30
|
+
with_driver_factory do |stand_in, calls|
|
|
31
|
+
account = WebAccount.new
|
|
32
|
+
_(account.driver).must_be_same_as(stand_in)
|
|
33
|
+
_(account.driver).must_be_same_as(stand_in)
|
|
34
|
+
_(calls.length).must_equal(1)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "is made with the browser and driver options given" do
|
|
39
|
+
with_driver_factory do |stand_in, calls|
|
|
40
|
+
WebAccount.new(browser: 'Firefox', driver_options: :options).driver
|
|
41
|
+
_(calls).must_equal([[:firefox, :options]])
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
data/webaccount.gemspec
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require_relative './lib/WebAccount/VERSION'
|
|
2
|
+
|
|
3
|
+
class Gem::Specification
|
|
4
|
+
def dependencies=(gems)
|
|
5
|
+
gems.each{|gem| add_dependency(*gem)}
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def development_dependencies=(gems)
|
|
9
|
+
gems.each{|gem| add_development_dependency(*gem)}
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Gem::Specification.new do |spec|
|
|
14
|
+
spec.name = 'webaccount'
|
|
15
|
+
spec.version = WebAccount::VERSION
|
|
16
|
+
|
|
17
|
+
spec.summary = "An abstract super-class for navigating a web-based user account via Selenium WebDriver."
|
|
18
|
+
spec.description = "Easily log into web accounts by supplying just a username and password, the URL of the login page, and a few page ids to a sub-class of WebAccount."
|
|
19
|
+
|
|
20
|
+
spec.author = 'thoran'
|
|
21
|
+
spec.email = 'code@thoran.com'
|
|
22
|
+
spec.homepage = 'https://github.com/thoran/webaccount'
|
|
23
|
+
spec.license = 'MIT'
|
|
24
|
+
|
|
25
|
+
spec.require_paths = ['lib']
|
|
26
|
+
spec.required_ruby_version = '>= 3.3'
|
|
27
|
+
|
|
28
|
+
spec.files = [
|
|
29
|
+
'CHANGELOG',
|
|
30
|
+
'LICENSE',
|
|
31
|
+
'Gemfile',
|
|
32
|
+
Dir['lib/**/*.rb'],
|
|
33
|
+
'Rakefile',
|
|
34
|
+
'README.md',
|
|
35
|
+
Dir['test/**/*.rb'],
|
|
36
|
+
'webaccount.gemspec'
|
|
37
|
+
].flatten
|
|
38
|
+
|
|
39
|
+
spec.dependencies = [
|
|
40
|
+
['selenium-webdriver', '>= 4.0']
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
spec.development_dependencies = %w{
|
|
44
|
+
minitest
|
|
45
|
+
minitest-spec-context
|
|
46
|
+
rake
|
|
47
|
+
}
|
|
48
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: webaccount
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- thoran
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: selenium-webdriver
|
|
@@ -16,9 +15,51 @@ dependencies:
|
|
|
16
15
|
requirements:
|
|
17
16
|
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0'
|
|
18
|
+
version: '4.0'
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '4.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: minitest
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: minitest-spec-context
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rake
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
22
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
64
|
requirements:
|
|
24
65
|
- - ">="
|
|
@@ -31,23 +72,24 @@ executables: []
|
|
|
31
72
|
extensions: []
|
|
32
73
|
extra_rdoc_files: []
|
|
33
74
|
files:
|
|
34
|
-
-
|
|
35
|
-
-
|
|
75
|
+
- CHANGELOG
|
|
76
|
+
- Gemfile
|
|
77
|
+
- LICENSE
|
|
78
|
+
- README.md
|
|
79
|
+
- Rakefile
|
|
36
80
|
- lib/Thoran/Selenium.rb
|
|
37
81
|
- lib/Thoran/Selenium/WebDriver/Driver/Attempt/attempt.rb
|
|
38
|
-
- lib/Thoran/Selenium/WebDriver/
|
|
39
|
-
- lib/Thoran/Selenium/WebDriver/SearchContext/ElementPresentQ/element_presentQ.rb
|
|
40
|
-
- lib/Thoran/Selenium/WebDriver/SearchContext/ElementsPresentQ/elements_presentQ.rb
|
|
41
|
-
- lib/Thoran/Selenium/WebDriver/Setup/setup.rb
|
|
42
|
-
- lib/Thoran/String/ToConst/to_const.rb
|
|
43
|
-
- lib/WebAccount.rb
|
|
44
|
-
- lib/WebAccount/VERSION.rb
|
|
82
|
+
- lib/Thoran/Selenium/WebDriver/Driver/ElementPresentQ/element_presentQ.rb
|
|
45
83
|
- lib/web_account.rb
|
|
46
|
-
|
|
84
|
+
- lib/webaccount.rb
|
|
85
|
+
- lib/webaccount/VERSION.rb
|
|
86
|
+
- test/Thoran/Selenium/WebDriver/Driver/Attempt_test.rb
|
|
87
|
+
- test/webaccount_test.rb
|
|
88
|
+
- webaccount.gemspec
|
|
89
|
+
homepage: https://github.com/thoran/webaccount
|
|
47
90
|
licenses:
|
|
48
|
-
-
|
|
91
|
+
- MIT
|
|
49
92
|
metadata: {}
|
|
50
|
-
post_install_message:
|
|
51
93
|
rdoc_options: []
|
|
52
94
|
require_paths:
|
|
53
95
|
- lib
|
|
@@ -55,15 +97,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
55
97
|
requirements:
|
|
56
98
|
- - ">="
|
|
57
99
|
- !ruby/object:Gem::Version
|
|
58
|
-
version: '
|
|
100
|
+
version: '3.3'
|
|
59
101
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
102
|
requirements:
|
|
61
103
|
- - ">="
|
|
62
104
|
- !ruby/object:Gem::Version
|
|
63
105
|
version: '0'
|
|
64
106
|
requirements: []
|
|
65
|
-
rubygems_version:
|
|
66
|
-
signing_key:
|
|
107
|
+
rubygems_version: 4.0.22
|
|
67
108
|
specification_version: 4
|
|
68
109
|
summary: An abstract super-class for navigating a web-based user account via Selenium
|
|
69
110
|
WebDriver.
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# Thoran/Array/AllButFirst/all_but_first.rb
|
|
2
|
-
# Thoran::Array::AllButFirst#all_but_first
|
|
3
|
-
|
|
4
|
-
# 20141223
|
|
5
|
-
# 0.1.0
|
|
6
|
-
|
|
7
|
-
# Description: This returns a copy of the receiving array with the first element removed.
|
|
8
|
-
|
|
9
|
-
# Changes:
|
|
10
|
-
# 1. + Thoran namespace.
|
|
11
|
-
|
|
12
|
-
require 'Thoran/Array/FirstX/firstX'
|
|
13
|
-
|
|
14
|
-
module Thoran
|
|
15
|
-
module Array
|
|
16
|
-
module AllButFirst
|
|
17
|
-
|
|
18
|
-
def all_but_first
|
|
19
|
-
d = self.dup
|
|
20
|
-
d.first!
|
|
21
|
-
d
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
Array.send(:include, Thoran::Array::AllButFirst)
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# Thoran/Array/FirstX/firstX.rb
|
|
2
|
-
# Thoran::Array::FirstX#first!
|
|
3
|
-
|
|
4
|
-
# 20141223
|
|
5
|
-
# 0.1.0
|
|
6
|
-
|
|
7
|
-
# Description: Sometimes it makes more sense to treat arrays this way.
|
|
8
|
-
|
|
9
|
-
module Thoran
|
|
10
|
-
module Array
|
|
11
|
-
module FirstX
|
|
12
|
-
|
|
13
|
-
def first!
|
|
14
|
-
shift
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
Array.send(:include, Thoran::Array::FirstX)
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# Thoran/Selenium/WebDriver/Remote/W3C/BridgeMonkeyPatch/ConvertLocators.convert_locators.rb
|
|
2
|
-
# Thoran::Selenium::WebDriver::Remote::W3C::BridgeMonkeyPatch::ConvertLocators.convert_locators
|
|
3
|
-
|
|
4
|
-
# 20200418
|
|
5
|
-
# 0.0.0
|
|
6
|
-
|
|
7
|
-
# Changes:
|
|
8
|
-
# 1. + Thoran namespace.
|
|
9
|
-
|
|
10
|
-
module Thoran
|
|
11
|
-
module Selenium
|
|
12
|
-
module WebDriver
|
|
13
|
-
module Remote
|
|
14
|
-
module W3C
|
|
15
|
-
module Bridge
|
|
16
|
-
module ConvertLocators
|
|
17
|
-
|
|
18
|
-
def convert_locators(how, what)
|
|
19
|
-
case how.to_s
|
|
20
|
-
when 'class name'
|
|
21
|
-
how = 'css selector'
|
|
22
|
-
what = ".#{escape_css(what)}"
|
|
23
|
-
when 'id'
|
|
24
|
-
how = 'css selector'
|
|
25
|
-
what = "##{escape_css(what)}"
|
|
26
|
-
when 'name'
|
|
27
|
-
how = 'css selector'
|
|
28
|
-
what = "*[name='#{escape_css(what)}']"
|
|
29
|
-
when 'tag name'
|
|
30
|
-
how = 'css selector'
|
|
31
|
-
end
|
|
32
|
-
[how, what]
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
module Selenium
|
|
44
|
-
module WebDriver
|
|
45
|
-
module Remote
|
|
46
|
-
module W3C
|
|
47
|
-
Bridge.prepend(Thoran::Selenium::WebDriver::Remote::W3C::Bridge::ConvertLocators)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|