page_magic 1.2.9 → 2.0.0.alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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