forked from SeleniumHQ/selenium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cdp_client_generator.rb
111 lines (93 loc) · 3.99 KB
/
cdp_client_generator.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# frozen_string_literal: true
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
require 'erb'
require 'fileutils'
require 'json'
module Selenium
module DevTools
module Support
class CDPClientGenerator
# Input JSON files are generated from PDL tasks.
DIR = __dir__ || ''
DOMAIN_TEMPLATE_PATH = File.expand_path('cdp/domain.rb.erb', DIR)
LOADER_TEMPLATE_PATH = File.expand_path('cdp/loader.rb.erb', DIR)
RESERVED_KEYWORDS = %w[end].freeze
def call(output_dir:, version:, **opts)
@domain_template = ERB.new(File.read(DOMAIN_TEMPLATE_PATH))
@loader_template = ERB.new(File.read(LOADER_TEMPLATE_PATH))
@output_dir = output_dir
@loader_path = opts.delete(:loader_path) || "#{@output_dir}.rb"
@version = version
browser_protocol_path = opts.delete(:browser_protocol_path) do
File.expand_path('cdp/browser_protocol.json', DIR)
end
js_protocol_path = opts.delete(:js_protocol_path) { File.expand_path('cdp/js_protocol.json', DIR) }
raise ArgumentError, "Invalid arguments: #{opts.keys}" unless opts.empty?
browser_protocol = JSON.parse(File.read(browser_protocol_path), symbolize_names: true)
js_protocol = JSON.parse(File.read(js_protocol_path), symbolize_names: true)
FileUtils.mkdir_p(@output_dir)
all_domains = browser_protocol[:domains] + js_protocol[:domains]
all_domains.each { |domain| process_domain(domain) }
process_loader(all_domains)
end
def process_domain(domain)
result = @domain_template.result_with_hash(domain: domain, version: @version.upcase, h: self)
filename = File.join(@output_dir, "#{snake_case(domain[:domain])}.rb")
File.write(filename, remove_empty_lines(result))
end
def snake_case(string)
name = string.gsub('JavaScript', 'Javascript')
.gsub(/([A-Z]+)([A-Z][a-z]{2,})/, '\1_\2')
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
.downcase
# Certain CDP parameters conflict with Ruby keywords
# so we prefix the name with underscore.
name = "_#{name}" if RESERVED_KEYWORDS.include?(name)
name
end
def kwargs(parameters)
parameters = parameters.map do |parameter|
if parameter[:optional]
"#{snake_case(parameter[:name])}: nil"
else
"#{snake_case(parameter[:name])}:"
end
end
parameters.join(', ')
end
def remove_empty_lines(string)
string.split("\n").grep_v(/^\s+$/).join("\n")
end
def process_loader(domains)
result = @loader_template.result_with_hash(domains: domains, version: @version.upcase, h: self)
File.write(@loader_path, remove_empty_lines(result))
end
end
end
end
end
if $PROGRAM_NAME == __FILE__
browser_protocol_path, js_protocol_path, loader_path, version = *ARGV
Selenium::DevTools::Support::CDPClientGenerator.new.call(
browser_protocol_path: browser_protocol_path,
js_protocol_path: js_protocol_path,
output_dir: loader_path&.sub(/\.rb$/, ''),
loader_path: loader_path,
version: version
)
end