page_magic 1.2.8 → 2.0.2

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 (101) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +23 -4
  3. data/.simplecov +5 -3
  4. data/.zsh_config +6 -0
  5. data/Dockerfile +11 -0
  6. data/Gemfile +13 -13
  7. data/Gemfile.lock +136 -148
  8. data/Makefile +17 -0
  9. data/README.md +26 -5
  10. data/Rakefile +12 -2
  11. data/VERSION +1 -1
  12. data/circle.yml +3 -1
  13. data/lib/active_support/core_ext/object/to_query.rb +84 -0
  14. data/lib/page_magic.rb +31 -24
  15. data/lib/page_magic/class_methods.rb +5 -2
  16. data/lib/page_magic/comparator.rb +37 -0
  17. data/lib/page_magic/comparator/fuzzy.rb +23 -0
  18. data/lib/page_magic/comparator/literal.rb +22 -0
  19. data/lib/page_magic/comparator/null.rb +26 -0
  20. data/lib/page_magic/comparator/parameter_map.rb +52 -0
  21. data/lib/page_magic/driver.rb +3 -0
  22. data/lib/page_magic/drivers.rb +6 -5
  23. data/lib/page_magic/drivers/poltergeist.rb +2 -0
  24. data/lib/page_magic/drivers/rack_test.rb +3 -1
  25. data/lib/page_magic/drivers/selenium.rb +4 -2
  26. data/lib/page_magic/element.rb +35 -15
  27. data/lib/page_magic/element/locators.rb +8 -5
  28. data/lib/page_magic/element/not_found.rb +38 -0
  29. data/lib/page_magic/element/query.rb +21 -20
  30. data/lib/page_magic/element/query/multiple_results.rb +21 -0
  31. data/lib/page_magic/element/query/prefetched_result.rb +26 -0
  32. data/lib/page_magic/element/query/single_result.rb +20 -0
  33. data/lib/page_magic/element/selector.rb +41 -16
  34. data/lib/page_magic/element/selector/methods.rb +18 -0
  35. data/lib/page_magic/element/selector/model.rb +21 -0
  36. data/lib/page_magic/element_context.rb +7 -21
  37. data/lib/page_magic/element_definition_builder.rb +20 -24
  38. data/lib/page_magic/elements.rb +65 -69
  39. data/lib/page_magic/elements/config.rb +103 -0
  40. data/lib/page_magic/elements/inheritance_hooks.rb +15 -0
  41. data/lib/page_magic/elements/types.rb +25 -0
  42. data/lib/page_magic/exceptions.rb +6 -1
  43. data/lib/page_magic/instance_methods.rb +8 -3
  44. data/lib/page_magic/mapping.rb +79 -0
  45. data/lib/page_magic/session.rb +15 -35
  46. data/lib/page_magic/session_methods.rb +3 -1
  47. data/lib/page_magic/transitions.rb +49 -0
  48. data/lib/page_magic/utils/string.rb +18 -0
  49. data/lib/page_magic/utils/url.rb +20 -0
  50. data/lib/page_magic/wait_methods.rb +3 -0
  51. data/lib/page_magic/watcher.rb +12 -17
  52. data/lib/page_magic/watchers.rb +31 -15
  53. data/page_magic.gemspec +15 -11
  54. data/spec/lib/active_support/core_ext/object/to_query_test.rb +78 -0
  55. data/spec/page_magic/class_methods_spec.rb +66 -37
  56. data/spec/page_magic/comparator/fuzzy_spec.rb +44 -0
  57. data/spec/page_magic/comparator/literal_spec.rb +41 -0
  58. data/spec/page_magic/comparator/null_spec.rb +35 -0
  59. data/spec/page_magic/comparator/parameter_map_spec.rb +75 -0
  60. data/spec/page_magic/driver_spec.rb +26 -28
  61. data/spec/page_magic/drivers/poltergeist_spec.rb +6 -7
  62. data/spec/page_magic/drivers/rack_test_spec.rb +6 -9
  63. data/spec/page_magic/drivers/selenium_spec.rb +11 -12
  64. data/spec/page_magic/drivers_spec.rb +38 -29
  65. data/spec/page_magic/element/locators_spec.rb +28 -25
  66. data/spec/page_magic/element/not_found_spec.rb +24 -0
  67. data/spec/page_magic/element/query/multiple_results_spec.rb +14 -0
  68. data/spec/page_magic/element/query/single_result_spec.rb +21 -0
  69. data/spec/page_magic/element/query_spec.rb +26 -45
  70. data/spec/page_magic/element/selector_spec.rb +120 -110
  71. data/spec/page_magic/element_context_spec.rb +47 -87
  72. data/spec/page_magic/element_definition_builder_spec.rb +14 -71
  73. data/spec/page_magic/element_spec.rb +256 -0
  74. data/spec/page_magic/elements/config_spec.rb +203 -0
  75. data/spec/page_magic/elements_spec.rb +90 -134
  76. data/spec/page_magic/instance_methods_spec.rb +65 -63
  77. data/spec/page_magic/mapping_spec.rb +181 -0
  78. data/spec/page_magic/session_methods_spec.rb +29 -25
  79. data/spec/page_magic/session_spec.rb +109 -199
  80. data/spec/page_magic/transitions_spec.rb +43 -0
  81. data/spec/page_magic/utils/string_spec.rb +29 -0
  82. data/spec/page_magic/utils/url_spec.rb +9 -0
  83. data/spec/page_magic/wait_methods_spec.rb +16 -22
  84. data/spec/page_magic/watcher_spec.rb +22 -0
  85. data/spec/page_magic/watchers_spec.rb +58 -62
  86. data/spec/page_magic_spec.rb +37 -29
  87. data/spec/spec_helper.rb +9 -2
  88. data/spec/support/shared_contexts.rb +3 -1
  89. data/spec/support/shared_examples.rb +17 -17
  90. metadata +101 -48
  91. data/lib/page_magic/element/query_builder.rb +0 -48
  92. data/lib/page_magic/element/selector_methods.rb +0 -13
  93. data/lib/page_magic/matcher.rb +0 -121
  94. data/spec/element_spec.rb +0 -249
  95. data/spec/page_magic/element/query_builder_spec.rb +0 -108
  96. data/spec/page_magic/matcher_spec.rb +0 -336
  97. data/spec/support/shared_contexts/files_context.rb +0 -7
  98. data/spec/support/shared_contexts/nested_elements_html_context.rb +0 -16
  99. data/spec/support/shared_contexts/rack_application_context.rb +0 -9
  100. data/spec/support/shared_contexts/webapp_fixture_context.rb +0 -39
  101. data/spec/watcher_spec.rb +0 -61
@@ -0,0 +1,35 @@
1
+ RSpec.describe PageMagic::Comparator::Null do
2
+ describe '#fuzzy?' do
3
+ context 'when one value is fuzzy' do
4
+ it 'returns true' do
5
+ expect(described_class.new).not_to be_fuzzy
6
+ end
7
+ end
8
+ end
9
+
10
+ describe 'match?' do
11
+ it 'returns false' do
12
+ expect(described_class.new).to be_match(true)
13
+ end
14
+ end
15
+
16
+ describe '#<=>' do
17
+ context 'when other is `Null`' do
18
+ it 'is equal' do
19
+ expect(described_class.new <=> described_class.new).to be 0
20
+ end
21
+ end
22
+
23
+ context 'when other is `Fuzzy`' do
24
+ it 'is greater' do
25
+ expect(described_class.new <=> PageMagic::Comparator::Fuzzy.new(//)).to be 1
26
+ end
27
+ end
28
+
29
+ context 'when other is `Literal`' do
30
+ it 'is greater' do
31
+ expect(described_class.new <=> PageMagic::Comparator::Literal.new('/')).to be 1
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,75 @@
1
+ RSpec.describe PageMagic::Comparator::ParameterMap do
2
+ describe '#fuzzy?' do
3
+ context 'when one value is fuzzy' do
4
+ it 'returns true' do
5
+ map = described_class.new({ param1: //, param2: '' })
6
+ expect(map).to be_fuzzy
7
+ end
8
+ end
9
+
10
+ context 'when all values are literal' do
11
+ it 'returns true' do
12
+ map = described_class.new({ param1: '', param2: '' })
13
+ expect(map).not_to be_fuzzy
14
+ end
15
+ end
16
+ end
17
+
18
+ describe '#match?' do
19
+ context 'when param has compatible params' do
20
+ it 'returns true' do
21
+ expect(described_class.new({ param: '1' })).to be_match(param: '1')
22
+ end
23
+ end
24
+
25
+ context 'when it does not have compatible params' do
26
+ it 'returns false' do
27
+ expect(described_class.new({ param: '1' })).not_to be_match(param: '2')
28
+ end
29
+ end
30
+
31
+ context 'when it does not meet all of the requirements' do
32
+ it 'returns false' do
33
+ expect(described_class.new({ param: '1', another_param: '2' })).not_to be_match(param: '1')
34
+ end
35
+ end
36
+ end
37
+
38
+ describe '#<=>' do
39
+ context 'when other is empty' do
40
+ context 'and self is empty' do
41
+ it 'is equal' do
42
+ expect(described_class.new({}) <=> described_class.new({})).to be 0
43
+ end
44
+ end
45
+
46
+ context 'self is not empty' do
47
+ it 'is greater' do
48
+ expect(described_class.new({ param: 1 }) <=> described_class.new({})).to be 1
49
+ end
50
+ end
51
+ end
52
+
53
+ context 'when other contains matchers' do
54
+ context 'when other has the same number' do
55
+ context 'and matchers are of the same type' do
56
+ it 'is equal' do
57
+ expect(described_class.new({ param: // }) <=> described_class.new({ param: // })).to be 0
58
+ end
59
+ end
60
+
61
+ context 'and has less literal matchers' do
62
+ it 'is lesser' do
63
+ expect(described_class.new({ param: '' }) <=> described_class.new({ param: // })).to be 1
64
+ end
65
+ end
66
+ end
67
+
68
+ context 'when other has the less' do
69
+ it 'is lesser' do
70
+ expect(described_class.new({ param: // }) <=> described_class.new({})).to be 1
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,41 +1,39 @@
1
- require 'page_magic/driver'
1
+ # frozen_string_literal: true
2
2
 
3
- module PageMagic
4
- describe Driver do
5
- subject do
6
- described_class.new :custom_browser
3
+ RSpec.describe PageMagic::Driver do
4
+ describe '#build' do
5
+ it 'returns the result of the block passed to the driver class constructor' do
6
+ subject = described_class.new(:custom_browser) do
7
+ :driver
8
+ end
9
+ expect(subject.build(:rack_app, browser: :custom_browser, options: {})).to eq(:driver)
7
10
  end
8
11
 
9
- describe '#build' do
10
- it 'returns the result of the block passed to the driver class constructor' do
11
- subject = described_class.new(:custom_browser) do
12
- :driver
13
- end
14
- expect(subject.build(:rack_app, browser: :custom_browser, options: :options)).to eq(:driver)
12
+ it 'passes rack app to the handler' do
13
+ subject = described_class.new(:custom_browser) do |app, options, browser|
14
+ expect(app).to eq(:rack_app)
15
+ expect(options).to eq(:options)
16
+ expect(browser).to eq(:browser)
15
17
  end
16
18
 
17
- it 'passes rack app to the handler' do
18
- subject = described_class.new(:custom_browser) do |app, options, browser|
19
- expect(app).to eq(:rack_app)
20
- expect(options).to eq(:options)
21
- expect(browser).to eq(:browser)
22
- end
19
+ subject.build(:rack_app, options: :options, browser: :browser)
20
+ end
21
+ end
23
22
 
24
- subject.build(:rack_app, options: :options, browser: :browser)
25
- end
23
+ describe '#supports?' do
24
+ subject do
25
+ described_class.new :custom_browser
26
26
  end
27
27
 
28
- describe '#supports?' do
29
- context 'browser is in supported browsers' do
30
- it 'returns true' do
31
- expect(subject.support?(:custom_browser)).to eq(true)
32
- end
28
+ context 'browser is in supported browsers' do
29
+ it 'returns true' do
30
+ expect(subject.support?(:custom_browser)).to eq(true)
33
31
  end
32
+ end
34
33
 
35
- context 'browser is not in supported browsers' do
36
- it 'returns false' do
37
- expect(subject.support?(:unsupported_browser)).to eq(false)
38
- end
34
+ context 'browser is not in supported browsers' do
35
+ it 'returns false' do
36
+ expect(subject.support?(:unsupported_browser)).to eq(false)
39
37
  end
40
38
  end
41
39
  end
@@ -1,9 +1,8 @@
1
- require 'page_magic/drivers/poltergeist'
2
- module PageMagic
3
- describe Drivers::Poltergeist do
4
- it "is capybara's poltergeist driver" do
5
- driver = described_class.build(:app, browser: :poltergeist, options: {})
6
- expect(driver).to be_a(Capybara::Poltergeist::Driver)
7
- end
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe PageMagic::Drivers::Poltergeist do
4
+ it "is capybara's poltergeist driver" do
5
+ driver = described_class.build(:app, browser: :poltergeist, options: {})
6
+ expect(driver).to be_a(Capybara::Poltergeist::Driver)
8
7
  end
9
8
  end
@@ -1,11 +1,8 @@
1
- require 'page_magic/drivers/rack_test'
2
- module PageMagic
3
- class Drivers
4
- describe RackTest do
5
- it "is capybara's rack test driver" do
6
- driver = described_class.build(:app, browser: :rack_test, options: {})
7
- expect(driver).to be_a(Capybara::RackTest::Driver)
8
- end
9
- end
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe PageMagic::Drivers::RackTest do
4
+ it "is capybara's rack test driver" do
5
+ driver = described_class.build(:app, browser: :rack_test, options: {})
6
+ expect(driver).to be_a(Capybara::RackTest::Driver)
10
7
  end
11
8
  end
@@ -1,16 +1,15 @@
1
- require 'page_magic/drivers/selenium'
2
- module PageMagic
3
- describe Drivers::Selenium do
4
- subject do
5
- described_class.build(:app, browser: :selenium, options: {})
6
- end
1
+ # frozen_string_literal: true
7
2
 
8
- it 'is selenium' do
9
- expect(subject).to be_a(Capybara::Selenium::Driver)
10
- end
3
+ RSpec.describe PageMagic::Drivers::Selenium do
4
+ subject do
5
+ described_class.build(:app, browser: :selenium, options: {})
6
+ end
7
+
8
+ it 'is selenium' do
9
+ expect(subject).to be_a(Capybara::Selenium::Driver)
10
+ end
11
11
 
12
- it 'sets the browser option' do
13
- expect(subject.options[:browser]).to be(:selenium)
14
- end
12
+ it 'sets the browser option' do
13
+ expect(subject.options[:browser]).to be(:selenium)
15
14
  end
16
15
  end
@@ -1,39 +1,48 @@
1
- require 'page_magic/drivers'
2
- module PageMagic
3
- describe Drivers do
4
- subject { described_class.new }
5
- let(:expected_driver) { Driver.new(:browser_driver) }
6
-
7
- describe '#find' do
8
- it 'returns the registered driver' do
9
- subject.register expected_driver
10
- expect(subject.find(:browser_driver)).to eq(expected_driver)
11
- end
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe PageMagic::Drivers do
4
+ describe '#find' do
5
+ it 'returns the registered driver' do
6
+ drivers = described_class.new
7
+ expected_driver = PageMagic::Driver.new(:browser_driver)
8
+
9
+ drivers.register expected_driver
10
+ expect(drivers.find(:browser_driver)).to eq(expected_driver)
11
+ end
12
+ end
13
+
14
+ describe '#load' do
15
+ require 'tmpdir'
16
+
17
+ def scratch_dir
18
+ @scratch_dir ||= Dir.mktmpdir
12
19
  end
13
20
 
14
- describe '#load' do
15
- include_context :files
16
- it 'loads the drivers in the specified path' do
17
- class_definition = <<-RUBY
18
- class CustomDriver;
19
- def self.support? browser
20
- true
21
- end
21
+ let(:class_definition) do
22
+ <<-RUBY
23
+ class CustomDriver;
24
+ def self.support?(_browser)
25
+ true
22
26
  end
23
- RUBY
27
+ end
28
+ RUBY
29
+ end
24
30
 
25
- File.write("#{scratch_dir}/custom_driver.rb", class_definition)
31
+ it 'loads the drivers in the specified path' do
32
+ File.write("#{scratch_dir}/custom_driver.rb", class_definition)
26
33
 
27
- subject.load(scratch_dir)
28
- expect(subject.find(:custom_browser)).to be(::CustomDriver)
29
- end
34
+ drivers = described_class.new
35
+ drivers.load(scratch_dir)
36
+ expect(drivers.find(:custom_browser)).to be(::CustomDriver)
30
37
  end
38
+ end
31
39
 
32
- describe '#register' do
33
- it 'stores the driver' do
34
- subject.register expected_driver
35
- expect(subject.all).to eq([expected_driver])
36
- end
40
+ describe '#register' do
41
+ it 'stores the driver' do
42
+ drivers = described_class.new
43
+ expected_driver = PageMagic::Driver.new(:browser_driver)
44
+ drivers.register expected_driver
45
+ expect(drivers.all).to eq([expected_driver])
37
46
  end
38
47
  end
39
48
  end
@@ -1,32 +1,35 @@
1
- module PageMagic
2
- class Element
3
- describe Locators do
4
- subject(:element_clazz) do
5
- Class.new do
6
- extend(Elements)
7
- include(Locators)
8
- end
9
- end
10
- subject { element_clazz.new }
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe PageMagic::Element::Locators do
4
+ subject { element_clazz.new }
5
+
6
+ let(:element_clazz) do
7
+ Class.new do
8
+ extend(PageMagic::Elements)
9
+ include(PageMagic::Element::Locators)
10
+ end
11
+ end
11
12
 
12
- describe '#element_by_name' do
13
- it 'returns the required element' do
14
- selector = { id: 'child' }
15
- element_clazz.element :child1, selector
16
- element_clazz.element :child2, id: 'child 2'
13
+ describe '#element_by_name' do
14
+ it 'returns the required element' do
15
+ selector = { id: 'child' }
16
+ element_clazz.element :child1, selector
17
+ element_clazz.element :child2, id: 'child 2'
17
18
 
18
- expected_builder = ElementDefinitionBuilder.new(definition_class: Element, type: :element, selector: selector)
19
+ child_1_builder = PageMagic::ElementDefinitionBuilder.new(
20
+ definition_class: PageMagic::Element,
21
+ selector: PageMagic::Element::Selector.find(:id).build(:element, 'child')
22
+ )
19
23
 
20
- expect(subject.element_by_name(:child1)).to eq(expected_builder)
21
- end
24
+ expect(subject.element_by_name(:child1)).to eq(child_1_builder)
25
+ end
22
26
 
23
- context 'element not found' do
24
- it 'raises an error' do
25
- expected_message = (described_class::ELEMENT_NOT_DEFINED_MSG % :child)
26
- command = proc { subject.element_by_name(:child) }
27
- expect(&command).to raise_exception ElementMissingException, expected_message
28
- end
29
- end
27
+ context 'element not found' do
28
+ it 'raises an error' do
29
+ expected_message = (described_class::ELEMENT_NOT_DEFINED_MSG % :child)
30
+ expect do
31
+ subject.element_by_name(:child)
32
+ end.to raise_exception PageMagic::ElementMissingException, expected_message
30
33
  end
31
34
  end
32
35
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe PageMagic::Element::NotFound do
4
+ describe '#method_missing' do
5
+ it 'raises an error' do
6
+ subject = described_class.new(Exception.new('message'))
7
+ expect { subject.any_missing_method }.to raise_exception(PageMagic::ElementMissingException, 'message')
8
+ end
9
+ end
10
+
11
+ describe '#visible?' do
12
+ it 'returns false' do
13
+ subject = described_class.new(Exception.new('message'))
14
+ expect(subject.visible?).to eq(false)
15
+ end
16
+ end
17
+
18
+ describe '#present?' do
19
+ it 'returns false' do
20
+ subject = described_class.new(Exception.new('message'))
21
+ expect(subject.present?).to eq(false)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe PageMagic::Element::Query::MultipleResults do
4
+ describe '#find' do
5
+ context 'when multiple results found' do
6
+ it 'returns an array' do
7
+ element = PageMagic::Element.load('<a></a><a></a>')
8
+ subject = described_class.new('a')
9
+ result = subject.execute(element)
10
+ expect(result.size).to eq(2)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe PageMagic::Element::Query::SingleResult do
4
+ describe '#find' do
5
+ context 'when more than one result is returned' do
6
+ it 'raises an error' do
7
+ element = PageMagic::Element.load('<a></a><a></a>')
8
+ query = described_class.new('a')
9
+ expected_message = 'Ambiguous match, found 2 elements matching visible css "a"'
10
+ expect { query.execute(element) }.to raise_error PageMagic::AmbiguousQueryException, expected_message
11
+ end
12
+ end
13
+
14
+ it 'returns the result of the capybara query' do
15
+ element = PageMagic::Element.load('<a>link</a>')
16
+ query = described_class.new('a')
17
+ result = query.execute(element)
18
+ expect(result.text).to eq('link')
19
+ end
20
+ end
21
+ end