mobilify 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +116 -0
- data/Rakefile +1 -0
- data/features/desktop_link.feature +20 -0
- data/features/mobile_link.feature +20 -0
- data/features/step_definitions/link_steps.rb +27 -0
- data/features/step_definitions/navigation_step.rb +14 -0
- data/features/support/env.rb +6 -0
- data/features/support/hooks.rb +3 -0
- data/features/support/manta_page.rb +10 -0
- data/lib/mobilify.rb +36 -0
- data/lib/mobilify/version.rb +3 -0
- data/mobilify.gemspec +28 -0
- metadata +165 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Johnson Denen
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# Mobilify
|
2
|
+
|
3
|
+
We don't like to maintain a lot of test code. Which means, we don't want to rewrite the same tests for the same web application on different platforms. It's easy when those different platforms are browsers, because the site doesn't change much (at all?).
|
4
|
+
|
5
|
+
But, it's a challenge to reuse code when the different platforms are desktop and mobile browsers. The elements move, and their identifiers change. We could create separate page objects for desktop and mobile, with a mixin object for the shared stuff. Or we could create one page object with all the elements, and write two different tests. Seems like a waste both ways.
|
6
|
+
|
7
|
+
Mobilify allows you to create one page object and write one test. You write tests for the desktop, and it will grab mobile elements when necessary. Just define the context during page initialization.
|
8
|
+
|
9
|
+
#### Usage
|
10
|
+
To Mobilify your page objects, ```include Mobilify``` in the page class. For each method requiring a mobile replacement, create an element definition with ```mobile_``` prepended to the original's name.
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
# method
|
14
|
+
text_field(:password, :id => "user-pw")
|
15
|
+
# replacement
|
16
|
+
text_field(:mobile_password, :id => "mobile-pw")
|
17
|
+
```
|
18
|
+
|
19
|
+
Mobilify will replace called methods with their ```mobile_``` counterparts if two conditions are met. First, a hash with a key-value pair of ```:agent => :mobile``` is passed to the page object constructor. And second, the page object responds to a ```mobile_``` version of the called method.
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
# constructor
|
23
|
+
my_page = Page.new(@browser, :agent => :mobile)
|
24
|
+
```
|
25
|
+
|
26
|
+
To navigate to your page object during initialization, pass the key-value pair ```:visit => true``` to the constructor.
|
27
|
+
```ruby
|
28
|
+
# visiting
|
29
|
+
my_page = Page.new(@browser, :visit => true)
|
30
|
+
my_page = Page.new(@browser, :visit => true, :agent => :mobile)
|
31
|
+
```
|
32
|
+
|
33
|
+
#### Example
|
34
|
+
|
35
|
+
You're testing a responsive page with a link to your registration form. But you can only identify the link with XPath, and the XPath changes between your desktop-sized application and your mobile-sized application. You could:
|
36
|
+
|
37
|
+
* Call two different methods in two different specs, each pointing to its own XPath
|
38
|
+
* Call two different methods in one spec, using logic to determine the call correctly
|
39
|
+
* Call the same method in one spec and Mobilify the page object for mobile testing
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
# spec/page.rb
|
43
|
+
require 'mobilify'
|
44
|
+
|
45
|
+
class Page
|
46
|
+
include Mobilify
|
47
|
+
|
48
|
+
page_url "http://my-page.com"
|
49
|
+
|
50
|
+
link(:to_registration, :xpath => '//xpath/to/desktop/register/link')
|
51
|
+
link(:mobile_to_registration, :xpath => '//xpath/to/mobile/register/link')
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
# spec/spec_helper.rb
|
57
|
+
require 'watir-webdriver'
|
58
|
+
require 'webdriver-user-agent'
|
59
|
+
|
60
|
+
RSpec.configure do |config|
|
61
|
+
|
62
|
+
config.before :all do
|
63
|
+
case ENV['BROWSER']
|
64
|
+
when 'desktop'
|
65
|
+
@browser = Watir::Browser.new :firefox
|
66
|
+
@agent = :desktop
|
67
|
+
when 'mobile'
|
68
|
+
driver = Webdriver::UserAgent.driver(:browser => :firefox, :agent => :iphone)
|
69
|
+
@browser = Watir::Browser.new driver
|
70
|
+
@agent = :mobile
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
# spec/registration_link_spec.rb
|
78
|
+
require 'spec_helper'
|
79
|
+
require 'page'
|
80
|
+
|
81
|
+
describe Page do
|
82
|
+
let(:page) { Page.new(@browser, :agent => @agent, :visit => true) }
|
83
|
+
|
84
|
+
describe "#to_registration" do
|
85
|
+
it "takes me to the registration form" do
|
86
|
+
page.to_registration
|
87
|
+
@browser.url.should == "http://my-page.com/registration"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
## Installation
|
94
|
+
|
95
|
+
Add this line to your application's Gemfile:
|
96
|
+
|
97
|
+
gem 'mobilify'
|
98
|
+
|
99
|
+
And then execute:
|
100
|
+
|
101
|
+
$ bundle
|
102
|
+
|
103
|
+
Or install it yourself as:
|
104
|
+
|
105
|
+
$ gem install mobilify
|
106
|
+
|
107
|
+
## Contributing
|
108
|
+
|
109
|
+
1. Fork it
|
110
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
111
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
112
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
113
|
+
5. Create new Pull Request
|
114
|
+
|
115
|
+
## Questions, Comments, Concerns
|
116
|
+
Easiest place to reach me is Twitter, [@jpdenen](http://twitter.com/jpdenen)
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Desktop Link
|
2
|
+
To use one spec/feature per functionality
|
3
|
+
Testers will need to use normal page-object functionality on the desktop
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given I am using Firefox
|
7
|
+
And I navigate to a Manta profile
|
8
|
+
|
9
|
+
Scenario: Finding a link
|
10
|
+
When I query the map link
|
11
|
+
Then I should receive true
|
12
|
+
|
13
|
+
Scenario: Grabbing a link
|
14
|
+
When I ask for the map link element
|
15
|
+
Then I should receive the desktop link element
|
16
|
+
|
17
|
+
Scenario: Clicking a link
|
18
|
+
When I click the map link
|
19
|
+
Then I should land on the map page
|
20
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Mobile Link
|
2
|
+
To use one spec/feature per functionality
|
3
|
+
Testers will need to use mobilified page-object functionality on mobile devices
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given I am using a mobile device
|
7
|
+
And I navigate to a Manta profile
|
8
|
+
|
9
|
+
Scenario: Finding a link
|
10
|
+
When I query the map link
|
11
|
+
Then I should receive true
|
12
|
+
|
13
|
+
Scenario: Grabbing a link
|
14
|
+
When I ask for the map link element
|
15
|
+
Then I should receive the mobile link element
|
16
|
+
|
17
|
+
Scenario: Clicking a link
|
18
|
+
When I click the map link
|
19
|
+
Then I should land on the map page
|
20
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
When /^I query the map link$/ do
|
2
|
+
@query = @page.map?
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I ask for the map link element$/ do
|
6
|
+
@element = @page.map_element
|
7
|
+
end
|
8
|
+
|
9
|
+
When /^I click the map link$/ do
|
10
|
+
@page.map
|
11
|
+
end
|
12
|
+
|
13
|
+
Then /^I should receive true$/ do
|
14
|
+
@query.should == true
|
15
|
+
end
|
16
|
+
|
17
|
+
Then /^I should receive the desktop link element$/ do
|
18
|
+
@element.inspect.should include(':id=>"map-tab-link"')
|
19
|
+
end
|
20
|
+
|
21
|
+
Then /^I should receive the mobile link element$/ do
|
22
|
+
@element.inspect.should include(':class=>"pvm prm"')
|
23
|
+
end
|
24
|
+
|
25
|
+
Then /^I should land on the map page$/ do
|
26
|
+
@page.current_url.should include('/cmap/')
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Given /^I am using Firefox$/ do
|
2
|
+
@browser = Watir::Browser.new
|
3
|
+
@agent = :desktop
|
4
|
+
end
|
5
|
+
|
6
|
+
Given /^I am using a mobile device$/ do
|
7
|
+
driver = Webdriver::UserAgent.driver(:browser => :firefox, :agent => :iphone)
|
8
|
+
@browser = Watir::Browser.new driver
|
9
|
+
@agent = :mobile
|
10
|
+
end
|
11
|
+
|
12
|
+
Given /^I navigate to a Manta profile$/ do
|
13
|
+
@page = MantaPage.new(@browser, :agent => @agent, :visit => true)
|
14
|
+
end
|
data/lib/mobilify.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'page-object'
|
2
|
+
|
3
|
+
module Mobilify
|
4
|
+
include PageObject
|
5
|
+
|
6
|
+
def initialize(browser, opts = {})
|
7
|
+
super(browser, opts[:visit] || false)
|
8
|
+
@mobile = opts[:agent] == :mobile
|
9
|
+
mobilify! if mobile?
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.included(klass)
|
13
|
+
klass.send :include, PageObject
|
14
|
+
end
|
15
|
+
|
16
|
+
def mobile?
|
17
|
+
@mobile
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def mobilify!
|
23
|
+
methods.
|
24
|
+
select { |m| m.to_s.start_with? 'mobile_' }.
|
25
|
+
select { |m| respond_to? m.to_s.gsub('mobile_', '') }.
|
26
|
+
map { |m| self.method(m) }.each do |method|
|
27
|
+
(class << self; self; end).class_eval do
|
28
|
+
define_method(method.name.to_s.gsub('mobile_', ''), method)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
require 'mobilify/version'
|
data/mobilify.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'mobilify/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "mobilify"
|
8
|
+
spec.version = Mobilify::VERSION
|
9
|
+
spec.authors = ["Johnson Denen"]
|
10
|
+
spec.email = ["jdenen@manta.com"]
|
11
|
+
spec.description = %q{Make your mobile testing easier with mobilified page objects}
|
12
|
+
spec.summary = %q{Make your mobile testing easier with mobilified page objects}
|
13
|
+
spec.homepage = "http://github.com/jdenen/mobilify"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
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_dependency "page-object"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "watir-webdriver"
|
26
|
+
spec.add_development_dependency "webdriver-user-agent"
|
27
|
+
spec.add_development_dependency "cucumber"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mobilify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Johnson Denen
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-12-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: page-object
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bundler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.3'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.3'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: watir-webdriver
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: webdriver-user-agent
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: cucumber
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
description: Make your mobile testing easier with mobilified page objects
|
111
|
+
email:
|
112
|
+
- jdenen@manta.com
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- .gitignore
|
118
|
+
- Gemfile
|
119
|
+
- LICENSE.txt
|
120
|
+
- README.md
|
121
|
+
- Rakefile
|
122
|
+
- features/desktop_link.feature
|
123
|
+
- features/mobile_link.feature
|
124
|
+
- features/step_definitions/link_steps.rb
|
125
|
+
- features/step_definitions/navigation_step.rb
|
126
|
+
- features/support/env.rb
|
127
|
+
- features/support/hooks.rb
|
128
|
+
- features/support/manta_page.rb
|
129
|
+
- lib/mobilify.rb
|
130
|
+
- lib/mobilify/version.rb
|
131
|
+
- mobilify.gemspec
|
132
|
+
homepage: http://github.com/jdenen/mobilify
|
133
|
+
licenses:
|
134
|
+
- MIT
|
135
|
+
post_install_message:
|
136
|
+
rdoc_options: []
|
137
|
+
require_paths:
|
138
|
+
- lib
|
139
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ! '>='
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
none: false
|
147
|
+
requirements:
|
148
|
+
- - ! '>='
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 1.8.25
|
154
|
+
signing_key:
|
155
|
+
specification_version: 3
|
156
|
+
summary: Make your mobile testing easier with mobilified page objects
|
157
|
+
test_files:
|
158
|
+
- features/desktop_link.feature
|
159
|
+
- features/mobile_link.feature
|
160
|
+
- features/step_definitions/link_steps.rb
|
161
|
+
- features/step_definitions/navigation_step.rb
|
162
|
+
- features/support/env.rb
|
163
|
+
- features/support/hooks.rb
|
164
|
+
- features/support/manta_page.rb
|
165
|
+
has_rdoc:
|