opal-browser 0.1.0.beta1 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/build.yml +95 -0
- data/.gitignore +3 -0
- data/.yardopts +1 -1
- data/Gemfile +22 -3
- data/LICENSE +20 -0
- data/README.md +200 -20
- data/Rakefile +29 -1
- data/config.ru +20 -2
- data/docs/polyfills.md +24 -0
- data/examples/2048/Gemfile +6 -0
- data/examples/2048/README.md +13 -0
- data/examples/2048/app/application.rb +169 -0
- data/examples/2048/config.ru +9 -0
- data/examples/canvas/Gemfile +6 -0
- data/examples/canvas/README.md +9 -0
- data/examples/canvas/app/application.rb +55 -0
- data/examples/canvas/config.ru +9 -0
- data/examples/component/Gemfile +6 -0
- data/examples/component/README.md +10 -0
- data/examples/component/app/application.rb +66 -0
- data/examples/component/config.ru +9 -0
- data/examples/integrations/README.md +24 -0
- data/examples/integrations/dynamic-rack-opal-sprockets-server/Gemfile +6 -0
- data/examples/integrations/dynamic-rack-opal-sprockets-server/README.md +16 -0
- data/examples/integrations/dynamic-rack-opal-sprockets-server/app/application.rb +6 -0
- data/examples/integrations/dynamic-rack-opal-sprockets-server/config.ru +9 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/.gitignore +1 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/Gemfile +7 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/README.md +22 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/Rakefile +4 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/app/application.rb +6 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/app.rb +32 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/config.ru +3 -0
- data/examples/integrations/dynamic-roda-tilt/.gitignore +1 -0
- data/examples/integrations/dynamic-roda-tilt/Gemfile +8 -0
- data/examples/integrations/dynamic-roda-tilt/README.md +17 -0
- data/examples/integrations/dynamic-roda-tilt/Rakefile +6 -0
- data/examples/integrations/dynamic-roda-tilt/app/application.rb +6 -0
- data/examples/integrations/dynamic-roda-tilt/app.rb +50 -0
- data/examples/integrations/dynamic-roda-tilt/config.ru +3 -0
- data/examples/integrations/dynamic-sinatra-opal-sprockets-server/Gemfile +7 -0
- data/examples/integrations/dynamic-sinatra-opal-sprockets-server/README.md +16 -0
- data/examples/integrations/dynamic-sinatra-opal-sprockets-server/app/application.rb +6 -0
- data/examples/integrations/dynamic-sinatra-opal-sprockets-server/config.ru +29 -0
- data/examples/integrations/static-bash/.gitignore +2 -0
- data/examples/integrations/static-bash/Gemfile +3 -0
- data/examples/integrations/static-bash/README.md +8 -0
- data/examples/integrations/static-bash/app/application.rb +6 -0
- data/examples/integrations/static-bash/build.sh +4 -0
- data/examples/integrations/static-bash/index.html +10 -0
- data/examples/integrations/static-bash-opal-parser/.gitignore +3 -0
- data/examples/integrations/static-bash-opal-parser/Gemfile +3 -0
- data/examples/integrations/static-bash-opal-parser/README.md +10 -0
- data/examples/integrations/static-bash-opal-parser/build.sh +4 -0
- data/examples/integrations/static-bash-opal-parser/index.html +19 -0
- data/examples/integrations/static-rake/.gitignore +1 -0
- data/examples/integrations/static-rake/Gemfile +4 -0
- data/examples/integrations/static-rake/README.md +7 -0
- data/examples/integrations/static-rake/Rakefile +10 -0
- data/examples/integrations/static-rake/app/application.rb +6 -0
- data/examples/integrations/static-rake/index.html +9 -0
- data/examples/integrations/static-rake-guard/.gitignore +1 -0
- data/examples/integrations/static-rake-guard/Gemfile +6 -0
- data/examples/integrations/static-rake-guard/Guardfile +3 -0
- data/examples/integrations/static-rake-guard/README.md +10 -0
- data/examples/integrations/static-rake-guard/Rakefile +10 -0
- data/examples/integrations/static-rake-guard/app/application.rb +6 -0
- data/examples/integrations/static-rake-guard/index.html +9 -0
- data/examples/svg/.gitignore +1 -0
- data/examples/svg/Gemfile +4 -0
- data/examples/svg/README.md +7 -0
- data/examples/svg/Rakefile +10 -0
- data/examples/svg/app/application.rb +11 -0
- data/examples/svg/index.html +17 -0
- data/examples/svg/index.svg +6 -0
- data/index.html.erb +24 -0
- data/lib/opal-browser.rb +1 -0
- data/opal/browser/animation_frame.rb +92 -10
- data/opal/browser/audio/node.rb +121 -0
- data/opal/browser/audio/param_schedule.rb +43 -0
- data/opal/browser/audio.rb +66 -0
- data/opal/browser/blob.rb +94 -0
- data/opal/browser/canvas/data.rb +2 -12
- data/opal/browser/canvas/gradient.rb +1 -11
- data/opal/browser/canvas/style.rb +3 -11
- data/opal/browser/canvas/text.rb +1 -11
- data/opal/browser/canvas.rb +86 -28
- data/opal/browser/console.rb +6 -38
- data/opal/browser/cookies.rb +90 -27
- data/opal/browser/crypto.rb +79 -0
- data/opal/browser/css/declaration.rb +1 -6
- data/opal/browser/css/rule.rb +1 -1
- data/opal/browser/css/style_sheet.rb +2 -2
- data/opal/browser/css.rb +23 -7
- data/opal/browser/database/sql.rb +193 -0
- data/opal/browser/delay.rb +94 -0
- data/opal/browser/dom/attribute.rb +16 -9
- data/opal/browser/dom/builder.rb +35 -25
- data/opal/browser/dom/character_data.rb +43 -7
- data/opal/browser/dom/document.rb +171 -37
- data/opal/browser/dom/document_fragment.rb +18 -0
- data/opal/browser/dom/document_or_shadow_root.rb +19 -0
- data/opal/browser/dom/element/attributes.rb +111 -0
- data/opal/browser/dom/element/button.rb +31 -0
- data/opal/browser/dom/element/custom.rb +177 -0
- data/opal/browser/dom/element/data.rb +82 -0
- data/opal/browser/dom/element/editable.rb +47 -0
- data/opal/browser/dom/element/form.rb +38 -0
- data/opal/browser/dom/element/iframe.rb +37 -0
- data/opal/browser/dom/element/image.rb +25 -0
- data/opal/browser/dom/element/input.rb +48 -1
- data/opal/browser/dom/element/media.rb +17 -0
- data/opal/browser/dom/element/offset.rb +32 -10
- data/opal/browser/dom/element/position.rb +11 -2
- data/opal/browser/dom/element/scroll.rb +139 -20
- data/opal/browser/dom/element/select.rb +42 -0
- data/opal/browser/dom/element/size.rb +46 -0
- data/opal/browser/dom/element/template.rb +11 -0
- data/opal/browser/dom/element/textarea.rb +26 -0
- data/opal/browser/dom/element.rb +496 -168
- data/opal/browser/dom/mutation_observer.rb +69 -9
- data/opal/browser/dom/node.rb +270 -83
- data/opal/browser/dom/node_set.rb +74 -41
- data/opal/browser/dom/shadow_root.rb +12 -0
- data/opal/browser/dom/text.rb +18 -3
- data/opal/browser/dom.rb +40 -18
- data/opal/browser/effects.rb +180 -3
- data/opal/browser/event/all.rb +26 -0
- data/opal/browser/event/animation.rb +40 -0
- data/opal/browser/{dom/event → event}/audio_processing.rb +10 -6
- data/opal/browser/event/base.rb +461 -0
- data/opal/browser/event/before_unload.rb +17 -0
- data/opal/browser/event/clipboard.rb +37 -0
- data/opal/browser/event/close.rb +49 -0
- data/opal/browser/event/composition.rb +52 -0
- data/opal/browser/event/custom.rb +65 -0
- data/opal/browser/event/data_transfer.rb +95 -0
- data/opal/browser/event/device_light.rb +25 -0
- data/opal/browser/{dom/event → event}/device_motion.rb +21 -6
- data/opal/browser/event/device_orientation.rb +50 -0
- data/opal/browser/{dom/event → event}/device_proximity.rb +10 -6
- data/opal/browser/event/drag.rb +123 -0
- data/opal/browser/event/focus.rb +41 -0
- data/opal/browser/event/gamepad.rb +62 -0
- data/opal/browser/{dom/event → event}/hash_change.rb +10 -6
- data/opal/browser/event/keyboard.rb +128 -0
- data/opal/browser/event/message.rb +72 -0
- data/opal/browser/{dom/event → event}/mouse.rb +37 -32
- data/opal/browser/event/page_transition.rb +25 -0
- data/opal/browser/event/pop_state.rb +35 -0
- data/opal/browser/event/progress.rb +45 -0
- data/opal/browser/event/sensor.rb +17 -0
- data/opal/browser/{dom/event → event}/storage.rb +10 -6
- data/opal/browser/{dom/event → event}/touch.rb +14 -21
- data/opal/browser/event/ui.rb +38 -0
- data/opal/browser/{dom/event → event}/wheel.rb +6 -4
- data/opal/browser/event.rb +163 -0
- data/opal/browser/event_source.rb +7 -4
- data/opal/browser/form_data.rb +225 -0
- data/opal/browser/history.rb +53 -21
- data/opal/browser/http/binary.rb +1 -0
- data/opal/browser/http/headers.rb +21 -2
- data/opal/browser/http/request.rb +83 -55
- data/opal/browser/http/response.rb +5 -1
- data/opal/browser/http.rb +47 -9
- data/opal/browser/immediate.rb +128 -10
- data/opal/browser/interval.rb +41 -23
- data/opal/browser/location.rb +20 -4
- data/opal/browser/navigator.rb +136 -13
- data/opal/browser/polyfill/visual_viewport.rb +216 -0
- data/opal/browser/screen.rb +34 -8
- data/opal/browser/setup/base.rb +6 -0
- data/opal/browser/setup/full.rb +13 -0
- data/opal/browser/setup/large.rb +17 -0
- data/opal/browser/setup/mini.rb +8 -0
- data/opal/browser/setup/traditional.rb +10 -0
- data/opal/browser/socket.rb +16 -8
- data/opal/browser/storage.rb +155 -52
- data/opal/browser/support.rb +299 -0
- data/opal/browser/utils.rb +116 -18
- data/opal/browser/version.rb +1 -1
- data/opal/browser/visual_viewport.rb +39 -0
- data/opal/browser/window/size.rb +47 -9
- data/opal/browser/window/view.rb +37 -4
- data/opal/browser/window.rb +46 -26
- data/opal/browser.rb +1 -10
- data/opal/opal-browser.rb +1 -0
- data/opal-browser.gemspec +10 -12
- data/spec/database/sql_spec.rb +139 -0
- data/spec/delay_spec.rb +41 -0
- data/spec/dom/attribute_spec.rb +49 -0
- data/spec/dom/builder_spec.rb +36 -19
- data/spec/dom/document_spec.rb +28 -6
- data/spec/dom/element/attributes_spec.rb +52 -0
- data/spec/dom/element/custom_spec.rb +106 -0
- data/spec/dom/element/subclass_spec.rb +144 -0
- data/spec/dom/element_spec.rb +184 -7
- data/spec/dom/mutation_observer_spec.rb +13 -9
- data/spec/dom/node_set_spec.rb +44 -0
- data/spec/dom/node_spec.rb +87 -27
- data/spec/dom_spec.rb +19 -9
- data/spec/event_source_spec.rb +18 -15
- data/spec/{dom/event_spec.rb → event_spec.rb} +55 -26
- data/spec/history_spec.rb +32 -19
- data/spec/http_spec.rb +25 -36
- data/spec/immediate_spec.rb +10 -7
- data/spec/interval_spec.rb +59 -0
- data/spec/native_cached_wrapper_spec.rb +46 -0
- data/spec/runner.rb +107 -0
- data/spec/socket_spec.rb +18 -14
- data/spec/spec_helper.rb +2 -4
- data/spec/spec_helper_promise.rb.erb +25 -0
- data/spec/storage_spec.rb +7 -7
- data/spec/wgxpath.install.js +49 -0
- data/spec/window_spec.rb +2 -2
- metadata +181 -93
- data/opal/browser/compatibility/animation_frame.rb +0 -93
- data/opal/browser/compatibility/dom/document/window.rb +0 -15
- data/opal/browser/compatibility/dom/element/css.rb +0 -15
- data/opal/browser/compatibility/dom/element/matches.rb +0 -31
- data/opal/browser/compatibility/dom/element/offset.rb +0 -20
- data/opal/browser/compatibility/dom/element/scroll.rb +0 -25
- data/opal/browser/compatibility/dom/element/style.rb +0 -15
- data/opal/browser/compatibility/dom/mutation_observer.rb +0 -47
- data/opal/browser/compatibility/http/request.rb +0 -15
- data/opal/browser/compatibility/immediate.rb +0 -107
- data/opal/browser/compatibility/window/scroll.rb +0 -27
- data/opal/browser/compatibility/window/size.rb +0 -13
- data/opal/browser/compatibility/window/view.rb +0 -13
- data/opal/browser/compatibility.rb +0 -59
- data/opal/browser/dom/compatibility.rb +0 -8
- data/opal/browser/dom/event/animation.rb +0 -26
- data/opal/browser/dom/event/base.rb +0 -207
- data/opal/browser/dom/event/before_unload.rb +0 -13
- data/opal/browser/dom/event/clipboard.rb +0 -26
- data/opal/browser/dom/event/close.rb +0 -35
- data/opal/browser/dom/event/composition.rb +0 -38
- data/opal/browser/dom/event/custom.rb +0 -30
- data/opal/browser/dom/event/device_light.rb +0 -21
- data/opal/browser/dom/event/device_orientation.rb +0 -36
- data/opal/browser/dom/event/drag.rb +0 -113
- data/opal/browser/dom/event/focus.rb +0 -23
- data/opal/browser/dom/event/gamepad.rb +0 -47
- data/opal/browser/dom/event/keyboard.rb +0 -93
- data/opal/browser/dom/event/message.rb +0 -50
- data/opal/browser/dom/event/page_transition.rb +0 -21
- data/opal/browser/dom/event/pop_state.rb +0 -21
- data/opal/browser/dom/event/progress.rb +0 -31
- data/opal/browser/dom/event/sensor.rb +0 -13
- data/opal/browser/dom/event/ui.rb +0 -22
- data/opal/browser/dom/event.rb +0 -240
- data/opal/browser/http/compatibility.rb +0 -1
- data/opal/browser/http/parameters.rb +0 -8
- data/opal/browser/timeout.rb +0 -60
- data/opal/browser/window/compatibility.rb +0 -3
- data/opal/browser/window/scroll.rb +0 -49
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'browser/event'
|
2
3
|
|
3
|
-
describe Browser::
|
4
|
+
describe Browser::Event do
|
4
5
|
html <<-HTML
|
5
6
|
<div id="event-spec">
|
6
7
|
u wot m8
|
@@ -16,13 +17,13 @@ describe Browser::DOM::Event do
|
|
16
17
|
count += 1
|
17
18
|
end
|
18
19
|
|
19
|
-
count.
|
20
|
+
expect(count).to eq(0)
|
20
21
|
elem.trigger :click
|
21
|
-
count.
|
22
|
+
expect(count).to eq(1)
|
22
23
|
elem.trigger :click
|
23
|
-
count.
|
24
|
+
expect(count).to eq(2)
|
24
25
|
elem.trigger 'mouse:down'
|
25
|
-
count.
|
26
|
+
expect(count).to eq(2)
|
26
27
|
end
|
27
28
|
|
28
29
|
it "listens for custom events" do
|
@@ -33,46 +34,53 @@ describe Browser::DOM::Event do
|
|
33
34
|
count += 1
|
34
35
|
end
|
35
36
|
|
36
|
-
count.
|
37
|
+
expect(count).to eq(0)
|
37
38
|
elem.trigger :huehue
|
38
|
-
count.
|
39
|
+
expect(count).to eq(1)
|
39
40
|
elem.trigger :huehue
|
40
|
-
count.
|
41
|
+
expect(count).to eq(2)
|
41
42
|
end
|
42
43
|
|
43
|
-
|
44
|
+
it "passes an event to the handler" do
|
44
45
|
elem = $document["event-spec"]
|
45
46
|
|
47
|
+
promise = Browser::Promise.new
|
48
|
+
|
46
49
|
elem.on :click do |event|
|
47
|
-
|
48
|
-
|
49
|
-
}
|
50
|
+
expect(event).to be_a(Browser::Event)
|
51
|
+
promise.resolve
|
50
52
|
end
|
51
53
|
|
52
54
|
elem.trigger :click
|
55
|
+
|
56
|
+
promise.for_rspec
|
53
57
|
end
|
54
58
|
|
55
|
-
|
59
|
+
it "passes additional arguments to the handler" do
|
56
60
|
elem = $document["event-spec"]
|
57
61
|
|
62
|
+
promise = Browser::Promise.new
|
63
|
+
|
58
64
|
elem.on :bazinga do |event, foo, bar, baz|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
}
|
65
|
+
expect(foo).to eq(1)
|
66
|
+
expect(bar).to eq(2)
|
67
|
+
expect(baz).to eq(3)
|
68
|
+
promise.resolve
|
64
69
|
end
|
65
70
|
|
66
71
|
elem.trigger :bazinga, 1, 2, 3
|
72
|
+
|
73
|
+
promise.for_rspec
|
67
74
|
end
|
68
75
|
|
69
|
-
|
76
|
+
it "works with delegated events" do
|
70
77
|
elem = $document["event-spec"]
|
71
78
|
|
79
|
+
promise = Browser::Promise.new
|
80
|
+
|
72
81
|
elem.on :bazinga, 'span.nami' do
|
73
|
-
|
74
|
-
|
75
|
-
}
|
82
|
+
expect(true).to be_truthy
|
83
|
+
promise.resolve
|
76
84
|
end
|
77
85
|
|
78
86
|
elem.add_child DOM { span.nami }
|
@@ -80,6 +88,27 @@ describe Browser::DOM::Event do
|
|
80
88
|
after 0.01 do
|
81
89
|
elem.first_element_child.trigger :bazinga
|
82
90
|
end
|
91
|
+
|
92
|
+
promise.for_rspec
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "#one" do
|
97
|
+
it "fires once, passes arguments, works with custom events" do
|
98
|
+
count = 0
|
99
|
+
elem = $document["event-spec"]
|
100
|
+
|
101
|
+
elem.one :testone do |event, a, b, c|
|
102
|
+
count += a + b*c
|
103
|
+
end
|
104
|
+
|
105
|
+
expect(count).to eq(0)
|
106
|
+
elem.trigger :testone, 1, 2, 3
|
107
|
+
expect(count).to eq(7)
|
108
|
+
elem.trigger :testone, 2, 3, 4
|
109
|
+
expect(count).to eq(7)
|
110
|
+
elem.trigger :testone, 3, 4, 5
|
111
|
+
expect(count).to eq(7)
|
83
112
|
end
|
84
113
|
end
|
85
114
|
|
@@ -97,11 +126,11 @@ describe Browser::DOM::Event do
|
|
97
126
|
end
|
98
127
|
|
99
128
|
elem.trigger :click
|
100
|
-
count.
|
129
|
+
expect(count).to eq(2)
|
101
130
|
|
102
131
|
elem.off :click
|
103
132
|
elem.trigger :click
|
104
|
-
count.
|
133
|
+
expect(count).to eq(2)
|
105
134
|
end
|
106
135
|
|
107
136
|
it "removes only the passed handler" do
|
@@ -117,11 +146,11 @@ describe Browser::DOM::Event do
|
|
117
146
|
end
|
118
147
|
|
119
148
|
elem.trigger :click
|
120
|
-
count.
|
149
|
+
expect(count).to eq(2)
|
121
150
|
|
122
151
|
cb.off
|
123
152
|
elem.trigger :click
|
124
|
-
count.
|
153
|
+
expect(count).to eq(3)
|
125
154
|
end
|
126
155
|
end
|
127
156
|
end
|
data/spec/history_spec.rb
CHANGED
@@ -4,45 +4,58 @@ require 'browser/history'
|
|
4
4
|
describe Browser::History do
|
5
5
|
describe '#current' do
|
6
6
|
it 'should return the current location' do
|
7
|
-
$window.history.current.
|
7
|
+
expect($window.history.current).to eq('/')
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
11
|
describe '#push' do
|
12
12
|
it 'should change location' do
|
13
|
-
$window.history.current.
|
13
|
+
expect($window.history.current).to eq('/')
|
14
14
|
$window.history.push('/lol')
|
15
|
-
$window.history.current.
|
15
|
+
expect($window.history.current).to eq('/lol')
|
16
16
|
$window.history.push('/')
|
17
|
-
$window.history.current.
|
17
|
+
expect($window.history.current).to eq('/')
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
describe '#back' do
|
22
|
-
|
23
|
-
$window.history.current.
|
22
|
+
it 'should go back once' do
|
23
|
+
expect($window.history.current).to eq('/')
|
24
24
|
$window.history.push('/wut')
|
25
|
-
$window.history.current.
|
25
|
+
expect($window.history.current).to eq('/wut')
|
26
26
|
|
27
|
-
|
28
|
-
run_async {
|
29
|
-
$window.history.current.should == '/'
|
30
|
-
}
|
27
|
+
promise = Browser::Promise.new
|
31
28
|
|
32
|
-
|
29
|
+
$window.one 'pop:state' do |e|
|
30
|
+
expect($window.history.current).to eq('/')
|
31
|
+
promise.resolve
|
33
32
|
end
|
34
33
|
|
35
34
|
$window.history.back
|
35
|
+
promise.for_rspec
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
describe '#state' do
|
40
40
|
it 'gets the right state' do
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
# XX: The previous test creates a race condition with this one.
|
42
|
+
# Adding a delay fixes it.
|
43
|
+
promise = Browser::Promise.new
|
44
|
+
|
45
|
+
after 0.05 do
|
46
|
+
$window.history.push('/wut', 42)
|
47
|
+
$window.history.state.should eq(42)
|
48
|
+
$window.history.push('/omg', 23)
|
49
|
+
$window.history.state.should eq(23)
|
50
|
+
|
51
|
+
$window.one 'pop:state' do |e|
|
52
|
+
expect(true).to eq(true)
|
53
|
+
promise.resolve
|
54
|
+
end
|
55
|
+
|
56
|
+
$window.history.back(2)
|
57
|
+
end
|
58
|
+
promise.for_rspec
|
46
59
|
end
|
47
|
-
end
|
48
|
-
end
|
60
|
+
end if Browser.supports? 'History.state'
|
61
|
+
end if Browser::History.supported?
|
data/spec/http_spec.rb
CHANGED
@@ -1,87 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
1
2
|
require 'browser/http'
|
2
3
|
|
3
4
|
describe Browser::HTTP do
|
4
|
-
let
|
5
|
-
|
6
|
-
end
|
5
|
+
let(:path) { '/http' }
|
6
|
+
let(:path_file) { '/http-file' }
|
7
7
|
|
8
8
|
describe '.get' do
|
9
|
-
|
9
|
+
it 'fetches a path' do
|
10
10
|
Browser::HTTP.get(path).then {|res|
|
11
|
-
|
12
|
-
res.text.should == 'lol'
|
13
|
-
}
|
11
|
+
expect(res.text).to eq('lol')
|
14
12
|
}.rescue {
|
15
|
-
|
16
|
-
fail
|
17
|
-
}
|
13
|
+
fail
|
18
14
|
}
|
19
15
|
end
|
20
16
|
end
|
21
17
|
|
22
18
|
describe '.get!' do
|
23
19
|
it 'fetches a path' do
|
24
|
-
Browser::HTTP.get!(path).text.
|
20
|
+
expect(Browser::HTTP.get!(path).text).to eq('lol')
|
25
21
|
end
|
26
22
|
end
|
27
23
|
|
28
24
|
describe '.post' do
|
29
|
-
|
25
|
+
it 'sends parameters properly' do
|
30
26
|
Browser::HTTP.post(path, lol: 'wut').then {|res|
|
31
|
-
|
32
|
-
res.text.should == 'ok'
|
33
|
-
}
|
27
|
+
expect(res.text).to eq('ok')
|
34
28
|
}.rescue {
|
35
|
-
|
36
|
-
fail
|
37
|
-
}
|
29
|
+
fail
|
38
30
|
}
|
39
31
|
end
|
40
32
|
end
|
41
33
|
|
42
34
|
describe '.post!' do
|
43
35
|
it 'sends parameters properly' do
|
44
|
-
Browser::HTTP.post!(path, lol: 'wut').text.
|
36
|
+
expect(Browser::HTTP.post!(path, lol: 'wut').text).to eq('ok')
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'sends files properly' do
|
40
|
+
file = Browser::File.create(["content"], "yay.txt", type: "text/plain")
|
41
|
+
expect(Browser::HTTP.post!(path_file, lol: 'wut', file: file).text).to eq('ok')
|
45
42
|
end
|
46
43
|
end
|
47
44
|
|
48
45
|
describe '.put' do
|
49
|
-
|
46
|
+
it 'sends parameters properly' do
|
50
47
|
Browser::HTTP.put(path, lol: 'wut').then {|res|
|
51
|
-
|
52
|
-
res.text.should == 'ok'
|
53
|
-
}
|
48
|
+
expect(res.text).to eq('ok')
|
54
49
|
}.rescue {
|
55
|
-
|
56
|
-
fail
|
57
|
-
}
|
50
|
+
fail
|
58
51
|
}
|
59
52
|
end
|
60
53
|
end
|
61
54
|
|
62
55
|
describe '.put!' do
|
63
56
|
it 'sends parameters properly' do
|
64
|
-
Browser::HTTP.put!(path, lol: 'wut').text.
|
57
|
+
expect(Browser::HTTP.put!(path, lol: 'wut').text).to eq('ok')
|
65
58
|
end
|
66
59
|
end
|
67
60
|
|
68
61
|
describe '.delete' do
|
69
|
-
|
62
|
+
it 'fetches a path' do
|
70
63
|
Browser::HTTP.delete(path).then {|res|
|
71
|
-
|
72
|
-
res.text.should == 'lol'
|
73
|
-
}
|
64
|
+
expect(res.text).to eq('lol')
|
74
65
|
}.rescue {
|
75
|
-
|
76
|
-
fail
|
77
|
-
}
|
66
|
+
fail
|
78
67
|
}
|
79
68
|
end
|
80
69
|
end
|
81
70
|
|
82
71
|
describe '.delete!' do
|
83
72
|
it 'fetches a path' do
|
84
|
-
Browser::HTTP.delete!(path).text.
|
73
|
+
expect(Browser::HTTP.delete!(path).text).to eq('lol')
|
85
74
|
end
|
86
75
|
end
|
87
|
-
end
|
76
|
+
end if Browser::HTTP.supported?
|
data/spec/immediate_spec.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'browser/immediate'
|
3
3
|
|
4
|
-
describe
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
describe Proc do
|
5
|
+
describe '#defer' do
|
6
|
+
it 'defers the parameters' do
|
7
|
+
promise = Browser::Promise.new
|
8
|
+
proc {|a|
|
9
|
+
expect(a).to eq(42)
|
10
|
+
promise.resolve
|
11
|
+
}.defer(42)
|
12
|
+
promise.for_rspec
|
13
|
+
end
|
11
14
|
end
|
12
15
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'browser/interval'
|
3
|
+
|
4
|
+
describe Browser::Window do
|
5
|
+
describe '#every' do
|
6
|
+
it 'calls the block multiple times' do
|
7
|
+
x = 0
|
8
|
+
|
9
|
+
promise = Browser::Promise.new
|
10
|
+
$window.every 0.3 do
|
11
|
+
x += 1
|
12
|
+
|
13
|
+
if x == 3
|
14
|
+
expect(true).to be_truthy
|
15
|
+
promise.resolve
|
16
|
+
end
|
17
|
+
end
|
18
|
+
promise.for_rspec
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe Kernel do
|
24
|
+
describe '#every' do
|
25
|
+
it 'calls the block multiple times' do
|
26
|
+
x = 0
|
27
|
+
|
28
|
+
promise = Browser::Promise.new
|
29
|
+
every 0.3 do
|
30
|
+
x += 1
|
31
|
+
|
32
|
+
if x == 3
|
33
|
+
expect(true).to be_truthy
|
34
|
+
promise.resolve
|
35
|
+
end
|
36
|
+
end
|
37
|
+
promise.for_rspec
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe Proc do
|
43
|
+
describe '#every' do
|
44
|
+
it 'calls the block multiple times' do
|
45
|
+
x = 0
|
46
|
+
|
47
|
+
promise = Browser::Promise.new
|
48
|
+
-> {
|
49
|
+
x += 1
|
50
|
+
|
51
|
+
if x == 3
|
52
|
+
expect(true).to be_truthy
|
53
|
+
promise.resolve
|
54
|
+
end
|
55
|
+
}.every 0.3
|
56
|
+
promise.for_rspec
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Browser::NativeCachedWrapper do
|
4
|
+
it 'deduplicates DOM objects' do
|
5
|
+
expect($document.at_css("body").hash).to eq($document.body.hash)
|
6
|
+
expect($document.body.hash).not_to eq($document.body.dup.hash) # Should dup/clone have different semantics?
|
7
|
+
expect($document.body.hash).not_to eq($document.head.hash)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'accurately intercepts the last new call' do
|
11
|
+
class Demo
|
12
|
+
include Browser::NativeCachedWrapper
|
13
|
+
|
14
|
+
def self.new(arg1, arg2)
|
15
|
+
super(`{arg1: #{arg1}, arg2: #{arg2}}`)
|
16
|
+
end
|
17
|
+
|
18
|
+
def data
|
19
|
+
[:data, `#@native.arg1`, `#@native.arg2`]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class SuperDemo < Demo
|
24
|
+
def self.new(arg1, arg2, arg3)
|
25
|
+
super("superdemo", "#{arg1} - #{arg2} - #{arg3}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
expect(Demo.new("a", "b").data).to eq([:data, "a", "b"])
|
30
|
+
expect(SuperDemo.new("1", "2", "3").data).to eq([:data, "superdemo", "1 - 2 - 3"])
|
31
|
+
end
|
32
|
+
|
33
|
+
html <<-HTML
|
34
|
+
<iframe id='ifr' src='about:blank' sandbox=''></iframe>
|
35
|
+
HTML
|
36
|
+
|
37
|
+
it 'supports restricted objects' do
|
38
|
+
# Window won't be restricted
|
39
|
+
expect($window.restricted?).to eq(false)
|
40
|
+
# Iframe itself won't be restricted
|
41
|
+
expect($document['ifr'].restricted?).to eq(false)
|
42
|
+
# But its content_window will be (due to CORS)
|
43
|
+
expect($document['ifr'].content_window.restricted?).to eq(true)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
data/spec/runner.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require 'webdrivers'
|
3
|
+
require 'selenium/webdriver'
|
4
|
+
require 'rest_client'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
print 'Loading...'
|
8
|
+
|
9
|
+
browser, options = case ENV['BROWSER']
|
10
|
+
when "chrome"
|
11
|
+
opts = Selenium::WebDriver::Chrome::Options.new(args: ['--headless', '--no-sandbox'])
|
12
|
+
[:chrome, opts]
|
13
|
+
when "gecko"
|
14
|
+
opts = Selenium::WebDriver::Firefox::Options.new(args: ['--headless'])
|
15
|
+
[:firefox, opts]
|
16
|
+
when "safari"
|
17
|
+
opts = Selenium::WebDriver::Safari::Options.new()
|
18
|
+
[:safari, opts]
|
19
|
+
when "edge"
|
20
|
+
opts = Selenium::WebDriver::Edge::Options.new(args: ['--headless'])
|
21
|
+
[:edge, opts]
|
22
|
+
else
|
23
|
+
raise "Wrong web browser provided in BROWSER. Acceptable values: chrome, gecko, safari, edge"
|
24
|
+
end
|
25
|
+
|
26
|
+
browser = Selenium::WebDriver.for(browser, capabilities: options)
|
27
|
+
browser.navigate.to('http://localhost:9292')
|
28
|
+
|
29
|
+
# if we don't quit the browser it will stall
|
30
|
+
at_exit {
|
31
|
+
browser.quit
|
32
|
+
}
|
33
|
+
|
34
|
+
puts "Browser: " + browser.execute_script("return window.navigator.userAgent")
|
35
|
+
|
36
|
+
# the title is a good way to know if anything went wrong while fetching the
|
37
|
+
# page
|
38
|
+
Selenium::WebDriver::Wait.new(timeout: 30, interval: 5).until {
|
39
|
+
not browser.title.strip.empty?
|
40
|
+
}
|
41
|
+
|
42
|
+
unless browser.title =~ /Opal Browser|RSpec results/
|
43
|
+
puts "\rThe page failed loading."
|
44
|
+
exit 1
|
45
|
+
end
|
46
|
+
|
47
|
+
# wait until the specs are running or there has been an error in the loading of
|
48
|
+
# the specs
|
49
|
+
begin
|
50
|
+
Selenium::WebDriver::Wait.new(timeout: 30, interval: 5).until {
|
51
|
+
(browser['rspec-error'] rescue false) ||
|
52
|
+
(browser[class: 'rspec-report'] rescue false)
|
53
|
+
}
|
54
|
+
|
55
|
+
if element = browser['rspec-error'] rescue nil
|
56
|
+
puts "\r#{element.text}"
|
57
|
+
exit 1
|
58
|
+
end
|
59
|
+
rescue Selenium::WebDriver::Error::TimeoutError; end
|
60
|
+
|
61
|
+
print "\rRunning specs..."
|
62
|
+
|
63
|
+
begin
|
64
|
+
# wait until the specs have finished, thus changing the content of #totals
|
65
|
+
Selenium::WebDriver::Wait.new(timeout: 3000, interval: 30).until {
|
66
|
+
print '.'
|
67
|
+
|
68
|
+
not browser['totals'].text.strip.empty?
|
69
|
+
}
|
70
|
+
|
71
|
+
totals = browser['totals'].text
|
72
|
+
duration = browser[css: '#duration strong'].text
|
73
|
+
|
74
|
+
print "\r#{totals} in #{duration}"
|
75
|
+
|
76
|
+
# no failures, happy times
|
77
|
+
if totals =~ / 0 failures/
|
78
|
+
exit 0
|
79
|
+
end
|
80
|
+
rescue Selenium::WebDriver::Error::TimeoutError
|
81
|
+
if element = browser['rspec-error'] rescue nil
|
82
|
+
print "\r#{element.text}"
|
83
|
+
else
|
84
|
+
print "\rThe specs have timed out."
|
85
|
+
end
|
86
|
+
ensure
|
87
|
+
# take a screenshot and upload it to imgur
|
88
|
+
begin
|
89
|
+
upload = lambda do |filepath|
|
90
|
+
response = RestClient.post('https://api.imgur.com/3/upload',
|
91
|
+
{ image: File.open(filepath) },
|
92
|
+
{ 'Authorization' => 'Client-ID 1979876fe2a097e' })
|
93
|
+
|
94
|
+
JSON.parse(response.to_str)['data']['link']
|
95
|
+
end
|
96
|
+
|
97
|
+
w, h = browser.execute_script("return [document.body.clientWidth, document.body.clientHeight];")
|
98
|
+
browser.manage.window.resize_to(w, h)
|
99
|
+
browser.save_screenshot('screenshot.png')
|
100
|
+
screenshot_url = upload.('screenshot.png')
|
101
|
+
puts " (#{screenshot_url})"
|
102
|
+
rescue Exception
|
103
|
+
puts
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
exit 1
|
data/spec/socket_spec.rb
CHANGED
@@ -1,43 +1,47 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'browser/location'
|
2
3
|
require 'browser/socket'
|
3
4
|
|
4
5
|
describe Browser::Socket do
|
5
6
|
# FIXME: find out why it doesn't work inline
|
6
7
|
ws = "ws://#{$window.location.host}/socket"
|
7
8
|
|
8
|
-
|
9
|
+
it 'creates a socket' do
|
10
|
+
promise = Browser::Promise.new
|
9
11
|
Browser::Socket.new ws do |s|
|
10
12
|
s.on :open do |e|
|
11
|
-
|
12
|
-
|
13
|
-
}
|
13
|
+
expect(e.target).to be_a(Browser::Socket)
|
14
|
+
promise.resolve
|
14
15
|
end
|
15
16
|
end
|
17
|
+
promise.for_rspec
|
16
18
|
end
|
17
19
|
|
18
|
-
|
20
|
+
it 'receives messages' do
|
21
|
+
promise = Browser::Promise.new
|
19
22
|
Browser::Socket.new ws do |s|
|
20
23
|
s.on :message do |e|
|
21
|
-
|
22
|
-
|
23
|
-
}
|
24
|
+
expect(e.data).to eq('lol')
|
25
|
+
promise.resolve
|
24
26
|
end
|
25
27
|
end
|
28
|
+
promise.for_rspec
|
26
29
|
end
|
27
30
|
|
28
|
-
|
31
|
+
it 'sends messages' do
|
32
|
+
promise = Browser::Promise.new
|
29
33
|
Browser::Socket.new ws do |s|
|
30
34
|
s.on :message do |e|
|
35
|
+
e.off
|
36
|
+
|
31
37
|
s.print 'omg'
|
32
38
|
|
33
39
|
s.on :message do |e|
|
34
|
-
|
35
|
-
|
36
|
-
}
|
40
|
+
expect(e.data).to eq('omg')
|
41
|
+
promise.resolve
|
37
42
|
end
|
38
|
-
|
39
|
-
e.off
|
40
43
|
end
|
41
44
|
end
|
45
|
+
promise.for_rspec
|
42
46
|
end
|
43
47
|
end if Browser::Socket.supported?
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
<% if ENV['OPAL_BROWSER_PROMISE'] == 'v2' %>
|
2
|
+
require 'promise'
|
3
|
+
require 'promise/v2'
|
4
|
+
<% else %>
|
5
|
+
require 'promise'
|
6
|
+
|
7
|
+
# Polyfill #to_v1, which isn't present before Opal v1.3.0
|
8
|
+
class Promise
|
9
|
+
unless Promise.method_defined? :to_v1
|
10
|
+
alias to_v1 itself
|
11
|
+
end
|
12
|
+
end
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
require 'browser/utils'
|
16
|
+
|
17
|
+
module Browser
|
18
|
+
class Promise
|
19
|
+
# Return a correct promise for opal-rspec, which for now is
|
20
|
+
# PromiseV1 until opal-rspec is ported.
|
21
|
+
def for_rspec
|
22
|
+
to_v1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|