wayfarer 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yaml +1 -1
- data/Gemfile.lock +20 -15
- data/docs/cookbook/user_agent.md +1 -1
- data/docs/guides/browser_automation/capybara.md +64 -1
- data/docs/guides/browser_automation/custom_adapters.md +100 -0
- data/docs/guides/browser_automation/ferrum.md +3 -3
- data/docs/guides/browser_automation/selenium.md +7 -5
- data/docs/guides/callbacks.md +117 -10
- data/docs/guides/configuration.md +16 -10
- data/docs/guides/error_handling.md +9 -5
- data/docs/guides/networking.md +77 -3
- data/docs/index.md +9 -1
- data/docs/reference/api/base.md +4 -4
- data/docs/reference/configuration_keys.md +42 -0
- data/docs/reference/environment_variables.md +25 -27
- data/lib/wayfarer/base.rb +7 -17
- data/lib/wayfarer/callbacks.rb +71 -0
- data/lib/wayfarer/cli/base.rb +5 -1
- data/lib/wayfarer/cli/job.rb +7 -3
- data/lib/wayfarer/cli/route.rb +2 -2
- data/lib/wayfarer/cli/route_printer.rb +7 -7
- data/lib/wayfarer/config/capybara.rb +10 -0
- data/lib/wayfarer/config/ferrum.rb +11 -0
- data/lib/wayfarer/config/networking.rb +26 -0
- data/lib/wayfarer/config/redis.rb +14 -0
- data/lib/wayfarer/config/root.rb +11 -0
- data/lib/wayfarer/config/selenium.rb +21 -0
- data/lib/wayfarer/config/strconv.rb +45 -0
- data/lib/wayfarer/config/struct.rb +72 -0
- data/lib/wayfarer/gc.rb +3 -7
- data/lib/wayfarer/middleware/fetch.rb +7 -3
- data/lib/wayfarer/middleware/router.rb +2 -2
- data/lib/wayfarer/middleware/worker.rb +12 -9
- data/lib/wayfarer/networking/capybara.rb +28 -0
- data/lib/wayfarer/networking/context.rb +36 -0
- data/lib/wayfarer/networking/ferrum.rb +17 -52
- data/lib/wayfarer/networking/http.rb +34 -0
- data/lib/wayfarer/networking/pool.rb +15 -10
- data/lib/wayfarer/networking/result.rb +1 -1
- data/lib/wayfarer/networking/selenium.rb +20 -47
- data/lib/wayfarer/networking/strategy.rb +38 -0
- data/lib/wayfarer/page.rb +2 -3
- data/lib/wayfarer/redis/pool.rb +3 -1
- data/lib/wayfarer/routing/dsl.rb +8 -8
- data/lib/wayfarer/routing/matchers/custom.rb +23 -0
- data/lib/wayfarer/routing/matchers/host.rb +19 -0
- data/lib/wayfarer/routing/matchers/path.rb +48 -0
- data/lib/wayfarer/routing/matchers/query.rb +63 -0
- data/lib/wayfarer/routing/matchers/scheme.rb +17 -0
- data/lib/wayfarer/routing/matchers/suffix.rb +17 -0
- data/lib/wayfarer/routing/matchers/url.rb +17 -0
- data/lib/wayfarer/routing/route.rb +1 -1
- data/lib/wayfarer.rb +9 -9
- data/spec/base_spec.rb +14 -0
- data/spec/callbacks_spec.rb +102 -0
- data/spec/cli/job_spec.rb +6 -6
- data/spec/config/capybara_spec.rb +18 -0
- data/spec/config/ferrum_spec.rb +24 -0
- data/spec/config/networking_spec.rb +73 -0
- data/spec/config/redis_spec.rb +32 -0
- data/spec/config/root_spec.rb +31 -0
- data/spec/config/selenium_spec.rb +56 -0
- data/spec/config/strconv_spec.rb +58 -0
- data/spec/config/struct_spec.rb +66 -0
- data/spec/gc_spec.rb +8 -6
- data/spec/middleware/fetch_spec.rb +20 -8
- data/spec/middleware/router_spec.rb +7 -0
- data/spec/middleware/worker_spec.rb +64 -27
- data/spec/networking/capybara_spec.rb +12 -0
- data/spec/networking/context_spec.rb +127 -0
- data/spec/networking/ferrum_spec.rb +6 -22
- data/spec/networking/http_spec.rb +12 -0
- data/spec/networking/pool_spec.rb +37 -12
- data/spec/networking/selenium_spec.rb +6 -22
- data/spec/networking/strategy.rb +170 -0
- data/spec/redis/pool_spec.rb +1 -1
- data/spec/routing/dsl_spec.rb +10 -10
- data/spec/routing/integration_spec.rb +22 -22
- data/spec/routing/{custom_matcher_spec.rb → matchers/custom_spec.rb} +4 -4
- data/spec/routing/{host_matcher_spec.rb → matchers/host_spec.rb} +6 -6
- data/spec/routing/{path_matcher_spec.rb → matchers/path_spec.rb} +6 -6
- data/spec/routing/{query_matcher_spec.rb → matchers/query_spec.rb} +15 -15
- data/spec/routing/{scheme_matcher_spec.rb → matchers/scheme_spec.rb} +4 -4
- data/spec/routing/{suffix_matcher_spec.rb → matchers/suffix_spec.rb} +4 -4
- data/spec/routing/{uri_matcher_spec.rb → matchers/uri_spec.rb} +4 -4
- data/spec/routing/path_finder_spec.rb +1 -1
- data/spec/routing/root_route_spec.rb +2 -2
- data/spec/routing/route_spec.rb +2 -2
- data/spec/spec_helpers.rb +13 -5
- data/spec/wayfarer_spec.rb +1 -1
- data/wayfarer.gemspec +8 -7
- metadata +74 -33
- data/lib/wayfarer/config.rb +0 -67
- data/lib/wayfarer/networking/healer.rb +0 -21
- data/lib/wayfarer/networking/net_http.rb +0 -52
- data/lib/wayfarer/routing/custom_matcher.rb +0 -21
- data/lib/wayfarer/routing/host_matcher.rb +0 -23
- data/lib/wayfarer/routing/path_matcher.rb +0 -46
- data/lib/wayfarer/routing/query_matcher.rb +0 -67
- data/lib/wayfarer/routing/scheme_matcher.rb +0 -21
- data/lib/wayfarer/routing/suffix_matcher.rb +0 -21
- data/lib/wayfarer/routing/url_matcher.rb +0 -21
- data/spec/config_spec.rb +0 -144
- data/spec/networking/adapter.rb +0 -135
- data/spec/networking/healer_spec.rb +0 -46
- 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(:
|
9
|
+
let(:agent) { spy }
|
8
10
|
subject(:fetch) { Wayfarer::Middleware::Fetch.new }
|
9
11
|
|
10
|
-
before
|
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
|
24
|
+
it "assigns the agent" do
|
20
25
|
expect {
|
21
26
|
fetch.call(task)
|
22
|
-
}.to change { task.metadata.
|
27
|
+
}.to change { task.metadata.agent }.to(agent)
|
23
28
|
end
|
24
29
|
|
25
30
|
it "retrieves the page" do
|
26
|
-
expect(
|
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(
|
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(
|
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(
|
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.
|
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 "#
|
57
|
-
|
58
|
-
|
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
|
-
|
61
|
-
|
62
|
-
worker
|
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(:
|
71
|
-
let(:
|
72
|
-
let(:live) { Object.new }
|
90
|
+
let(:agent) { spy }
|
91
|
+
let(:result) { Wayfarer::Networking::Result::Success.new(page) }
|
73
92
|
|
74
|
-
before
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
-
|
80
|
-
|
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
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
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 "
|
4
|
+
require_relative "strategy"
|
5
5
|
|
6
6
|
describe Wayfarer::Networking::Ferrum, ferrum: true do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
13
|
-
pool.with do |
|
14
|
-
expect(
|
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.
|
20
|
+
before { Wayfarer.config.network.agent = :ferrum }
|
22
21
|
|
23
22
|
it "yields Ferrum" do
|
24
|
-
pool.with do |
|
25
|
-
expect(
|
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.
|
30
|
+
before { Wayfarer.config.network.agent = :selenium }
|
33
31
|
|
34
32
|
it "yields Selenium" do
|
35
|
-
pool.with do |
|
36
|
-
expect(
|
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 "
|
4
|
+
require_relative "strategy"
|
5
5
|
|
6
6
|
describe Wayfarer::Networking::Selenium, selenium: true do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
data/spec/redis/pool_spec.rb
CHANGED