capybara 3.35.3 → 3.37.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/History.md +57 -1
- data/README.md +5 -1
- data/lib/capybara/config.rb +16 -4
- data/lib/capybara/driver/base.rb +4 -0
- data/lib/capybara/driver/node.rb +5 -1
- data/lib/capybara/dsl.rb +4 -10
- data/lib/capybara/helpers.rb +3 -12
- data/lib/capybara/minitest/spec.rb +2 -2
- data/lib/capybara/node/actions.rb +10 -5
- data/lib/capybara/node/document.rb +2 -2
- data/lib/capybara/node/element.rb +13 -2
- data/lib/capybara/node/finders.rb +9 -2
- data/lib/capybara/node/simple.rb +5 -1
- data/lib/capybara/queries/active_element_query.rb +18 -0
- data/lib/capybara/queries/ancestor_query.rb +2 -1
- data/lib/capybara/queries/current_path_query.rb +1 -1
- data/lib/capybara/queries/selector_query.rb +34 -8
- data/lib/capybara/queries/sibling_query.rb +2 -1
- data/lib/capybara/rack_test/browser.rb +56 -7
- data/lib/capybara/rack_test/driver.rb +4 -4
- data/lib/capybara/rack_test/node.rb +10 -7
- data/lib/capybara/registration_container.rb +0 -3
- data/lib/capybara/registrations/drivers.rb +3 -3
- data/lib/capybara/rspec/matcher_proxies.rb +3 -3
- data/lib/capybara/rspec/matchers/have_selector.rb +5 -5
- data/lib/capybara/rspec/matchers.rb +14 -14
- data/lib/capybara/selector/builders/css_builder.rb +1 -1
- data/lib/capybara/selector/builders/xpath_builder.rb +1 -1
- data/lib/capybara/selector/css.rb +1 -1
- data/lib/capybara/selector/definition/button.rb +9 -4
- data/lib/capybara/selector/definition/checkbox.rb +1 -1
- data/lib/capybara/selector/definition/file_field.rb +1 -1
- data/lib/capybara/selector/definition/fillable_field.rb +1 -1
- data/lib/capybara/selector/definition/radio_button.rb +1 -1
- data/lib/capybara/selector/definition.rb +3 -1
- data/lib/capybara/selector/filter_set.rb +4 -6
- data/lib/capybara/selector/selector.rb +5 -1
- data/lib/capybara/selector.rb +1 -0
- data/lib/capybara/selenium/driver.rb +25 -11
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +1 -1
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +1 -1
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +1 -1
- data/lib/capybara/selenium/node.rb +22 -8
- data/lib/capybara/selenium/nodes/chrome_node.rb +1 -1
- data/lib/capybara/selenium/nodes/edge_node.rb +1 -1
- data/lib/capybara/selenium/nodes/firefox_node.rb +1 -1
- data/lib/capybara/selenium/nodes/safari_node.rb +2 -2
- data/lib/capybara/server/animation_disabler.rb +35 -17
- data/lib/capybara/session/config.rb +1 -1
- data/lib/capybara/session.rb +20 -23
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +9 -13
- data/lib/capybara/spec/session/assert_text_spec.rb +17 -17
- data/lib/capybara/spec/session/check_spec.rb +9 -0
- data/lib/capybara/spec/session/choose_spec.rb +6 -0
- data/lib/capybara/spec/session/find_spec.rb +6 -0
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +4 -0
- data/lib/capybara/spec/session/has_button_spec.rb +24 -0
- data/lib/capybara/spec/session/has_current_path_spec.rb +2 -2
- data/lib/capybara/spec/session/has_field_spec.rb +25 -1
- data/lib/capybara/spec/session/has_link_spec.rb +30 -0
- data/lib/capybara/spec/session/has_select_spec.rb +4 -4
- data/lib/capybara/spec/session/has_selector_spec.rb +15 -0
- data/lib/capybara/spec/session/has_text_spec.rb +2 -6
- data/lib/capybara/spec/session/node_spec.rb +43 -1
- data/lib/capybara/spec/session/scroll_spec.rb +4 -4
- data/lib/capybara/spec/session/visit_spec.rb +20 -0
- data/lib/capybara/spec/session/window/window_spec.rb +1 -1
- data/lib/capybara/spec/spec_helper.rb +4 -3
- data/lib/capybara/spec/test_app.rb +66 -8
- data/lib/capybara/spec/views/animated.erb +1 -1
- data/lib/capybara/spec/views/form.erb +11 -3
- data/lib/capybara/spec/views/frame_child.erb +1 -1
- data/lib/capybara/spec/views/frame_one.erb +1 -1
- data/lib/capybara/spec/views/frame_parent.erb +1 -1
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +2 -1
- data/lib/capybara/spec/views/layout.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +1 -1
- data/lib/capybara/spec/views/offset.erb +2 -1
- data/lib/capybara/spec/views/path.erb +2 -2
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/react.erb +2 -2
- data/lib/capybara/spec/views/scroll.erb +2 -1
- data/lib/capybara/spec/views/spatial.erb +1 -1
- data/lib/capybara/spec/views/with_animation.erb +2 -3
- data/lib/capybara/spec/views/with_base_tag.erb +2 -2
- data/lib/capybara/spec/views/with_dragula.erb +2 -2
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
- data/lib/capybara/spec/views/with_hover.erb +2 -2
- data/lib/capybara/spec/views/with_html.erb +1 -1
- data/lib/capybara/spec/views/with_jquery_animation.erb +1 -1
- data/lib/capybara/spec/views/with_js.erb +2 -3
- data/lib/capybara/spec/views/with_jstree.erb +1 -1
- data/lib/capybara/spec/views/with_namespace.erb +1 -0
- data/lib/capybara/spec/views/with_shadow.erb +31 -0
- data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +2 -2
- data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
- data/lib/capybara/spec/views/with_windows.erb +1 -1
- data/lib/capybara/spec/views/within_frames.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +1 -1
- data/lib/capybara.rb +19 -22
- data/spec/basic_node_spec.rb +16 -3
- data/spec/dsl_spec.rb +3 -3
- data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -2
- data/spec/fixtures/selenium_driver_rspec_success.rb +2 -2
- data/spec/rack_test_spec.rb +20 -10
- data/spec/result_spec.rb +32 -35
- data/spec/rspec/features_spec.rb +3 -3
- data/spec/rspec/scenarios_spec.rb +1 -1
- data/spec/rspec/shared_spec_matchers.rb +2 -2
- data/spec/sauce_spec_chrome.rb +3 -3
- data/spec/selector_spec.rb +2 -2
- data/spec/selenium_spec_chrome.rb +9 -10
- data/spec/selenium_spec_chrome_remote.rb +9 -8
- data/spec/selenium_spec_firefox.rb +8 -3
- data/spec/selenium_spec_firefox_remote.rb +2 -2
- data/spec/selenium_spec_ie.rb +3 -6
- data/spec/selenium_spec_safari.rb +31 -19
- data/spec/server_spec.rb +5 -5
- data/spec/shared_selenium_node.rb +0 -4
- data/spec/shared_selenium_session.rb +20 -10
- data/spec/spec_helper.rb +1 -1
- metadata +37 -14
- data/lib/capybara/spec/views/with_title.erb +0 -5
|
@@ -18,6 +18,24 @@ Capybara::SpecHelper.spec '#has_link?' do
|
|
|
18
18
|
expect(@session).not_to have_link('A link', href: '/nonexistent-href')
|
|
19
19
|
expect(@session).not_to have_link('A link', href: /nonexistent/)
|
|
20
20
|
end
|
|
21
|
+
|
|
22
|
+
it 'should notify if an invalid locator is specified' do
|
|
23
|
+
allow(Capybara::Helpers).to receive(:warn).and_return(nil)
|
|
24
|
+
@session.has_link?(@session)
|
|
25
|
+
expect(Capybara::Helpers).to have_received(:warn).with(/Called from: .+/)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context 'with focused:', requires: [:active_element] do
|
|
29
|
+
it 'should be true if the given link is on the page and has focus' do
|
|
30
|
+
@session.send_keys(:tab)
|
|
31
|
+
|
|
32
|
+
expect(@session).to have_link('labore', focused: true)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'should be false if the given link is on the page and does not have focus' do
|
|
36
|
+
expect(@session).to have_link('labore', focused: false)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
21
39
|
end
|
|
22
40
|
|
|
23
41
|
Capybara::SpecHelper.spec '#has_no_link?' do
|
|
@@ -36,4 +54,16 @@ Capybara::SpecHelper.spec '#has_no_link?' do
|
|
|
36
54
|
expect(@session).to have_no_link('A link', href: '/nonexistent-href')
|
|
37
55
|
expect(@session).to have_no_link('A link', href: %r{/nonexistent-href})
|
|
38
56
|
end
|
|
57
|
+
|
|
58
|
+
context 'with focused:', requires: [:active_element] do
|
|
59
|
+
it 'should be true if the given link is on the page and has focus' do
|
|
60
|
+
expect(@session).to have_no_link('labore', focused: true)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'should be false if the given link is on the page and does not have focus' do
|
|
64
|
+
@session.send_keys(:tab)
|
|
65
|
+
|
|
66
|
+
expect(@session).to have_no_link('labore', focused: false)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
39
69
|
end
|
|
@@ -180,9 +180,9 @@ Capybara::SpecHelper.spec '#has_select?' do
|
|
|
180
180
|
end
|
|
181
181
|
|
|
182
182
|
it 'should support locator-less usage' do
|
|
183
|
-
expect(@session.has_select?(with_options: %w[Norway Sweden])).to
|
|
183
|
+
expect(@session.has_select?(with_options: %w[Norway Sweden])).to be true
|
|
184
184
|
expect(@session).to have_select(with_options: ['London'])
|
|
185
|
-
expect(@session.has_select?(with_selected: %w[Commando Boxerbriefs])).to
|
|
185
|
+
expect(@session.has_select?(with_selected: %w[Commando Boxerbriefs])).to be true
|
|
186
186
|
expect(@session).to have_select(with_selected: ['Briefs'])
|
|
187
187
|
end
|
|
188
188
|
end
|
|
@@ -302,9 +302,9 @@ Capybara::SpecHelper.spec '#has_no_select?' do
|
|
|
302
302
|
end
|
|
303
303
|
|
|
304
304
|
it 'should support locator-less usage' do
|
|
305
|
-
expect(@session.has_no_select?(with_options: %w[Norway Sweden Finland Latvia])).to
|
|
305
|
+
expect(@session.has_no_select?(with_options: %w[Norway Sweden Finland Latvia])).to be true
|
|
306
306
|
expect(@session).to have_no_select(with_options: ['New London'])
|
|
307
|
-
expect(@session.has_no_select?(id: 'form_underwear', with_selected: ['Boxers'])).to
|
|
307
|
+
expect(@session.has_no_select?(id: 'form_underwear', with_selected: ['Boxers'])).to be true
|
|
308
308
|
expect(@session).to have_no_select(id: 'form_underwear', with_selected: %w[Commando Boxers])
|
|
309
309
|
end
|
|
310
310
|
end
|
|
@@ -117,6 +117,21 @@ Capybara::SpecHelper.spec '#has_selector?' do
|
|
|
117
117
|
expect(@session).to have_selector(:id, 'h2one', text: 'Header Class Test One', exact_text: false)
|
|
118
118
|
expect(@session).to have_selector(:id, 'h2one', text: 'Header Class Test', exact_text: false)
|
|
119
119
|
end
|
|
120
|
+
|
|
121
|
+
it 'should warn if text option is a regexp that it is ignoring exact_text' do
|
|
122
|
+
allow(Capybara::Helpers).to receive(:warn)
|
|
123
|
+
expect(@session).to have_selector(:id, 'h2one', text: /Class Test/, exact_text: true)
|
|
124
|
+
expect(Capybara::Helpers).to have_received(:warn).with(/'exact_text' option is not supported/)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
context 'regexp' do
|
|
129
|
+
it 'should only match when it fully matches' do
|
|
130
|
+
expect(@session).to have_selector(:id, 'h2one', exact_text: /Header Class Test One/)
|
|
131
|
+
expect(@session).to have_no_selector(:id, 'h2one', exact_text: /Header Class Test/)
|
|
132
|
+
expect(@session).to have_no_selector(:id, 'h2one', exact_text: /Class Test One/)
|
|
133
|
+
expect(@session).to have_no_selector(:id, 'h2one', exact_text: /Class Test/)
|
|
134
|
+
end
|
|
120
135
|
end
|
|
121
136
|
end
|
|
122
137
|
|
|
@@ -127,11 +127,7 @@ Capybara::SpecHelper.spec '#has_text?' do
|
|
|
127
127
|
def to_hash; { value: 'Other hash' } end
|
|
128
128
|
end.new
|
|
129
129
|
@session.visit('/with_html')
|
|
130
|
-
|
|
131
|
-
expect(@session).to have_text(:visible, with_to_hash, **{})
|
|
132
|
-
else
|
|
133
|
-
expect(@session).to have_text(:visible, with_to_hash, {})
|
|
134
|
-
end
|
|
130
|
+
expect(@session).to have_text(:visible, with_to_hash, **{})
|
|
135
131
|
end
|
|
136
132
|
end
|
|
137
133
|
|
|
@@ -356,7 +352,7 @@ Capybara::SpecHelper.spec '#has_no_text?' do
|
|
|
356
352
|
expect(@session).to have_no_text(/xxxxyzzz/)
|
|
357
353
|
end
|
|
358
354
|
|
|
359
|
-
it 'should be false if the text in the page
|
|
355
|
+
it 'should be false if the text in the page matches given regexp' do
|
|
360
356
|
@session.visit('/with_html')
|
|
361
357
|
expect(@session).not_to have_no_text(/Lorem/)
|
|
362
358
|
end
|
|
@@ -1115,7 +1115,7 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
1115
1115
|
end
|
|
1116
1116
|
|
|
1117
1117
|
describe '#evaluate_script', requires: %i[js es_args] do
|
|
1118
|
-
it 'should evaluate the given script in the context of the element and
|
|
1118
|
+
it 'should evaluate the given script in the context of the element and return whatever it produces' do
|
|
1119
1119
|
@session.visit('/with_js')
|
|
1120
1120
|
el = @session.find(:css, '#with_change_event')
|
|
1121
1121
|
expect(el.evaluate_script('this.value')).to eq('default value')
|
|
@@ -1176,6 +1176,48 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
1176
1176
|
end
|
|
1177
1177
|
end
|
|
1178
1178
|
|
|
1179
|
+
describe '#shadow_root', requires: %i[js] do
|
|
1180
|
+
it 'should get the shadow root' do
|
|
1181
|
+
@session.visit('/with_shadow')
|
|
1182
|
+
expect do
|
|
1183
|
+
shadow_root = @session.find(:css, '#shadow_host').shadow_root
|
|
1184
|
+
expect(shadow_root).not_to be_nil
|
|
1185
|
+
end.not_to raise_error
|
|
1186
|
+
end
|
|
1187
|
+
|
|
1188
|
+
it 'should find elements inside the shadow dom using CSS' do
|
|
1189
|
+
@session.visit('/with_shadow')
|
|
1190
|
+
shadow_root = @session.find(:css, '#shadow_host').shadow_root
|
|
1191
|
+
expect(shadow_root).to have_css('#shadow_content', text: 'some text')
|
|
1192
|
+
end
|
|
1193
|
+
|
|
1194
|
+
it 'should find nested shadow roots' do
|
|
1195
|
+
@session.visit('/with_shadow')
|
|
1196
|
+
shadow_root = @session.find(:css, '#shadow_host').shadow_root
|
|
1197
|
+
nested_shadow_root = shadow_root.find(:css, '#nested_shadow_host').shadow_root
|
|
1198
|
+
expect(nested_shadow_root).to have_css('#nested_shadow_content', text: 'nested text')
|
|
1199
|
+
end
|
|
1200
|
+
|
|
1201
|
+
it 'should click on elements' do
|
|
1202
|
+
@session.visit('/with_shadow')
|
|
1203
|
+
shadow_root = @session.find(:css, '#shadow_host').shadow_root
|
|
1204
|
+
checkbox = shadow_root.find(:css, 'input[type="checkbox"]')
|
|
1205
|
+
expect(checkbox).not_to be_checked
|
|
1206
|
+
checkbox.click
|
|
1207
|
+
expect(checkbox).to be_checked
|
|
1208
|
+
end
|
|
1209
|
+
|
|
1210
|
+
it 'should use convenience methods once moved to a descendant of the shadow root' do
|
|
1211
|
+
@session.visit('/with_shadow')
|
|
1212
|
+
shadow_root = @session.find(:css, '#shadow_host').shadow_root
|
|
1213
|
+
descendant = shadow_root.find(:css, '#controls_wrapper')
|
|
1214
|
+
expect do
|
|
1215
|
+
descendant.check('shadow_checkbox')
|
|
1216
|
+
end.not_to raise_error
|
|
1217
|
+
expect(descendant).to have_checked_field('shadow_checkbox')
|
|
1218
|
+
end
|
|
1219
|
+
end
|
|
1220
|
+
|
|
1179
1221
|
describe '#reload', requires: [:js] do
|
|
1180
1222
|
it 'should reload elements found via ancestor with CSS' do
|
|
1181
1223
|
@session.visit('/with_js')
|
|
@@ -15,7 +15,7 @@ Capybara::SpecHelper.spec '#scroll_to', requires: [:scroll] do
|
|
|
15
15
|
el = @session.find(:css, '#scroll')
|
|
16
16
|
@session.scroll_to(el, align: :bottom)
|
|
17
17
|
el_bottom = el.evaluate_script('this.getBoundingClientRect().bottom')
|
|
18
|
-
viewport_bottom = el.evaluate_script('document.
|
|
18
|
+
viewport_bottom = el.evaluate_script('document.documentElement.clientHeight')
|
|
19
19
|
expect(el_bottom).to be_within(1).of(viewport_bottom)
|
|
20
20
|
end
|
|
21
21
|
|
|
@@ -23,7 +23,7 @@ Capybara::SpecHelper.spec '#scroll_to', requires: [:scroll] do
|
|
|
23
23
|
el = @session.find(:css, '#scroll')
|
|
24
24
|
@session.scroll_to(el, align: :center)
|
|
25
25
|
el_center = el.evaluate_script('(function(rect){return (rect.top + rect.bottom)/2})(this.getBoundingClientRect())')
|
|
26
|
-
viewport_bottom = el.evaluate_script('document.
|
|
26
|
+
viewport_bottom = el.evaluate_script('document.documentElement.clientHeight')
|
|
27
27
|
expect(el_center).to be_within(2).of(viewport_bottom / 2)
|
|
28
28
|
end
|
|
29
29
|
|
|
@@ -35,13 +35,13 @@ Capybara::SpecHelper.spec '#scroll_to', requires: [:scroll] do
|
|
|
35
35
|
|
|
36
36
|
it 'can scroll the window to the vertical bottom' do
|
|
37
37
|
@session.scroll_to :bottom
|
|
38
|
-
max_scroll = @session.evaluate_script('document.
|
|
38
|
+
max_scroll = @session.evaluate_script('document.documentElement.scrollHeight - document.documentElement.clientHeight')
|
|
39
39
|
expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [0, max_scroll]
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
it 'can scroll the window to the vertical center' do
|
|
43
43
|
@session.scroll_to :center
|
|
44
|
-
max_scroll = @session.evaluate_script('document.documentElement.scrollHeight - document.
|
|
44
|
+
max_scroll = @session.evaluate_script('document.documentElement.scrollHeight - document.documentElement.clientHeight')
|
|
45
45
|
expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [0, max_scroll / 2]
|
|
46
46
|
end
|
|
47
47
|
|
|
@@ -201,4 +201,24 @@ Capybara::SpecHelper.spec '#visit' do
|
|
|
201
201
|
@session.visit('/get_cookie')
|
|
202
202
|
expect(@session).to have_content('root cookie')
|
|
203
203
|
end
|
|
204
|
+
|
|
205
|
+
context 'with base element' do
|
|
206
|
+
it 'should use base href with relative links' do
|
|
207
|
+
@session.visit('/base/with_base')
|
|
208
|
+
@session.click_link('Title page')
|
|
209
|
+
expect(@session).to have_current_path('/with_title')
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it 'should use base href with bare queries' do
|
|
213
|
+
@session.visit('/base/with_base')
|
|
214
|
+
@session.click_link('Bare query')
|
|
215
|
+
expect(@session).to have_current_path('/?a=3')
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it 'should not use the base href with a new visit call' do
|
|
219
|
+
@session.visit('/base/with_other_base')
|
|
220
|
+
@session.visit('with_html')
|
|
221
|
+
expect(@session).to have_current_path('/with_html')
|
|
222
|
+
end
|
|
223
|
+
end
|
|
204
224
|
end
|
|
@@ -59,7 +59,7 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
|
|
|
59
59
|
it 'should return false if window is closed' do
|
|
60
60
|
@session.switch_to_window(other_window)
|
|
61
61
|
other_window.close
|
|
62
|
-
expect(other_window.current?).to
|
|
62
|
+
expect(other_window.current?).to be(false)
|
|
63
63
|
end
|
|
64
64
|
end
|
|
65
65
|
|
|
@@ -36,7 +36,7 @@ module Capybara
|
|
|
36
36
|
Capybara.test_id = nil
|
|
37
37
|
Capybara.predicates_wait = true
|
|
38
38
|
Capybara.default_normalize_ws = false
|
|
39
|
-
Capybara.
|
|
39
|
+
Capybara.use_html5_parsing = !ENV['HTML5_PARSING'].nil?
|
|
40
40
|
Capybara.w3c_click_offset = false
|
|
41
41
|
reset_threadsafe
|
|
42
42
|
end
|
|
@@ -117,8 +117,9 @@ module Capybara
|
|
|
117
117
|
|
|
118
118
|
def extract_results(session)
|
|
119
119
|
expect(session).to have_xpath("//pre[@id='results']")
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
perms = [(::Sinatra::IndifferentHash if defined? ::Sinatra::IndifferentHash)].compact
|
|
121
|
+
results = Capybara::HTML(session.body).xpath("//pre[@id='results']").first.inner_html.lstrip
|
|
122
|
+
YAML.safe_load results, permitted_classes: perms
|
|
122
123
|
end
|
|
123
124
|
|
|
124
125
|
def be_an_invalid_element_error(session)
|
|
@@ -53,8 +53,8 @@ class TestApp < Sinatra::Base
|
|
|
53
53
|
|
|
54
54
|
get '/referer_base' do
|
|
55
55
|
'<a href="/get_referer">direct link</a>' \
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
'<a href="/redirect_to_get_referer">link via redirect</a>' \
|
|
57
|
+
'<form action="/get_referer" method="get"><input type="submit"></form>'
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
get '/redirect_to_get_referer' do
|
|
@@ -163,21 +163,79 @@ class TestApp < Sinatra::Base
|
|
|
163
163
|
|
|
164
164
|
get '/with_title' do
|
|
165
165
|
<<-HTML
|
|
166
|
-
|
|
167
|
-
<
|
|
168
|
-
<
|
|
169
|
-
|
|
166
|
+
<!DOCTYPE html>
|
|
167
|
+
<html lang="en">
|
|
168
|
+
<head>
|
|
169
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
|
|
170
|
+
<title>#{params[:title] || 'Test Title'}</title>
|
|
171
|
+
</head>
|
|
172
|
+
|
|
173
|
+
<body>
|
|
174
|
+
<svg><title>abcdefg</title></svg>
|
|
175
|
+
</body>
|
|
176
|
+
</html>
|
|
177
|
+
HTML
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
get '/base/with_base' do
|
|
181
|
+
<<-HTML
|
|
182
|
+
<!DOCTYPE html>
|
|
183
|
+
<html>
|
|
184
|
+
<head>
|
|
185
|
+
<base href="/">
|
|
186
|
+
<title>Origin</title>
|
|
187
|
+
</head>
|
|
188
|
+
<body>
|
|
189
|
+
<a href="with_title">Title page</a>
|
|
190
|
+
<a href="?a=3">Bare query</a>
|
|
191
|
+
</body>
|
|
192
|
+
</html>
|
|
193
|
+
HTML
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
get '/base/with_other_base' do
|
|
197
|
+
<<-HTML
|
|
198
|
+
<!DOCTYPE html>
|
|
199
|
+
<html>
|
|
200
|
+
<head>
|
|
201
|
+
<base href="/base/">
|
|
202
|
+
<title>Origin</title>
|
|
203
|
+
</head>
|
|
204
|
+
<body>
|
|
205
|
+
<a href="with_title">Title page</a>
|
|
206
|
+
<a href="?a=3">Bare query</a>
|
|
207
|
+
</body>
|
|
208
|
+
</html>
|
|
209
|
+
HTML
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
get '/csp' do
|
|
213
|
+
response.headers['Content-Security-Policy'] = "default-src 'none'; connect-src 'self'; base-uri 'none'; font-src 'self'; img-src 'self' data:; object-src 'none'; script-src 'self' 'nonce-jAviMuMisoTisVXjgLoWdA=='; style-src 'self' 'nonce-jAviMuMisoTisVXjgLoWdA=='; form-action 'self';"
|
|
214
|
+
<<-HTML
|
|
215
|
+
<!DOCTYPE html>
|
|
216
|
+
<html lang="en">
|
|
217
|
+
<head>
|
|
218
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
|
|
219
|
+
<title>CSP</title>
|
|
220
|
+
</head>
|
|
221
|
+
|
|
222
|
+
<body>
|
|
223
|
+
<div>CSP</div>
|
|
224
|
+
</body>
|
|
225
|
+
</html>
|
|
170
226
|
HTML
|
|
171
227
|
end
|
|
172
228
|
|
|
173
229
|
get '/download.csv' do
|
|
174
230
|
content_type 'text/csv'
|
|
175
231
|
'This, is, comma, separated' \
|
|
176
|
-
|
|
232
|
+
'Thomas, Walpole, was , here'
|
|
177
233
|
end
|
|
178
234
|
|
|
179
235
|
get '/:view' do |view|
|
|
180
|
-
|
|
236
|
+
view_template = "#{__dir__}/views/#{view}.erb"
|
|
237
|
+
has_layout = File.exist?(view_template) && File.open(view_template) { |f| f.first.downcase.include?('doctype') }
|
|
238
|
+
erb view.to_sym, locals: { referrer: request.referrer }, layout: !has_layout
|
|
181
239
|
end
|
|
182
240
|
|
|
183
241
|
post '/form' do
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
|
|
2
1
|
<h1>Form</h1>
|
|
3
2
|
|
|
3
|
+
<button type="button" tabindex="1">A Button</button>
|
|
4
|
+
|
|
5
|
+
<label>
|
|
6
|
+
An Input
|
|
7
|
+
<input type="text" tabindex="2">
|
|
8
|
+
</label>
|
|
9
|
+
|
|
4
10
|
<form action="/form" method="post" novalidate>
|
|
5
11
|
|
|
6
12
|
<p>
|
|
7
13
|
<label for="form_title">Title</label>
|
|
8
|
-
<select name="form[title]" id="form_title" class="title">
|
|
14
|
+
<select name="form[title]" id="form_title" class="title" tabindex="3">
|
|
9
15
|
<option class="title">Mrs</option>
|
|
10
16
|
<option class="title">Mr</option>
|
|
11
17
|
<option>Miss</option>
|
|
@@ -170,7 +176,7 @@ New line after and before textarea tag
|
|
|
170
176
|
<label for="gender_male">Male</label>
|
|
171
177
|
<input type="radio" name="form[gender]" value="female" id="gender_female" checked="checked"/>
|
|
172
178
|
<label for="gender_female">Female</label>
|
|
173
|
-
<input type="radio" name="form[gender]" value="both" id="gender_both"/>
|
|
179
|
+
<input type="radio" name="form[gender]" value="both" id="gender_both" readonly="readonly"/>
|
|
174
180
|
<label for="gender_both">Both</label>
|
|
175
181
|
</p>
|
|
176
182
|
|
|
@@ -223,6 +229,8 @@ New line after and before textarea tag
|
|
|
223
229
|
</label>
|
|
224
230
|
<input type="checkbox" value="maserati" name="form[cars][]" id="form_cars_maserati" disabled="disabled"/>
|
|
225
231
|
<label for="form_cars_maserati">Maserati</label>
|
|
232
|
+
<input type="checkbox" value="lotus" name="form[cars][]" id="form_cars_lotus" style="display: none"/>
|
|
233
|
+
<label for="form_cars_lotus"><a href="#" onclick="return false;">Link here</a>Lotus</label>
|
|
226
234
|
</p>
|
|
227
235
|
|
|
228
236
|
<p>
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
<p class="para" id="first" data-random="abc\def" style="line-height: 25px;">
|
|
21
21
|
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
|
22
|
-
tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple">labore</a>
|
|
22
|
+
tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple" tabindex="1">labore</a>
|
|
23
23
|
et dolore magna aliqua. Ut enim ad minim veniam,
|
|
24
24
|
quis nostrud exercitation <a href="/foo" id="foo" data-test-id="test-foo">ullamco</a> laboris nisi
|
|
25
25
|
ut aliquip ex ea commodo consequat.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
<html
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
|
|
5
5
|
<title>with_js</title>
|
|
@@ -160,4 +160,3 @@
|
|
|
160
160
|
</script>
|
|
161
161
|
</body>
|
|
162
162
|
</html>
|
|
163
|
-
|