prickle 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc ADDED
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
7
+ environment_id="ruby-1.9.2-p180@prickle"
8
+
9
+ #
10
+ # Uncomment following line if you want options to be set only for given project.
11
+ #
12
+ # PROJECT_JRUBY_OPTS=( --1.9 )
13
+
14
+ #
15
+ # First we attempt to load the desired environment directly from the environment
16
+ # file. This is very fast and efficient compared to running through the entire
17
+ # CLI and selector. If you want feedback on which environment was used then
18
+ # insert the word 'use' after --create as this triggers verbose mode.
19
+ #
20
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
21
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
22
+ then
23
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
24
+
25
+ if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
26
+ then
27
+ . "${rvm_path:-$HOME/.rvm}/hooks/after_use"
28
+ fi
29
+ else
30
+ # If the environment file has not yet been created, use the RVM CLI to select.
31
+ if ! rvm --create use "$environment_id"
32
+ then
33
+ echo "Failed to create RVM environment '${environment_id}'."
34
+ exit 1
35
+ fi
36
+ fi
37
+
38
+ #
39
+ # If you use an RVM gemset file to install a list of gems (*.gems), you can have
40
+ # it be automatically loaded. Uncomment the following and adjust the filename if
41
+ # necessary.
42
+ #
43
+ # filename=".gems"
44
+ # if [[ -s "$filename" ]]
45
+ # then
46
+ # rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
47
+ # fi
48
+
49
+ # If you use bundler, this might be useful to you:
50
+ # if command -v bundle && [[ -s Gemfile ]]
51
+ # then
52
+ # bundle install
53
+ # fi
54
+
55
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,51 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ capybara (1.1.2)
5
+ mime-types (>= 1.16)
6
+ nokogiri (>= 1.3.3)
7
+ rack (>= 1.0.0)
8
+ rack-test (>= 0.5.4)
9
+ selenium-webdriver (~> 2.0)
10
+ xpath (~> 0.1.4)
11
+ childprocess (0.3.1)
12
+ ffi (~> 1.0.6)
13
+ diff-lcs (1.1.3)
14
+ ffi (1.0.11)
15
+ mime-types (1.17.2)
16
+ multi_json (1.0.4)
17
+ nokogiri (1.5.0)
18
+ rack (1.4.1)
19
+ rack-protection (1.2.0)
20
+ rack
21
+ rack-test (0.6.1)
22
+ rack (>= 1.0)
23
+ rspec (2.8.0)
24
+ rspec-core (~> 2.8.0)
25
+ rspec-expectations (~> 2.8.0)
26
+ rspec-mocks (~> 2.8.0)
27
+ rspec-core (2.8.0)
28
+ rspec-expectations (2.8.0)
29
+ diff-lcs (~> 1.1.2)
30
+ rspec-mocks (2.8.0)
31
+ rubyzip (0.9.6.1)
32
+ selenium-webdriver (2.19.0)
33
+ childprocess (>= 0.2.5)
34
+ ffi (~> 1.0.9)
35
+ multi_json (~> 1.0.4)
36
+ rubyzip
37
+ sinatra (1.3.2)
38
+ rack (~> 1.3, >= 1.3.6)
39
+ rack-protection (~> 1.2)
40
+ tilt (~> 1.3, >= 1.3.3)
41
+ tilt (1.3.3)
42
+ xpath (0.1.4)
43
+ nokogiri (~> 1.3)
44
+
45
+ PLATFORMS
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ capybara
50
+ rspec
51
+ sinatra
data/README.md ADDED
@@ -0,0 +1,70 @@
1
+ ![](http://github.com/despo/prickle/raw/master/prickle.png)
2
+
3
+ ## Configuration
4
+
5
+ To install prickle execute
6
+
7
+ ```ruby
8
+ gem install prickle
9
+ ```
10
+
11
+ and to configure
12
+
13
+ ```ruby
14
+ require 'prickle/capybara'
15
+
16
+ World do
17
+ include Capybara::DSL
18
+ include Prickle::Capybara #include it after Capybara
19
+ end
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ### Find elements by any html tag(s)
25
+
26
+ ```ruby
27
+ element(:href => "http://google.com")
28
+ element(:name => "blue")
29
+ element(:id => "key")
30
+ element(:class => "key", :id => "button")
31
+ ```
32
+
33
+ ### Find elements by type and html tag(s)
34
+
35
+ ```ruby
36
+ element(:link,:href => "http://google.com")
37
+ element(:input, :name => "blue")
38
+ ``
39
+
40
+ ### Apply a search, a click or a text matcher
41
+
42
+ ``ruby
43
+
44
+ element(:name => "flower")*.exists?*
45
+ element(:name => "flower")*.click*
46
+ element(:name => "flower")*.contains_text? "Roses"*
47
+ ```
48
+
49
+ ## Alternative syntax
50
+
51
+ ### Find
52
+
53
+ ```ruby
54
+ find_by_name "green"
55
+
56
+ find_button_by_name "green" #find_<element_tag>_by_name "<name>"
57
+ ```
58
+
59
+ ## Click
60
+
61
+ ```ruby
62
+ click_by_name "blue"
63
+ click_input_by_name "blue" #click_<element_tag>_by_name "<name>"
64
+ ``
65
+
66
+ ### Match text
67
+
68
+ ```ruby
69
+ div_contains_text? "text" #<element_tag>_contains_text? "text"
70
+ ```
@@ -0,0 +1,25 @@
1
+ module Prickle
2
+ module Actions
3
+ module Click
4
+
5
+ def click_by_name name
6
+ find_by_name(name).click
7
+ end
8
+
9
+ def click
10
+ find_element_by_identifier(@type, @identifier).click
11
+ end
12
+
13
+ private
14
+
15
+ def method_missing method, *args
16
+ if method =~ /^click_(.*)_by_name$/
17
+ find_by_name($1, args.first).click
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,16 @@
1
+ module Prickle
2
+ module Capybara
3
+ class ElementNotFound < Exception
4
+
5
+ def initialize type, identifier, text, e
6
+ element_text = "Element"
7
+ element_text = "\e[1m#{type}\e[0m\e[31m" unless type == "*"
8
+ text_string = " and text \e[1m#{text}\e[0m\e[31m" unless text.nil?
9
+
10
+ raise "#{element_text} with properties \e[1m#{identifier.to_s}\e[0m\e[31m#{text_string} was not found.\nError: #{e.message}"
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,36 @@
1
+ module Prickle
2
+ module Actions
3
+ module Find
4
+
5
+ def find_by_name type='*', name
6
+ find_element_by_identifier type, { :name => name }
7
+ end
8
+
9
+ def exists?
10
+ find_element_by_identifier @type, @identifier
11
+ end
12
+
13
+ private
14
+
15
+ def method_missing method, *args
16
+ if method =~ /^find_(.*)_by_name$/
17
+ find_by_name $1, args.first
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ def find_by_identifier_xpath element, identifier
24
+ "//#{type_of(element)}[#{xpath_for(identifier)}]"
25
+ end
26
+
27
+ def find_element_by_identifier element, identifier
28
+ @type = element; @identifier = identifier
29
+ handle_exception do
30
+ find_element_by(find_by_identifier_xpath(element, identifier ))
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,33 @@
1
+ module Prickle
2
+ module Actions
3
+ module Match
4
+
5
+ def contains_text? text
6
+ handle_exception do
7
+ find_element_by_name_and_text(@type, @identifier, text)
8
+ end
9
+ end
10
+
11
+ def method_missing method, *args
12
+ if method =~ /(^.*)_contains_text\?$/
13
+ find_element_by_name_and_text($1, { :name => args.first } , args[1])
14
+ else
15
+ super
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def find_by_name_and_text_xpath element, identifier, text
22
+ "//#{type_of(element)}[#{xpath_for(identifier)} and contains(text(), '#{text}')]"
23
+ end
24
+
25
+ def find_element_by_name_and_text element, name, text
26
+ handle_exception do
27
+ find_element_by(find_by_name_and_text_xpath(element, name, text))
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,57 @@
1
+ require_relative 'capybara/find'
2
+ require_relative 'capybara/click'
3
+ require_relative 'capybara/match'
4
+ require_relative 'capybara/exceptions'
5
+
6
+ module Prickle
7
+ TAGS = { :link => 'a',
8
+ :paragraph => 'p'
9
+ }
10
+
11
+ module Capybara
12
+
13
+ class << self
14
+ attr_accessor :wait_time
15
+
16
+ end
17
+
18
+ include Prickle::Actions::Find
19
+ include Prickle::Actions::Click
20
+ include Prickle::Actions::Match
21
+
22
+ def element type='*', identifier
23
+ @identifier = identifier
24
+ @type = type
25
+ self
26
+ end
27
+
28
+ private
29
+
30
+ def xpath_for identifier
31
+ return identifier.each_pair.to_a.map do |key, value|
32
+ "@#{key}='#{value}'"
33
+ end.join ' and '
34
+ end
35
+
36
+ def find_element_by xpath
37
+ wait_until(Prickle::Capybara.wait_time) do
38
+ find(:xpath, xpath).visible?
39
+ end unless Prickle::Capybara.wait_time.nil?
40
+
41
+ find(:xpath, xpath)
42
+ end
43
+
44
+ def type_of element
45
+ Prickle::TAGS[element.to_sym] || element
46
+ end
47
+
48
+ def handle_exception &block
49
+ begin
50
+ block.call
51
+ rescue Exception => e
52
+ raise Capybara::ElementNotFound.new(@type, @identifier, @text, e) if e.class.to_s == "Capybara::ElementNotFound"
53
+ raise
54
+ end
55
+ end
56
+ end
57
+ end
data/prickle.png ADDED
Binary file
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Prickle::Capybara do
4
+ let(:prickly) { Prickly.new }
5
+
6
+ before do
7
+ prickly.extend Prickle::Capybara
8
+ prickly.visit '/'
9
+ end
10
+
11
+ context 'Extended waits' do
12
+
13
+ before(:each) do
14
+ Prickle::Capybara.wait_time = nil
15
+ prickly.visit '/'
16
+ end
17
+
18
+ context "matching text" do
19
+ it 'can wait for an element to appear' do
20
+ Prickle::Capybara.wait_time = 4
21
+ prickly.element(:name => 'lagged').contains_text? "I lag"
22
+ end
23
+
24
+ it "can fail if an element doesn't appear after the default wait time" do
25
+ Prickle::Capybara.wait_time = 2
26
+ expect { prickly.element(:name => 'lagged').contains_text? "I lag" }.to raise_error Capybara::TimeoutError
27
+ end
28
+ end
29
+
30
+ context "finding elements" do
31
+ it 'can wait for an element to appear' do
32
+ Prickle::Capybara.wait_time = 4
33
+ prickly.find_by_name('lagged')
34
+ end
35
+ end
36
+
37
+ context "clicking elements" do
38
+ it 'fails to click an element that has not appeared yet' do
39
+ Prickle::Capybara.wait_time = 1
40
+ expect { prickly.click_by_name('lagged') }.to raise_error Capybara::TimeoutError
41
+ end
42
+
43
+ it 'can click an element after it appears' do
44
+ Prickle::Capybara.wait_time = 4
45
+ prickly.click_by_name('lagged')
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ describe Prickle::Capybara do
4
+ let(:prickly) { Prickly.new }
5
+
6
+ before do
7
+ prickly.extend Prickle::Capybara
8
+ prickly.visit '/'
9
+ end
10
+
11
+ context 'finding elements' do
12
+ it 'can find any element by name' do
13
+ prickly.find_by_name 'red'
14
+ end
15
+
16
+ context 'can find by element type and name' do
17
+ it 'can find a blue input type element' do
18
+ prickly.find_input_by_name 'blue'
19
+ end
20
+
21
+ it 'can find a pink button' do
22
+ prickly.find_button_by_name 'pink'
23
+ end
24
+
25
+ it "but it cannot find a pink link because it's not on the page" do
26
+ expect { prickly.find_a_by_name('pink') }.to raise_error
27
+ end
28
+ end
29
+
30
+ it 'can find a link' do
31
+ prickly.find_link_by_name 'red-dots'
32
+ end
33
+ end
34
+
35
+ context 'clicking on elements' do
36
+ it 'can click any element by name' do
37
+ prickly.click_by_name 'blue'
38
+ end
39
+
40
+ it 'can click any element by name and type' do
41
+ prickly.element(:input, :name => 'blue').click
42
+ end
43
+
44
+ context 'can click by element type and name' do
45
+ it 'can find a blue input type element' do
46
+ prickly.click_input_by_name 'blue'
47
+ end
48
+
49
+ it "but it cannot find a blue link because it's not on the page" do
50
+ expect { prickly.click_link_by_name 'blue' }.to raise_error
51
+ end
52
+ end
53
+ end
54
+
55
+ context 'matching text' do
56
+ it 'can find text in a paragraph' do
57
+ prickly.paragraph_contains_text? "yellow", "Hello!"
58
+ end
59
+ end
60
+
61
+ context 'DSL' do
62
+ it 'can find an element' do
63
+ prickly.element(:name => 'blue').should == prickly
64
+ end
65
+
66
+ it 'can match text in an element' do
67
+ prickly.element(:name => 'yellow').contains_text? "Hello!"
68
+ end
69
+
70
+ it 'can match text in specific elements' do
71
+ prickly.element(:li, :name => 'purple').contains_text? "Im not purple!"
72
+ end
73
+
74
+ it 'can match on link type elements' do
75
+ prickly.element(:link, :name => 'orangey').contains_text? "Me too!"
76
+ end
77
+
78
+ it 'can click specific element types by name' do
79
+ prickly.element(:paragraph, :name => 'yellow').click
80
+ end
81
+
82
+ it 'can find an element by type and identifier' do
83
+ prickly.element(:paragraph, :id => 'coffee').exists?
84
+ end
85
+
86
+ it 'can find and click on element by type and identifier' do
87
+ prickly.element(:link, :href => 'http://google.com').click
88
+ end
89
+
90
+ it 'can find an element by multiple identifiers' do
91
+ prickly.element(:name => 'orangey', :class => 'pink').contains_text? "Blue hippos"
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,16 @@
1
+ require File.join(File.dirname(__FILE__), "..", "lib", "prickle", "capybara")
2
+
3
+ require 'rspec'
4
+ require 'capybara'
5
+ require 'capybara/dsl'
6
+ require 'prickle/capybara'
7
+
8
+ class Prickly
9
+ include Capybara::DSL
10
+
11
+ end
12
+
13
+ require_relative 'stub/app'
14
+ Capybara.app = Sinatra::Application
15
+ Capybara.default_driver = :selenium
16
+ Capybara.default_wait_time = 0
data/spec/stub/app.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'sinatra'
2
+
3
+ get '/' do
4
+ File.read(File.join(File.dirname(__FILE__), 'index.html'))
5
+ end
@@ -0,0 +1,34 @@
1
+ <html>
2
+ <head>
3
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
4
+ </head>
5
+ <body>
6
+ <input name="red" type="button" />
7
+ <input name="blue" type="button" />
8
+
9
+ <button name="pink"></button>
10
+ <a name="red-dots"></button>
11
+ <p name="yellow">Hello!</p>
12
+
13
+ <li name="purple">Im not purple!</li>
14
+ <a name="orangey">Me too!!</a>
15
+
16
+ <div name='lagged' class='hidden'> I lag</div>
17
+ <div name='orangey' class='pink'> Blue hippos</div>
18
+
19
+ <p id='coffee'>Capuccino</p>
20
+
21
+ <a href="http://google.com">google</a>
22
+ <script>
23
+ $(document).ready(function() {
24
+ $('.hidden').hide();
25
+ setTimeout(showHidden, 3000);
26
+ });
27
+
28
+ function showHidden() {
29
+ $('.hidden').show();
30
+ }
31
+
32
+ </script>
33
+ </body>
34
+ </html>
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prickle
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Despo Pentara
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-02-10 00:00:00 +00:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: capybara
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: capybara
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ type: :development
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: rspec
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: 2.8.0
47
+ type: :development
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: sinatra
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ~>
56
+ - !ruby/object:Gem::Version
57
+ version: 1.3.2
58
+ type: :development
59
+ version_requirements: *id004
60
+ description: A simple DSL wrapped around Capybara for matching elements using html tags.
61
+ email: despo@extractmethod.com
62
+ executables: []
63
+
64
+ extensions: []
65
+
66
+ extra_rdoc_files: []
67
+
68
+ files:
69
+ - .rvmrc
70
+ - Gemfile
71
+ - Gemfile.lock
72
+ - README.md
73
+ - lib/prickle/capybara.rb
74
+ - lib/prickle/capybara/click.rb
75
+ - lib/prickle/capybara/exceptions.rb
76
+ - lib/prickle/capybara/find.rb
77
+ - lib/prickle/capybara/match.rb
78
+ - prickle.png
79
+ - spec/extended_wait_spec.rb
80
+ - spec/finders_spec.rb
81
+ - spec/spec_helper.rb
82
+ - spec/stub/app.rb
83
+ - spec/stub/index.html
84
+ has_rdoc: true
85
+ homepage: https://github.com/ExtractMethod/prickle
86
+ licenses:
87
+ - MIT
88
+ post_install_message:
89
+ rdoc_options: []
90
+
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: 1.9.2
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: "0"
105
+ requirements: []
106
+
107
+ rubyforge_project:
108
+ rubygems_version: 1.5.2
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: A simple DSL wrapped around Capybara for matching elements using html tags.
112
+ test_files: []
113
+