page_magic 1.2.9 → 2.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +3 -3
  3. data/.simplecov +4 -2
  4. data/.zsh_config +6 -0
  5. data/Dockerfile +10 -0
  6. data/Gemfile +10 -11
  7. data/Gemfile.lock +120 -133
  8. data/Makefile +13 -0
  9. data/Rakefile +3 -1
  10. data/VERSION +1 -1
  11. data/lib/page_magic.rb +5 -3
  12. data/lib/page_magic/class_methods.rb +4 -1
  13. data/lib/page_magic/driver.rb +3 -0
  14. data/lib/page_magic/drivers.rb +3 -1
  15. data/lib/page_magic/drivers/poltergeist.rb +2 -0
  16. data/lib/page_magic/drivers/rack_test.rb +3 -1
  17. data/lib/page_magic/drivers/selenium.rb +4 -2
  18. data/lib/page_magic/element.rb +8 -5
  19. data/lib/page_magic/element/locators.rb +4 -1
  20. data/lib/page_magic/element/query.rb +11 -2
  21. data/lib/page_magic/element/query_builder.rb +15 -2
  22. data/lib/page_magic/element/selector.rb +3 -0
  23. data/lib/page_magic/element/selector_methods.rb +3 -0
  24. data/lib/page_magic/element_context.rb +2 -0
  25. data/lib/page_magic/element_definition_builder.rb +4 -1
  26. data/lib/page_magic/elements.rb +42 -6
  27. data/lib/page_magic/exceptions.rb +3 -1
  28. data/lib/page_magic/instance_methods.rb +2 -0
  29. data/lib/page_magic/matcher.rb +10 -1
  30. data/lib/page_magic/session.rb +7 -5
  31. data/lib/page_magic/session_methods.rb +2 -0
  32. data/lib/page_magic/utils/string.rb +2 -0
  33. data/lib/page_magic/wait_methods.rb +3 -0
  34. data/lib/page_magic/watcher.rb +2 -0
  35. data/lib/page_magic/watchers.rb +4 -1
  36. data/spec/element_spec.rb +2 -0
  37. data/spec/page_magic/class_methods_spec.rb +2 -0
  38. data/spec/page_magic/driver_spec.rb +2 -0
  39. data/spec/page_magic/drivers/poltergeist_spec.rb +2 -0
  40. data/spec/page_magic/drivers/rack_test_spec.rb +2 -0
  41. data/spec/page_magic/drivers/selenium_spec.rb +2 -0
  42. data/spec/page_magic/drivers_spec.rb +2 -0
  43. data/spec/page_magic/element/locators_spec.rb +2 -0
  44. data/spec/page_magic/element/query_builder_spec.rb +7 -5
  45. data/spec/page_magic/element/query_spec.rb +6 -4
  46. data/spec/page_magic/element/selector_spec.rb +7 -5
  47. data/spec/page_magic/element_context_spec.rb +3 -1
  48. data/spec/page_magic/element_definition_builder_spec.rb +2 -0
  49. data/spec/page_magic/elements_spec.rb +9 -0
  50. data/spec/page_magic/instance_methods_spec.rb +2 -0
  51. data/spec/page_magic/matcher_spec.rb +3 -1
  52. data/spec/page_magic/session_methods_spec.rb +2 -0
  53. data/spec/page_magic/session_spec.rb +1 -1
  54. data/spec/page_magic/utils/string_spec.rb +2 -0
  55. data/spec/page_magic/wait_methods_spec.rb +5 -3
  56. data/spec/page_magic/watchers_spec.rb +2 -0
  57. data/spec/page_magic_spec.rb +5 -7
  58. data/spec/spec_helper.rb +3 -0
  59. data/spec/support/shared_contexts.rb +3 -1
  60. data/spec/support/shared_contexts/files_context.rb +2 -0
  61. data/spec/support/shared_contexts/nested_elements_html_context.rb +2 -0
  62. data/spec/support/shared_contexts/rack_application_context.rb +2 -0
  63. data/spec/support/shared_contexts/webapp_fixture_context.rb +2 -0
  64. data/spec/support/shared_examples.rb +2 -0
  65. data/spec/watcher_spec.rb +3 -0
  66. metadata +45 -29
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'forwardable'
2
4
  module PageMagic
3
5
  # module SessionMethods - contains methods for interacting with the {Session}
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  module Utils
3
5
  # module String - contains methods for manipulating strings
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  # module WaitMethods - contains methods for waiting
3
5
  module WaitMethods
@@ -10,6 +12,7 @@ module PageMagic
10
12
  start_time = Time.now
11
13
  until Time.now > start_time + timeout_after
12
14
  return true if yield == true
15
+
13
16
  sleep retry_every
14
17
  end
15
18
  raise TimeoutException, 'Action took to long'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  # class WatchedElementDefinition - Contains the specification the for checking if an subject has changed
3
5
  class Watcher
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'page_magic/watcher'
2
4
 
3
5
  module PageMagic
4
6
  # module Watchers - contains methods for adding watchers and checking them
5
7
  module Watchers
6
- ELEMENT_MISSING_MSG = 'Unable to defined watcher: Element or method with the name %s can not be found'.freeze
8
+ ELEMENT_MISSING_MSG = 'Unable to defined watcher: Element or method with the name %s can not be found'
7
9
 
8
10
  # @param [Symbol] name - the name of the watcher
9
11
  # @return [Boolean] true if a change is detected
@@ -24,6 +26,7 @@ module PageMagic
24
26
  # end
25
27
  def watch(name, method = nil, &block)
26
28
  raise ElementMissingException, (ELEMENT_MISSING_MSG % name) unless block || respond_to?(name)
29
+
27
30
  watched_element = block ? Watcher.new(name, &block) : Watcher.new(name, method)
28
31
  watchers.delete_if { |w| w.name == name }
29
32
  watchers << watched_element.check(self)
data/spec/element_spec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # rubocop:disable Metrics/ModuleLength
2
4
  module PageMagic
3
5
  describe Element do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  describe ClassMethods do
3
5
  subject do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'page_magic/driver'
2
4
 
3
5
  module PageMagic
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'page_magic/drivers/poltergeist'
2
4
  module PageMagic
3
5
  describe Drivers::Poltergeist do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'page_magic/drivers/rack_test'
2
4
  module PageMagic
3
5
  class Drivers
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'page_magic/drivers/selenium'
2
4
  module PageMagic
3
5
  describe Drivers::Selenium do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'page_magic/drivers'
2
4
  module PageMagic
3
5
  describe Drivers do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  class Element
3
5
  describe Locators do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  class Element
3
5
  describe QueryBuilder do
@@ -75,7 +77,7 @@ module PageMagic
75
77
  end
76
78
 
77
79
  it 'the same as all form field types' do
78
- expect(described_class).to eq(CHECKBOX).and eq(SELECT_LIST).and eq(RADIO).and eq(TEXTAREA)
80
+ expect(described_class).to eq(CHECKBOX).and eq(SELECT_LIST).and eq(RADIO).and eq(TEXTAREA).and eq(FILE_FIELD).and eq(FILLABLE_FIELD).and eq(RADIO_BUTTON)
79
81
  end
80
82
  end
81
83
  end
@@ -85,22 +87,22 @@ module PageMagic
85
87
  let(:capybara_session) { Capybara::Session.new(:rack_test, rack_app).tap { |s| s.visit('/elements') } }
86
88
 
87
89
  it 'finds fields' do
88
- query = QueryBuilder.find(:text_field).build(name: 'field_name')
90
+ query = QueryBuilder.find(:text_field).build({ name: 'field_name' })
89
91
  expect(query.execute(capybara_session).tag_name).to eq('input')
90
92
  end
91
93
 
92
94
  it 'finds buttons' do
93
- query = QueryBuilder.find(:button).build(text: 'a button')
95
+ query = QueryBuilder.find(:button).build({ text: 'a button' })
94
96
  expect(query.execute(capybara_session).tag_name).to eq('button')
95
97
  end
96
98
 
97
99
  it 'finds links' do
98
- query = QueryBuilder.find(:link).build(text: 'a link')
100
+ query = QueryBuilder.find(:link).build({ text: 'a link' })
99
101
  expect(query.execute(capybara_session).tag_name).to eq('a')
100
102
  end
101
103
 
102
104
  it 'finds elements' do
103
- query = QueryBuilder.find(:element).build(name: 'field_name')
105
+ query = QueryBuilder.find(:element).build({ name: 'field_name' })
104
106
  expect(query.execute(capybara_session).tag_name).to eq('input')
105
107
  end
106
108
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  class Element
3
5
  describe Query do
@@ -14,18 +16,18 @@ module PageMagic
14
16
  describe '#execute' do
15
17
  context 'no results found' do
16
18
  subject do
17
- QueryBuilder.find(:link).build(css: 'wrong')
19
+ QueryBuilder.find(:link).build({ css: 'wrong' })
18
20
  end
19
21
 
20
22
  it 'raises an error' do
21
- expected_message = 'Unable to find visible css "wrong"'
23
+ expected_message = 'Unable to find css "wrong"'
22
24
  expect { subject.execute(page.browser) }.to raise_exception(ElementMissingException, expected_message)
23
25
  end
24
26
  end
25
27
 
26
28
  context 'to many results returned' do
27
29
  subject do
28
- QueryBuilder.find(:link).build(css: 'a')
30
+ QueryBuilder.find(:link).build({ css: 'a' })
29
31
  end
30
32
 
31
33
  it 'raises an error' do
@@ -47,7 +49,7 @@ module PageMagic
47
49
  end
48
50
 
49
51
  it 'returns the result of the capybara query' do
50
- query = QueryBuilder.find(:link).build(id: 'form_link')
52
+ query = QueryBuilder.find(:link).build({ id: 'form_link' })
51
53
  result = query.execute(page.browser)
52
54
  expect(result.text).to eq('link in a form')
53
55
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  class Element
3
5
  describe Selector do
@@ -128,27 +130,27 @@ module PageMagic
128
130
  let(:capybara_session) { Capybara::Session.new(:rack_test, rack_app).tap { |s| s.visit('/elements') } }
129
131
 
130
132
  it 'finds elements by name' do
131
- query = QueryBuilder.find(:text_field).build(name: 'field_name')
133
+ query = QueryBuilder.find(:text_field).build({ name: 'field_name' })
132
134
  expect(query.execute(capybara_session)[:name]).to eq('field_name')
133
135
  end
134
136
 
135
137
  it 'finds elements by xpath' do
136
- query = QueryBuilder.find(:element).build(xpath: '//div/label/input')
138
+ query = QueryBuilder.find(:element).build({ xpath: '//div/label/input' })
137
139
  expect(query.execute(capybara_session)[:name]).to eq('field_name')
138
140
  end
139
141
 
140
142
  it 'finds elements by id' do
141
- query = QueryBuilder.find(:text_field).build(id: 'field_id')
143
+ query = QueryBuilder.find(:text_field).build({ id: 'field_id' })
142
144
  expect(query.execute(capybara_session)[:name]).to eq('field_name')
143
145
  end
144
146
 
145
147
  it 'finds elements by label' do
146
- query = QueryBuilder.find(:text_field).build(label: 'enter text')
148
+ query = QueryBuilder.find(:text_field).build({ label: 'enter text' })
147
149
  expect(query.execute(capybara_session)[:name]).to eq('field_name')
148
150
  end
149
151
 
150
152
  it 'finds elements by text' do
151
- query = QueryBuilder.find(:link).build(text: 'a link')
153
+ query = QueryBuilder.find(:link).build({ text: 'a link' })
152
154
  expect(query.execute(capybara_session).text).to eq('a link')
153
155
  end
154
156
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  describe ElementContext do
3
5
  include_context :webapp_fixture
@@ -53,7 +55,7 @@ module PageMagic
53
55
  it 'returns an array of element definitions' do
54
56
  elements_page.links :links, css: 'a'
55
57
  links = described_class.new(page).links
56
- expect(links.find_all { |e| e.class == Element }.size).to eq(2)
58
+ expect(links.find_all { |e| e.kind_of?(Element) }.size).to eq(2)
57
59
  expect(links.collect(&:text)).to eq(['a link', 'link in a form'])
58
60
  end
59
61
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  describe ElementDefinitionBuilder do
3
5
  describe '#initialize' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # rubocop:disable Metrics/ModuleLength
2
4
  module PageMagic
3
5
  describe Elements do
@@ -17,6 +19,13 @@ module PageMagic
17
19
 
18
20
  let(:child_selector) { { id: 'child' } }
19
21
 
22
+ context 'element types' do
23
+ it 'provides all of the type provided by capybara' do
24
+ capybara_elements = Capybara::Selector.all.except(*%i[element datalist_input datalist_option id xpath css]).keys
25
+ expect(described_class::TYPES).to include(*capybara_elements)
26
+ end
27
+ end
28
+
20
29
  describe '#element' do
21
30
  it 'sets the selector and type' do
22
31
  expected_definition = ElementDefinitionBuilder.new(definition_class: Element,
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  describe InstanceMethods do
3
5
  include_context :webapp_fixture
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # rubocop:disable Metrics/ModuleLength
2
4
  module PageMagic
3
5
  describe Matcher do
@@ -161,7 +163,7 @@ module PageMagic
161
163
 
162
164
  context 'parameter requirement is a regexp' do
163
165
  subject do
164
- described_class.new(parameters: { foo: /b[a]r/ })
166
+ described_class.new(parameters: { foo: /bar/ })
165
167
  end
166
168
 
167
169
  it 'returns true for a match on the regexp' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  describe SessionMethods do
3
5
  include_context :webapp_fixture
@@ -162,7 +162,7 @@ module PageMagic
162
162
  end
163
163
 
164
164
  describe '#url' do
165
- let!(:base_url) { 'http://example.com' }
165
+ let!(:base_url) { "http://example.com" }
166
166
  let!(:path) { 'home' }
167
167
  let!(:expected_url) { "#{base_url}/#{path}" }
168
168
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'page_magic/utils/string'
2
4
  module PageMagic
3
5
  module Utils
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  describe WaitMethods do
3
5
  subject do
@@ -9,20 +11,20 @@ module PageMagic
9
11
  let(:default_options) { { timeout_after: 0.1, retry_every: 0.05 } }
10
12
 
11
13
  it 'waits until the prescribed thing has happened' do
12
- expect { subject.wait_until(default_options) { true } }.to_not raise_exception
14
+ expect { subject.wait_until(**default_options) { true } }.to_not raise_exception
13
15
  end
14
16
 
15
17
  it 'should keep trying for a specified period' do
16
18
  start_time = Time.now
17
19
 
18
- expect { subject.wait_until(default_options) { false } }.to raise_exception TimeoutException
20
+ expect { subject.wait_until(**default_options) { false } }.to raise_exception TimeoutException
19
21
 
20
22
  expect(Time.now - default_options[:timeout_after]).to be > start_time
21
23
  end
22
24
 
23
25
  context 'timeout_after specified' do
24
26
  it 'throws an exception if when the prescribed action does not happen in time' do
25
- expect { subject.wait_until(default_options) { false } }.to raise_error TimeoutException
27
+ expect { subject.wait_until(**default_options) { false } }.to raise_error TimeoutException
26
28
  end
27
29
  end
28
30
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PageMagic
2
4
  describe Watchers do
3
5
  let(:element) { OpenStruct.new(text: :current_value) }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'page_magic'
2
4
 
3
5
  describe PageMagic do
@@ -56,6 +58,8 @@ describe PageMagic do
56
58
  end
57
59
 
58
60
  describe '.session' do
61
+ include_context :rack_application
62
+
59
63
  let(:url) { 'http://url.com/' }
60
64
  let(:application) { rack_application.new }
61
65
 
@@ -75,12 +79,6 @@ describe PageMagic do
75
79
  end
76
80
  end
77
81
 
78
- include_context :rack_application
79
- it 'sets the base url for the session' do
80
- session = described_class.session(application: application, url: url)
81
- expect(session.current_url).to eq(url)
82
- end
83
-
84
82
  context 'specifying a rack application' do
85
83
  it 'configures capybara to run against the app' do
86
84
  session = described_class.session(application: application, url: url)
@@ -99,7 +97,7 @@ describe PageMagic do
99
97
 
100
98
  context 'driver for browser not found' do
101
99
  it 'raises an error' do
102
- expected_exception = described_class::UnspportedBrowserException
100
+ expected_exception = described_class::UnsupportedBrowserException
103
101
  expect { described_class.session(browser: :invalid, url: url) }.to raise_exception expected_exception
104
102
  end
105
103
  end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+ require 'bundler'
1
3
  Bundler.require
2
4
  $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib")
3
5
  require 'support/shared_contexts'
@@ -6,3 +8,4 @@ require 'support/shared_examples'
6
8
  require 'simplecov' if ENV['coverage']
7
9
 
8
10
  require 'page_magic'
11
+ Capybara.server = :webrick
@@ -1,3 +1,5 @@
1
- Dir["#{__dir__}/shared_contexts/*.rb"].each do |file|
1
+ # frozen_string_literal: true
2
+
3
+ Dir["#{__dir__}/shared_contexts/*.rb"].sort.each do |file|
2
4
  require file
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  shared_context :files do
2
4
  require 'tmpdir'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  shared_context :nested_elements_html do
2
4
  require 'sinatra/base'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  shared_context :rack_application do
2
4
  let(:rack_application) do
3
5
  Class.new do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  shared_context :webapp_fixture do
2
4
  require 'sinatra/base'
3
5