capybara-webkit 1.11.1 → 1.12.0
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/.travis.yml +11 -9
- data/Appraisals +8 -4
- data/Gemfile +2 -1
- data/Gemfile.lock +38 -48
- data/README.md +2 -2
- data/capybara-webkit.gemspec +5 -4
- data/gemfiles/2.11.gemfile +11 -0
- data/gemfiles/2.7.gemfile +3 -0
- data/gemfiles/master.gemfile +1 -0
- data/lib/capybara/webkit/browser.rb +4 -4
- data/lib/capybara/webkit/driver.rb +35 -5
- data/lib/capybara/webkit/node.rb +7 -5
- data/lib/capybara/webkit/version.rb +1 -1
- data/lib/capybara_webkit_builder.rb +15 -2
- data/spec/driver_spec.rb +82 -6
- data/spec/fixtures/fake_server.sh +3 -0
- data/spec/server_spec.rb +2 -6
- data/src/Evaluate.cpp +20 -1
- data/src/Execute.cpp +18 -1
- data/src/FrameFocus.cpp +9 -3
- data/src/JavascriptInvocation.cpp +7 -1
- data/src/Node.cpp +3 -0
- data/src/WebPage.cpp +12 -0
- data/src/WebPage.h +3 -0
- data/src/capybara.js +11 -2
- data/src/webkit_server.pro +3 -0
- metadata +16 -28
- data/gemfiles/2.6.gemfile +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: efdcc01079f8576da25de8dff0b6c127170509e5
|
4
|
+
data.tar.gz: 48a04c108401162206fb5961fd2fa44fabd18e2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 234683f1ab1be1f2c7a1ddbdcac6c0389b705a385947e5a86d142b92d6317f6ad4e9fce7d19a55e07f398f3822bd1dcb214d92295301b74c38d72fb6479a6f1c
|
7
|
+
data.tar.gz: 9b6ad7da59e67012182e27044619b229674f961429cf272dc0c96298eac4fee1fd3aed74c15dbaf7c2db44b724b510b0a99542e9b0abbc7b87a8584b9fa66ce8
|
data/.travis.yml
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
sudo: required
|
2
|
+
dist: trusty
|
1
3
|
language: ruby
|
2
4
|
rvm:
|
3
5
|
- 1.9.3
|
@@ -11,7 +13,8 @@ env:
|
|
11
13
|
global:
|
12
14
|
- BUNDLE_JOBS=4
|
13
15
|
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
|
14
|
-
- QMAKE=/usr/lib/x86_64-linux-gnu/
|
16
|
+
- QMAKE=/usr/lib/x86_64-linux-gnu/qt5/bin/qmake
|
17
|
+
- JAVA_OPTS=-Djava.security.egd=file:/dev/urandom
|
15
18
|
addons:
|
16
19
|
apt:
|
17
20
|
sources:
|
@@ -22,19 +25,18 @@ addons:
|
|
22
25
|
matrix:
|
23
26
|
include:
|
24
27
|
- rvm: 1.9.3
|
25
|
-
gemfile: gemfiles/2.
|
26
|
-
env: QMAKE=/usr/lib/x86_64-linux-gnu/
|
28
|
+
gemfile: gemfiles/2.7.gemfile
|
29
|
+
env: QMAKE=/usr/lib/x86_64-linux-gnu/qt4/bin/qmake
|
27
30
|
- rvm: 1.9.3
|
28
|
-
gemfile: gemfiles/2.
|
29
|
-
env: QMAKE=/usr/lib/x86_64-linux-gnu/
|
30
|
-
- rvm: 2.
|
31
|
+
gemfile: gemfiles/2.11.gemfile
|
32
|
+
env: QMAKE=/usr/lib/x86_64-linux-gnu/qt4/bin/qmake
|
33
|
+
- rvm: 2.3.1
|
31
34
|
gemfile: gemfiles/master.gemfile
|
32
|
-
env: QMAKE=/usr/lib/x86_64-linux-gnu/qt5/bin/qmake
|
33
35
|
allow_failures:
|
34
36
|
- gemfile: gemfiles/master.gemfile
|
35
37
|
gemfile:
|
36
|
-
- gemfiles/2.
|
37
|
-
- gemfiles/2.
|
38
|
+
- gemfiles/2.7.gemfile
|
39
|
+
- gemfiles/2.11.gemfile
|
38
40
|
before_install:
|
39
41
|
- gem install bundler
|
40
42
|
install: bundle
|
data/Appraisals
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
-
appraise "2.6" do
|
2
|
-
gem "capybara", "~> 2.6.0"
|
3
|
-
end
|
4
|
-
|
5
1
|
appraise "2.7" do
|
6
2
|
gem "capybara", "~> 2.7.0"
|
3
|
+
gem 'addressable', '< 2.5.0', :platforms=>[:ruby_19, :jruby_19] # 2.5 requires public_suffix which requires ruby 2.0
|
4
|
+
gem 'nokogiri', '< 1.7.0', :platforms=>[:ruby_19, :jruby_19] # 1.7.0 requires ruby 2.1+
|
5
|
+
end
|
6
|
+
|
7
|
+
appraise "2.11" do
|
8
|
+
gem "capybara", "~> 2.11.0"
|
9
|
+
gem 'addressable', '< 2.5.0', :platforms=>[:ruby_19, :jruby_19] # 2.5 requires public_suffix which requires ruby 2.0
|
10
|
+
gem 'nokogiri', '< 1.7.0', :platforms=>[:ruby_19, :jruby_19] # 1.7.0 requires ruby 2.1+
|
7
11
|
end
|
8
12
|
|
9
13
|
appraise "master" do
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,71 +1,61 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
capybara-webkit (1.
|
5
|
-
capybara (>= 2.3.0, < 2.
|
4
|
+
capybara-webkit (1.12.0)
|
5
|
+
capybara (>= 2.3.0, < 2.13.0)
|
6
6
|
json
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
addressable (2.
|
12
|
-
|
11
|
+
addressable (2.5.0)
|
12
|
+
public_suffix (~> 2.0, >= 2.0.2)
|
13
|
+
appraisal (0.4.1)
|
13
14
|
bundler
|
14
15
|
rake
|
15
|
-
capybara (2.
|
16
|
+
capybara (2.11.0)
|
17
|
+
addressable
|
16
18
|
mime-types (>= 1.16)
|
17
19
|
nokogiri (>= 1.3.3)
|
18
20
|
rack (>= 1.0.0)
|
19
21
|
rack-test (>= 0.5.4)
|
20
22
|
xpath (~> 2.0)
|
21
|
-
|
22
|
-
|
23
|
-
diff-lcs (1.2.4)
|
24
|
-
ffi (1.9.8)
|
25
|
-
ffi (1.9.8-java)
|
26
|
-
ffi (1.9.8-x86-mingw32)
|
23
|
+
diff-lcs (1.2.5)
|
24
|
+
ffi (1.9.14-java)
|
27
25
|
json (1.8.3)
|
28
|
-
|
26
|
+
json (1.8.3-java)
|
27
|
+
launchy (2.4.3)
|
29
28
|
addressable (~> 2.3)
|
30
|
-
launchy (2.4.
|
29
|
+
launchy (2.4.3-java)
|
31
30
|
addressable (~> 2.3)
|
32
31
|
spoon (~> 0.0.1)
|
33
|
-
mime-types (2.
|
34
|
-
mini_magick (
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
rack (1.
|
41
|
-
rack-protection (1.3.2)
|
32
|
+
mime-types (2.99.3)
|
33
|
+
mini_magick (4.6.0)
|
34
|
+
mini_portile2 (2.1.0)
|
35
|
+
nokogiri (1.7.0.1)
|
36
|
+
mini_portile2 (~> 2.1.0)
|
37
|
+
public_suffix (2.0.5)
|
38
|
+
rack (1.6.5)
|
39
|
+
rack-protection (1.5.3)
|
42
40
|
rack
|
43
41
|
rack-test (0.6.3)
|
44
42
|
rack (>= 1.0)
|
45
|
-
rake (
|
46
|
-
rspec (2.
|
47
|
-
rspec-core (~> 2.
|
48
|
-
rspec-expectations (~> 2.
|
49
|
-
rspec-mocks (~> 2.
|
50
|
-
rspec-core (2.
|
51
|
-
rspec-expectations (2.
|
43
|
+
rake (11.3.0)
|
44
|
+
rspec (2.99.0)
|
45
|
+
rspec-core (~> 2.99.0)
|
46
|
+
rspec-expectations (~> 2.99.0)
|
47
|
+
rspec-mocks (~> 2.99.0)
|
48
|
+
rspec-core (2.99.2)
|
49
|
+
rspec-expectations (2.99.2)
|
52
50
|
diff-lcs (>= 1.1.3, < 2.0)
|
53
|
-
rspec-mocks (2.
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
websocket (~> 1.0)
|
60
|
-
sinatra (1.3.5)
|
61
|
-
rack (~> 1.4)
|
62
|
-
rack-protection (~> 1.3)
|
63
|
-
tilt (~> 1.3, >= 1.3.3)
|
64
|
-
spoon (0.0.4)
|
51
|
+
rspec-mocks (2.99.4)
|
52
|
+
sinatra (1.4.7)
|
53
|
+
rack (~> 1.5)
|
54
|
+
rack-protection (~> 1.4)
|
55
|
+
tilt (>= 1.3, < 3)
|
56
|
+
spoon (0.0.6)
|
65
57
|
ffi
|
66
|
-
|
67
|
-
tilt (1.3.3)
|
68
|
-
websocket (1.2.1)
|
58
|
+
tilt (2.0.5)
|
69
59
|
xpath (2.0.0)
|
70
60
|
nokogiri (~> 1.3)
|
71
61
|
|
@@ -77,13 +67,13 @@ PLATFORMS
|
|
77
67
|
DEPENDENCIES
|
78
68
|
appraisal (~> 0.4.0)
|
79
69
|
capybara-webkit!
|
70
|
+
json (< 2.0)
|
80
71
|
launchy
|
81
72
|
mime-types (< 3.0)
|
82
73
|
mini_magick
|
83
|
-
rake
|
84
|
-
rspec (~> 2.14
|
85
|
-
selenium-webdriver
|
74
|
+
rake (< 12.0.0)
|
75
|
+
rspec (~> 2.14)
|
86
76
|
sinatra
|
87
77
|
|
88
78
|
BUNDLED WITH
|
89
|
-
1.
|
79
|
+
1.13.6
|
data/README.md
CHANGED
@@ -11,7 +11,7 @@ Qt Dependency and Installation Issues
|
|
11
11
|
|
12
12
|
capybara-webkit depends on a WebKit implementation from Qt, a cross-platform
|
13
13
|
development toolkit. You'll need to download the Qt libraries to build and
|
14
|
-
install the gem. You can find instructions for downloading and installing
|
14
|
+
install the gem. You can find instructions for downloading and installing Qt on
|
15
15
|
the
|
16
16
|
[capybara-webkit wiki](https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit).
|
17
17
|
capybara-webkit requires Qt version 4.8 or greater.
|
@@ -39,7 +39,7 @@ If you don't have any luck there, please post to [Stack Overflow]. Please don't
|
|
39
39
|
open a Github issue for a system-specific compiler issue.
|
40
40
|
|
41
41
|
[Reporting Crashes]: https://github.com/thoughtbot/capybara-webkit/wiki/Reporting-Crashes
|
42
|
-
[
|
42
|
+
[wiki]: https://github.com/thoughtbot/capybara-webkit/wiki
|
43
43
|
[Stack Overflow]: http://stackoverflow.com/questions/tagged/capybara-webkit
|
44
44
|
|
45
45
|
CI
|
data/capybara-webkit.gemspec
CHANGED
@@ -19,16 +19,17 @@ Gem::Specification.new do |s|
|
|
19
19
|
|
20
20
|
s.required_ruby_version = ">= 1.9.0"
|
21
21
|
|
22
|
-
s.
|
22
|
+
s.requirements << "Qt >= 4.8"
|
23
|
+
|
24
|
+
s.add_runtime_dependency("capybara", ">= 2.3.0", "< 2.13.0")
|
23
25
|
s.add_runtime_dependency("json")
|
24
26
|
|
25
|
-
s.add_development_dependency("rspec", "~> 2.14
|
27
|
+
s.add_development_dependency("rspec", "~> 2.14")
|
26
28
|
# Sinatra is used by Capybara's TestApp
|
27
29
|
s.add_development_dependency("sinatra")
|
28
30
|
s.add_development_dependency("mini_magick")
|
29
|
-
s.add_development_dependency("rake")
|
31
|
+
s.add_development_dependency("rake", "< 12.0.0")
|
30
32
|
s.add_development_dependency("appraisal", "~> 0.4.0")
|
31
|
-
s.add_development_dependency("selenium-webdriver")
|
32
33
|
s.add_development_dependency("launchy")
|
33
34
|
end
|
34
35
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "mime-types", "< 3.0", :platforms=>[:ruby_19, :jruby_19]
|
6
|
+
gem "json", "< 2.0", :platforms=>[:ruby_19, :jruby_19]
|
7
|
+
gem "capybara", "~> 2.11.0"
|
8
|
+
gem "addressable", "< 2.5.0", :platforms=>[:ruby_19, :jruby_19]
|
9
|
+
gem "nokogiri", "< 1.7.0", :platforms=>[:ruby_19, :jruby_19]
|
10
|
+
|
11
|
+
gemspec :path=>"../"
|
data/gemfiles/2.7.gemfile
CHANGED
@@ -3,6 +3,9 @@
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
5
|
gem "mime-types", "< 3.0", :platforms=>[:ruby_19, :jruby_19]
|
6
|
+
gem "json", "< 2.0", :platforms=>[:ruby_19, :jruby_19]
|
6
7
|
gem "capybara", "~> 2.7.0"
|
8
|
+
gem "addressable", "< 2.5.0", :platforms=>[:ruby_19, :jruby_19]
|
9
|
+
gem "nokogiri", "< 1.7.0", :platforms=>[:ruby_19, :jruby_19]
|
7
10
|
|
8
11
|
gemspec :path=>"../"
|
data/gemfiles/master.gemfile
CHANGED
@@ -223,13 +223,13 @@ https://github.com/thoughtbot/capybara-webkit/wiki/Reporting-Crashes
|
|
223
223
|
MESSAGE
|
224
224
|
end
|
225
225
|
|
226
|
-
def evaluate_script(script)
|
227
|
-
json = command('Evaluate', script)
|
226
|
+
def evaluate_script(script, *args)
|
227
|
+
json = command('Evaluate', script, args.to_json)
|
228
228
|
JSON.parse("[#{json}]").first
|
229
229
|
end
|
230
230
|
|
231
|
-
def execute_script(script)
|
232
|
-
command('Execute', script)
|
231
|
+
def execute_script(script, *args)
|
232
|
+
command('Execute', script, args.to_json)
|
233
233
|
end
|
234
234
|
|
235
235
|
def render(path, width, height)
|
@@ -76,13 +76,18 @@ module Capybara::Webkit
|
|
76
76
|
@browser.title
|
77
77
|
end
|
78
78
|
|
79
|
-
def execute_script(script)
|
80
|
-
value = @browser.execute_script
|
81
|
-
|
79
|
+
def execute_script(script, *args)
|
80
|
+
value = @browser.execute_script(script, *encode_args(args))
|
81
|
+
|
82
|
+
if value.empty?
|
83
|
+
nil
|
84
|
+
else
|
85
|
+
value
|
86
|
+
end
|
82
87
|
end
|
83
88
|
|
84
|
-
def evaluate_script(script)
|
85
|
-
@browser.evaluate_script
|
89
|
+
def evaluate_script(script, *args)
|
90
|
+
@browser.evaluate_script(script, *encode_args(args))
|
86
91
|
end
|
87
92
|
|
88
93
|
def console_messages
|
@@ -144,6 +149,21 @@ module Capybara::Webkit
|
|
144
149
|
end
|
145
150
|
end
|
146
151
|
|
152
|
+
def switch_to_frame(frame)
|
153
|
+
case frame
|
154
|
+
when :top
|
155
|
+
begin
|
156
|
+
loop { @browser.frame_focus }
|
157
|
+
rescue Capybara::Webkit::InvalidResponseError => e
|
158
|
+
raise unless e.message =~ /Already at parent frame/
|
159
|
+
end
|
160
|
+
when :parent
|
161
|
+
@browser.frame_focus
|
162
|
+
else
|
163
|
+
@browser.frame_focus(frame)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
147
167
|
def within_window(selector)
|
148
168
|
current_window = current_window_handle
|
149
169
|
switch_to_window(selector)
|
@@ -391,5 +411,15 @@ module Capybara::Webkit
|
|
391
411
|
"This option is global and can be configured once" \
|
392
412
|
" (not in a `before` or `setup` block)."
|
393
413
|
end
|
414
|
+
|
415
|
+
def encode_args(args)
|
416
|
+
args.map do |arg|
|
417
|
+
if arg.is_a?(Capybara::Webkit::Node)
|
418
|
+
{ ELEMENT: arg.native }.to_json
|
419
|
+
else
|
420
|
+
arg.to_json
|
421
|
+
end
|
422
|
+
end
|
423
|
+
end
|
394
424
|
end
|
395
425
|
end
|
data/lib/capybara/webkit/node.rb
CHANGED
@@ -114,11 +114,13 @@ module Capybara::Webkit
|
|
114
114
|
end
|
115
115
|
|
116
116
|
def disabled?
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
self
|
121
|
-
|
117
|
+
xpath = "parent::optgroup[@disabled] | " \
|
118
|
+
"ancestor::select[@disabled] | " \
|
119
|
+
"parent::fieldset[@disabled] | " \
|
120
|
+
"ancestor::*[not(self::legend) or " \
|
121
|
+
"preceding-sibling::legend][parent::fieldset[@disabled]]"
|
122
|
+
|
123
|
+
self["disabled"] || !find_xpath(xpath).empty?
|
122
124
|
end
|
123
125
|
|
124
126
|
def path
|
@@ -45,7 +45,7 @@ module CapybaraWebkitBuilder
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def qmake
|
48
|
-
|
48
|
+
make "qmake"
|
49
49
|
end
|
50
50
|
|
51
51
|
def path_to_binary
|
@@ -58,7 +58,7 @@ module CapybaraWebkitBuilder
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def build
|
61
|
-
|
61
|
+
make or return false
|
62
62
|
|
63
63
|
FileUtils.mkdir("bin") unless File.directory?("bin")
|
64
64
|
FileUtils.cp(path_to_binary, "bin", :preserve => true)
|
@@ -89,4 +89,17 @@ module CapybaraWebkitBuilder
|
|
89
89
|
build &&
|
90
90
|
clean
|
91
91
|
end
|
92
|
+
|
93
|
+
def make(target = "")
|
94
|
+
env_hide("CDPATH") { sh("#{make_bin} #{target}") }
|
95
|
+
end
|
96
|
+
|
97
|
+
def env_hide(name)
|
98
|
+
@stored_env ||= {}
|
99
|
+
@stored_env[name] = ENV.delete(name)
|
100
|
+
|
101
|
+
yield
|
102
|
+
ensure
|
103
|
+
ENV[name] = @stored_env[name]
|
104
|
+
end
|
92
105
|
end
|
data/spec/driver_spec.rb
CHANGED
@@ -62,12 +62,25 @@ describe Capybara::Webkit::Driver do
|
|
62
62
|
</head>
|
63
63
|
<body>
|
64
64
|
<script type="text/javascript">
|
65
|
-
document.write("<p id='farewell'>goodbye</p>");
|
65
|
+
document.write("<p id='farewell'>goodbye</p><iframe id='g' src='/iframe2'></iframe>");
|
66
66
|
</script>
|
67
67
|
</body>
|
68
68
|
</html>
|
69
69
|
HTML
|
70
70
|
end
|
71
|
+
|
72
|
+
get '/iframe2' do
|
73
|
+
<<-HTML
|
74
|
+
<html>
|
75
|
+
<head>
|
76
|
+
<title>Frame 2</title>
|
77
|
+
</head>
|
78
|
+
<body>
|
79
|
+
<div>In frame 2</div>
|
80
|
+
</body>
|
81
|
+
</html>
|
82
|
+
HTML
|
83
|
+
end
|
71
84
|
end
|
72
85
|
end
|
73
86
|
|
@@ -95,6 +108,37 @@ describe Capybara::Webkit::Driver do
|
|
95
108
|
end
|
96
109
|
end
|
97
110
|
|
111
|
+
it "switches to frame by element" do
|
112
|
+
frame = driver.find_xpath('//iframe').first
|
113
|
+
element = double(Capybara::Node::Base, base: frame)
|
114
|
+
driver.switch_to_frame(element)
|
115
|
+
driver.find_xpath("//*[contains(., 'goodbye')]").should_not be_empty
|
116
|
+
driver.switch_to_frame(:parent)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "can switch back to the parent frame" do
|
120
|
+
frame = driver.find_xpath('//iframe').first
|
121
|
+
element = double(Capybara::Node::Base, base: frame)
|
122
|
+
driver.switch_to_frame(element)
|
123
|
+
driver.switch_to_frame(:parent)
|
124
|
+
driver.find_xpath("//*[contains(., 'greeting')]").should_not be_empty
|
125
|
+
driver.find_xpath("//*[contains(., 'goodbye')]").should be_empty
|
126
|
+
end
|
127
|
+
|
128
|
+
it "can switch to the top frame" do
|
129
|
+
frame = driver.find_xpath('//iframe').first
|
130
|
+
element = double(Capybara::Node::Base, base: frame)
|
131
|
+
driver.switch_to_frame(element)
|
132
|
+
frame2 = driver.find_xpath('//iframe[@id="g"]').first
|
133
|
+
element2 = double(Capybara::Node::Base, base: frame2)
|
134
|
+
driver.switch_to_frame(element2)
|
135
|
+
driver.find_xpath("//div[contains(., 'In frame 2')]").should_not be_empty
|
136
|
+
driver.switch_to_frame(:top)
|
137
|
+
driver.find_xpath("//*[contains(., 'greeting')]").should_not be_empty
|
138
|
+
driver.find_xpath("//*[contains(., 'goodbye')]").should be_empty
|
139
|
+
driver.find_xpath("//div[contains(., 'In frame 2')]").should be_empty
|
140
|
+
end
|
141
|
+
|
98
142
|
it "raises error for missing frame by index" do
|
99
143
|
expect { driver.within_frame(1) { } }.
|
100
144
|
to raise_error(Capybara::Webkit::InvalidResponseError)
|
@@ -528,6 +572,38 @@ describe Capybara::Webkit::Driver do
|
|
528
572
|
to raise_error(Capybara::Webkit::InvalidResponseError)
|
529
573
|
end
|
530
574
|
|
575
|
+
it "passes arguments to executed Javascript" do
|
576
|
+
driver.execute_script(%<document.getElementById('greeting').innerHTML = arguments[0]>, "My argument")
|
577
|
+
driver.find_xpath("//p[contains(., 'My argument')]").should_not be_empty
|
578
|
+
end
|
579
|
+
|
580
|
+
it "passes multiple arguments to executed Javascript" do
|
581
|
+
driver.execute_script(
|
582
|
+
%<document.getElementById('greeting').innerHTML = arguments[0] + arguments[1] + arguments[2].color>,
|
583
|
+
"random", 4, {color: 'red'})
|
584
|
+
driver.find_xpath("//p[contains(., 'random4red')]").should_not be_empty
|
585
|
+
end
|
586
|
+
|
587
|
+
it "passes page elements to executed Javascript" do
|
588
|
+
greeting = driver.find_xpath("//p[@id='greeting']").first
|
589
|
+
driver.execute_script(%<arguments[0].innerHTML = arguments[1]>, greeting, "new content")
|
590
|
+
driver.find_xpath("//p[@id='greeting'][contains(., 'new content')]").should_not be_empty
|
591
|
+
end
|
592
|
+
|
593
|
+
it "passes arguments to evaaluated Javascript" do
|
594
|
+
driver.evaluate_script(%<arguments[0]>, 3).should eq 3
|
595
|
+
end
|
596
|
+
|
597
|
+
it "passes multiple arguments to evaluated Javascript" do
|
598
|
+
driver.evaluate_script(%<arguments[0] + arguments[1] + arguments[2].num>, 3, 4, {num: 5}).should eq 12
|
599
|
+
end
|
600
|
+
|
601
|
+
it "passes page elements to evaluated Javascript" do
|
602
|
+
greeting = driver.find_xpath("//p[@id='greeting']").first
|
603
|
+
driver.evaluate_script(%<arguments[1].innerHTML = arguments[0]; arguments[2]>, "newer content", greeting, 7).should eq 7
|
604
|
+
driver.find_xpath("//p[@id='greeting'][contains(., 'newer content')]").should_not be_empty
|
605
|
+
end
|
606
|
+
|
531
607
|
it "doesn't raise an error for Javascript that doesn't return anything" do
|
532
608
|
lambda { driver.execute_script(%<(function () { "returns nothing" })()>) }.
|
533
609
|
should_not raise_error
|
@@ -726,7 +802,7 @@ describe Capybara::Webkit::Driver do
|
|
726
802
|
</head>
|
727
803
|
<body>
|
728
804
|
<script type="text/javascript">
|
729
|
-
alert('First alert');
|
805
|
+
alert('First alert');
|
730
806
|
</script>
|
731
807
|
<input type="button" onclick="alert('Second alert')" name="test"/>
|
732
808
|
</body>
|
@@ -764,12 +840,12 @@ describe Capybara::Webkit::Driver do
|
|
764
840
|
end
|
765
841
|
|
766
842
|
it 'finds two alert windows in a row' do
|
767
|
-
driver.accept_modal(:alert, text: 'First alert') do
|
843
|
+
driver.accept_modal(:alert, text: 'First alert') do
|
768
844
|
visit('/double')
|
769
845
|
end
|
770
846
|
|
771
847
|
expect {
|
772
|
-
driver.accept_modal(:alert, text: 'Boom') do
|
848
|
+
driver.accept_modal(:alert, text: 'Boom') do
|
773
849
|
driver.find_xpath("//input").first.click
|
774
850
|
end
|
775
851
|
}.to raise_error Capybara::ModalNotFound, "Unable to find modal dialog with Boom"
|
@@ -2795,7 +2871,7 @@ CACHE MANIFEST
|
|
2795
2871
|
visit("/")
|
2796
2872
|
|
2797
2873
|
expect(stderr).to include("http://example.com/path")
|
2798
|
-
expect(stderr).not_to include(driver.current_url)
|
2874
|
+
expect(stderr).not_to include(driver.current_url)
|
2799
2875
|
end
|
2800
2876
|
|
2801
2877
|
it "can block unknown hosts" do
|
@@ -3140,7 +3216,7 @@ CACHE MANIFEST
|
|
3140
3216
|
end
|
3141
3217
|
end
|
3142
3218
|
|
3143
|
-
it "reports and relaunches on reset" do
|
3219
|
+
it "reports and relaunches on reset", skip_on_windows: true, skip_on_jruby: true do
|
3144
3220
|
connection = fork_connection
|
3145
3221
|
Process.kill "KILL", connection.pid
|
3146
3222
|
expect { driver.reset! }.to raise_error(Capybara::Webkit::CrashError)
|
data/spec/server_spec.rb
CHANGED
@@ -36,7 +36,7 @@ describe Capybara::Webkit::Connection do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it "raises an error if the server is not ready", skip_on_windows: true do
|
39
|
-
server_path = "
|
39
|
+
server_path = File.expand_path(File.join(__FILE__, "..", "fixtures", "fake_server.sh"))
|
40
40
|
stub_const("Capybara::Webkit::Server::SERVER_PATH", server_path)
|
41
41
|
start_timeout = 0.5
|
42
42
|
stub_const(
|
@@ -45,11 +45,7 @@ describe Capybara::Webkit::Connection do
|
|
45
45
|
)
|
46
46
|
|
47
47
|
error_string =
|
48
|
-
|
49
|
-
"#{server_path} failed to start."
|
50
|
-
else
|
51
|
-
"#{server_path} failed to start after #{start_timeout} seconds."
|
52
|
-
end
|
48
|
+
"#{server_path} failed to start after #{start_timeout} seconds."
|
53
49
|
|
54
50
|
expect { start_server }.
|
55
51
|
to raise_error(Capybara::Webkit::ConnectionError, error_string)
|
data/src/Evaluate.cpp
CHANGED
@@ -8,7 +8,26 @@ Evaluate::Evaluate(WebPageManager *manager, QStringList &arguments, QObject *par
|
|
8
8
|
}
|
9
9
|
|
10
10
|
void Evaluate::start() {
|
11
|
-
|
11
|
+
QString script = arguments()[0];
|
12
|
+
QString jsonArgs;
|
13
|
+
if (arguments().length()>1){
|
14
|
+
jsonArgs = arguments()[1];
|
15
|
+
} else {
|
16
|
+
jsonArgs ="[]";
|
17
|
+
}
|
18
|
+
QString eval_script = QString("(function(){"
|
19
|
+
" for(var i=0; i<arguments.length; i++) {"
|
20
|
+
" arguments[i] = JSON.parse(arguments[i]);"
|
21
|
+
" if (arguments[i]['ELEMENT']) {"
|
22
|
+
" arguments[i] = Capybara.getNode(arguments[i]['ELEMENT']);"
|
23
|
+
" };"
|
24
|
+
" };"
|
25
|
+
" return eval(\"%1\");"
|
26
|
+
" }).apply(null, %2)").arg(script.replace("\"","\\\"").remove("\n"), jsonArgs);
|
27
|
+
QObject invocation_stub;
|
28
|
+
invocation_stub.setProperty("allowUnattached", false);
|
29
|
+
page()->currentFrame()->addToJavaScriptWindowObject("CapybaraInvocation", &invocation_stub);
|
30
|
+
QVariant result = page()->currentFrame()->evaluateJavaScript(eval_script);
|
12
31
|
JsonSerializer serializer;
|
13
32
|
finish(true, serializer.serialize(result));
|
14
33
|
}
|
data/src/Execute.cpp
CHANGED
@@ -7,7 +7,24 @@ Execute::Execute(WebPageManager *manager, QStringList &arguments, QObject *paren
|
|
7
7
|
}
|
8
8
|
|
9
9
|
void Execute::start() {
|
10
|
-
QString
|
10
|
+
QString jsonArgs;
|
11
|
+
if (arguments().length()>1){
|
12
|
+
jsonArgs = arguments()[1];
|
13
|
+
} else {
|
14
|
+
jsonArgs ="[]";
|
15
|
+
}
|
16
|
+
QString script = QString("(function(){"
|
17
|
+
" for(var i=0; i<arguments.length; i++) {"
|
18
|
+
" arguments[i] = JSON.parse(arguments[i]);"
|
19
|
+
" if (arguments[i]['ELEMENT']) {"
|
20
|
+
" arguments[i] = Capybara.getNode(arguments[i]['ELEMENT']);"
|
21
|
+
" };"
|
22
|
+
" };"
|
23
|
+
" %1 }).apply(null, %2); 'success'").arg(arguments()[0], jsonArgs);
|
24
|
+
|
25
|
+
QObject invocation_stub;
|
26
|
+
invocation_stub.setProperty("allowUnattached", false);
|
27
|
+
page()->currentFrame()->addToJavaScriptWindowObject("CapybaraInvocation", &invocation_stub);
|
11
28
|
QVariant result = page()->currentFrame()->evaluateJavaScript(script);
|
12
29
|
if (result.isValid()) {
|
13
30
|
finish(true);
|
data/src/FrameFocus.cpp
CHANGED
@@ -8,7 +8,6 @@ FrameFocus::FrameFocus(WebPageManager *manager, QStringList &arguments, QObject
|
|
8
8
|
}
|
9
9
|
|
10
10
|
void FrameFocus::start() {
|
11
|
-
findFrames();
|
12
11
|
switch(arguments().length()) {
|
13
12
|
case 1:
|
14
13
|
focusId(arguments()[0]);
|
@@ -26,8 +25,10 @@ void FrameFocus::findFrames() {
|
|
26
25
|
}
|
27
26
|
|
28
27
|
void FrameFocus::focusIndex(int index) {
|
28
|
+
findFrames();
|
29
29
|
if (isFrameAtIndex(index)) {
|
30
30
|
frames[index]->setFocus();
|
31
|
+
page()->setCurrentFrameParent(frames[index]->parentFrame());
|
31
32
|
success();
|
32
33
|
} else {
|
33
34
|
frameNotFound();
|
@@ -39,9 +40,11 @@ bool FrameFocus::isFrameAtIndex(int index) {
|
|
39
40
|
}
|
40
41
|
|
41
42
|
void FrameFocus::focusId(QString name) {
|
43
|
+
findFrames();
|
42
44
|
for (int i = 0; i < frames.length(); i++) {
|
43
45
|
if (frames[i]->frameName().compare(name) == 0) {
|
44
46
|
frames[i]->setFocus();
|
47
|
+
page()->setCurrentFrameParent(frames[i]->parentFrame());
|
45
48
|
success();
|
46
49
|
return;
|
47
50
|
}
|
@@ -51,10 +54,13 @@ void FrameFocus::focusId(QString name) {
|
|
51
54
|
}
|
52
55
|
|
53
56
|
void FrameFocus::focusParent() {
|
54
|
-
if (page()->currentFrame()->parentFrame() == 0) {
|
57
|
+
// if (page()->currentFrame()->parentFrame() == 0) {
|
58
|
+
if (page()->currentFrameParent() == 0) {
|
55
59
|
finish(false, new ErrorMessage("Already at parent frame."));
|
56
60
|
} else {
|
57
|
-
page()->currentFrame()->parentFrame()->setFocus();
|
61
|
+
// page()->currentFrame()->parentFrame()->setFocus();
|
62
|
+
page()->currentFrameParent()->setFocus();
|
63
|
+
page()->setCurrentFrameParent(page()->currentFrameParent()->parentFrame());
|
58
64
|
success();
|
59
65
|
}
|
60
66
|
}
|
@@ -37,8 +37,14 @@ InvocationResult JavascriptInvocation::invoke(QWebFrame *frame) {
|
|
37
37
|
QVariant result = frame->evaluateJavaScript("Capybara.invoke()");
|
38
38
|
if (getError().isValid())
|
39
39
|
return InvocationResult(getError(), true);
|
40
|
-
else
|
40
|
+
else {
|
41
|
+
if (functionName() == "leftClick") {
|
42
|
+
// Don't trigger the left click from JS incase the frame closes
|
43
|
+
QVariantMap qm = result.toMap();
|
44
|
+
leftClick(qm["absoluteX"].toInt(), qm["absoluteY"].toInt());
|
45
|
+
}
|
41
46
|
return InvocationResult(result);
|
47
|
+
}
|
42
48
|
}
|
43
49
|
|
44
50
|
void JavascriptInvocation::leftClick(int x, int y) {
|
data/src/Node.cpp
CHANGED
@@ -11,6 +11,9 @@ void Node::start() {
|
|
11
11
|
QString functionName = functionArguments.takeFirst();
|
12
12
|
QString allowUnattached = functionArguments.takeFirst();
|
13
13
|
InvocationResult result = page()->invokeCapybaraFunction(functionName, allowUnattached == "true", functionArguments);
|
14
|
+
if (functionName == "focus") {
|
15
|
+
page()->setCurrentFrameParent(page()->currentFrame()->parentFrame());
|
16
|
+
}
|
14
17
|
finish(&result);
|
15
18
|
}
|
16
19
|
|
data/src/WebPage.cpp
CHANGED
@@ -21,6 +21,7 @@ WebPage::WebPage(WebPageManager *manager, QObject *parent) : QWebPage(parent) {
|
|
21
21
|
m_uuid = QUuid::createUuid().toString();
|
22
22
|
m_confirmAction = true;
|
23
23
|
m_promptAction = false;
|
24
|
+
m_currentFrameParent = 0;
|
24
25
|
|
25
26
|
setForwardUnsupportedContent(true);
|
26
27
|
loadJavascript();
|
@@ -255,6 +256,7 @@ bool WebPage::javaScriptPrompt(QWebFrame *frame, const QString &message, const Q
|
|
255
256
|
|
256
257
|
void WebPage::loadStarted() {
|
257
258
|
m_loading = true;
|
259
|
+
m_currentFrameParent = currentFrame()->parentFrame();
|
258
260
|
m_errorPageMessage = QString();
|
259
261
|
}
|
260
262
|
|
@@ -485,3 +487,13 @@ void WebPage::addModalMessage(bool expectedType, const QString &message, const Q
|
|
485
487
|
m_modalMessages << QString();
|
486
488
|
emit modalReady();
|
487
489
|
}
|
490
|
+
|
491
|
+
QWebFrame* WebPage::currentFrameParent() {
|
492
|
+
return m_currentFrameParent;
|
493
|
+
}
|
494
|
+
|
495
|
+
void WebPage::setCurrentFrameParent(QWebFrame* frame) {
|
496
|
+
m_currentFrameParent = frame;
|
497
|
+
}
|
498
|
+
|
499
|
+
|
data/src/WebPage.h
CHANGED
@@ -55,6 +55,8 @@ class WebPage : public QWebPage {
|
|
55
55
|
void resize(int, int);
|
56
56
|
int modalCount();
|
57
57
|
QString modalMessage();
|
58
|
+
void setCurrentFrameParent(QWebFrame* frame);
|
59
|
+
QWebFrame* currentFrameParent();
|
58
60
|
|
59
61
|
public slots:
|
60
62
|
bool shouldInterruptJavaScript();
|
@@ -105,6 +107,7 @@ class WebPage : public QWebPage {
|
|
105
107
|
QList<QVariantMap> m_modalResponses;
|
106
108
|
QStringList m_modalMessages;
|
107
109
|
void addModalMessage(bool, const QString &, const QRegExp &);
|
110
|
+
QWebFrame* m_currentFrameParent;
|
108
111
|
};
|
109
112
|
|
110
113
|
#endif //_WEBPAGE_H
|
data/src/capybara.js
CHANGED
@@ -5,7 +5,11 @@ Capybara = {
|
|
5
5
|
|
6
6
|
invoke: function () {
|
7
7
|
try {
|
8
|
-
|
8
|
+
if (CapybaraInvocation.functionName == "leftClick") {
|
9
|
+
return this["verifiedClickPosition"].apply(this, CapybaraInvocation.arguments);
|
10
|
+
} else {
|
11
|
+
return this[CapybaraInvocation.functionName].apply(this, CapybaraInvocation.arguments);
|
12
|
+
}
|
9
13
|
} catch (e) {
|
10
14
|
CapybaraInvocation.error = e;
|
11
15
|
}
|
@@ -204,12 +208,17 @@ Capybara = {
|
|
204
208
|
throw new Capybara.UnpositionedElement(this.pathForNode(node), visible);
|
205
209
|
},
|
206
210
|
|
207
|
-
|
211
|
+
verifiedClickPosition: function (index) {
|
208
212
|
var node = this.getNode(index);
|
209
213
|
node.scrollIntoViewIfNeeded();
|
210
214
|
var pos = this.clickPosition(node);
|
211
215
|
CapybaraInvocation.hover(pos.relativeX, pos.relativeY);
|
212
216
|
this.expectNodeAtPosition(node, pos);
|
217
|
+
return pos;
|
218
|
+
},
|
219
|
+
|
220
|
+
click: function (index, action) {
|
221
|
+
var pos = this.verifiedClickPosition(index);
|
213
222
|
action(pos.absoluteX, pos.absoluteY);
|
214
223
|
},
|
215
224
|
|
data/src/webkit_server.pro
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capybara-webkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thoughtbot
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date:
|
16
|
+
date: 2017-01-13 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: capybara
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
version: 2.3.0
|
25
25
|
- - "<"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 2.
|
27
|
+
version: 2.13.0
|
28
28
|
type: :runtime
|
29
29
|
prerelease: false
|
30
30
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
version: 2.3.0
|
35
35
|
- - "<"
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 2.
|
37
|
+
version: 2.13.0
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: json
|
40
40
|
requirement: !ruby/object:Gem::Requirement
|
@@ -55,14 +55,14 @@ dependencies:
|
|
55
55
|
requirements:
|
56
56
|
- - "~>"
|
57
57
|
- !ruby/object:Gem::Version
|
58
|
-
version: 2.14
|
58
|
+
version: '2.14'
|
59
59
|
type: :development
|
60
60
|
prerelease: false
|
61
61
|
version_requirements: !ruby/object:Gem::Requirement
|
62
62
|
requirements:
|
63
63
|
- - "~>"
|
64
64
|
- !ruby/object:Gem::Version
|
65
|
-
version: 2.14
|
65
|
+
version: '2.14'
|
66
66
|
- !ruby/object:Gem::Dependency
|
67
67
|
name: sinatra
|
68
68
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,16 +95,16 @@ dependencies:
|
|
95
95
|
name: rake
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
97
97
|
requirements:
|
98
|
-
- - "
|
98
|
+
- - "<"
|
99
99
|
- !ruby/object:Gem::Version
|
100
|
-
version:
|
100
|
+
version: 12.0.0
|
101
101
|
type: :development
|
102
102
|
prerelease: false
|
103
103
|
version_requirements: !ruby/object:Gem::Requirement
|
104
104
|
requirements:
|
105
|
-
- - "
|
105
|
+
- - "<"
|
106
106
|
- !ruby/object:Gem::Version
|
107
|
-
version:
|
107
|
+
version: 12.0.0
|
108
108
|
- !ruby/object:Gem::Dependency
|
109
109
|
name: appraisal
|
110
110
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,20 +119,6 @@ dependencies:
|
|
119
119
|
- - "~>"
|
120
120
|
- !ruby/object:Gem::Version
|
121
121
|
version: 0.4.0
|
122
|
-
- !ruby/object:Gem::Dependency
|
123
|
-
name: selenium-webdriver
|
124
|
-
requirement: !ruby/object:Gem::Requirement
|
125
|
-
requirements:
|
126
|
-
- - ">="
|
127
|
-
- !ruby/object:Gem::Version
|
128
|
-
version: '0'
|
129
|
-
type: :development
|
130
|
-
prerelease: false
|
131
|
-
version_requirements: !ruby/object:Gem::Requirement
|
132
|
-
requirements:
|
133
|
-
- - ">="
|
134
|
-
- !ruby/object:Gem::Version
|
135
|
-
version: '0'
|
136
122
|
- !ruby/object:Gem::Dependency
|
137
123
|
name: launchy
|
138
124
|
requirement: !ruby/object:Gem::Requirement
|
@@ -169,7 +155,7 @@ files:
|
|
169
155
|
- bin/Info.plist
|
170
156
|
- capybara-webkit.gemspec
|
171
157
|
- extconf.rb
|
172
|
-
- gemfiles/2.
|
158
|
+
- gemfiles/2.11.gemfile
|
173
159
|
- gemfiles/2.7.gemfile
|
174
160
|
- gemfiles/master.gemfile
|
175
161
|
- lib/capybara-webkit.rb
|
@@ -194,6 +180,7 @@ files:
|
|
194
180
|
- spec/driver_resize_window_spec.rb
|
195
181
|
- spec/driver_spec.rb
|
196
182
|
- spec/errors_spec.rb
|
183
|
+
- spec/fixtures/fake_server.sh
|
197
184
|
- spec/integration/session_spec.rb
|
198
185
|
- spec/selenium_compatibility_spec.rb
|
199
186
|
- spec/self_signed_ssl_cert.rb
|
@@ -395,9 +382,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
395
382
|
- - ">="
|
396
383
|
- !ruby/object:Gem::Version
|
397
384
|
version: '0'
|
398
|
-
requirements:
|
385
|
+
requirements:
|
386
|
+
- Qt >= 4.8
|
399
387
|
rubyforge_project:
|
400
|
-
rubygems_version: 2.
|
388
|
+
rubygems_version: 2.5.1
|
401
389
|
signing_key:
|
402
390
|
specification_version: 4
|
403
391
|
summary: Headless Webkit driver for Capybara
|
@@ -411,6 +399,7 @@ test_files:
|
|
411
399
|
- spec/driver_resize_window_spec.rb
|
412
400
|
- spec/driver_spec.rb
|
413
401
|
- spec/errors_spec.rb
|
402
|
+
- spec/fixtures/fake_server.sh
|
414
403
|
- spec/integration/session_spec.rb
|
415
404
|
- spec/selenium_compatibility_spec.rb
|
416
405
|
- spec/self_signed_ssl_cert.rb
|
@@ -419,4 +408,3 @@ test_files:
|
|
419
408
|
- spec/support/app_runner.rb
|
420
409
|
- spec/support/matchers/include_response.rb
|
421
410
|
- spec/support/output_writer.rb
|
422
|
-
has_rdoc:
|