webkit_remote 0.5.5 → 0.6.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.
@@ -1,6 +1,5 @@
1
1
  require 'fileutils'
2
2
  require 'net/http'
3
- require 'posix/spawn'
4
3
  require 'tmpdir'
5
4
 
6
5
  module WebkitRemote
@@ -17,13 +16,11 @@ class Process
17
16
  # @option opts [Hash<Symbol, Number>] window set the :left, :top, :width and
18
17
  # :height of the browser window; by default, the browser window is
19
18
  # 256x256 starting at 0,0.
20
- # @option opts [Hash<Symbol, Number>, Boolean] xvfb use Xvfb instead of a
21
- # real screen; set the :display, :width, :height, :depth and :dpi of the
22
- # server, or use the default display number 20, at 1280x1024x32 with
23
- # 72dpi
24
19
  # @option opts [Boolean] allow_popups when true, the popup blocker is
25
20
  # disabled; this is sometimes necessary when driving a Web UI via
26
21
  # JavaScript
22
+ # @option opts [Boolean] headless if true, Chrome runs without any dependency
23
+ # on a display server
27
24
  # @option opts [String] chrome_binary path to the Chrome binary to be used;
28
25
  # by default, the path is automatically detected
29
26
  def initialize(opts = {})
@@ -32,21 +29,11 @@ class Process
32
29
  @running = false
33
30
  @data_dir = Dir.mktmpdir 'webkit-remote'
34
31
  @pid = nil
35
- @xvfb_pid = nil
36
32
  if opts[:window]
37
33
  @window = opts[:window]
38
34
  else
39
35
  @window = { }
40
36
  end
41
- if opts[:xvfb]
42
- @xvfb_cli = xvfb_cli opts
43
- if opts[:xvfb].respond_to? :[]
44
- @window[:width] ||= opts[:xvfb][:width]
45
- @window[:height] ||= opts[:xvfb][:height]
46
- end
47
- else
48
- @xvfb_cli = nil
49
- end
50
37
  @window[:top] ||= 0
51
38
  @window[:left] ||= 0
52
39
  @window[:width] ||= 256
@@ -62,14 +49,7 @@ class Process
62
49
  def start
63
50
  return self if running?
64
51
 
65
- if @xvfb_cli
66
- unless @xvfb_pid = POSIX::Spawn.spawn(*@xvfb_cli)
67
- # The Xvfb launch failed.
68
- return nil
69
- end
70
- end
71
-
72
- unless @pid = POSIX::Spawn.spawn(*@cli)
52
+ unless @pid = ::Process.spawn(*@cli)
73
53
  # The launch failed.
74
54
  stop
75
55
  return nil
@@ -78,7 +58,7 @@ class Process
78
58
  (@timeout * 20).times do
79
59
  # Check if the browser exited.
80
60
  begin
81
- break if status = ::Process.wait(@pid, ::Process::WNOHANG)
61
+ break if ::Process.wait(@pid, ::Process::WNOHANG)
82
62
  rescue SystemCallError # no children
83
63
  break
84
64
  end
@@ -119,18 +99,7 @@ class Process
119
99
  end
120
100
  end
121
101
 
122
- if @xvfb_pid
123
- begin
124
- ::Process.kill 'TERM', @xvfb_pid
125
- ::Process.wait @xvfb_pid
126
- rescue SystemCallError
127
- # Process died on its own.
128
- ensure
129
- @xvfb_pid = nil
130
- end
131
- end
132
-
133
- FileUtils.rm_rf @data_dir if File.exists?(@data_dir)
102
+ FileUtils.rm_rf @data_dir if File.exist?(@data_dir)
134
103
  @running = false
135
104
  self
136
105
  end
@@ -140,7 +109,7 @@ class Process
140
109
 
141
110
  # Remove temporary directory if it's still there at garbage collection time.
142
111
  def finalize
143
- PathUtils.rm_rf @data_dir if File.exists?(@data_dir)
112
+ PathUtils.rm_rf @data_dir if File.exist?(@data_dir)
144
113
  end
145
114
 
146
115
  # Command-line that launches Google Chrome / Chromium
@@ -151,7 +120,6 @@ class Process
151
120
  # The Chromium wiki recommends this page for available flags:
152
121
  # http://peter.sh/experiments/chromium-command-line-switches/
153
122
  [
154
- chrome_env(opts),
155
123
  opts[:chrome_binary] || self.class.chrome_binary,
156
124
  ] + chrome_cli_flags(opts) + [
157
125
  "--remote-debugging-port=#{@port}", # Webkit remote debugging
@@ -164,7 +132,8 @@ class Process
164
132
  chdir: @data_dir,
165
133
  in: '/dev/null',
166
134
  out: File.join(@data_dir, '.stdout'),
167
- err: File.join(@data_dir, '.stderr')
135
+ err: File.join(@data_dir, '.stderr'),
136
+ close_others: true,
168
137
  },
169
138
  ]
170
139
  end
@@ -174,11 +143,12 @@ class Process
174
143
  # @param [Hash] opts options passed to the WebkitRemote::Process constructor
175
144
  # @return [Array<String>] flags used on the command line for launching Chrome
176
145
  def chrome_cli_flags(opts)
146
+ # TODO - look at --data-path --homedir --profile-directory
177
147
  flags = [
178
148
  '--bwsi', # disable extensions, sync, bookmarks
149
+ '--disable-cloud-import', # no talking with the Google servers
179
150
  '--disable-default-apps', # no bundled apps
180
151
  '--disable-extensions', # no extensions
181
- '--disable-java', # no plugins
182
152
  '--disable-logging', # don't trash stdout / stderr
183
153
  '--disable-plugins', # no native content
184
154
  '--disable-prompt-on-repost', # no confirmation dialog on POST refresh
@@ -193,73 +163,15 @@ class Process
193
163
  '--no-default-browser-check', # don't hang when Chrome isn't default
194
164
  '--no-experiments', # not sure this is useful
195
165
  '--no-first-run', # don't show the help UI
196
- '--no-js-randomness', # consistent Date.now() and Math.random()
197
- '--no-message-box', # don't let user scripts show dialogs
198
166
  '--no-service-autorun', # don't mess with autorun settings
199
167
  '--noerrdialogs', # don't hang on error dialogs
200
168
  ]
201
169
  flags << '--disable-popup-blocking' if opts[:allow_popups]
202
- flags
203
- end
204
-
205
- # Environment variables set when launching Chrome.
206
- #
207
- # @param [Hash] opts options passed to the WebkitRemote::Process constructor
208
- # @return [Hash<String, String>] variables to be added to the environment of
209
- # the Chrome process before launching
210
- def chrome_env(opts)
211
- if opts[:xvfb]
212
- if opts[:xvfb].respond_to?(:[]) and opts[:xvfb][:display]
213
- display = opts[:xvfb][:display]
214
- else
215
- display = 20
216
- end
217
- { 'DISPLAY' => ":#{display}.0" }
218
- else
219
- {}
220
- end
221
- end
222
-
223
- # Command-line that launches Xvfb.
224
- #
225
- # @param [Hash] opts options passed to the WebkitRemote::Process constructor
226
- # @return [Array<String>] command line for launching Xvfb
227
- def xvfb_cli(opts)
228
- # The OSX man page for Xvfb:
229
- # http://developer.apple.com/library/mac/documentation/darwin/reference/manpages/man1/Xvfb.1.html
230
-
231
- xvfb_opts = opts[:xvfb]
232
- unless xvfb_opts.respond_to? :[]
233
- xvfb_opts = {}
170
+ if opts[:headless]
171
+ flags << '--headless' # don't create a UI
172
+ flags << '--disable-gpu' # needed for --headless to work at the moment
234
173
  end
235
-
236
- display = xvfb_opts[:display] || 20
237
- width = xvfb_opts[:width] || 1280
238
- height = xvfb_opts[:height] || 1024
239
- depth = xvfb_opts[:depth] || 32
240
- dpi = xvfb_opts[:dpi] || 72
241
-
242
- # https://bugs.freedesktop.org/show_bug.cgi?id=17453
243
- if depth == 32
244
- depth = '24+32'
245
- end
246
-
247
- [
248
- self.class.xvfb_binary,
249
- ":#{display}",
250
- '-screen', '0', "#{width}x#{height}x#{depth}",
251
- '-auth', File.join(@data_dir, '.Xauthority'),
252
- '-c',
253
- '-dpi', dpi.to_s,
254
- '-terminate',
255
- '-wr',
256
- {
257
- chdir: @data_dir,
258
- in: '/dev/null',
259
- out: File.join(@data_dir, '.X_stdout'),
260
- err: File.join(@data_dir, '.X_stderr'),
261
- },
262
- ]
174
+ flags
263
175
  end
264
176
 
265
177
  # Path to a Google Chrome / Chromium binary.
@@ -297,20 +209,6 @@ class Process
297
209
  @chrome_binary ||= nil
298
210
  end
299
211
  @chrome_binary = false
300
-
301
- # Path to the Xvfb virtual X server binary.
302
- #
303
- # @return [String] full-qualified path to a binary that launches Xvfb.
304
- def self.xvfb_binary
305
- return @xvfb_binary unless @xvfb_binary == false
306
-
307
- path = `which Xvfb`
308
- unless path.empty?
309
- @xvfb_binary = path.strip
310
- end
311
- @xvfb_binary ||= nil
312
- end
313
- @xvfb_binary = false
314
212
  end # class WebkitRemote::Browser
315
213
 
316
214
  end # namespace WebkitRemote
@@ -8,9 +8,9 @@ module WebkitRemote
8
8
  # WebKit process; the client will automatically stop the process when
9
9
  # closed
10
10
  def self.local(opts = {})
11
- # Use Xvfb if no desktop is available.
12
- if !opts.has_key?(:xvfb) && (!ENV['DISPLAY'] || ENV['DISPLAY'].empty?)
13
- opts = { xvfb: true }.merge! opts
11
+ # Use headless if no desktop is available.
12
+ if !opts.has_key?(:headless) && (!ENV['DISPLAY'] || ENV['DISPLAY'].empty?)
13
+ opts = { headless: true }.merge! opts
14
14
  end
15
15
  process = WebkitRemote::Process.new opts
16
16
 
@@ -25,7 +25,7 @@
25
25
  };
26
26
  var keyEventDetails = function (event) {
27
27
  return "keyCode: " + event.keyCode + " charCode: " + event.charCode +
28
- " keyIdentifier: " + event.keyIdentifier + " text: " + event.text +
28
+ " key: " + event.key + " text: " + event.text +
29
29
  " repeat: " + event.repeat + " shift: " + event.shiftKey +
30
30
  " ctrl: " + event.ctrlKey + " alt: " + event.altKey +
31
31
  " meta: " + event.metaKey;
@@ -52,4 +52,3 @@
52
52
  </script>
53
53
  </body>
54
54
  </html>
55
-
@@ -17,7 +17,7 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
17
17
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
18
18
  require 'webkit_remote'
19
19
 
20
- require 'debugger'
20
+ require 'byebug'
21
21
  require 'pp'
22
22
  require 'thread'
23
23
  Thread.abort_on_exception = true
@@ -2,7 +2,7 @@ require File.expand_path('../helper.rb', File.dirname(__FILE__))
2
2
 
3
3
  describe WebkitRemote::Browser do
4
4
  before :each do
5
- @process = WebkitRemote::Process.new port: 9669, xvfb: true
5
+ @process = WebkitRemote::Process.new port: 9669, headless: true
6
6
  @process.start
7
7
  end
8
8
  after :each do
@@ -26,9 +26,6 @@ describe WebkitRemote::Client::Console do
26
26
  lambda {
27
27
  @client.wait_for type: WebkitRemote::Event::ConsoleMessage
28
28
  }.must_raise ArgumentError
29
- lambda {
30
- @client.wait_for type: WebkitRemote::Event::ConsoleMessageRepeated
31
- }.must_raise ArgumentError
32
29
  lambda {
33
30
  @client.wait_for type: WebkitRemote::Event::ConsoleCleared
34
31
  }.must_raise ArgumentError
@@ -43,9 +40,6 @@ describe WebkitRemote::Client::Console do
43
40
  @message_events = @events.select do |event|
44
41
  event.kind_of? WebkitRemote::Event::ConsoleMessage
45
42
  end
46
- @repeat_events = @events.select do |event|
47
- event.kind_of? WebkitRemote::Event::ConsoleMessageRepeated
48
- end
49
43
  @messages = @client.console_messages
50
44
  end
51
45
 
@@ -57,30 +51,28 @@ describe WebkitRemote::Client::Console do
57
51
  @message_events.wont_be :empty?
58
52
  end
59
53
 
60
- it 'receives ConsoleMessageRepeated events' do
61
- @repeat_events.wont_be :empty?
62
- end
63
-
64
54
  it 'collects messages into Client#console_messages' do
65
55
  @message_events[0].message.must_equal @messages[0]
66
56
  @message_events[1].message.must_equal @messages[1]
67
57
  @message_events[2].message.must_equal @messages[2]
68
58
  @message_events[3].message.must_equal @messages[3]
69
- @repeat_events[0].message.must_equal @messages[3]
70
- @repeat_events[1].message.must_equal @messages[3]
71
59
  end
72
60
 
73
61
  it 'parses text correctly' do
74
62
  @messages[0].text.must_equal 'hello ruby'
75
- @messages[0].params.must_equal ['hello ruby']
76
63
  @messages[0].level.must_equal :warning
77
- @messages[0].count.must_equal 1
78
64
  @messages[0].reason.must_equal :console_api
79
- @messages[0].type.must_equal :log
80
65
  @messages[0].source_url.must_equal fixture_url(:console)
81
66
  @messages[0].source_line.must_equal 7
67
+
68
+ @messages[1].text.must_equal 'stack test'
69
+ @messages[1].level.must_equal :log
70
+ @messages[2].text.must_match(/^params /)
71
+ @messages[2].level.must_equal :error
82
72
  end
83
73
 
74
+ =begin
75
+ TODO(pwnall): Stacks are now available in Runtime.consoleAPICalled
84
76
  it 'parses the stack trace correctly' do
85
77
  @messages[1].text.must_equal 'stack test'
86
78
  @messages[1].level.must_equal :log
@@ -92,6 +84,7 @@ describe WebkitRemote::Client::Console do
92
84
  ]
93
85
  end
94
86
 
87
+ TODO(pwnall): Params are now available as args in Runtime.consoleAPICalled
95
88
  it 'parses parameters correctly' do
96
89
  @messages[2].text.must_match(/^params /)
97
90
  @messages[2].level.must_equal :error
@@ -100,16 +93,11 @@ describe WebkitRemote::Client::Console do
100
93
 
101
94
  @messages[2].params[3].must_be_kind_of WebkitRemote::Client::JsObject
102
95
  @messages[2].params[3].properties['hello'].value.must_equal 'ruby'
103
- @messages[2].params[3].group.name.must_equal nil
104
- end
105
-
106
- it 'parses repeated messages correctly' do
107
- @messages[3].text.must_equal 'one more time'
108
- @messages[3].count.must_equal 3
109
- @repeat_events[0].count.must_equal 2
110
- @repeat_events[1].count.must_equal 3
96
+ @messages[2].params[3].group.name.must_be_nil
111
97
  end
98
+ =end
112
99
 
100
+ =begin
113
101
  describe 'clear_console' do
114
102
  before :all do
115
103
  @client.clear_console
@@ -135,8 +123,11 @@ describe WebkitRemote::Client::Console do
135
123
  @message_events[2].message.params[3].released?.must_equal true
136
124
  end
137
125
  end
126
+ =end
138
127
  end
139
128
 
129
+ =begin
130
+ TODO(pwnall): These events are now available as Log.entryAdded
140
131
  describe 'with console and network events enabled' do
141
132
  before :all do
142
133
  @client.console_events = true
@@ -159,7 +150,7 @@ describe WebkitRemote::Client::Console do
159
150
  end
160
151
 
161
152
  it 'associates messages with network requests' do
162
- @messages[0].text.must_match /not found/i
153
+ @messages[0].text.must_match(/not found/i)
163
154
  @messages[0].network_resource.wont_equal nil
164
155
  @messages[0].network_resource.document_url.
165
156
  must_equal fixture_url(:network)
@@ -169,4 +160,5 @@ describe WebkitRemote::Client::Console do
169
160
  @messages[0].type.must_equal :log
170
161
  end
171
162
  end
163
+ =end
172
164
  end
@@ -57,7 +57,7 @@ describe WebkitRemote::Client::DomNode do
57
57
  describe 'with a selector that does not match' do
58
58
  it 'returns nil' do
59
59
  node = @root.query_selector '#this-id-should-not-exist'
60
- node.must_equal nil
60
+ node.must_be_nil
61
61
  end
62
62
  end
63
63
  end
@@ -1,6 +1,6 @@
1
1
  require File.expand_path('../../helper.rb', File.dirname(__FILE__))
2
2
 
3
- describe WebkitRemote::Client::Console do
3
+ describe WebkitRemote::Client::Input do
4
4
  before :all do
5
5
  @client = WebkitRemote.local port: 9669
6
6
  @client.page_events = true
@@ -12,6 +12,7 @@ describe WebkitRemote::Client::Console do
12
12
  @client.close
13
13
  end
14
14
 
15
+ =begin
15
16
  describe '#mouse_event' do
16
17
  it 'generates a move correctly' do
17
18
  @client.mouse_event :move, 50, 50
@@ -32,12 +33,12 @@ describe WebkitRemote::Client::Console do
32
33
  end
33
34
 
34
35
  it 'generates a second press correctly' do
35
- @client.mouse_event :down, 51, 52, button: :left, clicks: 2,
36
+ @client.mouse_event :down, 51, 52, button: :right, clicks: 2,
36
37
  modifiers: [:alt, :ctrl]
37
38
  events = @client.wait_for type: WebkitRemote::Event::ConsoleMessage
38
39
 
39
40
  events.last.message.text.must_equal(
40
- 'Down. x: 51 y: 52 button: 0 detail: 2 shift: false ctrl: true ' +
41
+ 'Down. x: 51 y: 52 button: 2 detail: 2 shift: false ctrl: true ' +
41
42
  'alt: true meta: false')
42
43
  end
43
44
 
@@ -46,10 +47,11 @@ describe WebkitRemote::Client::Console do
46
47
  events = @client.wait_for type: WebkitRemote::Event::ConsoleMessage
47
48
 
48
49
  events.last.message.text.must_equal(
49
- 'Up. x: 51 y: 52 button: 0 detail: 0 shift: false ctrl: false ' +
50
+ 'Up. x: 51 y: 52 button: 1 detail: 0 shift: false ctrl: false ' +
50
51
  'alt: false meta: true')
51
52
  end
52
53
  end
54
+ =end
53
55
 
54
56
  describe '#key_event' do
55
57
  it 'generates a char correctly' do
@@ -58,42 +60,38 @@ describe WebkitRemote::Client::Console do
58
60
  events = @client.wait_for type: WebkitRemote::Event::ConsoleMessage
59
61
 
60
62
  events.last.message.text.must_equal(
61
- 'KPress. keyCode: 97 charCode: 97 keyIdentifier: text: undefined ' +
63
+ 'KPress. keyCode: 97 charCode: 97 key: text: undefined ' +
62
64
  'repeat: false shift: false ctrl: false alt: false meta: false')
63
65
  end
64
66
 
65
67
  it 'generates a down correctly' do
66
- @client.key_event :down, vkey: 0x41, key_id: 'U+0041'
68
+ @client.key_event :down, vkey: 0x41, key: 'A'
67
69
 
68
70
  events = @client.wait_for type: WebkitRemote::Event::ConsoleMessage
69
71
 
70
72
  events.last.message.text.must_equal(
71
- 'KDown. keyCode: 65 charCode: 0 keyIdentifier: U+0041 ' +
72
- 'text: undefined ' +
73
+ 'KDown. keyCode: 65 charCode: 0 key: A text: undefined ' +
73
74
  'repeat: false shift: false ctrl: false alt: false meta: false')
74
75
  end
75
76
 
76
77
  it 'generates an up correctly' do
77
- @client.key_event :up, vkey: 0x41, key_id: 'U+0041'
78
+ @client.key_event :up, vkey: 0x41, key: 'A'
78
79
 
79
80
  events = @client.wait_for type: WebkitRemote::Event::ConsoleMessage
80
81
 
81
82
  events.last.message.text.must_equal(
82
- 'KUp. keyCode: 65 charCode: 0 keyIdentifier: U+0041 ' +
83
- 'text: undefined ' +
83
+ 'KUp. keyCode: 65 charCode: 0 key: A text: undefined ' +
84
84
  'repeat: false shift: false ctrl: false alt: false meta: false')
85
85
  end
86
86
 
87
87
  it 'generates a raw_down correctly' do
88
- @client.key_event :raw_down, vkey: 0x41, key_id: 'U+0041'
88
+ @client.key_event :raw_down, vkey: 0x41, key: 'A'
89
89
 
90
90
  events = @client.wait_for type: WebkitRemote::Event::ConsoleMessage
91
91
 
92
92
  events.last.message.text.must_equal(
93
- 'KDown. keyCode: 65 charCode: 0 keyIdentifier: U+0041 ' +
94
- 'text: undefined ' +
93
+ 'KDown. keyCode: 65 charCode: 0 key: A text: undefined ' +
95
94
  'repeat: false shift: false ctrl: false alt: false meta: false')
96
95
  end
97
96
  end
98
97
  end
99
-