capybara-workflows 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e0ced3bcfbcf204817c8806227b5b79452b3e98e
4
+ data.tar.gz: 621b5b0a3fb3ddd880aa04d71f81fcbde9c5180f
5
+ SHA512:
6
+ metadata.gz: b15ca25183a838ea484b862af871902f151ebbe926ddfd38022d7558ef5fb45184e24795f04d8c0f452c977943a1fe5f7d180a5a19dc3869099d37c902822336
7
+ data.tar.gz: 26ba2e5ba1fac9581fad180a32ddfb6cd9e93e44d1d49e3ff37610e370f9688371217709c6d5f5db94ffe480af95b3b4854f4a3c69f53418cd2aef52f8751635
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .ruby-version
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in capybara-workflows.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Nicholas Rutherford
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,199 @@
1
+ # Capybara::Workflows
2
+
3
+ Organise your Capybara helper library into by-role workflow sets or [page objects](https://code.google.com/p/selenium/wiki/PageObjects).
4
+
5
+ Helpers are executed by the original Capybara session, which you provide by dependency injection, as if you'd written the code where you call the method. All your usual helpers are available.
6
+
7
+ Example:
8
+
9
+ ```ruby
10
+ specify 'I can enter my qualifications' do
11
+ qualifications = QualificationWorkflows.new(self)
12
+ qualifications.add_course 'GCSE', 'Maths', 'A', 'Predicted'
13
+ qualifications.add_course 'A2', 'Other', 'A*', '2010'
14
+ qualifications.add_course 'AS', 'Chemistry', 'B', '2011'
15
+ expect(page).to have_css('tr', text: 'GCSE Maths A Predicted')
16
+ expect(page).to have_css('tr', text: 'A2 Other A* 2010')
17
+ expect(page).to have_css('tr', text: 'AS Chemistry B 2011')
18
+ end
19
+ ```
20
+
21
+ Where you have defined the QualificationWorkflows class and its #add_course method as explained below.
22
+
23
+
24
+ ## Installation
25
+
26
+ Add to your Gemfile's test group:
27
+
28
+ ```ruby
29
+ gem 'capybara-workflows'
30
+ ```
31
+
32
+ And then execute:
33
+
34
+ $ bundle
35
+
36
+ Or install it yourself as:
37
+
38
+ $ gem install capybara-workflows
39
+
40
+ ## Usage
41
+
42
+ How you group things is up to you. This could have been called Capybara::PageObjectModel instead, but I wasn't grouping them that way at time of writing, and don't want to stand on [site_prism's](https://github.com/natritmeyer/site_prism) toes.
43
+
44
+ That is to say, rather than having classes like
45
+
46
+ ```ruby
47
+ MemberWorkflows.new(self, email, password).log_in
48
+ ```
49
+
50
+ you could instead have
51
+
52
+ ```ruby
53
+ MemberLoginPage.new(self).log_in(email, password)
54
+ ```
55
+
56
+ or whichever structure you care to think of.
57
+
58
+ All this actually does is enable you to write lines of capybara test code in another class, and share it between test files, reducing LOC and increasing sharing.
59
+
60
+ The trick is executing that code in the context of the capybara session, not the object holding the helpers. That's why you pass the session in when initialising the object, and why you write workflow blocks rather than method definitions.
61
+
62
+
63
+ ### Defining workflows
64
+
65
+ For simplicity you may want to start writing these class definitions directly into your test files, just to get started. See Loading workflows for some ideas how to reorganise later.
66
+
67
+ ```ruby
68
+ class MemberWorkflows < Capybara::Workflows::WorkflowSet
69
+ # sign in
70
+ workflow :login_with do |email, password|
71
+ visit '/member'
72
+ fill_in("member_email", :with => email)
73
+ fill_in("member_password", :with => password)
74
+ click_button("member_submit")
75
+ end
76
+
77
+ workflow :logout do
78
+ visit '/member'
79
+ click_on "Sign out"
80
+ end
81
+ end
82
+ ```
83
+
84
+ Here's something a little more complex, which tracks previous logins (if made through the same object's interface). The optional workflow parameter gives access to instance variables and other workflow definitions. It's passed to your block as its final argument.
85
+
86
+ ```ruby
87
+ class MemberWorkflows < Capybara::Workflows::WorkflowSet
88
+ attr_accessor :logged_in, :email, :password
89
+ def initialize(session, email, password)
90
+ self.email = email
91
+ self.password = password
92
+ self.logged_in = false
93
+ super(session)
94
+ end
95
+
96
+ # sign in
97
+ workflow :login do |workflow|
98
+ unless workflow.logged_in
99
+ visit '/member'
100
+ fill_in("member_email", with: workflow.email)
101
+ fill_in("member_password", with: workflow.password)
102
+ click_button("member_submit")
103
+ workflow.logged_in = true
104
+ end
105
+ end
106
+
107
+ workflow :logout do |workflow|
108
+ visit '/member'
109
+ click_on "Sign out"
110
+ workflow.logged_in = false
111
+ end
112
+
113
+ workflow :post_article do |title, body, workflow|
114
+ workflow.login unless workflow.logged_in
115
+ visit new_article_path
116
+ fill_in "Title", with: title
117
+ fill_in "Body", with: body
118
+ click_on "Post article"
119
+ end
120
+ end
121
+ ```
122
+
123
+
124
+
125
+ ### Cucumber
126
+
127
+ Below demonstrates using workflows to help manage state between steps.
128
+
129
+ ```ruby
130
+ Given(/^I am in a group$/) do
131
+ @group = member.groups.make
132
+ gm = @group.group_managers.make
133
+ @group_manager = GroupManagerWorkflows.new(self, gm.email, gm.password)
134
+ end
135
+
136
+ Then(/^my teacher can't monitor my progress$/) do
137
+ @group_manager.view_student_progress(@member.email)
138
+ expect(page).to have_content("has not given you permission to monitor their progress. Please ask them to add you to their supervisor list in their account settings page.")
139
+ end
140
+
141
+ or
142
+
143
+ When(/^I go to my account page$/) do
144
+ MemberWorkflows.new(self).login_with(@member.email, @member.password)
145
+ ensure_on edit_member_path
146
+ end
147
+ ```
148
+
149
+ ### RSpec
150
+
151
+ ```ruby
152
+ describe "doing stuff" do
153
+ let(:member) {Member.make}
154
+ before(:each) do
155
+ MemberWorkflows.new(self).login_with(@member.email, @member.password)
156
+ end
157
+ end
158
+ ```
159
+
160
+ ### Loading workflows
161
+
162
+ Define workflow classes in spec/support, feature/support, or whichever directory you prefer that will be loaded before your tests run. Or require them explicitly in your tests.
163
+
164
+ One approach is to put the following snippet into spec/support/load_shared_test_lib.rb for RSpec, and features/support/load_shared_test_lib.rb for Cucumber
165
+
166
+ ```ruby
167
+ # -*- encoding : utf-8 -*-
168
+ Dir[
169
+ File.expand_path(
170
+ Rails.root.join 'test_helper_lib', '**', '*.rb'
171
+ )
172
+ ].each {|f| require f}
173
+ ```
174
+
175
+ We use:
176
+
177
+ ```
178
+ -|
179
+ |- feature
180
+ |- spec
181
+ |- test_helper_lib
182
+ |- workflows
183
+ |- member_workflows.rb
184
+ |- etc
185
+ ```
186
+
187
+ ## State encapsulation
188
+
189
+ Managing state, or context of execution, with shared cucumber steps is not fun. Assigning workflow objects to ivars and letting them track who is logged in, what their attributes are, what they can do, etc, may ease the pain.
190
+
191
+ For RSpec state encapsulation may or may not be useful, since test statements share scope and are typically easier to manage than Cucumber. However, when sharing with Cucumber it may be simpler to reuse identical workflows.
192
+
193
+ ## Contributing
194
+
195
+ 1. Fork it ( https://github.com/nruth/capybara-workflows/fork )
196
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
197
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
198
+ 4. Push to the branch (`git push origin my-new-feature`)
199
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capybara/workflows/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "capybara-workflows"
8
+ spec.version = Capybara::Workflows::VERSION
9
+ spec.authors = ["Nicholas Rutherford"]
10
+ spec.email = ["nick.rutherford@gmail.com"]
11
+ spec.summary = %q{Organise your Capybara helper library into by-role workflow sets or page objects}
12
+ spec.description = ""
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
@@ -0,0 +1,14 @@
1
+ require "capybara/workflows/version"
2
+
3
+ module Capybara
4
+ module Workflows
5
+ # for use in capybara integration tests
6
+ # session : the test session, where capybara and other libraries/helpers are available
7
+ class WorkflowSet < Struct.new(:session)
8
+ def self.workflow(name, &block)
9
+ workflow = Proc.new do |*args| session.instance_exec(*[*args, self], &block) end
10
+ define_method(name, &workflow)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ module Capybara
2
+ module Workflows
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capybara-workflows
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nicholas Rutherford
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: ''
42
+ email:
43
+ - nick.rutherford@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - LICENSE
51
+ - README.md
52
+ - Rakefile
53
+ - capybara-workflows.gemspec
54
+ - lib/capybara/workflows.rb
55
+ - lib/capybara/workflows/version.rb
56
+ homepage: ''
57
+ licenses:
58
+ - MIT
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 2.2.2
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: Organise your Capybara helper library into by-role workflow sets or page
80
+ objects
81
+ test_files: []