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.
- 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