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 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
- Mobilify allows you to create one page object and write one test for your web application, but execute different methods as part of that test given the context. Just change context when initializing your object.
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 Mobilify your page objects, ```include Mobilify``` in the page class. For each method requiring a mobile replacement, create an element (or method) definition with your context prepended to the original's name (like `mobile_`).
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
- To navigate to your page object during initialization, pass the key-value pair ```:visit => true``` to the constructor.
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
- # visiting
26
- my_page = Page.new(@browser, :visit => true)
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
- 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.
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
- # spec/page.rb
36
- require 'mobilify'
39
+ # login.rb
40
+ require "mobilify"
37
41
 
38
- class Page
42
+ class Login
39
43
  include Mobilify
40
44
 
41
- page_url "http://my-page.com"
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
- link(:to_registration, :xpath => '//xpath/to/desktop/register/link')
44
- link(:mobile_to_registration, :xpath => '//xpath/to/mobile/register/link')
45
- end
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
- config.before :all do
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
- # spec/registration_link_spec.rb
71
- require 'spec_helper'
72
- require 'page'
73
-
74
- describe Page do
75
- let(:page) { Page.new(@browser, :context => @my_context, :visit => true) }
76
-
77
- describe "#to_registration" do
78
- it "takes me to the registration form" do
79
- page.to_registration
80
- @browser.url.should == "http://my-page.com/registration"
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
 
@@ -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
- context = @context.to_s
24
-
25
- methods.
26
- select { |m| m.to_s.start_with? "#{context}_" }.
27
- select { |m| respond_to? m.to_s.gsub("#{context}_", '') }.
28
- map { |m| self.method(m) }.each do |method|
29
- (class << self; self; end).class_eval do
30
- define_method(method.name.to_s.gsub("#{context}_", ''), method)
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
- end
37
+ end
33
38
  end
34
- end
35
39
 
36
- require 'mobilify/version'
40
+ end
@@ -1,3 +1,3 @@
1
1
  module Mobilify
2
- VERSION = "1.1.1"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -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{switch seamlessly between page-object methods when testing your web app in different contexts}
12
- spec.summary = %q{switch seamlessly between page-object methods when testing your web app in different contexts}
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 "cucumber"
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,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mobilify do
4
+
5
+ describe "includes PageObject when included" do
6
+ Given { class Page; end }
7
+ When { Page.send :include, Mobilify }
8
+ Then { Page.included_modules[1].should == PageObject }
9
+ end
10
+
11
+ 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
+
@@ -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.1.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-01-30 00:00:00.000000000 Z
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: cucumber
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
- description: switch seamlessly between page-object methods when testing your web app
111
- in different contexts
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: switch seamlessly between page-object methods when testing your web app in
158
- different contexts
170
+ summary: page-object methods invoked with one call but defined contextually
159
171
  test_files:
160
- - features/desktop_link.feature
161
- - features/mobile_link.feature
162
- - features/step_definitions/link_steps.rb
163
- - features/step_definitions/navigation_step.rb
164
- - features/support/env.rb
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
@@ -1,6 +0,0 @@
1
- require 'rspec'
2
- require 'rspec-given'
3
- require 'watir-webdriver'
4
- require 'webdriver-user-agent'
5
-
6
- $:.unshift(File.dirname(File.expand_path('lib')))
@@ -1,3 +0,0 @@
1
- After do
2
- @browser.close
3
- end
@@ -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