mobilify 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +32 -46
- data/lib/mobilify.rb +18 -14
- data/lib/mobilify/version.rb +1 -1
- data/mobilify.gemspec +4 -3
- data/spec/multiple_context_spec.rb +29 -0
- data/spec/page_object_spec.rb +11 -0
- data/spec/simple_context_spec.rb +23 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/khan_academy.rb +12 -0
- metadata +31 -21
- data/features/desktop_link.feature +0 -20
- data/features/mobile_link.feature +0 -20
- data/features/step_definitions/link_steps.rb +0 -27
- data/features/step_definitions/navigation_step.rb +0 -14
- data/features/support/env.rb +0 -6
- data/features/support/hooks.rb +0 -3
- data/features/support/manta_page.rb +0 -10
data/README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# Mobilify
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/mobilify.png)](http://badge.fury.io/rb/mobilify)
|
3
3
|
|
4
|
-
|
4
|
+
Invoke one page-object method name but execute different definitions of that method based on the page-object's context.
|
5
|
+
|
6
|
+
We use it at [Manta](www.manta.com) to keep the number of test scripts low while testing against multiple versions of the same feature (legacy version, new desktop version, new mobile version, etc).
|
5
7
|
|
6
8
|
## Usage
|
7
|
-
To
|
9
|
+
To contextualize your page objects, ```include Mobilify``` in the page class. For each method requiring a contextual replacement, create an element (or method) definition with your context prepended to the original's name (like `mobile_` or `legacy_`).
|
8
10
|
|
9
11
|
```ruby
|
10
12
|
# method
|
@@ -20,66 +22,50 @@ Mobilify will replace called methods with their contextual counterparts if two c
|
|
20
22
|
my_page = Page.new(@browser, :context => :mobile)
|
21
23
|
```
|
22
24
|
|
23
|
-
|
25
|
+
Mobilify also supports multiple contexts per page-object instance, invoking the first applicable context it matches in a given array.
|
26
|
+
|
24
27
|
```ruby
|
25
|
-
#
|
26
|
-
my_page = Page.new(@browser, :
|
27
|
-
my_page = Page.new(@browser, :visit => true, :context => :mobile)
|
28
|
+
# multiple context constructor
|
29
|
+
my_page = Page.new(@browser, :context => [:legacy, :mobile])
|
28
30
|
```
|
29
31
|
|
30
32
|
#### Example
|
31
33
|
|
32
|
-
|
34
|
+
I want to test a login page, but my there are basically three versions of the same page in some cycle of development. There's legacy code, new responsive code at the desktop size, and new responsive code at the mobile size. All three have different identifiers for the login form.
|
35
|
+
|
36
|
+
I'll use Mobilify to write one script and test all browsers and environments.
|
33
37
|
|
34
38
|
```ruby
|
35
|
-
#
|
36
|
-
require
|
39
|
+
# login.rb
|
40
|
+
require "mobilify"
|
37
41
|
|
38
|
-
class
|
42
|
+
class Login
|
39
43
|
include Mobilify
|
40
44
|
|
41
|
-
|
45
|
+
text_field(:user, :id => "email")
|
46
|
+
text_field(:mobile_user, :id => "xs-email")
|
47
|
+
text_field(:legacy_user, :id => "member-email")
|
42
48
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
```
|
47
|
-
|
48
|
-
```ruby
|
49
|
-
# spec/spec_helper.rb
|
50
|
-
require 'watir-webdriver'
|
51
|
-
require 'webdriver-user-agent'
|
52
|
-
|
53
|
-
RSpec.configure do |config|
|
49
|
+
text_field(:password, :id => "password")
|
50
|
+
text_field(:mobile_password, :id => "xs-password")
|
51
|
+
text_field(:legacy_password, :id => "member-password")
|
54
52
|
|
55
|
-
|
56
|
-
case ENV['BROWSER']
|
57
|
-
when 'desktop'
|
58
|
-
@browser = Watir::Browser.new :firefox
|
59
|
-
@my_context = :desktop
|
60
|
-
when 'mobile'
|
61
|
-
driver = Webdriver::UserAgent.driver(:browser => :firefox, :agent => :iphone)
|
62
|
-
@browser = Watir::Browser.new driver
|
63
|
-
@my_context = :mobile
|
64
|
-
end
|
65
|
-
end
|
53
|
+
button(:submit, :id => "submit")
|
66
54
|
end
|
67
55
|
```
|
68
56
|
|
69
57
|
```ruby
|
70
|
-
#
|
71
|
-
require
|
72
|
-
require
|
73
|
-
|
74
|
-
describe
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
82
|
-
end
|
58
|
+
# login_spec.rb
|
59
|
+
require "rspec-given"
|
60
|
+
require "support/login"
|
61
|
+
|
62
|
+
describe "logging in" do
|
63
|
+
Given(:login) { Login.new(@browser, :context => [:mobile, :legacy]) }
|
64
|
+
When { login.goto }
|
65
|
+
When { login.user = "member@example.com" }
|
66
|
+
When { login.password = "password123" }
|
67
|
+
When { login.submit }
|
68
|
+
Then { ... }
|
83
69
|
end
|
84
70
|
```
|
85
71
|
|
data/lib/mobilify.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'mobilify/version'
|
1
2
|
require 'page-object'
|
2
3
|
|
3
4
|
module Mobilify
|
@@ -6,7 +7,7 @@ module Mobilify
|
|
6
7
|
def initialize(browser, opts = {})
|
7
8
|
super(browser, opts[:visit] || false)
|
8
9
|
@context = opts[:context]
|
9
|
-
mobilify! if context
|
10
|
+
mobilify! if @context
|
10
11
|
end
|
11
12
|
|
12
13
|
def self.included(klass)
|
@@ -17,20 +18,23 @@ module Mobilify
|
|
17
18
|
@context
|
18
19
|
end
|
19
20
|
|
20
|
-
private
|
21
|
-
|
22
21
|
def mobilify!
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
22
|
+
match = false
|
23
|
+
(contexts = []) << @context
|
24
|
+
|
25
|
+
contexts.flatten.each do |c|
|
26
|
+
next if match
|
27
|
+
context = c.to_s
|
28
|
+
methods.
|
29
|
+
select { |m| m.to_s.start_with? "#{context}_" }.
|
30
|
+
select { |m| respond_to? m.to_s.gsub("#{context}_", '') }.
|
31
|
+
map { |m| self.method(m) }.each do |method|
|
32
|
+
(class << self; self; end).class_eval do
|
33
|
+
define_method(method.name.to_s.gsub("#{context}_", ''), method)
|
34
|
+
match = true
|
35
|
+
end
|
31
36
|
end
|
32
|
-
|
37
|
+
end
|
33
38
|
end
|
34
|
-
end
|
35
39
|
|
36
|
-
|
40
|
+
end
|
data/lib/mobilify/version.rb
CHANGED
data/mobilify.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Mobilify::VERSION
|
9
9
|
spec.authors = ["Johnson Denen"]
|
10
10
|
spec.email = ["jdenen@manta.com"]
|
11
|
-
spec.description = %q{
|
12
|
-
spec.summary = %q{
|
11
|
+
spec.description = %q{page-object methods invoked with one call but defined contextually}
|
12
|
+
spec.summary = %q{page-object methods invoked with one call but defined contextually}
|
13
13
|
spec.homepage = "http://github.com/jdenen/mobilify"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -24,5 +24,6 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency "rake"
|
25
25
|
spec.add_development_dependency "watir-webdriver"
|
26
26
|
spec.add_development_dependency "webdriver-user-agent"
|
27
|
-
spec.add_development_dependency "
|
27
|
+
spec.add_development_dependency "rspec"
|
28
|
+
spec.add_development_dependency "rspec-given"
|
28
29
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mobilify do
|
4
|
+
after :each do
|
5
|
+
@browser.close
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "uses default method when given contexts do not apply" do
|
9
|
+
Given(:desktop) { KhanAcademy.new(desktop_browser, { :visit => true, :context => [:no_match, :wrong] }) }
|
10
|
+
Then { desktop.login_element.inspect.should include("log-in-link ellipsis highlight") }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "uses only applicable context given" do
|
14
|
+
context "when applicable context is first in the array" do
|
15
|
+
Given(:mobile) { KhanAcademy.new(mobile_browser, { :visit => true, :context => [:mobile, :wrong] }) }
|
16
|
+
Then { mobile.login_element.inspect.should include("simple-button big-button") }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when applicable context is second in the array" do
|
20
|
+
Given(:mobile) { KhanAcademy.new(mobile_browser, { :visit => true, :context => [:wrong, :mobile] }) }
|
21
|
+
Then { mobile.login_element.inspect.should include("simple-button big-button") }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "uses first context given when multiple applicable contexts are given" do
|
26
|
+
Given(:mobile) { KhanAcademy.new(mobile_browser, { :visit => true, :context => [:mobile, :ignored] }) }
|
27
|
+
Then { mobile.login_element.inspect.should include("simple-button big-button") }
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mobilify do
|
4
|
+
after :each do
|
5
|
+
@browser.close
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "uses default method when no context is given" do
|
9
|
+
Given(:desktop) { KhanAcademy.new(desktop_browser, { :visit => true }) }
|
10
|
+
Then { desktop.login_element.inspect.should include("log-in-link ellipsis highlight") }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "uses default method when non-applicable context is given" do
|
14
|
+
Given(:desktop) { KhanAcademy.new(desktop_browser, { :visit => true, :context => :wrong }) }
|
15
|
+
Then { desktop.login_element.inspect.should include("log-in-link ellipsis highlight") }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "uses contextual method for the given context" do
|
19
|
+
Given(:mobile) { KhanAcademy.new(mobile_browser, { :context => :mobile, :visit => true }) }
|
20
|
+
Then { mobile.login_element.inspect.should include("simple-button big-button") }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'rspec-given'
|
3
|
+
require 'watir-webdriver'
|
4
|
+
require 'webdriver-user-agent'
|
5
|
+
require './lib/mobilify'
|
6
|
+
require 'support/khan_academy'
|
7
|
+
|
8
|
+
def desktop_browser
|
9
|
+
@browser = Watir::Browser.new :firefox
|
10
|
+
end
|
11
|
+
|
12
|
+
def mobile_browser
|
13
|
+
device = Webdriver::UserAgent.driver(:browser => :firefox, :agent => :iphone)
|
14
|
+
@browser = Watir::Browser.new device
|
15
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "./lib/mobilify"
|
2
|
+
|
3
|
+
class KhanAcademy
|
4
|
+
include Mobilify
|
5
|
+
|
6
|
+
page_url "http://www.khanacademy.org"
|
7
|
+
|
8
|
+
link(:login, :class => "log-in-link ellipsis highlight")
|
9
|
+
link(:mobile_login, :class => "simple-button big-button")
|
10
|
+
link(:ignored_login, :class => "simple-button primary big-button")
|
11
|
+
end
|
12
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mobilify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-02-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: page-object
|
@@ -92,7 +92,7 @@ dependencies:
|
|
92
92
|
- !ruby/object:Gem::Version
|
93
93
|
version: '0'
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
|
-
name:
|
95
|
+
name: rspec
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
97
97
|
none: false
|
98
98
|
requirements:
|
@@ -107,8 +107,23 @@ dependencies:
|
|
107
107
|
- - ! '>='
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
|
-
|
111
|
-
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: rspec-given
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
description: page-object methods invoked with one call but defined contextually
|
112
127
|
email:
|
113
128
|
- jdenen@manta.com
|
114
129
|
executables: []
|
@@ -120,16 +135,14 @@ files:
|
|
120
135
|
- LICENSE.txt
|
121
136
|
- README.md
|
122
137
|
- Rakefile
|
123
|
-
- features/desktop_link.feature
|
124
|
-
- features/mobile_link.feature
|
125
|
-
- features/step_definitions/link_steps.rb
|
126
|
-
- features/step_definitions/navigation_step.rb
|
127
|
-
- features/support/env.rb
|
128
|
-
- features/support/hooks.rb
|
129
|
-
- features/support/manta_page.rb
|
130
138
|
- lib/mobilify.rb
|
131
139
|
- lib/mobilify/version.rb
|
132
140
|
- mobilify.gemspec
|
141
|
+
- spec/multiple_context_spec.rb
|
142
|
+
- spec/page_object_spec.rb
|
143
|
+
- spec/simple_context_spec.rb
|
144
|
+
- spec/spec_helper.rb
|
145
|
+
- spec/support/khan_academy.rb
|
133
146
|
homepage: http://github.com/jdenen/mobilify
|
134
147
|
licenses:
|
135
148
|
- MIT
|
@@ -154,13 +167,10 @@ rubyforge_project:
|
|
154
167
|
rubygems_version: 1.8.23
|
155
168
|
signing_key:
|
156
169
|
specification_version: 3
|
157
|
-
summary:
|
158
|
-
different contexts
|
170
|
+
summary: page-object methods invoked with one call but defined contextually
|
159
171
|
test_files:
|
160
|
-
-
|
161
|
-
-
|
162
|
-
-
|
163
|
-
-
|
164
|
-
-
|
165
|
-
- features/support/hooks.rb
|
166
|
-
- features/support/manta_page.rb
|
172
|
+
- spec/multiple_context_spec.rb
|
173
|
+
- spec/page_object_spec.rb
|
174
|
+
- spec/simple_context_spec.rb
|
175
|
+
- spec/spec_helper.rb
|
176
|
+
- spec/support/khan_academy.rb
|
@@ -1,20 +0,0 @@
|
|
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
|
-
|
@@ -1,20 +0,0 @@
|
|
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
|
-
|
@@ -1,27 +0,0 @@
|
|
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(':xpath=>"//div[@class=\'panel-body\']//a[contains(@href, \'/cmap/\')]"')
|
19
|
-
end
|
20
|
-
|
21
|
-
Then /^I should receive the mobile link element$/ do
|
22
|
-
@element.inspect.should include(':xpath=>"//div[@class=\'col-xs-6\']/a[contains(@href, \'/cmap/\')]"')
|
23
|
-
end
|
24
|
-
|
25
|
-
Then /^I should land on the map page$/ do
|
26
|
-
@page.current_url.should include('/cmap/')
|
27
|
-
end
|
@@ -1,14 +0,0 @@
|
|
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, :context => @agent, :visit => true)
|
14
|
-
end
|
data/features/support/env.rb
DELETED
data/features/support/hooks.rb
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
require 'mobilify'
|
2
|
-
|
3
|
-
class MantaPage
|
4
|
-
include Mobilify
|
5
|
-
|
6
|
-
page_url "http://www.manta.com/c/mm2fqg7"
|
7
|
-
|
8
|
-
link(:map, :xpath => "//div[@class='panel-body']//a[contains(@href, '/cmap/')]")
|
9
|
-
link(:mobile_map, :xpath => "//div[@class='col-xs-6']/a[contains(@href, '/cmap/')]")
|
10
|
-
end
|