wayfarer 0.4.0 → 0.4.1

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 (107) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yaml +1 -1
  3. data/Gemfile.lock +20 -15
  4. data/docs/cookbook/user_agent.md +1 -1
  5. data/docs/guides/browser_automation/capybara.md +64 -1
  6. data/docs/guides/browser_automation/custom_adapters.md +100 -0
  7. data/docs/guides/browser_automation/ferrum.md +3 -3
  8. data/docs/guides/browser_automation/selenium.md +7 -5
  9. data/docs/guides/callbacks.md +117 -10
  10. data/docs/guides/configuration.md +16 -10
  11. data/docs/guides/error_handling.md +9 -5
  12. data/docs/guides/networking.md +77 -3
  13. data/docs/index.md +9 -1
  14. data/docs/reference/api/base.md +4 -4
  15. data/docs/reference/configuration_keys.md +42 -0
  16. data/docs/reference/environment_variables.md +25 -27
  17. data/lib/wayfarer/base.rb +7 -17
  18. data/lib/wayfarer/callbacks.rb +71 -0
  19. data/lib/wayfarer/cli/base.rb +5 -1
  20. data/lib/wayfarer/cli/job.rb +7 -3
  21. data/lib/wayfarer/cli/route.rb +2 -2
  22. data/lib/wayfarer/cli/route_printer.rb +7 -7
  23. data/lib/wayfarer/config/capybara.rb +10 -0
  24. data/lib/wayfarer/config/ferrum.rb +11 -0
  25. data/lib/wayfarer/config/networking.rb +26 -0
  26. data/lib/wayfarer/config/redis.rb +14 -0
  27. data/lib/wayfarer/config/root.rb +11 -0
  28. data/lib/wayfarer/config/selenium.rb +21 -0
  29. data/lib/wayfarer/config/strconv.rb +45 -0
  30. data/lib/wayfarer/config/struct.rb +72 -0
  31. data/lib/wayfarer/gc.rb +3 -7
  32. data/lib/wayfarer/middleware/fetch.rb +7 -3
  33. data/lib/wayfarer/middleware/router.rb +2 -2
  34. data/lib/wayfarer/middleware/worker.rb +12 -9
  35. data/lib/wayfarer/networking/capybara.rb +28 -0
  36. data/lib/wayfarer/networking/context.rb +36 -0
  37. data/lib/wayfarer/networking/ferrum.rb +17 -52
  38. data/lib/wayfarer/networking/http.rb +34 -0
  39. data/lib/wayfarer/networking/pool.rb +15 -10
  40. data/lib/wayfarer/networking/result.rb +1 -1
  41. data/lib/wayfarer/networking/selenium.rb +20 -47
  42. data/lib/wayfarer/networking/strategy.rb +38 -0
  43. data/lib/wayfarer/page.rb +2 -3
  44. data/lib/wayfarer/redis/pool.rb +3 -1
  45. data/lib/wayfarer/routing/dsl.rb +8 -8
  46. data/lib/wayfarer/routing/matchers/custom.rb +23 -0
  47. data/lib/wayfarer/routing/matchers/host.rb +19 -0
  48. data/lib/wayfarer/routing/matchers/path.rb +48 -0
  49. data/lib/wayfarer/routing/matchers/query.rb +63 -0
  50. data/lib/wayfarer/routing/matchers/scheme.rb +17 -0
  51. data/lib/wayfarer/routing/matchers/suffix.rb +17 -0
  52. data/lib/wayfarer/routing/matchers/url.rb +17 -0
  53. data/lib/wayfarer/routing/route.rb +1 -1
  54. data/lib/wayfarer.rb +9 -9
  55. data/spec/base_spec.rb +14 -0
  56. data/spec/callbacks_spec.rb +102 -0
  57. data/spec/cli/job_spec.rb +6 -6
  58. data/spec/config/capybara_spec.rb +18 -0
  59. data/spec/config/ferrum_spec.rb +24 -0
  60. data/spec/config/networking_spec.rb +73 -0
  61. data/spec/config/redis_spec.rb +32 -0
  62. data/spec/config/root_spec.rb +31 -0
  63. data/spec/config/selenium_spec.rb +56 -0
  64. data/spec/config/strconv_spec.rb +58 -0
  65. data/spec/config/struct_spec.rb +66 -0
  66. data/spec/gc_spec.rb +8 -6
  67. data/spec/middleware/fetch_spec.rb +20 -8
  68. data/spec/middleware/router_spec.rb +7 -0
  69. data/spec/middleware/worker_spec.rb +64 -27
  70. data/spec/networking/capybara_spec.rb +12 -0
  71. data/spec/networking/context_spec.rb +127 -0
  72. data/spec/networking/ferrum_spec.rb +6 -22
  73. data/spec/networking/http_spec.rb +12 -0
  74. data/spec/networking/pool_spec.rb +37 -12
  75. data/spec/networking/selenium_spec.rb +6 -22
  76. data/spec/networking/strategy.rb +170 -0
  77. data/spec/redis/pool_spec.rb +1 -1
  78. data/spec/routing/dsl_spec.rb +10 -10
  79. data/spec/routing/integration_spec.rb +22 -22
  80. data/spec/routing/{custom_matcher_spec.rb → matchers/custom_spec.rb} +4 -4
  81. data/spec/routing/{host_matcher_spec.rb → matchers/host_spec.rb} +6 -6
  82. data/spec/routing/{path_matcher_spec.rb → matchers/path_spec.rb} +6 -6
  83. data/spec/routing/{query_matcher_spec.rb → matchers/query_spec.rb} +15 -15
  84. data/spec/routing/{scheme_matcher_spec.rb → matchers/scheme_spec.rb} +4 -4
  85. data/spec/routing/{suffix_matcher_spec.rb → matchers/suffix_spec.rb} +4 -4
  86. data/spec/routing/{uri_matcher_spec.rb → matchers/uri_spec.rb} +4 -4
  87. data/spec/routing/path_finder_spec.rb +1 -1
  88. data/spec/routing/root_route_spec.rb +2 -2
  89. data/spec/routing/route_spec.rb +2 -2
  90. data/spec/spec_helpers.rb +13 -5
  91. data/spec/wayfarer_spec.rb +1 -1
  92. data/wayfarer.gemspec +8 -7
  93. metadata +74 -33
  94. data/lib/wayfarer/config.rb +0 -67
  95. data/lib/wayfarer/networking/healer.rb +0 -21
  96. data/lib/wayfarer/networking/net_http.rb +0 -52
  97. data/lib/wayfarer/routing/custom_matcher.rb +0 -21
  98. data/lib/wayfarer/routing/host_matcher.rb +0 -23
  99. data/lib/wayfarer/routing/path_matcher.rb +0 -46
  100. data/lib/wayfarer/routing/query_matcher.rb +0 -67
  101. data/lib/wayfarer/routing/scheme_matcher.rb +0 -21
  102. data/lib/wayfarer/routing/suffix_matcher.rb +0 -21
  103. data/lib/wayfarer/routing/url_matcher.rb +0 -21
  104. data/spec/config_spec.rb +0 -144
  105. data/spec/networking/adapter.rb +0 -135
  106. data/spec/networking/healer_spec.rb +0 -46
  107. data/spec/networking/net_http_spec.rb +0 -37
@@ -3,11 +3,16 @@
3
3
  require "spec_helpers"
4
4
 
5
5
  describe Wayfarer::Middleware::Fetch do
6
+ let(:klass) { Class.new(Wayfarer::Base) }
7
+ let(:job) { klass.new }
6
8
  let(:task) { build(:task) }
7
- let(:adapter) { spy }
9
+ let(:agent) { spy }
8
10
  subject(:fetch) { Wayfarer::Middleware::Fetch.new }
9
11
 
10
- before { allow(fetch.pool).to receive(:with).and_yield(adapter) }
12
+ before do
13
+ task.job = job
14
+ allow(fetch.pool).to receive(:with).and_yield(agent)
15
+ end
11
16
 
12
17
  describe "#call" do
13
18
  it "assigns the task" do
@@ -16,27 +21,34 @@ describe Wayfarer::Middleware::Fetch do
16
21
  }.to change { fetch.task }.to(task)
17
22
  end
18
23
 
19
- it "assigns the adapter" do
24
+ it "assigns the agent" do
20
25
  expect {
21
26
  fetch.call(task)
22
- }.to change { task.metadata.adapter }.to(adapter)
27
+ }.to change { task.metadata.agent }.to(agent)
23
28
  end
24
29
 
25
30
  it "retrieves the page" do
26
- expect(adapter).to receive(:fetch).with(task.url)
31
+ expect(agent).to receive(:fetch).with(task.url)
27
32
  fetch.call(task)
28
33
  end
29
34
 
35
+ it "runs callbacks" do
36
+ expect { |spy|
37
+ klass.before_fetch(&spy)
38
+ fetch.call(task)
39
+ }.to yield_control
40
+ end
41
+
30
42
  context "when encountering an HTTP redirect" do
31
43
  let(:redirect_url) { "https://redirect.com" }
32
44
 
33
45
  let(:result) do
34
- Wayfarer::Networking::Result::Redirect.new(task.url, redirect_url)
46
+ Wayfarer::Networking::Result::Redirect.new(redirect_url)
35
47
  end
36
48
 
37
49
  before do
38
50
  task.metadata.staged_urls = Set.new
39
- allow(adapter).to receive(:fetch).with(task.url).and_return(result)
51
+ allow(agent).to receive(:fetch).with(task.url).and_return(result)
40
52
  end
41
53
 
42
54
  it "stages the redirect URL" do
@@ -55,7 +67,7 @@ describe Wayfarer::Middleware::Fetch do
55
67
  let(:result) { Wayfarer::Networking::Result::Success.new(page) }
56
68
 
57
69
  before do
58
- allow(adapter).to receive(:fetch).with(task.url).and_return(result)
70
+ allow(agent).to receive(:fetch).with(task.url).and_return(result)
59
71
  end
60
72
 
61
73
  it "assigns the page" do
@@ -27,6 +27,13 @@ describe Wayfarer::Middleware::Router do
27
27
  expect(task.metadata.action).to be(:index)
28
28
  expect(task.metadata.params).to eq({})
29
29
  end
30
+
31
+ describe "params" do
32
+ it "is a HashWithIndifferentAccess" do
33
+ router.call(task)
34
+ expect(task.metadata.params).to be_a(ActiveSupport::HashWithIndifferentAccess)
35
+ end
36
+ end
30
37
  end
31
38
 
32
39
  context "when URL does not match a route" do
@@ -5,8 +5,6 @@ require "spec_helpers"
5
5
  describe Wayfarer::Middleware::Worker do
6
6
  let(:task) { build(:task) }
7
7
 
8
- before { task.metadata.action = :index }
9
-
10
8
  let(:job) do
11
9
  Class.new(Wayfarer::Base) do
12
10
  def index
@@ -15,6 +13,11 @@ describe Wayfarer::Middleware::Worker do
15
13
  end
16
14
  end
17
15
 
16
+ before do
17
+ task.metadata.action = :index
18
+ allow_any_instance_of(job).to receive(:arguments).and_return([task])
19
+ end
20
+
18
21
  describe "::route" do
19
22
  it "returns a route" do
20
23
  expect(job.route).to be_a(Wayfarer::Routing::Route)
@@ -22,11 +25,6 @@ describe Wayfarer::Middleware::Worker do
22
25
  end
23
26
 
24
27
  describe "#call" do
25
- it "assigns the task" do
26
- worker = job.new
27
- expect { worker.call(task) }.to change { worker.task }.to(task)
28
- end
29
-
30
28
  it "calls the action method" do
31
29
  worker = job.new
32
30
  expect(worker).to receive(:index)
@@ -41,7 +39,7 @@ describe Wayfarer::Middleware::Worker do
41
39
  describe "#chain" do
42
40
  it "returns its middleware chain" do
43
41
  worker = job.new
44
- expect(worker.chain.middlewares).to eq([*Wayfarer.core_middleware, worker])
42
+ expect(worker.chain.middlewares).to eq([*Wayfarer.middleware, worker])
45
43
  end
46
44
  end
47
45
 
@@ -53,37 +51,76 @@ describe Wayfarer::Middleware::Worker do
53
51
  end
54
52
  end
55
53
 
56
- describe "#page" do
57
- let(:page) { Object.new }
58
- let(:worker) { job.new }
54
+ describe "#params" do
55
+ it "delegates to task metadata" do
56
+ worker = job.new
57
+ expect(worker.task.metadata).to receive(:params)
58
+ worker.params
59
+ end
60
+ end
59
61
 
60
- before do
61
- task.metadata.page = page
62
- worker.task = task
62
+ describe "#agent" do
63
+ it "delegates to task metadata" do
64
+ worker = job.new
65
+ expect(worker.task.metadata).to receive(:agent)
66
+ worker.agent
63
67
  end
68
+ end
69
+
70
+ describe "#browser" do
71
+ it "returns the context's instance" do
72
+ worker = job.new
73
+ context = spy
74
+ expect(worker.task.metadata).to receive(:agent).and_return(context)
75
+ expect(context).to receive(:instance)
76
+ worker.browser
77
+ end
78
+ end
79
+
80
+ describe "#page" do
81
+ let(:worker) { job.new }
82
+ let(:page) { Object.new }
64
83
 
65
84
  it "returns the page" do
85
+ task.metadata.page = page
66
86
  expect(worker.page).to be(page)
67
87
  end
68
88
 
69
89
  context "with live keyword" do
70
- let(:adapter) { spy }
71
- let(:body) { "foobar" }
72
- let(:live) { Object.new }
90
+ let(:agent) { spy }
91
+ let(:result) { Wayfarer::Networking::Result::Success.new(page) }
73
92
 
74
- before do
75
- task.metadata.adapter = adapter
76
- allow(adapter).to receive(:live).with(page).and_return(live)
77
- end
93
+ before { task.metadata.agent = agent }
94
+
95
+ context "when agent returns Result" do
96
+ before { allow(agent).to receive(:live).and_return(result) }
97
+
98
+ it "returns the page" do
99
+ expect(worker.page(live: true)).to be(page)
100
+ end
78
101
 
79
- it "returns a live page" do
80
- expect(worker.page(live: true)).to be(live)
102
+ it "replaces the existing page" do
103
+ expect {
104
+ worker.page(live: true)
105
+ }.to change { task.metadata.page }.to(page)
106
+ end
81
107
  end
82
108
 
83
- it "replaces the existing page" do
84
- expect {
85
- worker.page(live: true)
86
- }.to change { task.metadata.page }.to(live)
109
+ context "when agent returns nil" do
110
+ before do
111
+ task.metadata.page = page
112
+ allow(agent).to receive(:live).and_return(nil)
113
+ end
114
+
115
+ it "returns the existing page" do
116
+ expect(worker.page(live: true)).to be(page)
117
+ end
118
+
119
+ it "does not replace the existing page" do
120
+ expect {
121
+ worker.page(live: true)
122
+ }.not_to(change { task.metadata.page })
123
+ end
87
124
  end
88
125
  end
89
126
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helpers"
4
+ require_relative "strategy"
5
+
6
+ describe Wayfarer::Networking::Capybara, ferrum: true do
7
+ include_examples "Network strategy", strategy: described_class,
8
+ browser: true,
9
+ request_headers: false,
10
+ response_headers: true,
11
+ status_code: true
12
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helpers"
4
+
5
+ describe Wayfarer::Networking::Context do
6
+ let(:instance) { Object.new }
7
+ let(:strategy) { spy }
8
+ let(:renewing_error) { Class.new(StandardError) }
9
+ subject(:context) { Wayfarer::Networking::Context.new(strategy) }
10
+
11
+ before do
12
+ allow(strategy).to receive(:renew_on).and_return([renewing_error])
13
+ allow(strategy).to receive(:create).and_return(instance)
14
+ end
15
+
16
+ describe "#new" do
17
+ it "assigns the strategy" do
18
+ expect(context.strategy).to be(strategy)
19
+ end
20
+
21
+ it "assigns the instance" do
22
+ expect(context.strategy).to be(strategy)
23
+ end
24
+ end
25
+
26
+ describe "#fetch" do
27
+ let(:url) { Object.new }
28
+
29
+ it "fetches" do
30
+ expect(strategy).to receive(:fetch).with(instance, url)
31
+ context.fetch(url)
32
+ end
33
+
34
+ context "with renewing exception raised" do
35
+ before do
36
+ allow(strategy).to receive(:fetch).and_raise(renewing_error)
37
+ end
38
+
39
+ it "renews and reraises" do
40
+ expect(context).to receive(:renew)
41
+
42
+ expect {
43
+ context.fetch(url)
44
+ }.to raise_error(renewing_error)
45
+ end
46
+ end
47
+
48
+ context "with non-renewing exception raised" do
49
+ before do
50
+ allow(strategy).to receive(:fetch).and_raise(StandardError)
51
+ end
52
+
53
+ it "reraises" do
54
+ expect(context).not_to receive(:renew)
55
+
56
+ expect {
57
+ context.fetch(url)
58
+ }.to raise_error(StandardError)
59
+ end
60
+ end
61
+ end
62
+
63
+ describe "#live" do
64
+ let(:page) { Object.new }
65
+
66
+ it "calls live" do
67
+ expect(strategy).to receive(:live).with(instance)
68
+ context.live
69
+ end
70
+
71
+ context "with renewing exception raised" do
72
+ before do
73
+ allow(strategy).to receive(:live).and_raise(renewing_error)
74
+ end
75
+
76
+ it "renews and reraises" do
77
+ expect(context).to receive(:renew)
78
+
79
+ expect {
80
+ context.live
81
+ }.to raise_error(renewing_error)
82
+ end
83
+
84
+ context "when renewing raises" do
85
+ let(:other_error) { Class.new(StandardError) }
86
+
87
+ before do
88
+ allow(context).to receive(:renew).and_raise(other_error)
89
+ end
90
+
91
+ it "reraises the original exception" do
92
+ expect {
93
+ context.live
94
+ }.to raise_error(renewing_error)
95
+ end
96
+ end
97
+ end
98
+
99
+ context "with non-renewing exception raised" do
100
+ before do
101
+ allow(strategy).to receive(:live).and_raise(StandardError)
102
+ end
103
+
104
+ it "reraises" do
105
+ expect(context).not_to receive(:renew)
106
+
107
+ expect {
108
+ context.live(page)
109
+ }.to raise_error(StandardError)
110
+ end
111
+ end
112
+ end
113
+
114
+ describe "#renew" do
115
+ it "destroys" do
116
+ expect(strategy).to receive(:destroy).with(instance)
117
+ context.renew
118
+ end
119
+ end
120
+
121
+ describe "#instance" do
122
+ it "creates an instance" do
123
+ expect(strategy).to receive(:create).and_return(instance)
124
+ expect(context.instance).to be(instance)
125
+ end
126
+ end
127
+ end
@@ -1,28 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helpers"
4
- require_relative "adapter"
4
+ require_relative "strategy"
5
5
 
6
6
  describe Wayfarer::Networking::Ferrum, ferrum: true do
7
- subject(:adapter) { Wayfarer::Networking::Ferrum.new }
8
-
9
- after { adapter.free }
10
-
11
- include_examples "Network adapter", browser: true,
12
- capybara: true,
13
- request_headers: true
14
-
15
- describe "#fetch" do
16
- it "sets the status code" do
17
- url = test_app_path("/status_code/418")
18
- page = adapter.fetch(url).page
19
- expect(page.status_code).to be(418)
20
- end
21
-
22
- it "sets response headers" do
23
- url = test_app_path("/hello_world")
24
- page = adapter.fetch(url).page
25
- expect(page.headers["hello"]).to eq("world")
26
- end
27
- end
7
+ include_examples "Network strategy", strategy: described_class,
8
+ browser: true,
9
+ request_headers: true,
10
+ response_headers: true,
11
+ status_code: true
28
12
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helpers"
4
+ require_relative "strategy"
5
+
6
+ describe Wayfarer::Networking::HTTP do
7
+ include_examples "Network strategy", strategy: described_class,
8
+ browser: false,
9
+ request_headers: true,
10
+ response_headers: true,
11
+ status_code: true
12
+ end
@@ -9,34 +9,59 @@ describe Wayfarer::Networking::Pool do
9
9
 
10
10
  describe "#with" do
11
11
  context "by default" do
12
- it "yields NetHTTP" do
13
- pool.with do |adapter|
14
- expect(adapter).to be_a(Wayfarer::Networking::Healer)
15
- expect(adapter.adapter).to be_a(Wayfarer::Networking::NetHTTP)
12
+ it "yields HTTP" do
13
+ pool.with do |context|
14
+ expect(context.strategy).to be_a(Wayfarer::Networking::HTTP)
16
15
  end
17
16
  end
18
17
  end
19
18
 
20
19
  context "when using Ferrum", ferrum: true do
21
- before { Wayfarer.config.adapter = :ferrum }
20
+ before { Wayfarer.config.network.agent = :ferrum }
22
21
 
23
22
  it "yields Ferrum" do
24
- pool.with do |adapter|
25
- expect(adapter).to be_a(Wayfarer::Networking::Healer)
26
- expect(adapter.adapter).to be_a(Wayfarer::Networking::Ferrum)
23
+ pool.with do |context|
24
+ expect(context.strategy).to be_a(Wayfarer::Networking::Ferrum)
27
25
  end
28
26
  end
29
27
  end
30
28
 
31
29
  context "when using Selenium", selenium: true do
32
- before { Wayfarer.config.adapter = :selenium }
30
+ before { Wayfarer.config.network.agent = :selenium }
33
31
 
34
32
  it "yields Selenium" do
35
- pool.with do |adapter|
36
- expect(adapter).to be_a(Wayfarer::Networking::Healer)
37
- expect(adapter.adapter).to be_a(Wayfarer::Networking::Selenium)
33
+ pool.with do |context|
34
+ expect(context.strategy).to be_a(Wayfarer::Networking::Selenium)
38
35
  end
39
36
  end
40
37
  end
38
+
39
+ context "when using Capybara", ferrum: true do
40
+ before do
41
+ Wayfarer.config.network.agent = :capybara
42
+ Wayfarer.config.capybara.driver = :cuprite
43
+ end
44
+
45
+ it "yields Capybara" do
46
+ pool.with do |context|
47
+ expect(context.strategy).to be_a(Wayfarer::Networking::Capybara)
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ describe "#free" do
54
+ let(:strategy) { double(create: spy) }
55
+
56
+ before do
57
+ pool.class.registry[:foobar] = double(new: strategy)
58
+ Wayfarer.config.network.agent = :foobar
59
+ end
60
+
61
+ it "destroys the strategy" do
62
+ expect(strategy).to receive(:destroy)
63
+ pool.with {}
64
+ pool.free
65
+ end
41
66
  end
42
67
  end
@@ -1,28 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helpers"
4
- require_relative "adapter"
4
+ require_relative "strategy"
5
5
 
6
6
  describe Wayfarer::Networking::Selenium, selenium: true do
7
- subject(:adapter) { Wayfarer::Networking::Selenium.new }
8
-
9
- after { adapter.free }
10
-
11
- include_examples "Network adapter", browser: true,
12
- capybara: true,
13
- request_headers: false
14
-
15
- describe "#fetch" do
16
- it "sets a fake status code" do
17
- url = test_app_path("/status_code/404")
18
- page = adapter.fetch(url).page
19
- expect(page.status_code).to be(Wayfarer::Networking::Selenium::FAKE_STATUS_CODE)
20
- end
21
-
22
- it "sets fake response headers" do
23
- url = test_app_path("/hello_world")
24
- page = adapter.fetch(url).page
25
- expect(page.headers).to eq(Wayfarer::Networking::Selenium::FAKE_RESPONSE_HEADERS)
26
- end
27
- end
7
+ include_examples "Network strategy", strategy: described_class,
8
+ browser: true,
9
+ request_headers: false,
10
+ response_headers: false,
11
+ status_code: false
28
12
  end
@@ -0,0 +1,170 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helpers"
4
+
5
+ RSpec.shared_examples "Network strategy" do |options|
6
+ attr_accessor :context
7
+
8
+ before(:all) do
9
+ self.context = Wayfarer::Networking::Context.new(options[:strategy].new)
10
+ end
11
+
12
+ after(:all) do
13
+ context.renew
14
+ end
15
+
16
+ describe "#renew_on" do
17
+ it "returns an Array" do
18
+ expect(context.strategy.renew_on).to be_an(Array)
19
+ end
20
+ end
21
+
22
+ describe "Context" do
23
+ describe "#fetch" do
24
+ it "returns Success" do
25
+ url = test_app_path("/hello_world")
26
+ result = context.fetch(url)
27
+ expect(result).to be_a(Wayfarer::Networking::Result::Success)
28
+ expect(result.page).to be_a(Wayfarer::Page)
29
+ end
30
+
31
+ it "sets the URL" do
32
+ url = test_app_path("/status_code/404")
33
+ page = context.fetch(url).page
34
+ expect(page.url).to eq test_app_path("/status_code/404")
35
+ end
36
+
37
+ it "sets the response body" do
38
+ url = test_app_path("/hello_world")
39
+ page = context.fetch(url).page
40
+ expect(page.body).to match(/Hello world!/)
41
+ end
42
+
43
+ it "sets the status code" do
44
+ skip unless options[:status_code]
45
+
46
+ url = test_app_path("/status_code/418")
47
+ page = context.fetch(url).page
48
+ expect(page.status_code).to be(418)
49
+ end
50
+
51
+ it "sets response headers" do
52
+ skip unless options[:response_headers]
53
+
54
+ url = test_app_path("/hello_world")
55
+ page = context.fetch(url).page
56
+ expect(page.headers["hello"]).to eq("world")
57
+ end
58
+
59
+ context "Selenium" do
60
+ before { skip unless context.strategy.is_a?(Wayfarer::Networking::Selenium) }
61
+
62
+ it "sets a mock status code" do
63
+ skip if options[:status_code]
64
+
65
+ url = test_app_path("/status_code/418")
66
+ page = context.fetch(url).page
67
+ expect(page.status_code).to be(options[:strategy]::MOCK_STATUS_CODE)
68
+ end
69
+
70
+ it "sets mock response headers" do
71
+ url = test_app_path("/hello_world")
72
+ page = context.fetch(url).page
73
+ expect(page.headers).to eq(options[:strategy]::MOCK_RESPONSE_HEADERS)
74
+ end
75
+ end
76
+
77
+ describe "HTTP headers" do
78
+ before do
79
+ Wayfarer.config.network.http_headers = { "User-Agent" => "Foobar" }
80
+ context.renew
81
+ end
82
+
83
+ it "uses configured HTTP headers" do
84
+ skip unless options[:request_headers]
85
+
86
+ url = test_app_path("/headers/HTTP_USER_AGENT")
87
+ page = context.fetch(url).page
88
+ expect(page.body).to match(/Foobar/)
89
+ end
90
+ end
91
+
92
+ context "when encountering a redirect" do
93
+ it "returns a Redirect" do
94
+ skip if options[:browser]
95
+
96
+ url = test_app_path("/redirect?times=3")
97
+ result = context.fetch(url)
98
+ expect(result).to be_a(Wayfarer::Networking::Result::Redirect)
99
+ expect(result.redirect_url).to eq test_app_path("/redirect?times=2")
100
+ end
101
+ end
102
+ end
103
+
104
+ describe "#live" do
105
+ context "when automating a browser" do
106
+ let(:url) { test_app_path("/body/foobar") }
107
+
108
+ before do
109
+ skip unless options[:browser]
110
+
111
+ context.fetch(test_app_path("/hello_world"))
112
+ context.strategy.navigate(context.instance, url)
113
+ end
114
+
115
+ subject(:page) { context.live.page }
116
+
117
+ it "sets the URL" do
118
+ expect(page.url).to eq(url)
119
+ end
120
+
121
+ it "sets the response body" do
122
+ expect(page.body).to match(/foobar/)
123
+ end
124
+
125
+ it "sets response headers" do
126
+ skip unless options[:response_headers]
127
+
128
+ expect(page.headers["content-length"]).to eq("6")
129
+ end
130
+
131
+ it "sets the status code" do
132
+ skip unless options[:status_code]
133
+
134
+ expect(page.status_code).to be(200)
135
+ end
136
+ end
137
+
138
+ context "when using plain HTTP" do
139
+ it "returns nil" do
140
+ skip if options[:browser]
141
+
142
+ expect(context.live).to be(nil)
143
+ end
144
+ end
145
+ end
146
+
147
+ describe "#renew" do
148
+ it "replaces the instance", foo: true do
149
+ expect {
150
+ context.renew
151
+ }.to(change { context.instance })
152
+ end
153
+ end
154
+ end
155
+
156
+ describe "Selenium" do
157
+ before { skip unless context.strategy.is_a?(Wayfarer::Networking::Selenium) }
158
+
159
+ describe "Client timeout" do
160
+ before do
161
+ Wayfarer.config.selenium.client_timeout = 42
162
+ context.renew
163
+ end
164
+
165
+ it "sets the client timeout" do
166
+ expect(context.instance.send(:bridge).send(:http).read_timeout).to be(42)
167
+ end
168
+ end
169
+ end
170
+ end
@@ -8,7 +8,7 @@ describe Wayfarer::Redis::Pool, redis: true do
8
8
 
9
9
  describe "::with" do
10
10
  before do
11
- Wayfarer.config.redis_factory = -> { conn }
11
+ Wayfarer.config.redis.factory = ->(_) { conn }
12
12
  end
13
13
 
14
14
  it "instantiates the factory and yields" do