capybara-experience 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/README.md +129 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/capybara-experience.gemspec +31 -0
- data/lib/capybara/experience.rb +60 -0
- data/lib/capybara/experience/rspec.rb +30 -0
- data/lib/capybara/experience/session.rb +57 -0
- data/lib/capybara/experience/version.rb +5 -0
- metadata +102 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 481ac53f31988f2b33cf5fe8cf21f1e5a283ad0e33500b727384c66ac68ec18c
|
4
|
+
data.tar.gz: 58e8aa2c7002f148b85817b744a518f71b97e5f923cff42161e738487a000be3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2c6b11b8f1306cd98fa93f10ab444b440466cc53a3341abb16581af2cbdfcbe86c8172d41c5854e50e581408ee7978f69998dfa45401dea3fe575063083af61d
|
7
|
+
data.tar.gz: 726c207dc4b809cb05da765029f6027eb876b6f16ef5c4e3163a3e2d0a0e24de6ac9af0dc2968b65b49b2bd4d1e9e339410b7bbdcdf9c99c69bbd0ca0b4a4c78
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
# Capybara::Experience
|
2
|
+
We love Capybara! We think it's a great interface for testing Ruby web applications. But there are some pain points with the developer experience of using Capybara. We created this gem to address some of those pain points and added a few niceties along the way.
|
3
|
+
|
4
|
+
Problems with/unsolved by vanilla Capybara:
|
5
|
+
* Managing multiple user sessions in a single test, e.g. comparing customer-facing and admin experiences after interactions on either end.
|
6
|
+
* Managing shared behavior for component interactions irrespective of page or test context
|
7
|
+
* Provide semantically rich context to a collection of interactions & assertions, with clearer scope than comments
|
8
|
+
|
9
|
+
Capybara::Experience has a few core concepts:
|
10
|
+
* Capabilities
|
11
|
+
* Experiences
|
12
|
+
* Behaviors
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
Add this line to your application's Gemfile:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
gem 'capybara-experience'
|
20
|
+
```
|
21
|
+
|
22
|
+
And then execute:
|
23
|
+
|
24
|
+
$ bundle
|
25
|
+
|
26
|
+
Or install it yourself as:
|
27
|
+
|
28
|
+
$ gem install capybara-experience
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
### Basic
|
33
|
+
This scenario is for your standard user/admin.
|
34
|
+
1. We need to create a file for each experience
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
# spec/support/experiences/user_experience.rb
|
38
|
+
class UserExperience < Capybara::Experience
|
39
|
+
def login(user)
|
40
|
+
@user = user
|
41
|
+
login_as user, scope: :user
|
42
|
+
visit '/'
|
43
|
+
assert_text "#{@user.name} Welcome!"
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
attr_reader :user
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
# spec/support/experiences/user_experience.rb
|
55
|
+
class AdminExperience < Capybara::Experience
|
56
|
+
def initialize(*args)
|
57
|
+
super
|
58
|
+
end
|
59
|
+
|
60
|
+
def login(user)
|
61
|
+
@user = user
|
62
|
+
login_as user, scope: :admin
|
63
|
+
visit '/admin/login'
|
64
|
+
assert_text "Home"
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
attr_reader :user
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
2. now we need to create some capabilities. These capability files associate to each page, imagine each capability is an api to a page.
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
# spec/support/capabilities/sign_up.rb
|
77
|
+
module Capabilities::SignUp
|
78
|
+
def navigate_to_sign_up
|
79
|
+
click_link "Sign Up"
|
80
|
+
end
|
81
|
+
|
82
|
+
def sign_up(email: , password: "password")
|
83
|
+
fill_in "email", with: email
|
84
|
+
fill_in "password", with: password
|
85
|
+
fill_in "password_confirmation", with: password
|
86
|
+
click_button "Submit"
|
87
|
+
assert_text "Welcome #{email}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
3. write the spec
|
93
|
+
```ruby
|
94
|
+
# spec/features/sign_up_flow_spec.rb
|
95
|
+
RSpec.describe "sign up flow", feature: true do
|
96
|
+
let(:guest_experience) { GuestExperience.new.extend(Capabilities::SignUp) }
|
97
|
+
let(:admin_experience) { AdminExperience.new.extend(Capabilities::Admin::ManageUser) }
|
98
|
+
|
99
|
+
it "works" do
|
100
|
+
behavior "user can sign up" do # behaviors are an added DSL by capybara-experiences to group interactions & assertions
|
101
|
+
guest_ux = GuestExpereince.new
|
102
|
+
guest_ux.navigate_to_sign_up
|
103
|
+
|
104
|
+
guest_ux.sign_up(
|
105
|
+
email: "user@example.com"
|
106
|
+
)
|
107
|
+
|
108
|
+
expect(guest_ux).to have_content "user@example.com"
|
109
|
+
expect(guest_ux).to_not have_content "Login"
|
110
|
+
end
|
111
|
+
|
112
|
+
behavior "admin can see user" do
|
113
|
+
admin_ux = AdminExperience.new
|
114
|
+
admin_ux.login
|
115
|
+
admin_ux.to have_content "user@example.com"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
```
|
120
|
+
|
121
|
+
## Development
|
122
|
+
|
123
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
124
|
+
|
125
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
126
|
+
|
127
|
+
## Contributing
|
128
|
+
|
129
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ryanong/capybara-experience.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "capybara/experience"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "capybara/experience/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "capybara-experience"
|
7
|
+
spec.version = Capybara::Experience::VERSION
|
8
|
+
spec.authors = ["Ryan Ong", "Britt Lewis"]
|
9
|
+
spec.email = ["ryanong@gmail.com", "brittlewis12@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{Simplify Capybara testing for larger applications}
|
12
|
+
spec.description = %q{Abstractions for Capybara to manage multiple user sessions, encapsulate shared test behavior, and semantically contextualize test code.}
|
13
|
+
spec.homepage = "https://github.com/ryanong/capybara-experience"
|
14
|
+
|
15
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
16
|
+
spec.metadata["source_code_uri"] = "https://github.com/ryanong/capybara-experience"
|
17
|
+
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
18
|
+
|
19
|
+
# Specify which files should be added to the gem when it is released.
|
20
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
21
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
22
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
23
|
+
end
|
24
|
+
spec.bindir = "exe"
|
25
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
26
|
+
spec.require_paths = ["lib"]
|
27
|
+
|
28
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
29
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
30
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
31
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "capybara/experience/version"
|
3
|
+
require "capybara/experience/session"
|
4
|
+
|
5
|
+
module Capybara
|
6
|
+
class Experience
|
7
|
+
include Capybara::DSL
|
8
|
+
include Rails.application.routes.url_helpers
|
9
|
+
include Warden::Test::Helpers
|
10
|
+
|
11
|
+
delegate :t, to: I18n
|
12
|
+
|
13
|
+
def initialize(driver_name: nil)
|
14
|
+
@driver_name = driver_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def reload_page
|
18
|
+
visit current_url
|
19
|
+
end
|
20
|
+
|
21
|
+
def driver_name
|
22
|
+
@driver_name ||= Capybara.current_driver
|
23
|
+
end
|
24
|
+
|
25
|
+
delegate :driver, to: :page
|
26
|
+
|
27
|
+
def page
|
28
|
+
@page ||= Experiences::Session.next(driver: driver_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.wait_for_pending_requests
|
32
|
+
Experiences::Session.pool.taken.each do |session|
|
33
|
+
session.server.try(:wait_for_pending_requests)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def save_and_open_screenshot_full(path = nil, options = {})
|
38
|
+
save_and_open_screenshot(path, options.merge(full: true))
|
39
|
+
end
|
40
|
+
|
41
|
+
def current_driver_adapter
|
42
|
+
adapter = ShowMeTheCookies.adapters[driver_name]
|
43
|
+
if adapter.nil?
|
44
|
+
raise(ShowMeTheCookies::UnknownDriverError, "Unsupported driver #{driver_name}, use one of #{ShowMeTheCookies.adapters.keys} or register your new driver with ShowMeTheCookies.register_adapter")
|
45
|
+
end
|
46
|
+
adapter.new(page.driver)
|
47
|
+
end
|
48
|
+
|
49
|
+
def click_with_js(element)
|
50
|
+
xpath = element.path
|
51
|
+
execute_script <<~JS
|
52
|
+
document.evaluate('#{xpath}', document, null, XPathResult.ANY_TYPE, null)
|
53
|
+
.iterateNext()
|
54
|
+
.click()
|
55
|
+
JS
|
56
|
+
end
|
57
|
+
|
58
|
+
class Error < StandardError; end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module BehaviorDSL
|
3
|
+
def behavior(name, &block)
|
4
|
+
metadata[:description_args].push(name)
|
5
|
+
refresh_description unless in_continuous_integration_env?
|
6
|
+
yield
|
7
|
+
metadata[:description_args].pop
|
8
|
+
refresh_description unless in_continuous_integration_env?
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def refresh_description
|
14
|
+
metadata[:description] = metadata[:description_args].join(" ")
|
15
|
+
metadata[:full_description] = [metadata[:example_group][:full_description]].concat(metadata[:description_args]).join(" ")
|
16
|
+
end
|
17
|
+
|
18
|
+
def metadata
|
19
|
+
RSpec.current_example.metadata
|
20
|
+
end
|
21
|
+
|
22
|
+
def in_continuous_integration_env?
|
23
|
+
ENV["CI"].present?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
RSpec.configure do |config|
|
28
|
+
config.include BehaviorDSL
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Capybara
|
4
|
+
class Experience
|
5
|
+
module Session
|
6
|
+
class << self
|
7
|
+
def next(driver:)
|
8
|
+
pool.next(driver)
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(driver)
|
12
|
+
::Capybara::Session.new(driver, Capybara.app)
|
13
|
+
end
|
14
|
+
|
15
|
+
def pool
|
16
|
+
@pool ||= Pool.new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Pool
|
21
|
+
attr_accessor :idle, :taken
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@idle = []
|
25
|
+
@taken = []
|
26
|
+
end
|
27
|
+
|
28
|
+
def next(driver)
|
29
|
+
take_idle(driver) || create(driver)
|
30
|
+
end
|
31
|
+
|
32
|
+
def release
|
33
|
+
taken.each(&:reset!)
|
34
|
+
idle.concat(taken)
|
35
|
+
taken.clear
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def take_idle(driver)
|
41
|
+
idle.find { |s| s.mode == driver }.tap do |session|
|
42
|
+
if session
|
43
|
+
idle.delete(session)
|
44
|
+
taken.push(session)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def create(driver)
|
50
|
+
::Capybara::Experience::Session.create(driver).tap do |session|
|
51
|
+
taken.push(session)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: capybara-experience
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan Ong
|
8
|
+
- Britt Lewis
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2020-04-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '2.0'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '2.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '10.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '10.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '3.0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '3.0'
|
56
|
+
description: Abstractions for Capybara to manage multiple user sessions, encapsulate
|
57
|
+
shared test behavior, and semantically contextualize test code.
|
58
|
+
email:
|
59
|
+
- ryanong@gmail.com
|
60
|
+
- brittlewis12@gmail.com
|
61
|
+
executables: []
|
62
|
+
extensions: []
|
63
|
+
extra_rdoc_files: []
|
64
|
+
files:
|
65
|
+
- ".gitignore"
|
66
|
+
- ".rspec"
|
67
|
+
- ".travis.yml"
|
68
|
+
- Gemfile
|
69
|
+
- README.md
|
70
|
+
- Rakefile
|
71
|
+
- bin/console
|
72
|
+
- bin/setup
|
73
|
+
- capybara-experience.gemspec
|
74
|
+
- lib/capybara/experience.rb
|
75
|
+
- lib/capybara/experience/rspec.rb
|
76
|
+
- lib/capybara/experience/session.rb
|
77
|
+
- lib/capybara/experience/version.rb
|
78
|
+
homepage: https://github.com/ryanong/capybara-experience
|
79
|
+
licenses: []
|
80
|
+
metadata:
|
81
|
+
homepage_uri: https://github.com/ryanong/capybara-experience
|
82
|
+
source_code_uri: https://github.com/ryanong/capybara-experience
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubygems_version: 3.1.2
|
99
|
+
signing_key:
|
100
|
+
specification_version: 4
|
101
|
+
summary: Simplify Capybara testing for larger applications
|
102
|
+
test_files: []
|