Skip to content

Commit 9485a1e

Browse files
committed
Support opening Chrome automatically on windows
1 parent a402e73 commit 9485a1e

File tree

1 file changed

+82
-27
lines changed

1 file changed

+82
-27
lines changed

lib/debug/server_cdp.rb

+82-27
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@
77
require 'stringio'
88
require 'open3'
99
require 'tmpdir'
10+
require 'tempfile'
1011

1112
module DEBUGGER__
1213
module UI_CDP
1314
SHOW_PROTOCOL = ENV['RUBY_DEBUG_CDP_SHOW_PROTOCOL'] == '1'
1415

16+
class UnsupportedError < StandardError; end
17+
class NotFoundChromeEndpointError < StandardError; end
18+
1519
class << self
1620
def setup_chrome addr
1721
return if CONFIG[:chrome_path] == ''
@@ -59,46 +63,97 @@ def setup_chrome addr
5963
end
6064
end
6165
pid
62-
rescue Errno::ENOENT
66+
rescue Errno::ENOENT, UnsupportedError, NotFoundChromeEndpointError
6367
nil
6468
end
6569

66-
def get_chrome_path
67-
return CONFIG[:chrome_path] if CONFIG[:chrome_path]
70+
def run_new_chrome
71+
path = CONFIG[:chrome_path]
6872

69-
# The process to check OS is based on `selenium` project.
73+
data = nil
74+
port = nil
75+
wait_thr = nil
7076
case RbConfig::CONFIG['host_os']
7177
when /mswin|msys|mingw|cygwin|emc/
72-
'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
78+
if path.nil?
79+
candidates = ['C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe', 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe']
80+
path = get_chrome_path candidates
81+
end
82+
uuid = SecureRandom.uuid
83+
# The path is based on https://github.com/sindresorhus/open/blob/v8.4.0/index.js#L128.
84+
stdin, stdout, stderr, wait_thr = *Open3.popen3("#{ENV['SystemRoot']}\\System32\\WindowsPowerShell\\v1.0\\powershell")
85+
tf = Tempfile.create(['debug-', '.txt'])
86+
87+
stdin.puts("Start-process '#{path}' -Argumentlist '--remote-debugging-port=0', '--no-first-run', '--no-default-browser-check', '--user-data-dir=C:\\temp' -Wait -RedirectStandardError #{tf.path}")
88+
stdin.close
89+
stdout.close
90+
stderr.close
91+
port, path = get_devtools_endpoint(tf.path)
92+
93+
at_exit{
94+
DEBUGGER__.skip_all
95+
96+
stdin, stdout, stderr, wait_thr = *Open3.popen3("#{ENV['SystemRoot']}\\System32\\WindowsPowerShell\\v1.0\\powershell")
97+
stdin.puts("Stop-process -Name chrome")
98+
stdin.close
99+
stdout.close
100+
stderr.close
101+
tf.close
102+
begin
103+
File.unlink(tf)
104+
rescue Errno::EACCES
105+
end
106+
}
73107
when /darwin|mac os/
74-
'/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome'
75-
when /linux/
76-
'google-chrome'
108+
path = path || '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome'
109+
dir = Dir.mktmpdir
110+
# The command line flags are based on: https://developer.mozilla.org/en-US/docs/Tools/Remote_Debugging/Chrome_Desktop#connecting.
111+
stdin, stdout, stderr, wait_thr = *Open3.popen3("#{path} --remote-debugging-port=0 --no-first-run --no-default-browser-check --user-data-dir=#{dir}")
112+
stdin.close
113+
stdout.close
114+
data = stderr.readpartial 4096
115+
stderr.close
116+
if data.match /DevTools listening on ws:\/\/127.0.0.1:(\d+)(.*)/
117+
port = $1
118+
path = $2
119+
end
120+
121+
at_exit{
122+
DEBUGGER__.skip_all
123+
FileUtils.rm_rf dir
124+
}
77125
else
78-
raise "Unsupported OS"
126+
raise UnsupportedError
79127
end
80-
end
81128

82-
def run_new_chrome
83-
dir = Dir.mktmpdir
84-
# The command line flags are based on: https://developer.mozilla.org/en-US/docs/Tools/Remote_Debugging/Chrome_Desktop#connecting
85-
stdin, stdout, stderr, wait_thr = *Open3.popen3("#{get_chrome_path} --remote-debugging-port=0 --no-first-run --no-default-browser-check --user-data-dir=#{dir}")
86-
stdin.close
87-
stdout.close
88-
89-
data = stderr.readpartial 4096
90-
if data.match /DevTools listening on ws:\/\/127.0.0.1:(\d+)(.*)/
91-
port = $1
92-
path = $2
93-
end
94-
stderr.close
129+
[port, path, wait_thr.pid]
130+
end
95131

96-
at_exit{
97-
DEBUGGER__.skip_all
98-
FileUtils.rm_rf dir
132+
def get_chrome_path candidates
133+
candidates.each{|c|
134+
if File.exist? c
135+
return c
136+
end
99137
}
138+
raise UnsupportedError
139+
end
100140

101-
[port, path, wait_thr.pid]
141+
ITERATIONS = 50
142+
143+
def get_devtools_endpoint tf
144+
i = 1
145+
while i < ITERATIONS
146+
i += 1
147+
if File.exist?(tf) && data = File.read(tf)
148+
if data.match /DevTools listening on ws:\/\/127.0.0.1:(\d+)(.*)/
149+
port = $1
150+
path = $2
151+
return [port, path]
152+
end
153+
end
154+
sleep 0.1
155+
end
156+
raise NotFoundChromeEndpointError
102157
end
103158
end
104159

0 commit comments

Comments
 (0)