moby.rb 1.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 +7 -0
- data/CHANGES.txt +32 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +172 -0
- data/Rakefile +22 -0
- data/bin/moby +67 -0
- data/lib/File/self.collect.rb +10 -0
- data/lib/Moby/Backends/MechanizeBackend.rb +157 -0
- data/lib/Moby/Backends/SeleniumBackend.rb +236 -0
- data/lib/Moby/Configuration.rb +113 -0
- data/lib/Moby/RandomInputGenerator.rb +49 -0
- data/lib/Moby/VERSION.rb +6 -0
- data/lib/Moby.rb +179 -0
- data/lib/Selenium/WebDriver/Driver/Attempt/attempt.rb +18 -0
- data/lib/Selenium/WebDriver/SearchContext/ElementPresentQ/element_presentQ.rb +13 -0
- data/lib/Thoran/File/SelfCollect/self.collect.rb +22 -0
- data/lib/Thoran/Selenium/WebDriver/Driver/Attempt/attempt.rb +53 -0
- data/lib/Thoran/Selenium/WebDriver/SearchContext/ElementPresentQ/element_presentQ.rb +39 -0
- data/moby.gemspec +51 -0
- data/test/Moby/VERSION_test.rb +23 -0
- data/test/moby_test.rb +295 -0
- data/test/test_helper.rb +36 -0
- metadata +153 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 59fc23e9713b37a55d2e866bc1109b525dd188f04136092b05ae0b8f2a860d10
|
|
4
|
+
data.tar.gz: 6945ecfdea1a8f3437bae309c1d9b0e20dbe31d3a28006699e145e9dd57abec9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f909d78a0a23c40143f3ed9d876a80b5fdd1f963670cbaea39d5f5ad42224ee0458adf1a095c9734c65e95e122b6ba9b69ea65fe95e860edf03c12442c2eab65
|
|
7
|
+
data.tar.gz: 1eb639787025eccdcc74517655651eef1e0ef2d142015abaad3523eab31dcc298f33e1a5bf7afb66735b281856261a49f03f499792eca4f7ad8c93c6f89036e1
|
data/CHANGES.txt
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
1.0.0 - 2026-01-08
|
|
2
|
+
Ensure that tests are in place and that version handling is working properly.
|
|
3
|
+
+ tests
|
|
4
|
+
+ moby.gemspec
|
|
5
|
+
~ lib/moby.rb: - Moby::VERSION_STRING
|
|
6
|
+
~ lib/moby.rb: Fix finding username and password fields by name. It was returning the name of the field and not the field object.
|
|
7
|
+
+ lib/Moby/VERSION.rb
|
|
8
|
+
~ bin/moby: + --version flag
|
|
9
|
+
~ README.md: Updated installation and usage.
|
|
10
|
+
~ CHANGES.txt: Reorganised in descending order and added dates.
|
|
11
|
+
~ LICENSE.txt: Updated the years to include the year this was started: /2026/2006-2026/
|
|
12
|
+
|
|
13
|
+
0.9.1 - 2026-01-05
|
|
14
|
+
~ README.md: Fix syntax errors.
|
|
15
|
+
~ lib/Moby.rb: VERSION_STRING: /0.9.0/0.9.1/
|
|
16
|
+
|
|
17
|
+
0.9.0 - 2024-06-05
|
|
18
|
+
Merged the 2019 0.8.0 version of moby with the 2023 0.8.1 version of whale.
|
|
19
|
+
|
|
20
|
+
0.8.1 - 2023-12-06
|
|
21
|
+
~ lib/Whale: ~ set_username_field(): Fix when username field number is specified or nothing is specified.
|
|
22
|
+
~ lib/Whale: ~ set_password_field(): Fix when password field number is specified or nothing is specified.
|
|
23
|
+
|
|
24
|
+
0.8.0 - 2023-11-19
|
|
25
|
+
+ README.md
|
|
26
|
+
+ CHANGES.txt
|
|
27
|
+
+ Gemfile
|
|
28
|
+
~ bin/whale: ~ main(): - args (unnecessary)
|
|
29
|
+
~ bin/whale VERSION_STRING --> lib/Whale::VERSION_STRING
|
|
30
|
+
~ bin/whale: ~ switches(): use Whale::VERSION_STRING
|
|
31
|
+
~ lib/Whale.rb: general tidying
|
|
32
|
+
+ lib/File/self.collect.rb
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2006-2026 thoran
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# moby
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
## Description
|
|
7
|
+
|
|
8
|
+
"Sometimes when they go fishing, they get a whale and it sinks their boat."
|
|
9
|
+
|
|
10
|
+
Moby is a credentials poisoning tool which floods phishing forms with fake credentials. When phishing operations collect data, the overwhelming volume of fake credentials makes the collected data worthless.
|
|
11
|
+
|
|
12
|
+
Use responsibly. Only target confirmed phishing sites.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### Prerequisites
|
|
17
|
+
1. Some version of Ruby.
|
|
18
|
+
2. \*nix, so that it has access to /usr/share/dict/words.
|
|
19
|
+
|
|
20
|
+
### 1. via RubyGems
|
|
21
|
+
```shell
|
|
22
|
+
$ gem install moby.rb
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### 2. via Bundler
|
|
26
|
+
Add to your Gemfile:
|
|
27
|
+
```ruby
|
|
28
|
+
gem 'moby.rb'
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Then run:
|
|
32
|
+
```shell
|
|
33
|
+
$ bundle install
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 3. via Homebrew
|
|
37
|
+
```shell
|
|
38
|
+
$ brew tap thoran/tap
|
|
39
|
+
$ brew install thoran/tap/moby
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 4. via git
|
|
43
|
+
```shell
|
|
44
|
+
$ git clone git@github.com:thoran/moby.git
|
|
45
|
+
$ cd moby
|
|
46
|
+
$ bundle install
|
|
47
|
+
$ rake test
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Usage
|
|
51
|
+
|
|
52
|
+
### From the command line
|
|
53
|
+
|
|
54
|
+
#### 1. Specify form name and field names
|
|
55
|
+
```shell
|
|
56
|
+
$ moby --url https://phishing.site --form_name form-name --username_field_name login --password_field_name password
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### 2. Specify form name and field names with short switches
|
|
60
|
+
This is the same as above, but using alternate switches:
|
|
61
|
+
|
|
62
|
+
```shell
|
|
63
|
+
$ moby --url https://phishing.site --f form-name --user_field login --pass_field password
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### 3. Specify form number and field numbers
|
|
67
|
+
This selects the second form on the page (using zero-based indexing) and the first and second fields:
|
|
68
|
+
|
|
69
|
+
```shell
|
|
70
|
+
$ moby --url https://phishing.site --form_number 1 --username_field_number 0 --password_field_number 1
|
|
71
|
+
```
|
|
72
|
+
#### 4. Specify form number and field numbers with short switches
|
|
73
|
+
This selects the second form on the page (using zero-based indexing) and the first and second fields:
|
|
74
|
+
|
|
75
|
+
```shell
|
|
76
|
+
$ moby --url https://phishing.site --form_number 1 --user_field_number 0 --pass_field_number 1
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### 5. Specify nothing but the URL
|
|
80
|
+
```shell
|
|
81
|
+
$ moby --url https://phishing.site
|
|
82
|
+
```
|
|
83
|
+
This is equivalent to:
|
|
84
|
+
|
|
85
|
+
```shell
|
|
86
|
+
$ moby --url https://phishing.site --form_number 0 --username_field_number 0 --password_field_number 1
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### 6. With other options
|
|
90
|
+
```shell
|
|
91
|
+
$ moby --url https://phishing.site --debug --user_agent 'Mozilla/5.0' --username_hostname mydomain.com --username_is_email_address --verbose
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Note that `username_hostname` is useful only if `username_is_email_address` is true.
|
|
95
|
+
|
|
96
|
+
### From within Ruby
|
|
97
|
+
|
|
98
|
+
#### 1. Specify form name and field names
|
|
99
|
+
```ruby
|
|
100
|
+
require 'moby'
|
|
101
|
+
|
|
102
|
+
moby = Moby.new(
|
|
103
|
+
url: 'https://phishing.site',
|
|
104
|
+
form_name: 'form-name',
|
|
105
|
+
username_field_name: 'login',
|
|
106
|
+
password_field_name: 'password'
|
|
107
|
+
)
|
|
108
|
+
moby.counter_phish
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### 2. Specify form number and field numbers
|
|
112
|
+
This selects the second form on the page (using zero-based indexing) and uses the first and second fields therein:
|
|
113
|
+
|
|
114
|
+
```ruby
|
|
115
|
+
require 'moby'
|
|
116
|
+
|
|
117
|
+
moby = Moby.new(
|
|
118
|
+
url: 'https://phishing.site',
|
|
119
|
+
form_number: 1,
|
|
120
|
+
username_field_number: 0,
|
|
121
|
+
password_field_number: 1,
|
|
122
|
+
)
|
|
123
|
+
moby.counter_phish
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
#### 3. Specify nothing but the URL
|
|
127
|
+
```ruby
|
|
128
|
+
require 'moby'
|
|
129
|
+
|
|
130
|
+
moby = Moby.new(
|
|
131
|
+
url: 'https://phishing.site',
|
|
132
|
+
)
|
|
133
|
+
moby.counter_phish
|
|
134
|
+
```
|
|
135
|
+
This is equivalent to:
|
|
136
|
+
|
|
137
|
+
```ruby
|
|
138
|
+
require 'moby'
|
|
139
|
+
|
|
140
|
+
moby = Moby.new(
|
|
141
|
+
url: 'https://phishing.site',
|
|
142
|
+
form_number: 0,
|
|
143
|
+
username_field_number: 0,
|
|
144
|
+
password_field_number: 1,
|
|
145
|
+
)
|
|
146
|
+
moby.counter_phish
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
#### 4. With other options
|
|
150
|
+
```ruby
|
|
151
|
+
require 'moby'
|
|
152
|
+
|
|
153
|
+
moby = Moby.new(
|
|
154
|
+
url: 'https://phishing.site',
|
|
155
|
+
debug: true,
|
|
156
|
+
user_agent: 'Mozilla/5.0',
|
|
157
|
+
username_hostname: 'mydomain.com', # Only useful if username_is_email_address is true.
|
|
158
|
+
username_is_email_address: true,
|
|
159
|
+
verbose: true
|
|
160
|
+
)
|
|
161
|
+
moby.counter_phish
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Note that there's no equivalent short names for constructor arguments.
|
|
165
|
+
|
|
166
|
+
## Contributing
|
|
167
|
+
|
|
168
|
+
1. Fork it: `https://github.com/thoran/moby/fork`
|
|
169
|
+
2. Create your feature branch: `git checkout -b my-new-feature`
|
|
170
|
+
3. Commit your changes: `git commit -am 'Add some feature'`
|
|
171
|
+
4. Push to the branch: `git push origin my-new-feature`
|
|
172
|
+
5. Create a new pull request
|
data/Rakefile
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Rakefile
|
|
2
|
+
|
|
3
|
+
require 'rake/testtask'
|
|
4
|
+
|
|
5
|
+
Rake::TestTask.new(:test) do |t|
|
|
6
|
+
t.libs << 'lib'
|
|
7
|
+
t.libs << 'test'
|
|
8
|
+
t.test_files = FileList['test/**/*_test.rb']
|
|
9
|
+
t.verbose = true
|
|
10
|
+
t.warning = false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
task default: :test
|
|
14
|
+
|
|
15
|
+
desc "Run tests"
|
|
16
|
+
task :spec => :test
|
|
17
|
+
|
|
18
|
+
desc "Show version"
|
|
19
|
+
task :version do
|
|
20
|
+
require_relative './lib/Moby/VERSION'
|
|
21
|
+
puts "moby #{Moby::VERSION}"
|
|
22
|
+
end
|
data/bin/moby
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# moby
|
|
3
|
+
|
|
4
|
+
# moby is a credentials poisoning tool which floods phishing forms with fake credentials.
|
|
5
|
+
|
|
6
|
+
lib_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
7
|
+
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
|
8
|
+
|
|
9
|
+
require 'Moby'
|
|
10
|
+
require 'switches.rb'
|
|
11
|
+
|
|
12
|
+
def switches
|
|
13
|
+
Switches.new do |s|
|
|
14
|
+
s.banner = 'Usage: whale <url> and any of the following options...'
|
|
15
|
+
s.set(:a, :user_agent){'What webclient I should pretend to be.'}
|
|
16
|
+
s.set(:debug?){'Show debugging information.'}
|
|
17
|
+
s.set(:e?, :username_is_email_address?){'Automatically generate a username which is in the form of an email address.'}
|
|
18
|
+
s.set(:f, :form, :form_name){'If left empty, the first form on the page will be used.'}
|
|
19
|
+
s.set(:help){'Usage: whale <url> and any of the following options...'}
|
|
20
|
+
s.set(:n, :form_number){'This will set the number of the form in order of appearance on the page. Use zero-based indexing.'}
|
|
21
|
+
s.set(:pass_field, :password_field, :pass_field_name, :password_field_name){'The name of the password field.'}
|
|
22
|
+
s.set(:pass_field_number, :password_field_number){'The position of the password field in relation to the form it is attached to. Use zero-based indexing.'}
|
|
23
|
+
s.set(:url){'The location of the phishing form.'}
|
|
24
|
+
s.set(:user_field, :username_field, :user_field_name, :username_field_name){'The name of the username field.'}
|
|
25
|
+
s.set(:user_field_number, :username_field_number){'The position of the username field in relation to the form it is attached to. Use zero-based indexing.'}
|
|
26
|
+
s.set(:username_hostname){'The hostname to be used when the username is an email address.'}
|
|
27
|
+
s.set(:username_prefilled){'No need to supply an email address in the form.'}
|
|
28
|
+
s.set(:v?, :verbose?){'Outputs each submission as it goes.'}
|
|
29
|
+
s.perform(:version) do
|
|
30
|
+
puts "moby #{Moby::VERSION}"
|
|
31
|
+
exit
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def main
|
|
37
|
+
args = switches.to_h
|
|
38
|
+
debug = args[:debug?]
|
|
39
|
+
form_name = args[:form_name]
|
|
40
|
+
form_number = args[:form_number]
|
|
41
|
+
password_field_name = args[:password_field_name]
|
|
42
|
+
password_field_number = args[:password_field_number]
|
|
43
|
+
url = args[:url]
|
|
44
|
+
user_agent = args[:user_agent]
|
|
45
|
+
username_field_name = args[:username_field_name]
|
|
46
|
+
username_field_number = args[:username_field_number]
|
|
47
|
+
username_hostname = args[:username_hostname]
|
|
48
|
+
username_is_email_address = args[:username_is_email_address?]
|
|
49
|
+
verbose = args[:verbose?]
|
|
50
|
+
moby = Moby.new(
|
|
51
|
+
debug: debug,
|
|
52
|
+
form_name: form_name,
|
|
53
|
+
form_number: form_number,
|
|
54
|
+
password_field_name: password_field_name,
|
|
55
|
+
password_field_number: password_field_number,
|
|
56
|
+
url: url,
|
|
57
|
+
user_agent: user_agent,
|
|
58
|
+
username_field_name: username_field_name,
|
|
59
|
+
username_field_number: username_field_number,
|
|
60
|
+
username_hostname: username_hostname,
|
|
61
|
+
username_is_email_address: username_is_email_address,
|
|
62
|
+
verbose: verbose
|
|
63
|
+
)
|
|
64
|
+
moby.counter_phish
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
main
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# lib/moby/backends/mechanize_backend.rb
|
|
2
|
+
# Moby::Backends::MechanizeBackend
|
|
3
|
+
|
|
4
|
+
require 'mechanize'
|
|
5
|
+
require 'pp'
|
|
6
|
+
|
|
7
|
+
class Moby
|
|
8
|
+
module Backends
|
|
9
|
+
class MechanizeBackend
|
|
10
|
+
def counter_phish
|
|
11
|
+
set_up_agent
|
|
12
|
+
load_page
|
|
13
|
+
repeatedly_fill_and_submit_login_form
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def initialize(config:, random_input_generator:)
|
|
19
|
+
@config = config
|
|
20
|
+
@random_input_generator = random_input_generator
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def agent
|
|
24
|
+
@agent ||= (
|
|
25
|
+
puts "Setting up Mechanize agent..." if @config.verbose?
|
|
26
|
+
agent = Mechanize.new
|
|
27
|
+
puts "Agent setup complete." if @config.verbose?
|
|
28
|
+
agent
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
alias_method :set_up_agent, :agent
|
|
32
|
+
|
|
33
|
+
def page
|
|
34
|
+
@page ||= (
|
|
35
|
+
puts "Navigating to #{@config.url}..." if @config.verbose?
|
|
36
|
+
page = agent.get(@config.url)
|
|
37
|
+
puts "Page loaded successfully." if @config.verbose?
|
|
38
|
+
page
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
alias_method :load_page, :page
|
|
42
|
+
|
|
43
|
+
def form
|
|
44
|
+
@form ||= (
|
|
45
|
+
if @config.using_form_name?
|
|
46
|
+
find_form_by_name
|
|
47
|
+
else
|
|
48
|
+
find_form_by_number
|
|
49
|
+
end
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def repeatedly_fill_and_submit_login_form
|
|
54
|
+
start_time = Time.now
|
|
55
|
+
puts "moby session begun #{start_time}."
|
|
56
|
+
submission_count = 0
|
|
57
|
+
begin
|
|
58
|
+
if @config.fixed_number_of_submissions?
|
|
59
|
+
@config.iterations.times do |iteration|
|
|
60
|
+
fill_and_submit_login_form
|
|
61
|
+
submission_count += 1
|
|
62
|
+
puts "Iteration #{submission_count} of #{@config.iterations}." if @config.verbose?
|
|
63
|
+
end
|
|
64
|
+
puts "Successfully completed #{@config.iterations} submissions." if @config.verbose?
|
|
65
|
+
else
|
|
66
|
+
loop do
|
|
67
|
+
fill_and_submit_login_form
|
|
68
|
+
submission_count += 1
|
|
69
|
+
puts "#{submission_count} #{username}:#{password}" if @config.verbose?
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
ensure
|
|
73
|
+
finish_time = Time.now
|
|
74
|
+
time_delta_in_minutes = (finish_time - start_time) / 60
|
|
75
|
+
submissions_per_minute = submission_count / time_delta_in_minutes
|
|
76
|
+
puts "moby session terminated #{finish_time} with #{submission_count} counter-phishes served in #{time_delta_in_minutes} minutes for an average of #{submissions_per_minute} submissions per minute."
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def fill_and_submit_login_form
|
|
81
|
+
puts "Filling with: #{username}:#{password}" if @config.verbose?
|
|
82
|
+
agent.user_agent_alias = @config.user_agent
|
|
83
|
+
username_field.value = username
|
|
84
|
+
password_field.value = password
|
|
85
|
+
pp page if @config.debug?
|
|
86
|
+
result = agent.submit(form)
|
|
87
|
+
pp result if @config.debug?
|
|
88
|
+
sleep @config.delay if @config.delay > 0
|
|
89
|
+
rescue Net::HTTP::Persistent::Error
|
|
90
|
+
puts "\n\nNet::HTTP::Persistent::Error rescued.\n\n" if @config.verbose?
|
|
91
|
+
rescue Net::OpenTimeout
|
|
92
|
+
puts "\n\nNet::OpenTimeout rescued.\n\n" if @config.verbose?
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def find_form_by_name
|
|
96
|
+
page.form_with(name: @config.form_name) ||
|
|
97
|
+
page.form_with(id: @config.form_name) ||
|
|
98
|
+
raise("Could not find a form with the name or id of #{@config.form_name}.")
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def find_form_by_number
|
|
102
|
+
page.forms[@config.form_number] ||
|
|
103
|
+
raise("Could not find a form at index #{@config.form_number}.")
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def username
|
|
107
|
+
@random_input_generator.random_username
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def password
|
|
111
|
+
@random_input_generator.random_password
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def username_field
|
|
115
|
+
@username_field ||=(
|
|
116
|
+
if @config.using_username_field_name?
|
|
117
|
+
find_username_field_by_name
|
|
118
|
+
else
|
|
119
|
+
find_username_field_by_number
|
|
120
|
+
end
|
|
121
|
+
)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def password_field
|
|
125
|
+
@password_field ||= (
|
|
126
|
+
if @config.using_password_field_name?
|
|
127
|
+
find_password_field_by_name
|
|
128
|
+
else
|
|
129
|
+
find_password_field_by_number
|
|
130
|
+
end
|
|
131
|
+
)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def find_username_field_by_name
|
|
135
|
+
form.field_with(name: @config.username_field_name) ||
|
|
136
|
+
form.field_with(id: @config.username_field_name) ||
|
|
137
|
+
raise("Could not find username field: #{@config.username_field_name}")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def find_username_field_by_number
|
|
141
|
+
form.fields[@config.username_field_number] ||
|
|
142
|
+
raise("Could not find username field at index #{@config.username_field_number}")
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def find_password_field_by_name
|
|
146
|
+
form.field_with(name: @config.password_field_name) ||
|
|
147
|
+
form.field_with(id: @config.password_field_name) ||
|
|
148
|
+
raise("Could not find password field: #{@config.password_field_name}.")
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def find_password_field_by_number
|
|
152
|
+
form.fields[@config.password_field_number] ||
|
|
153
|
+
raise("Could not find password field at index: #{@config.password_field_number}.")
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|