auto_test 0.0.7.4 → 0.0.7.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+