wayfarer 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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