selenium-webdriver-viewers 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Michael Collas
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = selenium-webdriver-viewers
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Michael Collas. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,67 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "selenium-webdriver-viewers"
8
+ gem.summary = 'Makes page objects and views for tests using selenium-webdriver.'
9
+ gem.description = <<-END_DESCRIPTION
10
+ This gem makes it easy to create page and web viewer objects for use by tests that use selenium-webdriver. By
11
+ using page and viewer objects, you can decouple your tests from the html details so that they can focus
12
+ instead on describing the behaviour of your application.
13
+ END_DESCRIPTION
14
+ gem.email = "mcollas@yahoo.com"
15
+ gem.homepage = "http://github.com/michaelcollas/selenium-webdriver-viewers"
16
+ gem.authors = ["Michael Collas"]
17
+ gem.add_development_dependency "rspec", ">= 1.2.9"
18
+ gem.add_development_dependency "reek", ">= 1.2.8"
19
+ gem.add_development_dependency "sexp_processor", ">= 3.0.4"
20
+ gem.files.exclude('.gitignore')
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
26
+ end
27
+
28
+ require 'spec/rake/spectask'
29
+ Spec::Rake::SpecTask.new(:spec) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.spec_files = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
35
+ spec.libs << 'lib' << 'spec'
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :spec => :check_dependencies
41
+
42
+ begin
43
+ require 'reek/rake/task'
44
+ Reek::Rake::Task.new do |t|
45
+ t.fail_on_error = true
46
+ t.verbose = false
47
+ t.source_files = 'lib/**/*.rb'
48
+ t.reek_opts << ' --quiet'
49
+ t.ruby_opts << '-r' << 'rubygems'
50
+ end
51
+ rescue LoadError
52
+ task :reek do
53
+ abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
54
+ end
55
+ end
56
+
57
+ task :default => :spec
58
+
59
+ require 'rake/rdoctask'
60
+ Rake::RDocTask.new do |rdoc|
61
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
62
+
63
+ rdoc.rdoc_dir = 'rdoc'
64
+ rdoc.title = "selenium-webdriver-viewers #{version}"
65
+ rdoc.rdoc_files.include('README*')
66
+ rdoc.rdoc_files.include('lib/**/*.rb')
67
+ end
data/TODO ADDED
@@ -0,0 +1,14 @@
1
+ This project
2
+ ============
3
+ licence
4
+ attributes with different read/write types
5
+ samples
6
+ documentation
7
+
8
+ Related projects
9
+ ================
10
+ rspec-rails integration
11
+ cucumber integration
12
+ interaction objects
13
+ state objects
14
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,61 @@
1
+ require 'selenium-webdriver'
2
+ require 'selenium/webdriver/navigation'
3
+
4
+ module BrowserInstance
5
+
6
+ class << self
7
+
8
+ def base_url=(new_value)
9
+ @base_url = new_value
10
+ @browser.navigate.base_url = @base_url if @browser
11
+ end
12
+
13
+ def base_url
14
+ @base_url || ENV['BASE_URL'] || ''
15
+ end
16
+
17
+ def browser_instance
18
+ @browser ||= create_browser
19
+ end
20
+
21
+ def create_browser
22
+ browser = Selenium::WebDriver.for :firefox
23
+ browser.navigate.extend(BaseUrl).base_url = base_url
24
+ browser
25
+ end
26
+
27
+ def quit
28
+ return unless @browser
29
+ @browser.quit
30
+ @browser = nil
31
+ end
32
+
33
+ end
34
+
35
+ def browser
36
+ BrowserInstance.browser_instance
37
+ end
38
+
39
+ end
40
+
41
+ module BaseUrl
42
+
43
+ def self.extended(target)
44
+ super
45
+ class << target
46
+ alias_method :to_absolute, :to
47
+ alias_method :to, :to_relative
48
+ end
49
+ end
50
+
51
+ def to_relative(new_location)
52
+ to_absolute(@base_url + new_location)
53
+ end
54
+
55
+ def base_url=(base)
56
+ @base_url = base
57
+ end
58
+
59
+ end
60
+
61
+
@@ -0,0 +1,43 @@
1
+ module WebViewer
2
+
3
+ # ElementReader fetches a Selenium::WebDriver::Element for a particular selector. If the selector
4
+ # requires parameters, ElementReader defers reading from WebDriver until the parameters are
5
+ # provided using the [] method.
6
+ class ElementReader
7
+
8
+ def initialize(viewer, selector, selector_type)
9
+ @viewer = viewer
10
+ @selector = selector
11
+ @selector_type = selector_type
12
+ end
13
+
14
+ def requires_parameters?
15
+ @selector.respond_to?(:call) && @selector.respond_to?(:arity) && @selector.arity > 0
16
+ end
17
+
18
+ def callable_selector?
19
+ @selector.respond_to?(:call)
20
+ end
21
+
22
+ # return either self or element depending on whether selector needs parameters
23
+ def get(*arguments)
24
+ return element unless callable_selector?
25
+ if (arguments.length > 0) || !requires_parameters?
26
+ element(@selector.call(*arguments))
27
+ else
28
+ self
29
+ end
30
+ end
31
+
32
+ def [](*arguments)
33
+ selector_text = @selector.call(*arguments)
34
+ self.element(selector_text)
35
+ end
36
+
37
+ def element(selector_text = @selector)
38
+ @viewer.find_element(@selector_type, selector_text)
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,50 @@
1
+ module WebViewer
2
+
3
+ # ElementValueReader acts on a Selenium::WebDriver::Element by fetching its value, clicking on it,
4
+ # reading its text, etc.
5
+ class ElementValueReader
6
+
7
+ def initialize(element_reader, output_type)
8
+ @element_reader = element_reader
9
+ @output_type = output_type
10
+ end
11
+
12
+ # return either self or element_value depending on whether selector needs parameters
13
+ def get
14
+ if @element_reader.requires_parameters?
15
+ self
16
+ else
17
+ element_value
18
+ end
19
+ end
20
+
21
+ def [](*args)
22
+ element_value(*args)
23
+ end
24
+
25
+ def []=(*arguments)
26
+ value_to_assign = arguments.pop
27
+ element = @element_reader.get(*arguments)
28
+ ElementValueWriter.new(element, @output_type).value = value_to_assign
29
+ end
30
+
31
+ def element_value(*arguments)
32
+ if (Class === @output_type)
33
+ element_as_viewer(*arguments)
34
+ elsif [:auto, :link, :select_by_text, :select_by_value].include? @output_type
35
+ raise "not yet implemented"
36
+ else
37
+ @element_reader.get(*arguments).send(@output_type)
38
+ end
39
+ end
40
+
41
+ def element_as_viewer(*arguments)
42
+ viewer = @output_type.new
43
+ base_element_proc = lambda { @element_reader.get(*arguments) }
44
+ viewer.instance_variable_set(:@base_element_proc, base_element_proc)
45
+ viewer
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,19 @@
1
+ module WebViewer
2
+
3
+ # ElementValueWriter assigns a value to a Selenium::WebDriver::Element. It uses the element_type
4
+ # parameter passed in the constructor to determine how to write to the element.
5
+ class ElementValueWriter
6
+
7
+ def initialize(web_element, element_type)
8
+ @web_element = web_element
9
+ @element_type = element_type
10
+ end
11
+
12
+ def value=(new_value)
13
+ # do smart things with element_type in here
14
+ @web_element.value = new_value
15
+ end
16
+
17
+ end
18
+
19
+ end
data/lib/page.rb ADDED
@@ -0,0 +1,45 @@
1
+ require 'browser-instance'
2
+ require 'viewer'
3
+
4
+ module WebPage
5
+
6
+ def self.included(target)
7
+ super
8
+ target.extend ClassMethods
9
+ end
10
+
11
+ def load
12
+ if respond_to?(:url)
13
+ navigate.to_absolute(url)
14
+ elsif respond_to?(:path)
15
+ navigate.to_relative(path)
16
+ end
17
+ self
18
+ end
19
+
20
+ module ClassMethods
21
+
22
+ def url(url_value)
23
+ define_method(:url) { url_value }
24
+ end
25
+
26
+ def path(path_value)
27
+ define_method(:path) { path_value }
28
+ end
29
+
30
+ def load
31
+ new.load
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+
38
+ # WebPageObject is a base class for web viewers that represent a whole page. In addition to
39
+ # all the normal features of a web viewer, a web page object has url or path, and can
40
+ # navigate to the url or path using the load method.
41
+ class WebPageObject
42
+ include BrowserInstance
43
+ include WebViewer
44
+ include WebPage
45
+ end
@@ -0,0 +1,2 @@
1
+ require 'viewer'
2
+ require 'page'
data/lib/viewer.rb ADDED
@@ -0,0 +1,96 @@
1
+ require 'forwardable'
2
+ require 'browser-instance'
3
+ require 'webdriver-extensions'
4
+ require 'element_reader'
5
+ require 'element_value_reader'
6
+ require 'element_value_writer'
7
+
8
+ module WebViewer
9
+
10
+ extend Forwardable
11
+ def_delegators :browser, :close, :current_url, :execute_script, :get, :manage, :navigate, :page_source,
12
+ :save_screenshot, :screenshot_as, :script, :switch_to, :title, :visible=, :visible?,
13
+ :window_handle, :window_handles
14
+ def_delegators :base_element, :[], :all, :attribute, :clear, :click, :displayed?, :drag_and_drop_by, :drag_and_drop_on,
15
+ :enabled?, :find_element, :find_elements, :first, :hover, :location, :ref, :select, :selected?,
16
+ :send_key, :send_keys, :size, :style, :submit, :tag_name, :text, :toggle, :value,
17
+ :element_present?, :wait_for_element_present
18
+
19
+
20
+ def self.included(target)
21
+ super
22
+ target.extend ClassMethods
23
+ end
24
+
25
+ def base_element
26
+ return @base_element_proc.call if @base_element_proc
27
+ browser.find_element(:tag_name, 'html')
28
+ end
29
+
30
+ def showing?
31
+ base_element
32
+ true
33
+ rescue Selenium::WebDriver::Error::NoSuchElementError
34
+ false
35
+ end
36
+
37
+ module ClassMethods
38
+
39
+ def base_element(selector, selector_type=:id)
40
+ define_method(:base_element) do
41
+ browser.find_element selector_type, selector
42
+ end
43
+ end
44
+
45
+ def default_selector_type(selector_type)
46
+ @default_selector_type = selector_type
47
+ end
48
+
49
+ # :as options: :auto, :text, :click, :link, :select_by_text, :select_by_value, :hover, :location, :size, :toggle, :value, ViewerClass
50
+ def element(name, selector=name.to_s, options={}, &selector_proc)
51
+ if options.empty? && selector.is_a?(::Hash)
52
+ options = selector
53
+ selector = name
54
+ end
55
+ selector = selector_proc if selector_proc
56
+ selector_type = options[:by] || @default_selector_type || :id
57
+ output_type = options[:as] || :value
58
+
59
+ define_method("#{name}_element_reader") do
60
+ ElementReader.new(self, selector, selector_type)
61
+ end
62
+
63
+ define_method("#{name}_element") do
64
+ send("#{name}_element_reader").get
65
+ end
66
+
67
+ define_method(name) do
68
+ element_reader = send("#{name}_element_reader")
69
+ ElementValueReader.new(element_reader, output_type).get
70
+ end
71
+
72
+ # only define this method if result type suggests assignability
73
+ define_method("#{name}=") do |new_value|
74
+ element_reader = send("#{name}_element_reader")
75
+ raise "parameters required" if element_reader.requires_parameters?
76
+ ElementValueWriter.new(element_reader.get, output_type).value = new_value
77
+ end
78
+
79
+ define_method("#{name}_present?") do |*arguments|
80
+ raise ArgumentError(1, arguments.length) if arguments.length > 1
81
+ timeout = arguments[0].to_f
82
+ element_present? selector_type, selector, timeout
83
+ end
84
+ alias_method "has_#{name}?", "#{name}_present?"
85
+
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+
92
+ class WebViewerObject
93
+ include BrowserInstance
94
+ include WebViewer
95
+ end
96
+
@@ -0,0 +1,53 @@
1
+ require 'selenium-webdriver'
2
+
3
+ module HumaneWebDriverExtensions
4
+ # deal with different html element types:
5
+ # boolean for checkboxes, radio buttons, and individual options in select controls
6
+ # string for inputs, textarea, and selects
7
+ # send JavaScript for hidden inputs?
8
+ def value=(new_value)
9
+ case self.tag_name.to_sym
10
+ when :input, :textarea
11
+ clear
12
+ send_keys new_value.to_s
13
+ else
14
+ raise "cannot set value for a #{self.tag_name} element - only input and textarea supported"
15
+ end
16
+ end
17
+ end
18
+
19
+ module Selenium
20
+ module WebDriver
21
+
22
+ module Find
23
+
24
+ def element_present?(how, what, how_long=0)
25
+ wait_for_element_present(how, what, how_long)
26
+ true
27
+ rescue Selenium::WebDriver::Error::NoSuchElementError
28
+ false
29
+ end
30
+
31
+ def wait_for_element_present(how, what, how_long)
32
+ attempts_left = how_long / 0.1
33
+ begin
34
+ find_element(how, what)
35
+ rescue Selenium::WebDriver::Error::NoSuchElementError
36
+ if attempts_left > 0
37
+ attempts_left -= 1
38
+ sleep 0.1
39
+ retry
40
+ end
41
+ fail
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ class Element
48
+ include HumaneWebDriverExtensions
49
+ end
50
+
51
+ end
52
+ end
53
+
@@ -0,0 +1,83 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{selenium-webdriver-viewers}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Michael Collas"]
12
+ s.date = %q{2010-12-16}
13
+ s.description = %q{ This gem makes it easy to create page and web viewer objects for use by tests that use selenium-webdriver. By
14
+ using page and viewer objects, you can decouple your tests from the html details so that they can focus
15
+ instead on describing the behaviour of your application.
16
+ }
17
+ s.email = %q{mcollas@yahoo.com}
18
+ s.extra_rdoc_files = [
19
+ "LICENSE",
20
+ "README.rdoc",
21
+ "TODO"
22
+ ]
23
+ s.files = [
24
+ ".document",
25
+ "LICENSE",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "TODO",
29
+ "VERSION",
30
+ "lib/browser-instance.rb",
31
+ "lib/element_reader.rb",
32
+ "lib/element_value_reader.rb",
33
+ "lib/element_value_writer.rb",
34
+ "lib/page.rb",
35
+ "lib/selenium-webdriver-viewers.rb",
36
+ "lib/viewer.rb",
37
+ "lib/webdriver-extensions.rb",
38
+ "selenium-webdriver-viewers.gemspec",
39
+ "spec/browser-instance_spec.rb",
40
+ "spec/element_reader_spec.rb",
41
+ "spec/element_value_reader_spec.rb",
42
+ "spec/element_value_writer_spec.rb",
43
+ "spec/page_spec.rb",
44
+ "spec/selenium-webdriver-viewers_spec.rb",
45
+ "spec/spec.opts",
46
+ "spec/spec_helper.rb",
47
+ "spec/viewer_spec.rb"
48
+ ]
49
+ s.homepage = %q{http://github.com/michaelcollas/selenium-webdriver-viewers}
50
+ s.require_paths = ["lib"]
51
+ s.rubygems_version = %q{1.3.7}
52
+ s.summary = %q{Makes page objects and views for tests using selenium-webdriver.}
53
+ s.test_files = [
54
+ "spec/browser-instance_spec.rb",
55
+ "spec/element_reader_spec.rb",
56
+ "spec/element_value_reader_spec.rb",
57
+ "spec/element_value_writer_spec.rb",
58
+ "spec/page_spec.rb",
59
+ "spec/selenium-webdriver-viewers_spec.rb",
60
+ "spec/spec_helper.rb",
61
+ "spec/viewer_spec.rb"
62
+ ]
63
+
64
+ if s.respond_to? :specification_version then
65
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
66
+ s.specification_version = 3
67
+
68
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
69
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
70
+ s.add_development_dependency(%q<reek>, [">= 1.2.8"])
71
+ s.add_development_dependency(%q<sexp_processor>, [">= 3.0.4"])
72
+ else
73
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
74
+ s.add_dependency(%q<reek>, [">= 1.2.8"])
75
+ s.add_dependency(%q<sexp_processor>, [">= 3.0.4"])
76
+ end
77
+ else
78
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
79
+ s.add_dependency(%q<reek>, [">= 1.2.8"])
80
+ s.add_dependency(%q<sexp_processor>, [">= 3.0.4"])
81
+ end
82
+ end
83
+
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe BrowserInstance do
4
+
5
+ describe '#base_url' do
6
+
7
+ before do
8
+ BrowserInstance.base_url = nil
9
+ end
10
+
11
+ after do
12
+ BrowserInstance.base_url = nil
13
+ end
14
+
15
+ it 'should have an empty base url by default' do
16
+ BrowserInstance.base_url.should == ''
17
+ end
18
+
19
+ it 'should have the base url set by base_url=' do
20
+ BrowserInstance.base_url = 'http://something'
21
+ BrowserInstance.base_url.should == 'http://something'
22
+ end
23
+
24
+ it 'should have a base url provided by environment variable if none has been set by base_url=' do
25
+ ENV.stub!(:[]).with('BASE_URL').and_return('http://from-environment')
26
+ BrowserInstance.base_url.should == 'http://from-environment'
27
+ end
28
+
29
+ end
30
+
31
+ describe 'browser_instance' do
32
+
33
+ before do
34
+ @driver = stub('firefox driver')
35
+ class << @driver
36
+ attr_reader :last_to_location
37
+ def to(location)
38
+ @last_to_location = location
39
+ end
40
+ end
41
+ @driver.stub!(:navigate).and_return(@driver)
42
+ Selenium::WebDriver.stub!(:for).and_return(@driver)
43
+ end
44
+
45
+ after do
46
+ BrowserInstance.instance_variable_set(:@browser, nil)
47
+ end
48
+
49
+ it 'should create a new WebDriver driver instance for firefox' do
50
+ Selenium::WebDriver.should_receive(:for).with(:firefox).and_return(@driver)
51
+ BrowserInstance.browser_instance
52
+ end
53
+
54
+ it 'should return the created driver from browser_instance' do
55
+ BrowserInstance.browser_instance.should equal(@driver)
56
+ end
57
+
58
+ describe 'navigate interface' do
59
+
60
+ before do
61
+ BrowserInstance.base_url = 'http://flibble'
62
+ @browser = BrowserInstance.browser_instance
63
+ end
64
+
65
+ it 'should prepend the base url when to is used' do
66
+ @browser.navigate.to '/somewhere'
67
+ @browser.last_to_location.should == 'http://flibble/somewhere'
68
+ end
69
+
70
+ it 'should ignore the base url when navigate.to_absolute is used' do
71
+ @browser.navigate.to_absolute '/somewhere'
72
+ @browser.last_to_location.should == '/somewhere'
73
+ end
74
+
75
+ end
76
+
77
+ describe 'when a browser has already been requested' do
78
+
79
+ before do
80
+ BrowserInstance.browser_instance
81
+ end
82
+
83
+ it 'should not create another WebDriver driver instance' do
84
+ Selenium::WebDriver.should_not_receive(:for)
85
+ BrowserInstance.browser_instance
86
+ end
87
+
88
+ it 'should return the same instance on subsequent calls' do
89
+ BrowserInstance.browser_instance.should equal(BrowserInstance.browser_instance)
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+
96
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe WebViewer::ElementReader do
4
+
5
+ before do
6
+ @dummy_element = stub('webdriver element')
7
+ @viewer = stub('viewer', :find_element => @dummy_element)
8
+ end
9
+
10
+ describe 'when the selector is a proc' do
11
+
12
+ describe 'and the selector proc has parameters' do
13
+
14
+ before do
15
+ @reader = WebViewer::ElementReader.new(@viewer, proc {|argument| "proc based selector with #{argument}"}, :css)
16
+ end
17
+
18
+ it 'should require parameters' do
19
+ @reader.requires_parameters?.should be_true
20
+ end
21
+
22
+ describe '#get' do
23
+
24
+ it 'should return itself if parameters are not provided' do
25
+ @reader.get.should == @reader
26
+ end
27
+
28
+ it 'should fetch the element from the viewer using the result of calling the proc if parameters are provided' do
29
+ @viewer.should_receive(:find_element).with(:css, 'proc based selector with parameter value')
30
+ @reader.get('parameter value')
31
+ end
32
+
33
+ it 'should return the fetched element if parameters are provided' do
34
+ @reader.get('parameter value').should == @dummy_element
35
+ end
36
+
37
+ end
38
+
39
+ describe '#[]' do
40
+
41
+ it 'should fetch the element from the viewer using the result of calling the proc if parameters are provided' do
42
+ @viewer.should_receive(:find_element).with(:css, 'proc based selector with parameter value')
43
+ @reader['parameter value']
44
+ end
45
+
46
+ it 'should return the fetched element if parameters are provided' do
47
+ @reader['parameter value'].should == @dummy_element
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+
54
+ describe 'and the selector proc has no parameters' do
55
+
56
+ before do
57
+ @reader = WebViewer::ElementReader.new(@viewer, proc {'proc based selector'}, :css)
58
+ end
59
+
60
+ it 'should not require parameters if the selector is a proc with no parameters' do
61
+ @reader.requires_parameters?.should be_false
62
+ end
63
+
64
+ it 'should recognize that the selector is callable' do
65
+ @reader.callable_selector?.should be_true
66
+ end
67
+
68
+ it 'should fetch the element from the viewer using the result of calling the proc' do
69
+ @viewer.should_receive(:find_element).with(:css, 'proc based selector')
70
+ @reader.get
71
+ end
72
+
73
+ it 'should return the fetched element' do
74
+ @reader.get.should == @dummy_element
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
81
+ describe 'when the selector is a string' do
82
+
83
+ before do
84
+ @reader = WebViewer::ElementReader.new(@viewer, 'text based selector', :css)
85
+ end
86
+
87
+ it 'should not require parameters if the selector is a string' do
88
+ @reader.requires_parameters?.should be_false
89
+ end
90
+
91
+ it 'should recognize that the selector is not callable' do
92
+ @reader.callable_selector?.should be_false
93
+ end
94
+
95
+ it 'should fetch the element from the viewer' do
96
+ @viewer.should_receive(:find_element).with(:css, 'text based selector')
97
+ @reader.get
98
+ end
99
+
100
+ it 'should return the fetched element' do
101
+ @reader.get.should == @dummy_element
102
+ end
103
+
104
+ end
105
+
106
+ end
@@ -0,0 +1,161 @@
1
+ require 'spec_helper'
2
+
3
+ describe WebViewer::ElementValueReader do
4
+
5
+ share_as :UnimplementedOutputType do
6
+
7
+ it 'should raise an exception' do
8
+ output_type = self.class.options[:output_type]
9
+ value_reader = WebViewer::ElementValueReader.new(@element_reader, output_type)
10
+ read_operation = lambda { @element_reader.requires_parameters? ? value_reader['1'] : value_reader.get }
11
+ read_operation.should raise_error "not yet implemented"
12
+ end
13
+
14
+ end
15
+
16
+ describe 'when the element reader does not require parameters' do
17
+
18
+ before do
19
+ @dummy_element = stub(:value => 'element value')
20
+ @element_reader = stub('element reader', :requires_parameters? => false, :get => @dummy_element)
21
+ end
22
+
23
+ describe 'and the output type is not a class' do
24
+
25
+ before do
26
+ @value_reader = WebViewer::ElementValueReader.new(@element_reader, :value)
27
+ end
28
+
29
+ describe '#get' do
30
+
31
+ it 'should fetch the element from the element reader' do
32
+ @element_reader.should_receive(:get).and_return(@dummy_element)
33
+ @value_reader.get
34
+ end
35
+
36
+ it 'should call the method on the element with name equal to the output type parameter' do
37
+ @dummy_element.should_receive(:value)
38
+ @value_reader.get
39
+ end
40
+
41
+ it 'should return the result of calling the method on the element with name equal to the output type parameter' do
42
+ @value_reader.get.should == 'element value'
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+
49
+ describe ('and the type is :auto', :output_type => :auto) { it_should_behave_like UnimplementedOutputType }
50
+ describe ('and the type is :link', :output_type => :link) { it_should_behave_like UnimplementedOutputType }
51
+ describe ('and the type is :select_by_text', :output_type => :select_by_text) { it_should_behave_like UnimplementedOutputType }
52
+ describe ('and the type is :select_by_value', :output_type => :select_by_value) { it_should_behave_like UnimplementedOutputType }
53
+
54
+ describe 'and the output type is a class' do
55
+
56
+ class FakeViewer
57
+ attr :base_element_proc
58
+ end
59
+
60
+ before do
61
+ @value_reader = WebViewer::ElementValueReader.new(@element_reader, FakeViewer)
62
+ end
63
+
64
+ it 'should return an instance of the specified class' do
65
+ @value_reader.get.should be_instance_of(FakeViewer)
66
+ end
67
+
68
+ it 'should put a base_element_proc instance value into the returned object' do
69
+ @value_reader.get.base_element_proc.should_not be_nil
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
76
+ describe 'when the element reader requires parameters' do
77
+
78
+ before do
79
+ @dummy_element = stub(:value => 'element value')
80
+ @element_reader = stub('element reader', :requires_parameters? => true, :get => @dummy_element)
81
+ end
82
+
83
+ describe 'and the output type is not a class' do
84
+
85
+ before do
86
+ @value_reader = WebViewer::ElementValueReader.new(@element_reader, :value)
87
+ end
88
+
89
+ it '#get should return the element value reader' do
90
+ @value_reader.get.should == @value_reader
91
+ end
92
+
93
+ describe '#[]' do
94
+
95
+ it 'should fetch the element from the element reader passing provided parameters' do
96
+ @element_reader.should_receive(:get).with(1, 2, 3).and_return(@dummy_element)
97
+ @value_reader[1, 2, 3]
98
+ end
99
+
100
+ it 'should call the method on the element with name equal to the output type parameter' do
101
+ @dummy_element.should_receive(:value)
102
+ @value_reader[1]
103
+ end
104
+
105
+ it 'should return the result of calling the method on the element with name equal to the output type parameter' do
106
+ @value_reader[1].should == 'element value'
107
+ end
108
+
109
+ end
110
+
111
+ describe '#[]=' do
112
+
113
+ before do
114
+ @fake_value_writer = stub(:value= => nil)
115
+ WebViewer::ElementValueWriter.stub(:new).and_return(@fake_value_writer)
116
+ end
117
+
118
+ it 'should get the element from the element reader using all parameters except the assigned value' do
119
+ @element_reader.should_receive(:get).with(1, 2, 3).and_return(@dummy_element)
120
+ @value_reader[1, 2, 3] = 4
121
+ end
122
+
123
+ it 'should create an element value writer with the element and output type' do
124
+ WebViewer::ElementValueWriter.should_receive(:new).with(@dummy_element, :value)
125
+ @value_reader[1, 2, 3] = 4
126
+ end
127
+
128
+ it 'should assign the value to the writer using value=' do
129
+ @fake_value_writer.should_receive(:value=).with(4)
130
+ @value_reader[1, 2, 3] = 4
131
+ end
132
+
133
+ end
134
+
135
+ end
136
+
137
+ describe ('and the type is :auto', :output_type => :auto) { it_should_behave_like UnimplementedOutputType }
138
+ describe ('and the type is :link', :output_type => :link) { it_should_behave_like UnimplementedOutputType }
139
+ describe ('and the type is :select_by_text', :output_type => :select_by_text) { it_should_behave_like UnimplementedOutputType }
140
+ describe ('and the type is :select_by_value', :output_type => :select_by_value) { it_should_behave_like UnimplementedOutputType }
141
+
142
+ describe 'and the output type is a class' do
143
+
144
+ before do
145
+ @value_reader = WebViewer::ElementValueReader.new(@element_reader, FakeViewer)
146
+ end
147
+
148
+ it 'should return an instance of the specified class' do
149
+ @value_reader[1, 2].should be_instance_of(FakeViewer)
150
+ end
151
+
152
+ it 'should put a base_element_proc instance value that gets the element from the reader into the returned object' do
153
+ @element_reader.should_receive(:get).with(1, 2)
154
+ @value_reader[1, 2].base_element_proc.call
155
+ end
156
+
157
+ end
158
+
159
+ end
160
+
161
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe WebViewer::ElementValueWriter do
4
+
5
+ describe "#value=" do
6
+
7
+ it 'should assign the new value to its web element using value=' do
8
+ web_element = stub('WebDriver::Element')
9
+ writer = WebViewer::ElementValueWriter.new(web_element, :value)
10
+ web_element.should_receive(:value=).with('new value')
11
+ writer.value = 'new value'
12
+ end
13
+
14
+ end
15
+
16
+ end
data/spec/page_spec.rb ADDED
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'an object that includes WebPage' do
4
+
5
+ class SampleWebPage
6
+ include WebPage
7
+ end
8
+
9
+ before do
10
+ @page = SampleWebPage.new
11
+ @page.stub!(:navigate).and_return(stub('navigate interface'))
12
+ end
13
+
14
+ it 'should not have a url instance method if the url class method has not been called' do
15
+ @page.respond_to?(:url).should == false
16
+ end
17
+
18
+ it 'should not have a path instance method if the path class method has not been called' do
19
+ @page.respond_to?(:path).should == false
20
+ end
21
+
22
+ describe 'with a url set using the .url class method' do
23
+
24
+ before do
25
+ class << @page
26
+ url 'http://somewhere'
27
+ end
28
+ end
29
+
30
+ it 'should return the value from #url that was set by .url' do
31
+ @page.url.should == 'http://somewhere'
32
+ end
33
+
34
+ it 'should navigate to the absolute url when load is called' do
35
+ @page.navigate.should_receive(:to_absolute).with('http://somewhere')
36
+ @page.load
37
+ end
38
+
39
+ end
40
+
41
+ describe 'with a url set using the .url class method' do
42
+
43
+ before do
44
+ class << @page
45
+ path '/somewhere'
46
+ end
47
+ end
48
+
49
+ it 'should return the value from #path that was set by .path' do
50
+ @page.path.should == '/somewhere'
51
+ end
52
+
53
+ it 'should navigate to the relative path when load is called' do
54
+ @page.navigate.should_receive(:to_relative).with('/somewhere')
55
+ @page.load
56
+ end
57
+
58
+ end
59
+
60
+ it 'should construct itself and call #load when .load is called' do
61
+ SampleWebPage.stub!(:new).and_return(@page)
62
+ @page.should_receive(:load)
63
+ SampleWebPage.load
64
+ end
65
+
66
+ end
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "SeleniumWebdriverViewers" do
4
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --format specdoc
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rubygems'
4
+ require 'selenium-webdriver-viewers'
5
+ require 'spec'
6
+ require 'spec/autorun'
7
+
8
+ Spec::Runner.configure do |config|
9
+
10
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe WebViewer, 'included in a class' do
4
+
5
+ before do
6
+ @viewer_class = Class.new(Object).extend(WebViewer)
7
+ end
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: selenium-webdriver-viewers
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Michael Collas
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-16 00:00:00 +11:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 1
32
+ - 2
33
+ - 9
34
+ version: 1.2.9
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: reek
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 15
46
+ segments:
47
+ - 1
48
+ - 2
49
+ - 8
50
+ version: 1.2.8
51
+ type: :development
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: sexp_processor
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 15
62
+ segments:
63
+ - 3
64
+ - 0
65
+ - 4
66
+ version: 3.0.4
67
+ type: :development
68
+ version_requirements: *id003
69
+ description: " This gem makes it easy to create page and web viewer objects for use by tests that use selenium-webdriver. By\n using page and viewer objects, you can decouple your tests from the html details so that they can focus\n instead on describing the behaviour of your application. \n"
70
+ email: mcollas@yahoo.com
71
+ executables: []
72
+
73
+ extensions: []
74
+
75
+ extra_rdoc_files:
76
+ - LICENSE
77
+ - README.rdoc
78
+ - TODO
79
+ files:
80
+ - .document
81
+ - LICENSE
82
+ - README.rdoc
83
+ - Rakefile
84
+ - TODO
85
+ - VERSION
86
+ - lib/browser-instance.rb
87
+ - lib/element_reader.rb
88
+ - lib/element_value_reader.rb
89
+ - lib/element_value_writer.rb
90
+ - lib/page.rb
91
+ - lib/selenium-webdriver-viewers.rb
92
+ - lib/viewer.rb
93
+ - lib/webdriver-extensions.rb
94
+ - selenium-webdriver-viewers.gemspec
95
+ - spec/browser-instance_spec.rb
96
+ - spec/element_reader_spec.rb
97
+ - spec/element_value_reader_spec.rb
98
+ - spec/element_value_writer_spec.rb
99
+ - spec/page_spec.rb
100
+ - spec/selenium-webdriver-viewers_spec.rb
101
+ - spec/spec.opts
102
+ - spec/spec_helper.rb
103
+ - spec/viewer_spec.rb
104
+ has_rdoc: true
105
+ homepage: http://github.com/michaelcollas/selenium-webdriver-viewers
106
+ licenses: []
107
+
108
+ post_install_message:
109
+ rdoc_options: []
110
+
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ hash: 3
119
+ segments:
120
+ - 0
121
+ version: "0"
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ requirements: []
132
+
133
+ rubyforge_project:
134
+ rubygems_version: 1.3.7
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: Makes page objects and views for tests using selenium-webdriver.
138
+ test_files:
139
+ - spec/browser-instance_spec.rb
140
+ - spec/element_reader_spec.rb
141
+ - spec/element_value_reader_spec.rb
142
+ - spec/element_value_writer_spec.rb
143
+ - spec/page_spec.rb
144
+ - spec/selenium-webdriver-viewers_spec.rb
145
+ - spec/spec_helper.rb
146
+ - spec/viewer_spec.rb