taza 0.5.0 → 0.8.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.
- data/History.txt +33 -0
- data/Manifest.txt +39 -9
- data/README.txt +29 -7
- data/Rakefile +72 -13
- data/bin/taza +16 -3
- data/generators/flow/flow_generator.rb +57 -0
- data/generators/flow/templates/flow.rb.erb +12 -0
- data/generators/page/page_generator.rb +58 -0
- data/generators/page/templates/functional_page_spec.rb.erb +8 -0
- data/generators/page/templates/page.rb.erb +8 -0
- data/generators/site/site_generator.rb +55 -0
- data/generators/site/templates/site.rb.erb +10 -0
- data/generators/site/templates/site.yml.erb +3 -0
- data/lib/app_generators/taza/taza_generator.rb +76 -0
- data/lib/app_generators/taza/templates/config.yml.erb +3 -0
- data/lib/{taza/generators → app_generators/taza}/templates/rakefile.rb.erb +0 -0
- data/lib/app_generators/taza/templates/spec_helper.rb.erb +11 -0
- data/lib/taza.rb +44 -5
- data/lib/taza/browser.rb +40 -0
- data/lib/taza/browsers/ie_watir.rb +8 -0
- data/lib/taza/browsers/safari_watir.rb +8 -0
- data/lib/taza/flow.rb +45 -0
- data/lib/taza/page.rb +66 -19
- data/lib/taza/settings.rb +36 -0
- data/lib/taza/site.rb +122 -11
- data/lib/taza/tasks.rb +26 -34
- data/spec/browser_spec.rb +72 -0
- data/spec/flow_generator_spec.rb +70 -0
- data/spec/page_generator_spec.rb +57 -0
- data/spec/page_spec.rb +82 -0
- data/spec/platform/osx/browser_spec.rb +14 -0
- data/spec/platform/windows/browser_spec.rb +14 -0
- data/spec/project_generator_spec.rb +42 -0
- data/spec/sandbox/config.yml +3 -0
- data/spec/sandbox/config/config.yml +1 -0
- data/spec/sandbox/config/site_name.yml +5 -0
- data/spec/sandbox/flows/batman.rb +2 -0
- data/spec/sandbox/flows/robin.rb +4 -0
- data/spec/sandbox/pages/foo/bar.rb +9 -0
- data/spec/settings_spec.rb +88 -0
- data/spec/site_generator_spec.rb +53 -0
- data/spec/site_spec.rb +239 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/taza_bin_spec.rb +14 -0
- data/spec/taza_spec.rb +12 -0
- data/spec/taza_tasks_spec.rb +27 -0
- data/spec/unit_helper_spec.rb +14 -0
- metadata +103 -13
- data/lib/taza/generators.rb +0 -4
- data/lib/taza/generators/base.rb +0 -33
- data/lib/taza/generators/page.rb +0 -22
- data/lib/taza/generators/project.rb +0 -18
- data/lib/taza/generators/site.rb +0 -24
- data/lib/taza/generators/templates/page.rb.erb +0 -6
- data/lib/taza/generators/templates/site.rb.erb +0 -6
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'activesupport'
|
2
|
+
|
3
|
+
module Taza
|
4
|
+
class Settings
|
5
|
+
def self.config(site_name)
|
6
|
+
env_settings = {}
|
7
|
+
env_settings[:browser] = ENV['browser'].to_sym if ENV['browser']
|
8
|
+
env_settings[:driver] = ENV['driver'].to_sym if ENV['driver']
|
9
|
+
env_settings[:timeout] = ENV['timeout'] if ENV['timeout']
|
10
|
+
env_settings[:server_ip] = ENV['server_ip'] if ENV['server_ip']
|
11
|
+
env_settings[:server_port] = ENV['server_port'] if ENV['server_port']
|
12
|
+
env_settings = {:browser=>:firefox,:driver=>:selenium}.merge(config_file.merge(env_settings))
|
13
|
+
site_file(site_name).merge(env_settings)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.config_file # :nodoc:
|
17
|
+
YAML.load_file(config_file_path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.config_file_path # :nodoc:
|
21
|
+
File.join(config_folder,'config.yml')
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.config_folder # :nodoc:
|
25
|
+
File.join(path,'config')
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.site_file(site_name) # :nodoc:
|
29
|
+
YAML.load_file(File.join(config_folder,"#{site_name.underscore}.yml"))[ENV['TAZA_ENV']]
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.path # :nodoc:
|
33
|
+
'.'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/taza/site.rb
CHANGED
@@ -2,27 +2,138 @@ require 'rubygems'
|
|
2
2
|
require 'activesupport'
|
3
3
|
|
4
4
|
module Taza
|
5
|
+
# An abstraction of a website, but more really a container for a sites pages.
|
6
|
+
#
|
7
|
+
# You can generate a site by performing the following command:
|
8
|
+
# $ ./script/generate site google
|
9
|
+
#
|
10
|
+
# This will generate a site file for google, a flows folder, and a pages folder in lib
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
#
|
14
|
+
# require 'taza'
|
15
|
+
#
|
16
|
+
# class Google < Taza::Site
|
17
|
+
#
|
18
|
+
# end
|
5
19
|
class Site
|
6
|
-
|
20
|
+
@@before_browser_closes = Proc.new() {}
|
21
|
+
# Use this to do something with the browser before it closes, but note that it is a class method which
|
22
|
+
# means that this will get called for any instance of a site.
|
23
|
+
#
|
24
|
+
# Here's an example of how you might use it to print the DOM output of a browser before it closes:
|
25
|
+
#
|
26
|
+
# Taza::Site.before_browser_closes do |browser|
|
27
|
+
# puts browser.html
|
28
|
+
# end
|
29
|
+
def self.before_browser_closes(&block)
|
30
|
+
@@before_browser_closes = block
|
31
|
+
end
|
32
|
+
attr_accessor :browser
|
33
|
+
|
34
|
+
# A site can be called a few different ways
|
35
|
+
#
|
36
|
+
# The following example creates a new browser object and closes it:
|
37
|
+
# Google.new do
|
38
|
+
# google.search.set "taza"
|
39
|
+
# google.submit.click
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# This example will create a browser object but not close it:
|
43
|
+
# Google.new.search.set "taza"
|
44
|
+
#
|
45
|
+
# Sites can take a couple of parameters in the constructor:
|
46
|
+
# :browser => a browser object to act on instead of creating one automatically
|
47
|
+
# :url => the url of where to start the site
|
48
|
+
def initialize(params={})
|
49
|
+
@module_name = self.class.parent.to_s
|
50
|
+
@class_name = self.class.to_s.split("::").last
|
7
51
|
define_site_pages
|
52
|
+
config = Settings.config(@class_name)
|
53
|
+
if params[:browser]
|
54
|
+
@browser = params[:browser]
|
55
|
+
else
|
56
|
+
@browser = Browser.create(config)
|
57
|
+
@i_created_browser = true
|
58
|
+
end
|
59
|
+
@browser.goto(params[:url] || config[:url])
|
60
|
+
|
61
|
+
if block_given?
|
62
|
+
begin
|
63
|
+
yield self
|
64
|
+
rescue => site_block_exception
|
65
|
+
ensure
|
66
|
+
begin
|
67
|
+
@@before_browser_closes.call(browser)
|
68
|
+
rescue => before_browser_closes_block_exception
|
69
|
+
end
|
70
|
+
close_browser_and_raise_if site_block_exception || before_browser_closes_block_exception
|
71
|
+
end
|
72
|
+
end
|
8
73
|
end
|
9
74
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
75
|
+
def self.settings # :nodoc:
|
76
|
+
Taza::Settings.site_file(self.name.to_s.split("::").last)
|
77
|
+
end
|
78
|
+
|
79
|
+
def close_browser_and_raise_if original_error # :nodoc:
|
80
|
+
begin
|
81
|
+
if @i_created_browser
|
82
|
+
@browser.close
|
83
|
+
end
|
84
|
+
ensure
|
85
|
+
raise original_error if original_error
|
86
|
+
end
|
87
|
+
end
|
13
88
|
|
89
|
+
def define_site_pages # :nodoc:
|
90
|
+
Dir.glob(pages_path) do |file|
|
91
|
+
require file
|
14
92
|
page_name = File.basename(file,'.rb')
|
93
|
+
page_class = "#{@module_name}::#{page_name.camelize}"
|
15
94
|
self.class.class_eval <<-EOS
|
16
|
-
|
17
|
-
|
18
|
-
|
95
|
+
def #{page_name}
|
96
|
+
page = '#{page_class}'.constantize.new
|
97
|
+
page.browser = @browser
|
98
|
+
yield page if block_given?
|
99
|
+
page
|
100
|
+
end
|
19
101
|
EOS
|
20
102
|
end
|
21
103
|
end
|
22
104
|
|
23
|
-
|
24
|
-
|
105
|
+
# This is used to call a flow belonging to the site
|
106
|
+
#
|
107
|
+
# Example:
|
108
|
+
# Google.new do |google|
|
109
|
+
# google.flow(:perform_search, :query => "taza")
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# Where the flow would be defined under lib/sites/google/flows/perform_search.rb and look like:
|
113
|
+
# class PerformSearch < Taza::Flow
|
114
|
+
# alias :google :site
|
115
|
+
#
|
116
|
+
# def run(params={})
|
117
|
+
# google.search.set params[:query]
|
118
|
+
# google.submit.click
|
119
|
+
# end
|
120
|
+
# end
|
121
|
+
def flow(name,params={})
|
122
|
+
require File.join(path,'flows',name.to_s.underscore)
|
123
|
+
flow_class = "#{@module_name}::#{name.to_s.camelize}".constantize
|
124
|
+
flow_class.new(self).run(params)
|
125
|
+
end
|
126
|
+
|
127
|
+
def pages_path # :nodoc:
|
128
|
+
File.join(path,'pages','*.rb')
|
129
|
+
end
|
130
|
+
|
131
|
+
def path # :nodoc:
|
132
|
+
File.join(base_path,'lib','sites',@class_name.underscore)
|
25
133
|
end
|
26
|
-
end
|
27
|
-
end
|
28
134
|
|
135
|
+
def base_path # :nodoc:
|
136
|
+
'.'
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
data/lib/taza/tasks.rb
CHANGED
@@ -1,46 +1,38 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require 'rake/testtask'
|
3
3
|
require 'rubygems'
|
4
|
-
require 'taglob'
|
4
|
+
require 'taglob/rake/tasks'
|
5
5
|
require 'spec/rake/spectask'
|
6
|
-
require 'taza/generators'
|
7
6
|
|
8
|
-
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
environment_variable_keys.each do |environment_variable_key|
|
15
|
-
if ENV[environment_variable_key].nil?
|
16
|
-
STDERR.puts error_message
|
17
|
-
exit 1
|
18
|
-
end
|
7
|
+
namespace :spec do
|
8
|
+
def format_options(file_name)
|
9
|
+
file_name = "artifacts/#{file_name}/index.html"
|
10
|
+
dir_name = File.dirname(file_name)
|
11
|
+
FileUtils.mkdir_p(dir_name) unless File.directory?(dir_name)
|
12
|
+
["--format","html:#{file_name}","--format","p"]
|
19
13
|
end
|
20
|
-
end
|
21
|
-
|
22
|
-
public
|
23
14
|
|
24
|
-
desc "
|
25
|
-
Rake::
|
26
|
-
|
27
|
-
|
15
|
+
desc "Run all functional specs"
|
16
|
+
Spec::Rake::SpecTask.new :functional do |t|
|
17
|
+
t.spec_files = 'spec/functional/**/*_spec.rb'
|
18
|
+
t.spec_opts << format_options("functional/all")
|
19
|
+
end
|
20
|
+
desc "Run all integration specs"
|
21
|
+
Spec::Rake::SpecTask.new :integration do |t|
|
22
|
+
t.spec_files = 'spec/integration/**/*_spec.rb'
|
23
|
+
t.spec_opts << format_options("integration/all")
|
24
|
+
end
|
28
25
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
26
|
+
namespace :functional do
|
27
|
+
Dir.glob('./spec/functional/*/').each do |dir|
|
28
|
+
site_name = File.basename(dir)
|
33
29
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
30
|
+
desc "Run all functional specs for #{site_name}"
|
31
|
+
Spec::Rake::SpecTask.new site_name.to_sym do |t|
|
32
|
+
t.spec_files = "#{dir}**/*_spec.rb"
|
33
|
+
t.spec_opts << format_options("functional/#{site_name}/all")
|
34
|
+
end
|
40
35
|
|
41
|
-
|
42
|
-
task :page do
|
43
|
-
validate_required_environment_input_present("Usage: rake generate:page name=the_page_name site=the_site_name",'name','site')
|
44
|
-
Taza::Generators::Page.new(ENV['name'],ENV['site']).generate
|
36
|
+
end
|
45
37
|
end
|
46
38
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
require 'taza/browser'
|
3
|
+
require 'taza/settings'
|
4
|
+
require 'selenium'
|
5
|
+
require 'firewatir'
|
6
|
+
|
7
|
+
describe Taza::Browser do
|
8
|
+
|
9
|
+
before :each do
|
10
|
+
Taza::Settings.stubs(:config_file).returns({})
|
11
|
+
ENV['TAZA_ENV'] = 'isolation'
|
12
|
+
ENV['server_port'] = nil
|
13
|
+
ENV['server_ip'] = nil
|
14
|
+
ENV['browser'] = nil
|
15
|
+
ENV['driver'] = nil
|
16
|
+
ENV['timeout'] = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be able to create a watir driver" do
|
20
|
+
Taza::Browser.expects(:create_watir_ie)
|
21
|
+
Taza::Browser.create(:browser => :ie, :driver => :watir)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should be able to create a firewatir driver" do
|
25
|
+
Taza::Browser.expects(:create_watir_firefox)
|
26
|
+
Taza::Browser.create(:browser => :firefox,:driver => :watir)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should be able to create a safariwatir driver" do
|
30
|
+
Taza::Browser.expects(:create_watir_safari)
|
31
|
+
Taza::Browser.create(:browser => :safari,:driver => :watir)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should raise unknown browser error for unsupported watir browsers" do
|
35
|
+
lambda { Taza::Browser.create(:browser => :foo_browser_9000,:driver => :watir) }.should raise_error(BrowserUnsupportedError)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should use params browser type when creating selenium" do
|
39
|
+
browser_type = :opera
|
40
|
+
Selenium::SeleniumDriver.expects(:new).with(anything,anything,'*opera',anything)
|
41
|
+
Taza::Browser.create(:browser => browser_type, :driver => :selenium)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should raise selenium unsupported browser error" do
|
45
|
+
Taza::Browser.create(:browser => :foo, :driver => :selenium)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should be able to create a selenium instance" do
|
49
|
+
browser = Taza::Browser.create(:browser => :firefox, :driver => :selenium)
|
50
|
+
browser.should be_a_kind_of(Selenium::SeleniumDriver)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should use environment settings for server port and ip" do
|
54
|
+
Taza::Settings.stubs(:path).returns(File.join('spec','sandbox'))
|
55
|
+
ENV['server_port'] = 'server_port'
|
56
|
+
ENV['server_ip'] = 'server_ip'
|
57
|
+
Selenium::SeleniumDriver.expects(:new).with('server_ip','server_port',anything,anything)
|
58
|
+
Taza::Browser.create(Taza::Settings.config("SiteName"))
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should use environment settings for timeout" do
|
62
|
+
Taza::Settings.stubs(:path).returns(File.join('spec','sandbox'))
|
63
|
+
ENV['timeout'] = 'timeout'
|
64
|
+
Selenium::SeleniumDriver.expects(:new).with(anything,anything,anything,'timeout')
|
65
|
+
Taza::Browser.create(Taza::Settings.config("SiteName"))
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should create firewatir instance" do
|
69
|
+
FireWatir::Firefox.expects(:new)
|
70
|
+
Taza::Browser.create(:browser => :firefox, :driver => :watir)
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'taza'
|
5
|
+
require 'vendor/gems/gems/rubigen-1.3.2/test/test_generator_helper'
|
6
|
+
|
7
|
+
class Taza::Site
|
8
|
+
def flows
|
9
|
+
flows = []
|
10
|
+
Dir.glob(File.join(path,'flows','*.rb')).each do |file|
|
11
|
+
require file
|
12
|
+
|
13
|
+
flows << "#{self.class.parent.to_s}::#{File.basename(file,'.rb').camelize}".constantize
|
14
|
+
end
|
15
|
+
flows
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "Flow Generation" do
|
20
|
+
include RubiGen::GeneratorTestHelper
|
21
|
+
include Helpers::Generator
|
22
|
+
include Helpers::Taza
|
23
|
+
|
24
|
+
before :all do
|
25
|
+
@site_name = "Foo"
|
26
|
+
@site_folder = File.join(PROJECT_FOLDER,'lib','sites',"gap")
|
27
|
+
@site_file = File.join(PROJECT_FOLDER,'lib','sites',"gap.rb")
|
28
|
+
@flow_name = "CheckOut"
|
29
|
+
end
|
30
|
+
|
31
|
+
before :each do
|
32
|
+
run_generator('taza', [APP_ROOT], generator_sources)
|
33
|
+
@site_class = generate_site(@site_name)
|
34
|
+
end
|
35
|
+
|
36
|
+
after :each do
|
37
|
+
bare_teardown
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should give you usage if you do not give two arguments" do
|
41
|
+
FlowGenerator.any_instance.expects(:usage)
|
42
|
+
lambda { run_generator('flow', [@flow_name], generator_sources) }.should raise_error
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should give you usage if you give a site that does not exist" do
|
46
|
+
FlowGenerator.any_instance.expects(:usage)
|
47
|
+
$stderr.expects(:puts).with(regexp_matches(/NoSuchSite/))
|
48
|
+
lambda { run_generator('flow', [@flow_name,"NoSuchSite"], generator_sources) }.should raise_error
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should generate flows that will not have namespace collisions with pages" do
|
52
|
+
flow_name = "SignIn"
|
53
|
+
run_generator('flow', [flow_name,@site_class.to_s], generator_sources)
|
54
|
+
run_generator('page', [flow_name,@site_class.to_s], generator_sources)
|
55
|
+
stub_settings
|
56
|
+
stub_browser
|
57
|
+
site = @site_class.new
|
58
|
+
site.flow(:sign_in)
|
59
|
+
site.sign_in_page
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should generate flows that will not have namespace collisions with other sites' flows" do
|
63
|
+
new_site_class = generate_site('Pag')
|
64
|
+
run_generator('flow', [@flow_name,@site_class.to_s], generator_sources)
|
65
|
+
run_generator('flow', [@flow_name,new_site_class.to_s], generator_sources)
|
66
|
+
stub_settings
|
67
|
+
stub_browser
|
68
|
+
(@site_class.new.flows & new_site_class.new.flows).should be_empty
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'taza'
|
5
|
+
require 'vendor/gems/gems/rubigen-1.3.2/test/test_generator_helper'
|
6
|
+
|
7
|
+
describe "Page Generation" do
|
8
|
+
include RubiGen::GeneratorTestHelper
|
9
|
+
include Helpers::Generator
|
10
|
+
include Helpers::Taza
|
11
|
+
|
12
|
+
before :all do
|
13
|
+
@page_name = "CheckOut"
|
14
|
+
end
|
15
|
+
|
16
|
+
before :each do
|
17
|
+
run_generator('taza', [APP_ROOT], generator_sources)
|
18
|
+
@site_class = generate_site('Gap')
|
19
|
+
end
|
20
|
+
|
21
|
+
after :each do
|
22
|
+
bare_teardown
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should give you usage if you do not give two arguments" do
|
26
|
+
PageGenerator.any_instance.expects(:usage)
|
27
|
+
lambda { run_generator('page', [@page_name], generator_sources) }.should raise_error
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should give you usage if you give a site that does not exist" do
|
31
|
+
PageGenerator.any_instance.expects(:usage)
|
32
|
+
$stderr.expects(:puts).with(regexp_matches(/NoSuchSite/))
|
33
|
+
lambda { run_generator('page', [@page_name,"NoSuchSite"], generator_sources) }.should raise_error
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should generate a page spec that can be required" do
|
37
|
+
run_generator('page', [@page_name,@site_class.to_s], generator_sources)
|
38
|
+
page_functional_spec = File.join(PROJECT_FOLDER,'spec','functional',@site_class.to_s.underscore,'check_out_page_spec.rb')
|
39
|
+
system("ruby -c #{page_functional_spec} > #{null_device}").should be_true
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should be able to access the generated page from the site" do
|
43
|
+
run_generator('page', [@page_name,@site_class.to_s], generator_sources)
|
44
|
+
stub_settings
|
45
|
+
stub_browser
|
46
|
+
@site_class.new.check_out_page
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should be able to access the generated page for its site" do
|
50
|
+
stub_browser
|
51
|
+
stub_settings
|
52
|
+
new_site_class = generate_site('Pag')
|
53
|
+
run_generator('page', [@page_name,@site_class.to_s], generator_sources)
|
54
|
+
run_generator('page', [@page_name,new_site_class.to_s], generator_sources)
|
55
|
+
new_site_class.new.check_out_page.class.should_not eql(@site_class.new.check_out_page.class)
|
56
|
+
end
|
57
|
+
end
|