auto_test 0.0.7.4 → 0.0.7.5

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.
@@ -0,0 +1,9 @@
1
+ require 'auto_test'
2
+ require 'rails'
3
+ module AutoTest
4
+ class Railtie < Rails::Railtie
5
+ rake_tasks do
6
+ require 'tasks/auto_test.task'
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module AutoTest
2
- VERSION = "0.0.7.4"
2
+ VERSION = "0.0.7.5"
3
3
  end
data/lib/auto_test.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require "auto_test/version"
2
- require "auto_test/railtie" if defined?(Rails)
3
2
 
4
3
  def logger
5
4
  Rails.logger
@@ -7,6 +6,7 @@ end
7
6
 
8
7
 
9
8
  module AutoTest
9
+ require "lib/auto_test/railtie" if defined?(Rails)
10
10
 
11
11
  class << self
12
12
  attr_accessor :configuration
data/lib/dsl.rb ADDED
@@ -0,0 +1,91 @@
1
+ #require 'spec_helper'
2
+ require 'capybara/rspec'
3
+
4
+ module AutoTest
5
+ module Dsl
6
+ module_function
7
+
8
+ # set the links, that aren´t supposed to be clicked
9
+ # @*links List of two-element-arrays, first value link-text, second value link href
10
+ def links_to_exclude(*links)
11
+ Test.links_to_exclude(*links)
12
+ end
13
+
14
+ # add an array of the classname, key and value of the object to be checked every cycle
15
+ def always_present(class_name, key, value)
16
+ Test.always_present(class_name, key, value)
17
+ end
18
+
19
+ #set the maximal depth to which the links are clicked
20
+ def set_max_depth(value)
21
+ Test.set_max_depth(value)
22
+ end
23
+
24
+ def set_unique_login_attribute_name(name)
25
+ User.set_unique_login_attribute_name(name)
26
+ end
27
+
28
+ # for the name or part of the name of an input field, decide, which values to use
29
+ # if not set, random values matching the input type are used
30
+ def set_input(input, *values)
31
+ Test.set_input(input, *values)
32
+ end
33
+
34
+ # give data for logins, e.g. if the password for users is saved as salt and hash in
35
+ # the database
36
+ # the data has to be created in the test_seeds.rb file
37
+ def set_login_data(*data)
38
+ User.set_login_data(*data)
39
+ end
40
+
41
+ def get_users_from_db(user_class_name, bool)
42
+ User.get_users_from_db(user_class_name, bool)
43
+ end
44
+
45
+ # for all objects of class child, there has to be one object of class parent
46
+ # attribute_name is the column that joins the two tables
47
+ def set_object_dependency(child, parent, attribute_name)
48
+ Test.set_object_dependency(child, parent, attribute_name)
49
+ end
50
+
51
+ def set_number_of_sessions(number)
52
+ Test.set_number_of_sessions(number)
53
+ end
54
+
55
+ def set_max_number_of_session_links(no)
56
+ Test.set_max_number_of_session_links(no)
57
+ end
58
+
59
+
60
+ def set_no_auth
61
+ Test.set_no_auth
62
+ end
63
+
64
+ # set the login path
65
+ def set_login_path(path)
66
+ User.set_login_path(path)
67
+ end
68
+
69
+ # set the attribute_names and fields that are needed to login
70
+ # the argument is a list of pairs [attribute_name, field]
71
+ def set_login_attribute_names(names, fields)
72
+ User.set_login_attribute_names(names, fields)
73
+ User.set_login_fields(fields)
74
+ User.set_login_names(names)
75
+ end
76
+
77
+ def set_logout_path(path)
78
+ User.set_logout_path(path)
79
+ end
80
+
81
+ def stop_at_first_error(stop_at_first_error)
82
+ Test.stop_at_first_error(stop_at_first_error)
83
+ end
84
+
85
+ def set_number_of_test_runs(number)
86
+ Test.set_number_of_test_runs(number)
87
+ end
88
+
89
+ end
90
+ autoload :Test, 'auto_test/lib/auto_test/test'
91
+ end
data/lib/error.rb ADDED
@@ -0,0 +1,53 @@
1
+ #require 'spec_helper'
2
+ require 'capybara/rspec'
3
+
4
+ module AutoTest
5
+ module Error
6
+ module_function
7
+ # increment the errorcount in the first field of the array,
8
+ # add error messages
9
+ def inc_error(value)
10
+ if !get_error_messages.include? value then
11
+ @error[0] = @error[0] + 1
12
+ @error << value
13
+ if Test.stop_at_first_error? then
14
+ Test.stop!
15
+ end
16
+ end
17
+ end
18
+
19
+ def print_errors
20
+ if get_error > 0 then
21
+ if get_error == 1 then
22
+ puts "There was 1 Error in this test:"
23
+ get_error_messages.each do |m|
24
+ puts m
25
+ end
26
+ else
27
+ puts "There were " + get_error.to_s + " Errors in this test:"
28
+ get_error_messages.each do |m|
29
+ puts m
30
+ end
31
+ end
32
+ else
33
+ puts "There were no errors in this test"
34
+ end
35
+ end
36
+
37
+ def get_error
38
+ @error[0]
39
+ end
40
+
41
+ def get_error_messages
42
+ @error[1..@error.size-1]
43
+ end
44
+
45
+ def init_error
46
+ @error = [0]
47
+ end
48
+
49
+ end
50
+
51
+ autoload :Test, 'auto_test/lib/auto_test/test'
52
+
53
+ end
data/lib/page.rb ADDED
@@ -0,0 +1,269 @@
1
+ # encoding: utf-8
2
+
3
+ #require 'spec_helper'
4
+
5
+ require 'capybara/rspec'
6
+
7
+ class Time
8
+ def self.random
9
+ year = Time.now.year
10
+ month = rand(12) + 1
11
+ day = (rand * 28).ceil
12
+ Time.local(year, month, day)
13
+ end
14
+ end
15
+
16
+ module AutoTest
17
+ module Page
18
+ module_function
19
+
20
+ # click a link in a certain session
21
+ def run_session(i)
22
+ session = Test.get_sessions_array[i]
23
+ if !Test.stop? then
24
+ if Test.no_auth || Test.get_sessions(i,"current_user") <= User.get_users.size then
25
+ if Test.get_sessions(i,"depth") <= Test.get_max_depth then
26
+ if Test.get_sessions(i,"iteration") <= Test.get_sessions(i,"iterations") then
27
+ begin
28
+ if Test.get_sessions(i, "current_depth") == 0 && !Test.no_auth then
29
+ User.login(Test.get_sessions(i,"user"),session)
30
+ Test.check_invariants
31
+ end
32
+ if Test.no_auth then
33
+ session.visit "/"
34
+ end
35
+ if (Test.get_sessions(i,"current_depth") < Test.get_sessions(i,"depth")) then
36
+ links = all_links(session)
37
+ handle_excluded_links(links)
38
+ if !links.empty? then
39
+ Test.check_invariants
40
+ path = session.current_path
41
+ paths = Test.get_sessions(i,"paths")
42
+ paths[path] = links.size
43
+ Test.sessions(i, "paths", paths)
44
+ random_link = links[rand(links.size)]
45
+ if random_link[:href] != "#" then
46
+ hash = Hash.new
47
+ hash["#{i}:#{path}"] = random_link[:href]+"+++"+random_link.text
48
+ Test.add_to_action_path hash
49
+ end
50
+ random_link.click
51
+ STDOUT.write("\r#{Test.run}. run: \t#{Test.link_counter} links clicked, \t#{Test.users_logged_in} users logged in, \t#{Error.get_error} Errors")
52
+ Test.link_counter = Test.link_counter + 1
53
+ Test.check_invariants
54
+ handle_forms(session)
55
+ Test.check_invariants
56
+ Test.sessions(i, "current_depth", Test.get_sessions(i, "current_depth") + 1)
57
+ end
58
+ else
59
+ links = all_links(session)
60
+ handle_excluded_links(links)
61
+ if !links.empty? then
62
+ Test.sessions(i,"iterations", 0)
63
+ Test.get_sessions(i,"paths").each do |key, value|
64
+ Test.sessions(i,"iterations", Test.get_sessions(i, "iterations") + value)
65
+ end
66
+ end
67
+ if !Test.no_auth then
68
+ User.logout(session)
69
+ end
70
+ Test.sessions(i, "current_depth", 0)
71
+ Test.sessions(i, "paths", Hash.new)
72
+ Test.sessions(i, "iteration", Test.get_sessions(i, "iteration") + 1)
73
+ end
74
+ rescue => e
75
+ if Test.stop_at_first_error? then Test.stop! end
76
+ message = e.message.to_s + " :" + e.backtrace.first.to_s
77
+ Error.inc_error message
78
+ end
79
+ else
80
+ Test.sessions(i, "iteration", 0)
81
+ Test.sessions(i, "iterations", 0)
82
+ Test.sessions(i, "depth", Test.get_sessions(i, "depth") + 1)
83
+ Test.sessions(i, "paths", Hash.new)
84
+ end
85
+ else
86
+ if !Test.stop? && !Test.no_auth then
87
+ Test.users_logged_in = Test.users_logged_in + 1
88
+ end
89
+ if !Test.no_auth then
90
+ Test.sessions(i, "current_user", Test.get_sessions(i,"current_user")+1)
91
+ user = User.get_users[rand(User.get_users.size)]
92
+ Test.sessions(i, "user", user)
93
+ Test.add_to_action_path "#{i}:#{user.id}ID"
94
+ end
95
+ if Test.no_auth then
96
+ Test.ready(i)
97
+ end
98
+ Test.sessions(i, "depth", 0)
99
+ Test.sessions(i, "iterations", 0)
100
+ end
101
+ else
102
+ Test.ready(i)
103
+ end
104
+ end
105
+ end
106
+
107
+
108
+
109
+ # fill in all inputs of type email, text or radio
110
+ # assuming there´s only one submit button on the page
111
+ # later maybe decide on random button
112
+ def fill_in_forms(session)
113
+ inputs = all_inputs(session)
114
+ button = all_submits(session)[rand(all_submits(session).size)]
115
+ selects = all_selects(session)
116
+ texts = []
117
+ selects.each do |s|
118
+ select_option(s[:id], texts, session)
119
+ end
120
+ inputs.each do |i|
121
+ case i[:type]
122
+ when "email" then
123
+ text = Faker::Internet.email
124
+ texts << i[:name]
125
+ texts << text
126
+ session.fill_in i[:id], :with => text
127
+ when "text" then
128
+ if i[:class] == "datePicker" then
129
+ text = Time.random.to_date
130
+ session.fill_in i[:id], :with => text
131
+ texts << i[:name]
132
+ texts << text.to_s
133
+ else
134
+ text = Faker::Name.name
135
+ session.fill_in i[:id], :with => text
136
+ texts << i[:name]
137
+ texts << text
138
+ end
139
+ when "radio" then
140
+ choose_radio(i[:name], texts, session)
141
+ when "checkbox" then
142
+ choose_checkbox(i[:name], texts, session)
143
+ when "number" then
144
+ text = rand(100)
145
+ session.fill_in i[:id], :with => text
146
+ texts << i[:name]
147
+ texts << text.to_s
148
+ end
149
+ text = ""
150
+ end
151
+ inputs_to_set = Test.get_inputs
152
+ if !inputs_to_set.empty? then
153
+ inputs.each do |i|
154
+ if inputs_to_set[i[:id]] != nil then
155
+ text = inputs_to_set[i[:id]][rand(inputs_to_set[i[:id]].size)]
156
+ session.fill_in i[:id], :with => text
157
+ texts << i[:name]
158
+ texts << text.to_s
159
+ end
160
+ end
161
+ end
162
+ hash = Hash.new
163
+ hash["#{Test.get_sessions_array.index(session)}:#{session.current_path}"] = texts
164
+ Test.add_to_action_path hash
165
+ session.click_button button.value
166
+ Test.link_counter = Test.link_counter + 1
167
+
168
+ check_for_error_code(session)
169
+ end
170
+
171
+ # check for input fields and fill in the forms
172
+ # randomly decide, if inputs are filled in or links are clicked
173
+ def handle_forms(session)
174
+ if !all_submits(session).empty? then
175
+ if rand(2) == 1 then
176
+ fill_in_forms(session)
177
+ end
178
+ end
179
+ end
180
+
181
+ # choose a random radiobutton
182
+ def choose_radio(name, input_texts, session)
183
+ radios = session.all('input').find_all{ |i| i[:type] == "radio" && i[:name] == name}
184
+ choices = radios.collect{ |r| r[:value] }
185
+ i = rand(choices.length)
186
+ input_texts << "radio___" + name
187
+ input_texts << choices[i].to_s
188
+ session.choose choices[i]
189
+ end
190
+
191
+ # choose a random checkbox
192
+ def choose_checkbox(name, input_texts, session)
193
+ checkboxes = session.all('input').find_all{ |i| i[:type] == "checkbox" && i[:name] == name }
194
+ choices = checkboxes.collect{ |r| r[:value] }
195
+ i = rand(choices.length)
196
+ input_texts << "checkbox___" + name
197
+ input_texts << choices[i].to_s
198
+ session.check choices[i]
199
+ end
200
+
201
+ # select a random option from a select list
202
+ def select_option(id, input_texts, session)
203
+ options = session.find_by_id(id).all('option').collect{ |o| o.value }
204
+ i = rand(options.size)
205
+ input_texts << "select___"+id
206
+ input_texts << options[i].to_s
207
+ session.select options[i], :from => id
208
+ end
209
+
210
+ # if an alert pops up, randomly decide whether to accept or dismiss it
211
+ def handle_alert(session)
212
+ begin
213
+ if rand(2) == 1 then
214
+ session.page.driver.browser.switch_to.alert.accept
215
+ else
216
+ session.page.driver.browser.switch_to.alert.dismiss
217
+ end
218
+ rescue
219
+ end
220
+ end
221
+
222
+ # check, if the page includes an html error code
223
+ # if present, add the error and print the message
224
+ def check_for_error_code(session)
225
+ if session.status_code >= 400 then
226
+ message = "ERROR : Response : #{page.status_code}"
227
+ Error.inc_error(message)
228
+ puts message
229
+ end
230
+ end
231
+
232
+ # get all links on the current page
233
+ def all_links(session)
234
+ session.all('a')
235
+ end
236
+
237
+ # get all input forms
238
+ def all_inputs(session)
239
+ session.all('input')
240
+ end
241
+
242
+ # get all select-fields
243
+ def all_selects(session)
244
+ session.all('select')
245
+ end
246
+
247
+ # get all submit buttons
248
+ def all_submits(session)
249
+ session.all('input').find_all{ |i| i[:type] == "submit"}
250
+ end
251
+
252
+ # delete the links, not to be clicked
253
+ def handle_excluded_links(links)
254
+ Test.get_links_to_exclude.each do |link|
255
+ links.delete(links.find{ |l| l.text == link[0] && l[:href] == link[1]})
256
+ end
257
+ end
258
+
259
+ # go back one page
260
+ def go_back
261
+ redirect_to :back
262
+ end
263
+
264
+ end
265
+
266
+ autoload :Test, 'auto_test/lib/auto_test/test'
267
+ autoload :User, 'auto_test/lib/auto_test/user'
268
+ autoload :Error, 'auto_test/lib/auto_test/error'
269
+ end
data/lib/simulation.rb ADDED
@@ -0,0 +1,174 @@
1
+ #!/usr/bin/env ruby
2
+ ENV["RAILS_ENV"] ||= "test"
3
+ require File.expand_path("../../../../../config/environment", __FILE__)
4
+ require "watir-webdriver"
5
+
6
+ def login(login_attributes, browser, user)
7
+ if user_inputs("use_db_users") then
8
+ user_inputs("get_login_attributes").each do |field|
9
+ browser.text_field(:label => field[1]).set user.send(field[0].to_sym)
10
+ end
11
+ sleep 1
12
+ else
13
+ index = user_inputs("get_login_names").index(user_inputs("get_unique_login_attribute_name"))
14
+ user.class.find(:all).each do |u|
15
+ user_inputs("get_login_data").each do |d|
16
+ if d[index] == u.send(user_inputs("get_unique_login_attribute_name").to_sym) then
17
+ user_data = user_inputs("get_login_data")[index]
18
+ end
19
+ end
20
+ end
21
+ user_inputs("get_login_attributes").each_with_index do |field, i|
22
+ browser.text_field(:label => field[1]).set user_data[i]
23
+ end
24
+ end
25
+ sleep 2
26
+ browser.button(:type => 'submit').click
27
+ end
28
+
29
+ def init_user_inputs
30
+ @user_inputs = Hash.new
31
+ file = File.new("lib/auto_test/log/user_input.log", "r")
32
+ while line = file.gets do
33
+ b = line.split(/:/,2)
34
+ @user_inputs["#{b[0].strip}"] = b[1].chop
35
+ end
36
+ @user_inputs.each do |k,v|
37
+ if v.start_with? "[" then
38
+ x = v.split("],[")
39
+ result = []
40
+ x.each do |i|
41
+ result << i.delete("[]\"").split(",")
42
+ end
43
+ result.each do |r|
44
+ if r.class == String then
45
+ r.strip!
46
+ else
47
+ r.each do |s|
48
+ s.strip!
49
+ end
50
+ end
51
+ end
52
+ @user_inputs[k] = result
53
+ end
54
+ end
55
+ end
56
+
57
+ def user_inputs(key)
58
+ @user_inputs[key]
59
+ end
60
+
61
+ def get_sessions_array
62
+ @sessions_array
63
+ end
64
+
65
+ def init_sessions_array
66
+ @sessions_array = []
67
+ end
68
+
69
+ def add_to_sessions_array(i,session)
70
+ @sessions_array[i] = session
71
+ end
72
+
73
+ def path
74
+ @path
75
+ end
76
+
77
+ def init_path
78
+ @path = []
79
+ end
80
+
81
+ def add_path(value)
82
+ @path << value
83
+ end
84
+
85
+ def search_sessions
86
+ path_to_search = File.new("lib/auto_test/log/new_path.log")
87
+ sessions = Array.new
88
+ while line = path_to_search.gets do
89
+ line.gsub!(/[{}\"]/,'')
90
+ if line.class == String then
91
+ session = line.split(":").first.to_i
92
+ else
93
+ session = line.gsub!(/[{}\"]/,'').split(":").first.to_i
94
+ end
95
+ if !(sessions.include? session) then
96
+ sessions << session
97
+ end
98
+ end
99
+ return sessions
100
+ end
101
+
102
+
103
+ load "#{Rails.root}/db/test_seeds.rb"
104
+ init_path
105
+ init_sessions_array
106
+ init_user_inputs
107
+ puts "Firefox is getting started..."
108
+ paths = File.new("lib/auto_test/log/new_path.log")
109
+ home = "localhost:3002"
110
+ sessions = search_sessions
111
+ number_of_sessions = sessions.size
112
+ user = Array.new(user_inputs("get_number_of_sessions").to_i)
113
+ for i in 0..number_of_sessions-1 do
114
+ browser = Watir::Browser.new :ff
115
+ add_to_sessions_array(sessions[i], browser)
116
+ end
117
+ while line = paths.gets do
118
+ if !line.chop!.end_with? "ID" then
119
+ hash = Hash.new
120
+ a = line.gsub!(/[{}\"]/,'').split(/\=\>/)
121
+ session = get_sessions_array[a[0].split(":").first.to_i]
122
+ session_index = get_sessions_array.index(session)
123
+ session.windows.first.use
124
+ if a[0].split(":").second == user_inputs("get_login_path") then
125
+ session.goto home + user_inputs("get_login_path")
126
+ hash["#{a[0]}"] = a[1]
127
+ login(user_inputs("get_login_attributes"), session, user[session_index].class.find(user[session_index].id))
128
+ elsif a[1] == user_inputs("get_logout_path") then
129
+ hash["#{a[0]}"] = user_inputs("get_logout_path")
130
+ session.goto home + user_inputs("get_logout_path")
131
+ elsif a[1][0] == "[" then
132
+ texts = []
133
+ inputs = a[1][1,a[1].size-2].split(/,/)
134
+ i = 0
135
+ while i < inputs.size do
136
+ texts << inputs[i].strip
137
+ texts << inputs[i+1].strip
138
+ if inputs[i].strip.start_with? "radio___" then
139
+ session.radio(:name => inputs[i].gsub("radio___",'').strip,:value=> inputs[i + 1].strip).set
140
+ elsif inputs[i].strip.start_with? "select___" then
141
+ session.select_list(:id => inputs[i].gsub("select___",'').strip).select(inputs[i + 1].strip)
142
+ elsif inputs[i].strip.start_with? "checkbox___" then
143
+ session.checkbox(:name => inputs[i].gsub("checkbox___",'').strip, :value => inputs[i + 1].strip).set
144
+ else
145
+ session.text_field(:name => inputs[i].strip).flash
146
+ session.text_field(:name => inputs[i].strip).set inputs[i+1].strip
147
+ end
148
+ i = i + 2
149
+ end
150
+ hash["#{a[0]}"] = texts
151
+ session.button(:type => "submit").click
152
+ else
153
+ link = a[1].split(/\+\+\+/)
154
+ href = link[0]
155
+ text = link[1]
156
+ session.a(:href => href, :text => text).flash
157
+ session.a(:href => href, :text => text).click
158
+ begin
159
+ session.driver.switch_to.alert.accept
160
+ rescue
161
+ end
162
+ hash["#{a[0]}"] = a[1]
163
+ end
164
+ add_path(hash)
165
+ sleep 2
166
+ else
167
+ add_path(line)
168
+ line_parts = line.split(":")
169
+ session_index = line_parts[0].to_i
170
+ id = line_parts[1].to_i
171
+ # get the Constant from the String, to find the right class
172
+ user[session_index] = Kernel.const_get(user_inputs("user_class")).find(id)
173
+ end
174
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ # has to be run independently from other tests,
4
+ # run without cleaning the db between single tests
5
+ # see spec_helper for db-cleaner
6
+ require 'spec_helper'
7
+ require 'auto_test/lib/auto_test'
8
+
9
+
10
+ describe "Application" do
11
+
12
+ describe "auto_test" do
13
+ it "does test the application automatically" do
14
+ load "#{Rails.root}/db/test_seeds.rb"
15
+ t = AutoTest::TestStarter.new
16
+ t.test
17
+ end
18
+ end
19
+
20
+ end
21
+