rainforest-cli 1.2.2 → 1.3.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.md +17 -0
- data/Gemfile +0 -1
- data/README.md +78 -10
- data/lib/rainforest/cli.rb +8 -4
- data/lib/rainforest/cli/exporter.rb +86 -0
- data/lib/rainforest/cli/options.rb +11 -1
- data/lib/rainforest/cli/runner.rb +1 -0
- data/lib/rainforest/cli/sites.rb +35 -0
- data/lib/rainforest/cli/test_files.rb +44 -4
- data/lib/rainforest/cli/test_parser.rb +51 -17
- data/lib/rainforest/cli/uploader.rb +4 -2
- data/lib/rainforest/cli/validator.rb +1 -1
- data/lib/rainforest/cli/version.rb +1 -1
- data/spec/cli_spec.rb +13 -0
- data/spec/csv_importer_spec.rb +0 -3
- data/spec/exporter_spec.rb +140 -0
- data/spec/options_spec.rb +5 -0
- data/spec/rainforest-example/example_test.rfml +1 -0
- data/spec/redirection-examples/no_redirect.rfml +10 -0
- data/spec/redirection-examples/no_redirect_embedded.rfml +10 -0
- data/spec/redirection-examples/redirect.rfml +10 -0
- data/spec/redirection-examples/redirect_embedded.rfml +10 -0
- data/spec/redirection-examples/wrong_redirect.rfml +10 -0
- data/spec/redirection-examples/wrong_redirect_embedded.rfml +10 -0
- data/spec/redirection-examples/wrong_redirect_spacing.rfml +11 -0
- data/spec/sites_spec.rb +74 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/test_files_spec.rb +6 -4
- data/spec/test_parser_spec.rb +86 -0
- data/spec/uploader_spec.rb +3 -5
- metadata +24 -4
- data/circle.yml +0 -3
- data/lib/rainforest/cli/test_importer.rb +0 -182
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5eb860284f17f1642d76697d195b5352cd641f52
|
4
|
+
data.tar.gz: 18786715493b49e4dc981fa020f80c1083f7d3f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39ecb9e62e9cf82131dcdf141681da172cac675b74506de7376f223a68682fd5cc54b06811a8c2f0238741e8dcdb183efc16d26c20adcad1373931e40f8e0f8e
|
7
|
+
data.tar.gz: 8d40cb3cefe445792c033790806a921dadd2db1665ee48712c6a6ad0039c0c4b1c9ec7586d060dfa1b547f1d1d83c51fbc4e0a9c031004f2ddc44bd3685211ed
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# Rainforest CLI Changelog
|
2
2
|
|
3
|
+
# 1.3.0 - 7th April 2016
|
4
|
+
- Export tests with embedded tests unflattened. (0ed4c62cac8a0d5fbd98f03190d3c18c48ac7119,
|
5
|
+
@epaulet)
|
6
|
+
- Add option to save API token in environment rather than specifying in commands.
|
7
|
+
(eaa32e87dff2881074c920f6ffc278d1fcd25ae7, @valeriangalliat)
|
8
|
+
- Fixed a bug where tests would upload without the correct source attribute if
|
9
|
+
an upload command failed in the middle of executing. (92df14606304957c5c58719a8999471df5f4f8c0,
|
10
|
+
@epaulet)
|
11
|
+
- Specify app source url as a command line option. (d02f750e885824c1b6f141344af9a34fc99e7527,
|
12
|
+
@ukd1)
|
13
|
+
- Add support for redirect flag on steps and embedded test. (e54a3f78333d4b8398b8aece40ebfbaaf4113eb4,
|
14
|
+
@epaulet)
|
15
|
+
- Add support for site_id attribute in RFML test and add `sites` command for
|
16
|
+
site ID reference. (7b628b12879f5c2230181d5e4badf785c26c8035, @epaulet)
|
17
|
+
- Add support for exporting specified tests using test IDs found on dashboard.
|
18
|
+
(69d104d7452dcb2ba7925d1de86532f250b72f41, @ziahamza)
|
19
|
+
|
3
20
|
# 1.2.2 - 21st March 2016
|
4
21
|
- Add support for Ruby 1.9.3 for easier usage on CircleCI. (16d74306a160c0fca8d34bc32493119051179c90, @epaulet)
|
5
22
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -25,22 +25,24 @@ gem "rainforest-cli", require: false
|
|
25
25
|
## Basic Usage
|
26
26
|
To use the cli client, you'll need your API token from a test settings page from inside [Rainforest](https://app.rainforestqa.com/).
|
27
27
|
|
28
|
+
You can either pass the token with `--token YOUR_TOKEN_HERE` CLI option, or put it in the `RAINFOREST_API_TOKEN` environment variable.
|
29
|
+
|
28
30
|
Run all of your tests
|
29
31
|
|
30
32
|
```bash
|
31
|
-
rainforest run all
|
33
|
+
rainforest run all
|
32
34
|
```
|
33
35
|
|
34
36
|
Run all in the foreground and report
|
35
37
|
|
36
38
|
```bash
|
37
|
-
rainforest run all --fg
|
39
|
+
rainforest run all --fg
|
38
40
|
```
|
39
41
|
|
40
42
|
Run all tests with tag 'run-me' and abort previous in-progress runs.
|
41
43
|
|
42
44
|
```bash
|
43
|
-
rainforest run --tag run-me --fg --conflict abort
|
45
|
+
rainforest run --tag run-me --fg --conflict abort
|
44
46
|
```
|
45
47
|
|
46
48
|
Create new Rainforest test in RFML format (Rainforest Markup Language).
|
@@ -49,24 +51,77 @@ Create new Rainforest test in RFML format (Rainforest Markup Language).
|
|
49
51
|
rainforest new
|
50
52
|
```
|
51
53
|
|
52
|
-
Upload
|
54
|
+
Upload tests to Rainforest
|
55
|
+
|
56
|
+
```bash
|
57
|
+
rainforest upload
|
58
|
+
```
|
53
59
|
|
60
|
+
Export all tests from Rainforest
|
54
61
|
```bash
|
55
|
-
rainforest
|
62
|
+
rainforest export
|
56
63
|
```
|
57
64
|
|
58
65
|
## Options
|
59
66
|
|
60
67
|
### General
|
61
68
|
|
62
|
-
|
63
|
-
|
69
|
+
- `--token <your-rainforest-token>` - supply your token (get it from any tests API tab), if not set in `RAINFOREST_API_TOKEN` environment variable
|
70
|
+
|
71
|
+
### Writing Tests
|
72
|
+
Rainforest Tests written using RFML have the following format
|
73
|
+
|
74
|
+
```
|
75
|
+
#! [RFML ID]
|
76
|
+
# title: [TITLE]
|
77
|
+
# start_uri: [START_URI]
|
78
|
+
# tags: [TAGS]
|
79
|
+
# site_id: [SITE ID]
|
80
|
+
# [OTHER COMMENTS]
|
81
|
+
|
82
|
+
[ACTION 1]
|
83
|
+
[QUESTION 1]
|
64
84
|
|
85
|
+
# redirect: [REDIRECT FLAG]
|
86
|
+
- [EMBEDDED TEST RFML ID]
|
65
87
|
|
66
|
-
|
67
|
-
|
88
|
+
[ACTION 2]
|
89
|
+
[QUESTION 2]
|
68
90
|
|
69
|
-
|
91
|
+
... etc.
|
92
|
+
```
|
93
|
+
|
94
|
+
Required Fields:
|
95
|
+
- `RFML ID` - Unique identifier for your test. For newly generated tests, this will
|
96
|
+
be a UUID, but you are free to change it for easier reference (for example, your
|
97
|
+
login test might have the id `login_test`).
|
98
|
+
- `TITLE` - The title of your test.
|
99
|
+
- `START_URI` - The path used to direct the tester to the correct page to begin the test.
|
100
|
+
- `ACTION 1`, `ACTION 2`, ... - The directions for your tester to follow in this
|
101
|
+
step. You must have at least one step in your test.
|
102
|
+
- `QUESTION 1`, `QUESTION 2`, ... - The question you would like your tester to
|
103
|
+
answer in this step. You must have at least one step in your test.
|
104
|
+
|
105
|
+
Optional Fields:
|
106
|
+
- `SITE ID` - Site ID for the site this test is for. You can find your available
|
107
|
+
site IDs with the `sites` command. Sites can be configured at
|
108
|
+
https://app.rainforestqa.com/settings/sites.
|
109
|
+
- `TAGS` - Comma separated list of your desired tags for this test.
|
110
|
+
- `OTHER COMMENTS` - Any comments you'd like to save to this test. All lines beginning with
|
111
|
+
`#` will be ignored by Rainforest unless they begin with a supported data field,
|
112
|
+
such as `tags` or `start_uri`.
|
113
|
+
- `REDIRECT FLAG` - A `true` or `false` flag to designate whether the tester should be
|
114
|
+
redirected. The default value is `true`. This flag is only applicable for embedded
|
115
|
+
tests and the first step of a test.
|
116
|
+
- `EMBEDDED TEST RFML ID` - Embed the steps of another test within the current test
|
117
|
+
using the embedded test's RFML ID.
|
118
|
+
|
119
|
+
For more information on test writing, please visit our [documentation](http://support.rainforestqa.com/hc/en-us/sections/200585603-Writing-Tests).
|
120
|
+
|
121
|
+
### Command Line Options
|
122
|
+
|
123
|
+
Popular command line options are:
|
124
|
+
- `--browsers ie8` or `--browsers ie8,chrome` - specify the browsers you wish to run against. This overrides the test own settings. Valid browsers can be found in your account settings.
|
70
125
|
- `--tag run-me` - only run tests which have this tag (recommended if you have lots of [test-steps](http://docs.rainforestqa.com/pages/example-test-suite.html#test_steps))!)
|
71
126
|
- `--site-id` - only run tests for a specific site. Get in touch with us for help on getting that you site id if you are unable to.
|
72
127
|
- `--environment-id` - run your tests using this environment. Otherwise it will use your default environment
|
@@ -76,6 +131,19 @@ The most popular options are:
|
|
76
131
|
- `--custom-url` - use a custom url for this run. Example use case: an ad-hoc QA environment with [Fourchette](https://github.com/rainforestapp/fourchette). You will need to specify a `site_id` too for this to work. Note that we will be creating a new environment for this particular run.
|
77
132
|
- `--git-trigger` - only trigger a run when the last commit (for a git repo in the current working directory) has contains `@rainforest` and a list of one or more tags. E.g. "Fix checkout process. @rainforest #checkout" would trigger a run for everything tagged `checkout`. This over-rides `--tag` and any tests specified. If no `@rainforest` is detected it will exit 0.
|
78
133
|
- `--description "CI automatic run"` - add an arbitrary description for the run.
|
134
|
+
- `--embed-tests` - Use with `rainforest export` to export your tests without extracting the
|
135
|
+
steps of an embedded test.
|
136
|
+
|
137
|
+
|
138
|
+
#### Specifying Test IDs
|
139
|
+
Any integers input as arguments in the command line arguments are treated as
|
140
|
+
test IDs taken from the Rainforest dashboard. ie:
|
141
|
+
|
142
|
+
`rainforest run --token $TOKEN 1232 3212` - will export only tests
|
143
|
+
1232 and 3212. The `export` and `run` commands and are otherwise ignored.
|
144
|
+
|
145
|
+
All other argument types should be specified as seen above.
|
146
|
+
|
79
147
|
|
80
148
|
More detailed info on options can be [found here](https://github.com/rainforestapp/rainforest-cli/blob/master/lib/rainforest/cli/options.rb#L23-L74).
|
81
149
|
|
data/lib/rainforest/cli.rb
CHANGED
@@ -13,8 +13,9 @@ require 'rainforest/cli/test_parser'
|
|
13
13
|
require 'rainforest/cli/test_files'
|
14
14
|
require 'rainforest/cli/remote_tests'
|
15
15
|
require 'rainforest/cli/validator'
|
16
|
-
require 'rainforest/cli/
|
16
|
+
require 'rainforest/cli/exporter'
|
17
17
|
require 'rainforest/cli/uploader'
|
18
|
+
require 'rainforest/cli/sites'
|
18
19
|
|
19
20
|
module RainforestCli
|
20
21
|
def self.start(args)
|
@@ -33,8 +34,8 @@ module RainforestCli
|
|
33
34
|
runner = Runner.new(options)
|
34
35
|
runner.run
|
35
36
|
when 'new'
|
36
|
-
t =
|
37
|
-
t.
|
37
|
+
t = TestFiles.new(options)
|
38
|
+
t.create_file
|
38
39
|
when 'validate'
|
39
40
|
t = Validator.new(options)
|
40
41
|
t.validate
|
@@ -42,8 +43,11 @@ module RainforestCli
|
|
42
43
|
t = Uploader.new(options)
|
43
44
|
t.upload
|
44
45
|
when 'export'
|
45
|
-
t =
|
46
|
+
t = Exporter.new(options)
|
46
47
|
t.export
|
48
|
+
when 'sites'
|
49
|
+
t = Sites.new(options)
|
50
|
+
t.list_sites
|
47
51
|
else
|
48
52
|
logger.fatal 'Unknown command'
|
49
53
|
exit 2
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'securerandom'
|
3
|
+
require 'rainforest'
|
4
|
+
require 'parallel'
|
5
|
+
require 'ruby-progressbar'
|
6
|
+
|
7
|
+
class RainforestCli::Exporter
|
8
|
+
attr_reader :options, :client, :test_files
|
9
|
+
|
10
|
+
def initialize(options)
|
11
|
+
@options = options
|
12
|
+
::Rainforest.api_key = @options.token
|
13
|
+
@test_files = RainforestCli::TestFiles.new(@options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def logger
|
17
|
+
RainforestCli.logger
|
18
|
+
end
|
19
|
+
|
20
|
+
def threads
|
21
|
+
RainforestCli::THREADS
|
22
|
+
end
|
23
|
+
|
24
|
+
def export
|
25
|
+
test_ids =
|
26
|
+
if @options.tests.length > 0
|
27
|
+
@options.tests
|
28
|
+
else
|
29
|
+
Rainforest::Test.all(page_size: 1000).map { |t| t.id }
|
30
|
+
end
|
31
|
+
p = ProgressBar.create(title: 'Rows', total: test_ids.count, format: '%a %B %p%% %t')
|
32
|
+
Parallel.each(test_ids, in_threads: threads, finish: lambda { |_item, _i, _result| p.increment }) do |test_id|
|
33
|
+
# Get the full test from the API
|
34
|
+
test = Rainforest::Test.retrieve(test_id)
|
35
|
+
|
36
|
+
# File name
|
37
|
+
file_name = sprintf('%010d', test.id) + '_' + test.title.strip.gsub(/[^a-z0-9 ]+/i, '').gsub(/ +/, '_').downcase
|
38
|
+
file_name = test_files.create_file(file_name)
|
39
|
+
File.truncate(file_name, 0)
|
40
|
+
|
41
|
+
File.open(file_name, 'a') do |file|
|
42
|
+
file.puts(get_header(test))
|
43
|
+
|
44
|
+
test.elements.each_with_index do |element, index|
|
45
|
+
process_element(file, element, index)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def process_element file, element, index
|
54
|
+
case element[:type]
|
55
|
+
when 'test'
|
56
|
+
if @options.embed_tests
|
57
|
+
file.puts '' unless index == 0
|
58
|
+
file.puts "- #{element[:element][:rfml_id]}"
|
59
|
+
else
|
60
|
+
element[:element][:elements].each do |sub_element|
|
61
|
+
index = process_element(file, sub_element, index)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
when 'step'
|
65
|
+
file.puts '' unless index == 0
|
66
|
+
file.puts "# step #{index + 1}" if @options.debug
|
67
|
+
file.puts element[:element][:action]
|
68
|
+
file.puts element[:element][:response]
|
69
|
+
else
|
70
|
+
raise "Unknown element type: #{element[:type]}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_header(test)
|
75
|
+
browsers = test.browsers.map { |b| b[:name] if b[:state] == 'enabled' }.compact
|
76
|
+
<<-EOF
|
77
|
+
#! #{test.rfml_id}
|
78
|
+
# title: #{test.title}
|
79
|
+
# start_uri: #{test.start_uri}
|
80
|
+
# tags: #{test.tags.join(", ")}
|
81
|
+
# browsers: #{browsers.join(", ")}
|
82
|
+
#
|
83
|
+
|
84
|
+
EOF
|
85
|
+
end
|
86
|
+
end
|
@@ -6,7 +6,7 @@ module RainforestCli
|
|
6
6
|
attr_writer :file_name, :tags
|
7
7
|
attr_reader :command, :token, :tags, :conflict, :browsers, :site_id, :environment_id,
|
8
8
|
:import_file_name, :import_name, :custom_url, :description, :folder,
|
9
|
-
:debug, :file_name, :test_folder
|
9
|
+
:debug, :file_name, :test_folder, :embed_tests, :app_source_url
|
10
10
|
|
11
11
|
# Note, not all of these may be available to your account
|
12
12
|
# also, we may remove this in the future.
|
@@ -39,6 +39,7 @@ module RainforestCli
|
|
39
39
|
safari
|
40
40
|
ubuntu_chrome
|
41
41
|
ubuntu_firefox
|
42
|
+
iphone_6s_v9_0
|
42
43
|
}.freeze
|
43
44
|
TOKEN_NOT_REQUIRED = %w{new validate}.freeze
|
44
45
|
|
@@ -47,6 +48,7 @@ module RainforestCli
|
|
47
48
|
@tags = []
|
48
49
|
@browsers = nil
|
49
50
|
@debug = false
|
51
|
+
@token = ENV['RAINFOREST_API_TOKEN']
|
50
52
|
|
51
53
|
# NOTE: Disabling line length cop to allow for consistency of syntax
|
52
54
|
# rubocop:disable Metrics/LineLength
|
@@ -59,6 +61,10 @@ module RainforestCli
|
|
59
61
|
@file_name = value
|
60
62
|
end
|
61
63
|
|
64
|
+
opts.on('--app-source-url FILE', 'Import step variables; CSV data') do |value|
|
65
|
+
@app_source_url = value
|
66
|
+
end
|
67
|
+
|
62
68
|
opts.on('--test-folder FILE_PATH', 'Specify the test folder. Defaults to spec/rainforest if not set.') do |value|
|
63
69
|
@test_folder = value
|
64
70
|
end
|
@@ -119,6 +125,10 @@ module RainforestCli
|
|
119
125
|
@description = value
|
120
126
|
end
|
121
127
|
|
128
|
+
opts.on('--embed-tests', 'Export tests without expanding embedded test steps') do |_value|
|
129
|
+
@embed_tests = true
|
130
|
+
end
|
131
|
+
|
122
132
|
opts.on_tail('--help', 'Display help message and exit') do |_value|
|
123
133
|
puts opts
|
124
134
|
exit 0
|
@@ -99,6 +99,7 @@ module RainforestCli
|
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
|
+
post_opts[:app_source_url] = options.app_source_url if options.app_source_url
|
102
103
|
post_opts[:conflict] = options.conflict if options.conflict
|
103
104
|
post_opts[:browsers] = options.browsers if options.browsers
|
104
105
|
post_opts[:site_id] = options.site_id if options.site_id
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
class RainforestCli::Sites
|
3
|
+
def initialize(options)
|
4
|
+
@client = RainforestCli::HttpClient.new(token: options.token)
|
5
|
+
end
|
6
|
+
|
7
|
+
def list_sites
|
8
|
+
sites = fetch_sites
|
9
|
+
|
10
|
+
if sites.empty?
|
11
|
+
logger.info('No configured sites found on your account.')
|
12
|
+
logger.info('Please visit https://app.rainforestqa.com/settings/sites to create and edit your sites.')
|
13
|
+
else
|
14
|
+
print_site_table(sites)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def print_site_table(sites)
|
19
|
+
puts 'Site ID | Site Name'
|
20
|
+
puts '-------------------'
|
21
|
+
sites.each do |site|
|
22
|
+
puts "#{site['id'].to_s.rjust(7)} | #{site['name']}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def fetch_sites
|
29
|
+
@sites ||= @client.get('/sites')
|
30
|
+
end
|
31
|
+
|
32
|
+
def logger
|
33
|
+
RainforestCli.logger
|
34
|
+
end
|
35
|
+
end
|
@@ -2,15 +2,30 @@
|
|
2
2
|
class RainforestCli::TestFiles
|
3
3
|
DEFAULT_TEST_FOLDER = './spec/rainforest'
|
4
4
|
FILE_EXTENSION = '.rfml'
|
5
|
+
SAMPLE_FILE = <<EOF
|
6
|
+
#! %s
|
7
|
+
# title: New test
|
8
|
+
# start_uri: /
|
9
|
+
# tags: rfml-test
|
10
|
+
#
|
11
|
+
|
12
|
+
This is a step action.
|
13
|
+
This is a step question?
|
14
|
+
|
15
|
+
This is another step action.
|
16
|
+
This is another step question?
|
17
|
+
|
18
|
+
EOF
|
5
19
|
|
6
20
|
attr_reader :test_folder, :test_data
|
7
21
|
|
8
|
-
def initialize(
|
9
|
-
|
10
|
-
|
22
|
+
def initialize(options)
|
23
|
+
@options = options
|
24
|
+
if @options.test_folder.nil?
|
25
|
+
logger.info "No test folder supplied. Using default folder: #{DEFAULT_TEST_FOLDER}"
|
11
26
|
@test_folder = File.expand_path(DEFAULT_TEST_FOLDER)
|
12
27
|
else
|
13
|
-
@test_folder = File.expand_path(test_folder)
|
28
|
+
@test_folder = File.expand_path(@options.test_folder)
|
14
29
|
end
|
15
30
|
end
|
16
31
|
|
@@ -47,4 +62,29 @@ class RainforestCli::TestFiles
|
|
47
62
|
test_data.each { |rfml_test| dictionary[rfml_test.rfml_id] = rfml_test }
|
48
63
|
end
|
49
64
|
end
|
65
|
+
|
66
|
+
def ensure_directory_exists
|
67
|
+
FileUtils.mkdir_p(test_folder) unless Dir.exist?(test_folder)
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_file(file_name = @options.file_name)
|
71
|
+
ensure_directory_exists
|
72
|
+
|
73
|
+
uuid = SecureRandom.uuid
|
74
|
+
|
75
|
+
name = file_name || uuid.to_s
|
76
|
+
name += file_extension unless name[-file_extension.length..-1] == file_extension
|
77
|
+
name = File.join(test_folder, name)
|
78
|
+
|
79
|
+
File.open(name, 'w') { |file| file.write(sprintf(SAMPLE_FILE, uuid)) }
|
80
|
+
|
81
|
+
logger.info "Created #{name}"
|
82
|
+
name
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def logger
|
88
|
+
RainforestCli.logger
|
89
|
+
end
|
50
90
|
end
|