mini_autobot 0.0.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 +7 -0
- data/.gitignore +26 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +191 -0
- data/LICENSE +22 -0
- data/README.md +632 -0
- data/bin/mini_autobot +5 -0
- data/lib/mini_autobot.rb +44 -0
- data/lib/mini_autobot/connector.rb +288 -0
- data/lib/mini_autobot/console.rb +15 -0
- data/lib/mini_autobot/emails.rb +5 -0
- data/lib/mini_autobot/emails/mailbox.rb +15 -0
- data/lib/mini_autobot/endeca/base.rb +6 -0
- data/lib/mini_autobot/init.rb +63 -0
- data/lib/mini_autobot/logger.rb +12 -0
- data/lib/mini_autobot/page_objects.rb +22 -0
- data/lib/mini_autobot/page_objects/base.rb +264 -0
- data/lib/mini_autobot/page_objects/overlay/base.rb +76 -0
- data/lib/mini_autobot/page_objects/widgets/base.rb +47 -0
- data/lib/mini_autobot/parallel.rb +197 -0
- data/lib/mini_autobot/runner.rb +91 -0
- data/lib/mini_autobot/settings.rb +78 -0
- data/lib/mini_autobot/test_case.rb +233 -0
- data/lib/mini_autobot/test_cases.rb +7 -0
- data/lib/mini_autobot/utils.rb +10 -0
- data/lib/mini_autobot/utils/assertion_helper.rb +35 -0
- data/lib/mini_autobot/utils/castable.rb +103 -0
- data/lib/mini_autobot/utils/data_generator_helper.rb +145 -0
- data/lib/mini_autobot/utils/endeca_helper.rb +46 -0
- data/lib/mini_autobot/utils/loggable.rb +16 -0
- data/lib/mini_autobot/utils/overlay_and_widget_helper.rb +78 -0
- data/lib/mini_autobot/utils/page_object_helper.rb +209 -0
- data/lib/mini_autobot/version.rb +3 -0
- data/lib/minitap/minitest5_rent.rb +22 -0
- data/lib/minitest/autobot_settings_plugin.rb +77 -0
- data/lib/tapout/custom_reporters/fancy_tap_reporter.rb +94 -0
- data/lib/yard/tagged_test_case_handler.rb +61 -0
- data/mini_autobot.gemspec +38 -0
- metadata +299 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 07bfa98f67061e2dce64bed72de1d674bb30d3b6
|
4
|
+
data.tar.gz: 0fdc455f8d5bbf1ba1b25b8e91971bfb8733400e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4c499b1873bb699eda4907a921084ad05d5cbb08fdf9f847aab0e163111bc0e50b51bd91446f3476d2831140fdef6199c102ff4ab07b80bf22c50f9e026199b3
|
7
|
+
data.tar.gz: 92a4539d1dea671d6e5ba03b9f9570078d899a151e7b18381020305d897790cb0c3a07d0359a3f3a0346cafc47582249c1fbeffde92a1fda868c9796e328db60
|
data/.gitignore
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# vi swap files (the extra letters are used when there are duplicates)
|
2
|
+
*.sw[ponml]
|
3
|
+
.DS_Store
|
4
|
+
|
5
|
+
README.html
|
6
|
+
|
7
|
+
# emacs backup files (also used by other programs)
|
8
|
+
*~
|
9
|
+
\#*
|
10
|
+
.\#*
|
11
|
+
.nfs*
|
12
|
+
.bundle
|
13
|
+
|
14
|
+
# Ignore (IDE) project files
|
15
|
+
.idea
|
16
|
+
.project
|
17
|
+
.projects
|
18
|
+
.settings
|
19
|
+
*.sublime-*
|
20
|
+
|
21
|
+
# YARDoc files
|
22
|
+
.yardoc
|
23
|
+
doc
|
24
|
+
|
25
|
+
# temporary files
|
26
|
+
tmp
|
data/.rspec
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.3
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
mini_autobot (0.0.0)
|
5
|
+
activesupport (~> 4.2)
|
6
|
+
faker (~> 1.4)
|
7
|
+
google-api-client (~> 0.8)
|
8
|
+
google_drive (~> 1.0)
|
9
|
+
mail (~> 2.6)
|
10
|
+
minitap (~> 0.5.3)
|
11
|
+
minitest (~> 5.4.0)
|
12
|
+
pry (~> 0.10)
|
13
|
+
rest-client (~> 1.8)
|
14
|
+
selenium-webdriver (~> 2.46)
|
15
|
+
|
16
|
+
GEM
|
17
|
+
remote: https://rubygems.org/
|
18
|
+
specs:
|
19
|
+
activesupport (4.2.3)
|
20
|
+
i18n (~> 0.7)
|
21
|
+
json (~> 1.7, >= 1.7.7)
|
22
|
+
minitest (~> 5.1)
|
23
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
24
|
+
tzinfo (~> 1.1)
|
25
|
+
addressable (2.3.8)
|
26
|
+
ansi (1.5.0)
|
27
|
+
autoparse (0.3.3)
|
28
|
+
addressable (>= 2.3.1)
|
29
|
+
extlib (>= 0.9.15)
|
30
|
+
multi_json (>= 1.0.0)
|
31
|
+
childprocess (0.5.6)
|
32
|
+
ffi (~> 1.0, >= 1.0.11)
|
33
|
+
coderay (1.1.0)
|
34
|
+
diff-lcs (1.2.5)
|
35
|
+
domain_name (0.5.24)
|
36
|
+
unf (>= 0.0.5, < 1.0.0)
|
37
|
+
extlib (0.9.16)
|
38
|
+
faker (1.4.3)
|
39
|
+
i18n (~> 0.5)
|
40
|
+
faraday (0.9.1)
|
41
|
+
multipart-post (>= 1.2, < 3)
|
42
|
+
ffi (1.9.10)
|
43
|
+
formatador (0.2.5)
|
44
|
+
google-api-client (0.8.6)
|
45
|
+
activesupport (>= 3.2)
|
46
|
+
addressable (~> 2.3)
|
47
|
+
autoparse (~> 0.3)
|
48
|
+
extlib (~> 0.9)
|
49
|
+
faraday (~> 0.9)
|
50
|
+
googleauth (~> 0.3)
|
51
|
+
launchy (~> 2.4)
|
52
|
+
multi_json (~> 1.10)
|
53
|
+
retriable (~> 1.4)
|
54
|
+
signet (~> 0.6)
|
55
|
+
google_drive (1.0.1)
|
56
|
+
google-api-client (>= 0.7.0)
|
57
|
+
nokogiri (>= 1.4.4, != 1.5.2, != 1.5.1)
|
58
|
+
oauth (>= 0.3.6)
|
59
|
+
oauth2 (>= 0.5.0)
|
60
|
+
googleauth (0.4.2)
|
61
|
+
faraday (~> 0.9)
|
62
|
+
jwt (~> 1.4)
|
63
|
+
logging (~> 2.0)
|
64
|
+
memoist (~> 0.12)
|
65
|
+
multi_json (~> 1.11)
|
66
|
+
signet (~> 0.6)
|
67
|
+
guard (2.13.0)
|
68
|
+
formatador (>= 0.2.4)
|
69
|
+
listen (>= 2.7, <= 4.0)
|
70
|
+
lumberjack (~> 1.0)
|
71
|
+
nenv (~> 0.1)
|
72
|
+
notiffany (~> 0.0)
|
73
|
+
pry (>= 0.9.12)
|
74
|
+
shellany (~> 0.0)
|
75
|
+
thor (>= 0.18.1)
|
76
|
+
guard-compat (1.2.1)
|
77
|
+
guard-minitest (2.4.4)
|
78
|
+
guard-compat (~> 1.2)
|
79
|
+
minitest (>= 3.0)
|
80
|
+
http-cookie (1.0.2)
|
81
|
+
domain_name (~> 0.5)
|
82
|
+
i18n (0.7.0)
|
83
|
+
json (1.8.3)
|
84
|
+
jwt (1.5.1)
|
85
|
+
launchy (2.4.3)
|
86
|
+
addressable (~> 2.3)
|
87
|
+
listen (3.0.3)
|
88
|
+
rb-fsevent (>= 0.9.3)
|
89
|
+
rb-inotify (>= 0.9)
|
90
|
+
little-plugger (1.1.3)
|
91
|
+
logging (2.0.0)
|
92
|
+
little-plugger (~> 1.1)
|
93
|
+
multi_json (~> 1.10)
|
94
|
+
lumberjack (1.0.9)
|
95
|
+
mail (2.6.3)
|
96
|
+
mime-types (>= 1.16, < 3)
|
97
|
+
memoist (0.12.0)
|
98
|
+
method_source (0.8.2)
|
99
|
+
mime-types (2.6.1)
|
100
|
+
mini_portile (0.6.2)
|
101
|
+
minitap (0.5.3)
|
102
|
+
minitest (~> 5.0)
|
103
|
+
minitest-reporter-api (>= 0.0.2)
|
104
|
+
tapout (>= 0.3.0)
|
105
|
+
minitest (5.4.3)
|
106
|
+
minitest-reporter-api (0.0.5)
|
107
|
+
minitest (~> 5.0)
|
108
|
+
multi_json (1.11.2)
|
109
|
+
multi_xml (0.5.5)
|
110
|
+
multipart-post (2.0.0)
|
111
|
+
nenv (0.2.0)
|
112
|
+
netrc (0.10.3)
|
113
|
+
nokogiri (1.6.6.2)
|
114
|
+
mini_portile (~> 0.6.0)
|
115
|
+
notiffany (0.0.7)
|
116
|
+
nenv (~> 0.1)
|
117
|
+
shellany (~> 0.0)
|
118
|
+
oauth (0.4.7)
|
119
|
+
oauth2 (1.0.0)
|
120
|
+
faraday (>= 0.8, < 0.10)
|
121
|
+
jwt (~> 1.0)
|
122
|
+
multi_json (~> 1.3)
|
123
|
+
multi_xml (~> 0.5)
|
124
|
+
rack (~> 1.2)
|
125
|
+
pry (0.10.1)
|
126
|
+
coderay (~> 1.1.0)
|
127
|
+
method_source (~> 0.8.1)
|
128
|
+
slop (~> 3.4)
|
129
|
+
rack (1.6.4)
|
130
|
+
rake (10.4.2)
|
131
|
+
rb-fsevent (0.9.5)
|
132
|
+
rb-inotify (0.9.5)
|
133
|
+
ffi (>= 0.5.0)
|
134
|
+
rest-client (1.8.0)
|
135
|
+
http-cookie (>= 1.0.2, < 2.0)
|
136
|
+
mime-types (>= 1.16, < 3.0)
|
137
|
+
netrc (~> 0.7)
|
138
|
+
retriable (1.4.1)
|
139
|
+
rspec (3.3.0)
|
140
|
+
rspec-core (~> 3.3.0)
|
141
|
+
rspec-expectations (~> 3.3.0)
|
142
|
+
rspec-mocks (~> 3.3.0)
|
143
|
+
rspec-core (3.3.1)
|
144
|
+
rspec-support (~> 3.3.0)
|
145
|
+
rspec-expectations (3.3.0)
|
146
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
147
|
+
rspec-support (~> 3.3.0)
|
148
|
+
rspec-mocks (3.3.1)
|
149
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
150
|
+
rspec-support (~> 3.3.0)
|
151
|
+
rspec-support (3.3.0)
|
152
|
+
rubyzip (1.1.7)
|
153
|
+
selenium-webdriver (2.47.1)
|
154
|
+
childprocess (~> 0.5)
|
155
|
+
multi_json (~> 1.0)
|
156
|
+
rubyzip (~> 1.0)
|
157
|
+
websocket (~> 1.0)
|
158
|
+
shellany (0.0.1)
|
159
|
+
signet (0.6.1)
|
160
|
+
addressable (~> 2.3)
|
161
|
+
extlib (~> 0.9)
|
162
|
+
faraday (~> 0.9)
|
163
|
+
jwt (~> 1.5)
|
164
|
+
multi_json (~> 1.10)
|
165
|
+
slop (3.6.0)
|
166
|
+
tapout (0.4.5)
|
167
|
+
ansi
|
168
|
+
json
|
169
|
+
thor (0.19.1)
|
170
|
+
thread_safe (0.3.5)
|
171
|
+
tzinfo (1.2.2)
|
172
|
+
thread_safe (~> 0.1)
|
173
|
+
unf (0.1.4)
|
174
|
+
unf_ext
|
175
|
+
unf_ext (0.0.7.1)
|
176
|
+
websocket (1.2.2)
|
177
|
+
yard (0.8.7.6)
|
178
|
+
|
179
|
+
PLATFORMS
|
180
|
+
ruby
|
181
|
+
|
182
|
+
DEPENDENCIES
|
183
|
+
guard
|
184
|
+
guard-minitest
|
185
|
+
mini_autobot!
|
186
|
+
rake
|
187
|
+
rspec (~> 3.3.0)
|
188
|
+
yard
|
189
|
+
|
190
|
+
BUNDLED WITH
|
191
|
+
1.10.5
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 RentPath, Inc.
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,632 @@
|
|
1
|
+
|
2
|
+
# MiniAutobot
|
3
|
+
|
4
|
+
Wrapper of minitest and selenium-webdriver that supports multiple OS/browser
|
5
|
+
UI automation testing, for either testing multiple webapps in one automation repo,
|
6
|
+
or testing one webapp with tests embedded in the webapp repo directly with
|
7
|
+
configuration guide provided below.
|
8
|
+
|
9
|
+
It's ready to be integrated in development pipeline with jenkins and saucelabs.
|
10
|
+
|
11
|
+
|
12
|
+
## Prerequisites
|
13
|
+
|
14
|
+
#### Firefox
|
15
|
+
|
16
|
+
When running locally (with a browser installed on the same machine), all you
|
17
|
+
need is a supported version of the operating system and browser combination.
|
18
|
+
|
19
|
+
For example, to run against Firefox, all you need to do is run tests with the
|
20
|
+
`firefox` connector (which uses the `firefox` bridge). The connector (and the
|
21
|
+
bridge behind it) will automatically start the browser in the desired mode.
|
22
|
+
|
23
|
+
#### PhantomJS
|
24
|
+
|
25
|
+
On Mac OS X, PhantomJS can be installed on [HomeBrew](http://brew.sh). Once
|
26
|
+
you have HomeBrew installed, and `brew doctor` returns an all okay, you can:
|
27
|
+
|
28
|
+
$ brew install phantomjs
|
29
|
+
|
30
|
+
and it should be installed in a minute or so. Before any test are run, you'll
|
31
|
+
want to start PhantomJS:
|
32
|
+
|
33
|
+
$ phantomjs --webdriver=127.0.0.1:8910
|
34
|
+
|
35
|
+
Those parameters are compatible with the `phantomjs` connector supplied in this
|
36
|
+
project. It can also be run on a different machine; adjust the hostname and
|
37
|
+
port number parameters as necessary.
|
38
|
+
|
39
|
+
|
40
|
+
## Installation
|
41
|
+
|
42
|
+
The simplest way to install it is to use Bundler.
|
43
|
+
|
44
|
+
Add MiniAutobot (and any other dependencies) to a Gemfile in your project’s root:
|
45
|
+
|
46
|
+
gem 'mini_autobot'
|
47
|
+
|
48
|
+
then install it by running Bundler:
|
49
|
+
|
50
|
+
$ bundle
|
51
|
+
|
52
|
+
|
53
|
+
## Configuration
|
54
|
+
|
55
|
+
All configuration files should be placed under the `config/mini_autobot/` directory.
|
56
|
+
There are configuration files that are required for it to work properly:
|
57
|
+
|
58
|
+
* Tests directory structure, in `config/mini_autobot/tests.yml`, which define tests directory's
|
59
|
+
relative path and multi-host flag;
|
60
|
+
* Connector profiles, in `config/mini_autobot/connectors/*.yml`, which define WebDriver
|
61
|
+
properties, e.g., Firefox, SauceLabs;
|
62
|
+
* Environment profiles, in `config/mini_autobot/environments/*.yml`, which define which
|
63
|
+
environment tests are going to run against, e.g., QA, production; and
|
64
|
+
|
65
|
+
A typical config file structure looks like this:
|
66
|
+
|
67
|
+
config/
|
68
|
+
└── mini_autobot
|
69
|
+
├── connectors
|
70
|
+
│ ├── firefox.yml
|
71
|
+
│ ├── phantomjs.yml
|
72
|
+
│ └── saucelabs.yml
|
73
|
+
├── data
|
74
|
+
│ └── sitemap_states.yml
|
75
|
+
├── environments
|
76
|
+
│ ├── ag_ci.yml
|
77
|
+
│ ├── ag_qa.yml
|
78
|
+
│ ├── rent_ci.yml
|
79
|
+
│ └── rent_qa.yml
|
80
|
+
├── native_app_google_client.json
|
81
|
+
├── test_suite.yml
|
82
|
+
└── tests.yml
|
83
|
+
|
84
|
+
#### Tests Directory Structure
|
85
|
+
|
86
|
+
A Tests Directory Structure file is a regular YAML file, which tells mini_autobot
|
87
|
+
where to find tests and which tests to load.
|
88
|
+
|
89
|
+
It must be named and placed like this `config/tests.yml` with contents like:
|
90
|
+
|
91
|
+
---
|
92
|
+
tests_dir:
|
93
|
+
relative_path: 'web_tests'
|
94
|
+
multi-host: true
|
95
|
+
|
96
|
+
It defines two things:
|
97
|
+
|
98
|
+
1. Tests dir relative path(no trailing slash) - same directory where directories
|
99
|
+
test_cases and page_objects are located, eg. web_tests, xxx/yyyy/tests;
|
100
|
+
2. multi-host flag: false means test_cases dir is directly under tests_dir,
|
101
|
+
true means there's one more layer in middle: tests_dir/[hosts]/.
|
102
|
+
|
103
|
+
#### Connector Profile
|
104
|
+
|
105
|
+
A connector profile is a regular YAML file in a specific directory, which
|
106
|
+
describes how tests are run.
|
107
|
+
|
108
|
+
It should contain, at minimum, the `driver` key, which corresponds to the
|
109
|
+
browser argument to Selenium::WebDriver.for, which in turn is one of the bridge
|
110
|
+
types available. As of selenium-webdriver version 2.37.0, the values are:
|
111
|
+
|
112
|
+
* `firefox` or `ff` for a local version of Firefox;
|
113
|
+
* `internet_explorer` or `ie` for a local version of IE (Windows only);
|
114
|
+
* `chrome` for a local version of Google Chrome;
|
115
|
+
* `opera` for a local version of Opera;
|
116
|
+
* `safari` for a local version of Safari;
|
117
|
+
* `phantomjs` for a local _or_ remote instance of PhantomJS;
|
118
|
+
* `android` for a local version of the Android emulator on port 8080;
|
119
|
+
* `iphone` for a local version of the iPhone emulator on port 3001, which has
|
120
|
+
been deprecated in favor of a remote hub connection, e.g., to appium.io or
|
121
|
+
any such alternative; and
|
122
|
+
* `remote`, which is the generic remote bridge.
|
123
|
+
|
124
|
+
Overall, the bridge types are separated into two: local and remote. Whereas
|
125
|
+
a local bridge usually takes care of starting an internal server automatically,
|
126
|
+
a remote bridge is a service that is running a daemon (usually WebDriver Hub)
|
127
|
+
on a specific address-and-port combination.
|
128
|
+
|
129
|
+
For local bridges, the `driver` key is the only key necessary in the profile:
|
130
|
+
|
131
|
+
---
|
132
|
+
driver: 'firefox'
|
133
|
+
|
134
|
+
some local bridges may support multiple versions of the same browser, but
|
135
|
+
you are on your own to set that up.
|
136
|
+
|
137
|
+
For remote bridges, you'll usually need the correct `driver` and `hub.url`
|
138
|
+
keys in the profile, e.g., for a PhantomJS instance running on port 8910
|
139
|
+
on a remote host:
|
140
|
+
|
141
|
+
---
|
142
|
+
driver: 'phantomjs'
|
143
|
+
hub:
|
144
|
+
url: 'http://some_address.com:8910'
|
145
|
+
|
146
|
+
Of course, this assumes that the remote bridge doesn't require authentication.
|
147
|
+
For anything else, you'll need to specify the optional `hub.user` and
|
148
|
+
`hub.pass` keys:
|
149
|
+
|
150
|
+
---
|
151
|
+
driver: 'phantomjs'
|
152
|
+
hub:
|
153
|
+
url: 'http://some_address.com:8910'
|
154
|
+
user: 'username'
|
155
|
+
pass: 'password'
|
156
|
+
|
157
|
+
A more generic option for remote drivers is the `remote` bridge type. In our
|
158
|
+
case with PhantomJS, this also works, although your driver's capabilities
|
159
|
+
may not be set up correctly (and you may run into problems if the website
|
160
|
+
you are testing attempts to detect touch events, for instance):
|
161
|
+
|
162
|
+
---
|
163
|
+
driver: 'remote'
|
164
|
+
hub:
|
165
|
+
url: 'http://some_address.com:8910'
|
166
|
+
user: 'username'
|
167
|
+
pass: 'password'
|
168
|
+
|
169
|
+
With any WebDriver Hub, though, this generic remote bridge is exactly what
|
170
|
+
is required. A hub is an HTTP interface that multiplexes sessions on various
|
171
|
+
different browsers, machines, and across many versions, through one URL.
|
172
|
+
|
173
|
+
One great example is SauceLabs, which has over 30 different combinations of
|
174
|
+
testing platforms. Unfortunately, in order to configure the multiplexing,
|
175
|
+
you will need to set up different profiles for each combination. This is where
|
176
|
+
overrides come in. Let's take, for example, this profile:
|
177
|
+
|
178
|
+
---
|
179
|
+
driver: 'remote'
|
180
|
+
hub:
|
181
|
+
url: 'http://address.com/wd/hub'
|
182
|
+
overrides:
|
183
|
+
qateam:
|
184
|
+
hub:
|
185
|
+
user: 'qateam'
|
186
|
+
pass: '1234'
|
187
|
+
prodteam:
|
188
|
+
hub:
|
189
|
+
user: 'prodteam'
|
190
|
+
pass: '5678'
|
191
|
+
linux_ff20:
|
192
|
+
archetype: 'firefox'
|
193
|
+
capabilities:
|
194
|
+
version: '20.0'
|
195
|
+
platform: 'linux'
|
196
|
+
linux_chrome31:
|
197
|
+
archetype: 'chrome'
|
198
|
+
capabilities:
|
199
|
+
version: '31'
|
200
|
+
platform: 'linux'
|
201
|
+
|
202
|
+
Assuming the above profile is placed into `saucelabs.yml`, then when we run
|
203
|
+
tests with the connector profile `saucelabs:qateam:linux_ff20`, MiniAutobot would
|
204
|
+
have calculated the following _effective_ profile:
|
205
|
+
|
206
|
+
---
|
207
|
+
driver: 'remote'
|
208
|
+
hub:
|
209
|
+
url: 'http://address.com/wd/hub'
|
210
|
+
user: 'qateam'
|
211
|
+
pass: '1234'
|
212
|
+
archetype: 'firefox'
|
213
|
+
capabilities:
|
214
|
+
version: '20.0'
|
215
|
+
platform: 'linux'
|
216
|
+
|
217
|
+
where the contents of the keys `overrides.qateam` and `overrides.linux_ff20`
|
218
|
+
are promoted to the root of the profile, and everything else under `overrides`
|
219
|
+
is removed.
|
220
|
+
|
221
|
+
Now, the effective profile has a couple of new keys:
|
222
|
+
|
223
|
+
* `archetype` is used to signal to the remote driver what bridge it should use
|
224
|
+
in turn to connect to the browser on their end; while
|
225
|
+
* `capabilities` is a hash, determined by the remote driver, containing any
|
226
|
+
number of capability values that the browser should support.
|
227
|
+
|
228
|
+
Capabilities are usually determined by the remote webservice, and as such,
|
229
|
+
refer to the vendor's documentation on the valid values and examples. See also
|
230
|
+
the top of each connector profile file for a brief description, if any.
|
231
|
+
|
232
|
+
Additionally, some drivers also support timeout values under the `timeouts`
|
233
|
+
key, which can in turn contain the following keys, each taking a value, in
|
234
|
+
number of seconds:
|
235
|
+
|
236
|
+
* `driver` defines the length of time that the bridge will wait for a response
|
237
|
+
from the driver;
|
238
|
+
* `implicit_wait` defines the length of time that the bridge will ask the
|
239
|
+
driver to continuously poll the browser for a command, such as finding one or
|
240
|
+
more elements on the current page;
|
241
|
+
* `page_load` defines the amount of time the driver will wait for a page to
|
242
|
+
load before giving up and returning an error; and
|
243
|
+
* `script_timeout` defines the amount of time the driver will allow JavaScript
|
244
|
+
to be executed on a specific page before halting execution and returning an
|
245
|
+
error to the bridge.
|
246
|
+
|
247
|
+
An example of the `timeouts`:
|
248
|
+
|
249
|
+
---
|
250
|
+
driver: 'phantomjs'
|
251
|
+
hub:
|
252
|
+
url: 'http://some_address.com:8910'
|
253
|
+
timeouts:
|
254
|
+
driver: 90
|
255
|
+
implicit_wait: 90
|
256
|
+
|
257
|
+
It is important to note that not all drivers support all timesouts. The
|
258
|
+
`timeouts.driver` and `timeouts.implicit_wait` are the two safest to rely upon.
|
259
|
+
In general, `timeouts.driver` should be the longest of the timeouts, if
|
260
|
+
specified, because otherwise, the page could timeout after the driver does,
|
261
|
+
causing a false negative in the test (and often a cryptic error message).
|
262
|
+
|
263
|
+
|
264
|
+
#### Environment Profile
|
265
|
+
|
266
|
+
An environment profile is a regular YAML file in a specific directory, which
|
267
|
+
describes against what environment tests are run.
|
268
|
+
|
269
|
+
Only one key is required: `root`, which points to the root URL for the
|
270
|
+
environment:
|
271
|
+
|
272
|
+
---
|
273
|
+
root: 'http://www.env.host_address.com'
|
274
|
+
|
275
|
+
#### Test Suite
|
276
|
+
|
277
|
+
A typical test suite configuration file `config/test_suite.yml` looks like this:
|
278
|
+
|
279
|
+
----
|
280
|
+
regression:
|
281
|
+
tag_to_exclude: :non_regression
|
282
|
+
|
283
|
+
- Regression
|
284
|
+
|
285
|
+
- Integration
|
286
|
+
- Non-integration
|
287
|
+
|
288
|
+
- Non-regression
|
289
|
+
|
290
|
+
- Automated test that is not testing (user) features.
|
291
|
+
Examples: link checker(mainly for sitemap), events(tracking, logging)
|
292
|
+
|
293
|
+
When adding a new test, it'll be part of regression suite by default.
|
294
|
+
To make it part of integration in addition to regression, add tag :integration;
|
295
|
+
To exclude it from regression, add tag :non_regression (by default),
|
296
|
+
or find the appropriate tag_to_exclude in config/mini_autobot/test_suite.yml
|
297
|
+
|
298
|
+
|
299
|
+
## Executing Tests
|
300
|
+
|
301
|
+
Before you are able to run one or more tests, you'll need to select a connector
|
302
|
+
and an environment profile; see the _Configuration_ section below if you want
|
303
|
+
to add new profiles.
|
304
|
+
|
305
|
+
To run test headlessly on default environment(stg), set connector to GhostDriver,
|
306
|
+
which is Phantomjs's implementation of webdriver protocal, run:
|
307
|
+
|
308
|
+
$ bundle exec mini_autobot --connector=phantomjs
|
309
|
+
|
310
|
+
To override the connector to your local browser, and to override environment,
|
311
|
+
use these options:
|
312
|
+
|
313
|
+
$ bundle exec mini_autobot --connector=firefox --env=qa
|
314
|
+
|
315
|
+
which will use `config/mini_autobot/connectors/firefox.yml` and `config/mini_autobot/environments/qa.yml`
|
316
|
+
as the profiles.
|
317
|
+
|
318
|
+
Some profiles may contain a section named `overrides`, for example, to support
|
319
|
+
multiple browsers in a remote execution environment like SauceLabs. Such
|
320
|
+
profiles can be used like this:
|
321
|
+
|
322
|
+
$ bundle exec mini_autobot --connector=saucelabs:linux_ff20 --env=qa
|
323
|
+
|
324
|
+
which will use the `linux_ff20` override in the `saucelabs` connector profile,
|
325
|
+
and run tests against the `qa` environment. Multiple overrides may be specified
|
326
|
+
one after the other, after the profile name, and always separated by colons,
|
327
|
+
for example:
|
328
|
+
|
329
|
+
$ bundle exec mini_autobot -c saucelabs:linux_ff20:qateam:notimeouts -e qa
|
330
|
+
|
331
|
+
To make a specific connector or environment profile always be the default on
|
332
|
+
your machine or shell session, set the `AUTOBOT_CONNECTOR` or `AUTOBOT_ENV`
|
333
|
+
environment variables respectively. For example, you can add the following to
|
334
|
+
your shell profile (`.bash_profile` for bash or `.zlogin` for zsh):
|
335
|
+
|
336
|
+
export AUTOBOT_CONNECTOR=firefox
|
337
|
+
export AUTOBOT_ENV=qa
|
338
|
+
|
339
|
+
Refer to the _Configuration_ section below for advanced use cases, and refer
|
340
|
+
to `mini_autobot -h` for a complete list of command line options.
|
341
|
+
|
342
|
+
|
343
|
+
#### Running a Subset of Tests
|
344
|
+
|
345
|
+
Assuming you have a test in `MiniAutobot::TestCases::Search` that is defined as:
|
346
|
+
|
347
|
+
test :search_zip, tags: [:homepage, :srp, :zip, :critical] do
|
348
|
+
# Assertions go here
|
349
|
+
end
|
350
|
+
|
351
|
+
then you have a couple of different options to run it. The most straight-
|
352
|
+
forward case is to run all test cases:
|
353
|
+
|
354
|
+
$ bundle exec mini_autobot
|
355
|
+
|
356
|
+
As a second option, you can run only that specific test case. For that, you'll
|
357
|
+
need to know the name of the test case, and add `test_` in front of it. In the
|
358
|
+
example above, the name is `search_zip`, so it can be run like so:
|
359
|
+
|
360
|
+
$ bundle exec mini_autobot -n test_search_zip
|
361
|
+
|
362
|
+
As a third option, you can run any test case whose name contains the word
|
363
|
+
"search" in it:
|
364
|
+
|
365
|
+
$ bundle exec mini_autobot -n /search/
|
366
|
+
|
367
|
+
It should be noted that this form supports regular expressions so that:
|
368
|
+
|
369
|
+
$ bundle exec mini_autobot -n '/search_\d{5}/'
|
370
|
+
|
371
|
+
will run all test cases with the word `search_` followed by five digits. Keep
|
372
|
+
in mind that _special characters_ such as backslashes and curly braces must
|
373
|
+
either be escaped, or quoted.
|
374
|
+
|
375
|
+
The fourth option is to run test cases that match one or more tags. To run all
|
376
|
+
test cases with the tag `:srp`, we can:
|
377
|
+
|
378
|
+
$ bundle exec mini_autobot -t srp
|
379
|
+
|
380
|
+
The `-t` option is powerful, because it supports multiple tags. To run all test
|
381
|
+
cases tagged with `:homepage` *and* `:srp`, use:
|
382
|
+
|
383
|
+
$ bundle exec mini_autobot -t homepage,srp
|
384
|
+
|
385
|
+
To run all test cases tagged with `:homepage` or tagged with `:srp` (or both):
|
386
|
+
|
387
|
+
$ bundle exec mini_autobot -t homepage -t srp
|
388
|
+
|
389
|
+
And of course, the combination also works:
|
390
|
+
|
391
|
+
$ bundle exec mini_autobot -t srp,submarket -t srp,zip
|
392
|
+
|
393
|
+
But what about tests you want NOT to run, that are slow or test functionality
|
394
|
+
you know is broken? If your preferences correspond to a certain tag (say,
|
395
|
+
:slow), you can negate that tag by prefixing it with '!', which may need to be
|
396
|
+
quoted or escaped in some shells/contexts.
|
397
|
+
|
398
|
+
$ bundle exec mini_autobot -t 'myrent,!slow' # skip slow myrent tests
|
399
|
+
$ bundle exec mini_autobot -t myrent,\!slow # likewise
|
400
|
+
$ bundle exec mini_autobot -t \!search # run all non-search tests
|
401
|
+
|
402
|
+
Note, every test has a tag added automatically during run time, the tag is formatted
|
403
|
+
by removing all underscores from name of a class, and prefixing it with "class_".
|
404
|
+
For example, to run all tests in sign_in.rb,
|
405
|
+
|
406
|
+
$ bundle exec mini_autobot -t class_signin
|
407
|
+
|
408
|
+
|
409
|
+
Read Rakefile for how to run test with default settings through rake tasks
|
410
|
+
|
411
|
+
#### Debug output
|
412
|
+
|
413
|
+
It's not good style to clutter your code with puts messages. Instead, use the
|
414
|
+
handy built-in logger facility defined in MiniAutobot::Utils::Loggable, accessible
|
415
|
+
through the 'logger' method in TestCase and PageObject objects, like so:
|
416
|
+
|
417
|
+
test :my_fancy_test, tags: [:fancy] do
|
418
|
+
self.logger.debug "Let's get fancy!"
|
419
|
+
end
|
420
|
+
|
421
|
+
The logger prints messages to logs/mini_autobot.log. You won't see debug messages
|
422
|
+
there by default; for that you need to go beyond --verbose and add an extra 'v'
|
423
|
+
to your flags:
|
424
|
+
|
425
|
+
$ bundle exec mini_autobot -t fancy -vv
|
426
|
+
|
427
|
+
#### TAP
|
428
|
+
|
429
|
+
For more info on TAP (Test Anything Protocol), see also:
|
430
|
+
http://www.testanything.org/
|
431
|
+
|
432
|
+
The option in autobot is:
|
433
|
+
|
434
|
+
--tapy Use TapY reporter.
|
435
|
+
--tapj Use TapJ reporter.
|
436
|
+
|
437
|
+
The TapY is YAML, and the TapJ is JSON output.
|
438
|
+
|
439
|
+
#### TAPOUT
|
440
|
+
|
441
|
+
TAPOUT gets test result from TapY or TapJ, then output result using a reporter by your choice.
|
442
|
+
To see a list of options and reporters from gem TAPOUT,
|
443
|
+
|
444
|
+
$ tapout --help
|
445
|
+
|
446
|
+
To use our custom reporter, FancyTapReporter,
|
447
|
+
|
448
|
+
$ bundle exec mini_autobot --tapy | tapout -r ./lib/tapout/custom_reporters/fancy_tap_reporter.rb fancytap
|
449
|
+
|
450
|
+
To make it presentable to jenkins or other webpage, supress color/highlight codes,
|
451
|
+
|
452
|
+
$ bundle exec mini_autobot --tapy | tapout --no-color -r ./lib/tapout/custom_reporters/fancy_tap_reporter.rb fancytap
|
453
|
+
|
454
|
+
|
455
|
+
## Test Cases
|
456
|
+
|
457
|
+
Test cases should be added as a class under `MiniAutobot::TestCases` (plural), and
|
458
|
+
inherit from the class `MiniAutobot::TestCase` (singular).
|
459
|
+
|
460
|
+
The setup and teardown methods should be added as class attributes:
|
461
|
+
|
462
|
+
module MiniAutobot
|
463
|
+
module TestCases
|
464
|
+
class LeaseReport < TestCase
|
465
|
+
|
466
|
+
setup do
|
467
|
+
# Contents of the setup
|
468
|
+
end
|
469
|
+
|
470
|
+
teardown do
|
471
|
+
# Contents of the teardown
|
472
|
+
end
|
473
|
+
|
474
|
+
end
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
This approach is used in order to allow us to compose our objects correctly and
|
479
|
+
allow the inheritance chain to always be respected. The alternative to this is
|
480
|
+
the normal `setup` and `teardown` methods, but a `super()` must always be called
|
481
|
+
at the beginning and at the end of each, respectively. By using class attributes,
|
482
|
+
we don't need to do anything else special.
|
483
|
+
|
484
|
+
Similarly, test cases should be provided as an attribute on the class:
|
485
|
+
|
486
|
+
class LeaseReport # continuing from the example above, it already inherits
|
487
|
+
|
488
|
+
test :arbitrary_name, tags: [:foo, :bar] do
|
489
|
+
# Contents of test here, with assert_* calls
|
490
|
+
end
|
491
|
+
|
492
|
+
end
|
493
|
+
|
494
|
+
See {Running a Subset of Tests} for information on the `tags` option.
|
495
|
+
|
496
|
+
|
497
|
+
|
498
|
+
## Page Objects
|
499
|
+
|
500
|
+
Parts of a page should be added under `MiniAutobot::PageObjects::Components`, and
|
501
|
+
overlays should be added under `MiniAutobot::PageObjects::Overlay`.
|
502
|
+
|
503
|
+
Because of WebDriver's asynchronous nature, the order of operations is never
|
504
|
+
guaranteed. When casting a page to another page, the `cast` call _should_
|
505
|
+
happen right after the action that causes the page to change. For example, if
|
506
|
+
clicking on a link causes the page to move to another page, the cast should
|
507
|
+
happen after the click, and before anything else:
|
508
|
+
|
509
|
+
def some_action!
|
510
|
+
@driver.find_element(:id, 'main-link').click
|
511
|
+
# There should be nothing in between these two lines; in fact, the
|
512
|
+
# cast should be the last line of the method
|
513
|
+
cast(:new_page)
|
514
|
+
end
|
515
|
+
|
516
|
+
Page object methods that return a different page must end in `!`, signifying
|
517
|
+
that is returns a different page object, thus invalidating the current page
|
518
|
+
object. Page object invalidation is handled automatically through the use of
|
519
|
+
ruby object freezing.
|
520
|
+
|
521
|
+
#### Overlay
|
522
|
+
|
523
|
+
An Overlay represents a portion (an element) of a page that can be repeated
|
524
|
+
Multiple times across many pages. But only appear once per page at a time.
|
525
|
+
Some examples of overlays include:
|
526
|
+
-Password
|
527
|
+
-Hotlead
|
528
|
+
Overlays will be called via Includes on the page object, when accessing overlays
|
529
|
+
its best to return the current page as an object, ie:
|
530
|
+
#Check Availability link on srp,
|
531
|
+
# Return +HotLead+s representing hotlead overlay on
|
532
|
+
# the SRP.
|
533
|
+
def check_availability!
|
534
|
+
@driver.find_element(*LINK_CHECKAVAILABILITY).click
|
535
|
+
cast(:search)
|
536
|
+
end
|
537
|
+
Overlays are technically not new pages, and should be differentiated from actual pages.
|
538
|
+
|
539
|
+
## Best Practice
|
540
|
+
|
541
|
+
* Always use local variables, unless _absolutely_ necessary, then use instance
|
542
|
+
variables. Avoid constants and class variables unless you know what you're
|
543
|
+
doing. Never use global variables.
|
544
|
+
* To keep track of configuration settings, see the _CONFIGURATION_ section above.
|
545
|
+
* If you need to keep track of global state, you're doing it wrong. If you need
|
546
|
+
configuration settings, see previous bulletpoint.
|
547
|
+
* Comment your code. All methods must be commented, but you shouldn't add a
|
548
|
+
comment every line.
|
549
|
+
* Always explicitly open your modules and class definitions, e.g., use:
|
550
|
+
|
551
|
+
module A
|
552
|
+
module B
|
553
|
+
class C
|
554
|
+
# code goes here
|
555
|
+
end
|
556
|
+
end
|
557
|
+
end
|
558
|
+
|
559
|
+
instead of:
|
560
|
+
|
561
|
+
class A::B::C
|
562
|
+
# code goes here
|
563
|
+
end
|
564
|
+
|
565
|
+
because the latter will not properly resolve class names. See [this blog
|
566
|
+
post](http://cirw.in/blog/constant-lookup.html) for an explanation. There
|
567
|
+
are other alternatives, such as `ActiveSupport::Dependencies`, which brings
|
568
|
+
[other caveats](http://urbanautomaton.com/blog/2013/08/27/rails-autoloading-hell/)
|
569
|
+
to the table.
|
570
|
+
* Indent all Ruby code using 2 spaces.
|
571
|
+
* Page object methods that return a different page _must_ end in a `!`.
|
572
|
+
|
573
|
+
|
574
|
+
## Troubleshooting
|
575
|
+
|
576
|
+
**I receive a `Net::ReadTimeout` when running my tests.**
|
577
|
+
|
578
|
+
The cause for `Net::ReadTimeout` is usually one of two things:
|
579
|
+
|
580
|
+
* a temporary error caused by one or more external elements on the page that
|
581
|
+
blocks the browser from loading the page in its entirety; or
|
582
|
+
* a permanent error caused by the driver timeout being too low. See connector
|
583
|
+
profiles and the `timeouts.driver` key.
|
584
|
+
|
585
|
+
|
586
|
+
**I receive a `401`, `404` or other HTTP errors before even running my tests.**
|
587
|
+
|
588
|
+
HTTP status codes can be returned by the browser, or by the driver. If the
|
589
|
+
browser is returning those codes, then it is outside the scope of this page.
|
590
|
+
|
591
|
+
If, however, the driver is returning those codes, then there are several
|
592
|
+
possible reasons:
|
593
|
+
|
594
|
+
* on a 400, the bridge command is most likely sending an incomplete request,
|
595
|
+
and could mean that the bridge doesn't support certain features of the
|
596
|
+
driver;
|
597
|
+
* on a 401, you are most likely not using the correct username and password for
|
598
|
+
the hub URL (the `hub.user` and `hub.pass` keys);
|
599
|
+
* on a 404, you are most likely using an invalid command, possibly a command
|
600
|
+
that is not supported by the remote hub, or by the browser on the remote hub;
|
601
|
+
* on a 405, you are using a custom command incorrectly, e.g., using a GET to
|
602
|
+
the hub, rather than a POST;
|
603
|
+
* on a 501, the bridge (the ruby side) uses too new of a version compared to
|
604
|
+
the driver or browser, and a browser upgrade is usually recommended, or if
|
605
|
+
necessary, adjust the list of capabilities.
|
606
|
+
|
607
|
+
In addition to regular HTTP status codes, the bridge also understands the
|
608
|
+
standardized Response Status Codes as defined in the [Selenium WebDriver JSON
|
609
|
+
Wire Protocol](https://code.google.com/p/selenium/wiki/JsonWireProtocol).
|
610
|
+
|
611
|
+
|
612
|
+
**I receive a `StaleElementReferenceError` (or similar sounding name)**
|
613
|
+
**intermittently when running one or more tests.**
|
614
|
+
|
615
|
+
A stale element reference is a reference to an element that is no longer active
|
616
|
+
on the page. This usually happens when you find an element on a page, go a
|
617
|
+
different page (either by `get()`ing a new URL or by interacting with an
|
618
|
+
element), and then try to perform actions against the aforementioned element on
|
619
|
+
the page.
|
620
|
+
|
621
|
+
## Contributing
|
622
|
+
|
623
|
+
1. Fork it
|
624
|
+
2. Create your feature branch `git checkout -b my-new-feature`
|
625
|
+
3. Commit your changes `git commit -am 'Add some feature'`
|
626
|
+
4. Push to the branch `git push origin my-new-feature`
|
627
|
+
5. Create new Pull Request
|
628
|
+
|
629
|
+
## License
|
630
|
+
|
631
|
+
MiniAutobot is released under the MIT License. See the bundled LICENSE file for
|
632
|
+
details.
|