|
| 1 | +require 'net/http' |
| 2 | +require './lib/appium_lib_core' |
| 3 | + |
| 4 | +module Script |
| 5 | + class CommandsChecker |
| 6 | + attr_reader :spec_commands |
| 7 | + attr_reader :implemented_mjsonwp_commands, :implemented_w3c_commands, :implemented_core_commands |
| 8 | + attr_reader :webdriver_oss_commands, :webdriver_w3c_commands |
| 9 | + |
| 10 | + # Set commands implemented in this core library. |
| 11 | + # |
| 12 | + # - implemented_mjsonwp_commands: All commands include ::Selenium::WebDriver::Remote::OSS::Bridge::COMMANDS |
| 13 | + # - implemented_w3c_commands: All commands include ::Selenium::WebDriver::Remote::W3C::Bridge::COMMANDS |
| 14 | + # - implemented_core_commands: All commands except for selenium-webdriver's commands |
| 15 | + # - webdriver_oss_commands: ::Selenium::WebDriver::Remote::OSS::Bridge::COMMANDS |
| 16 | + # - webdriver_w3c_commands: ::Selenium::WebDriver::Remote::W3C::Bridge::COMMANDS |
| 17 | + # |
| 18 | + def initialize |
| 19 | + @implemented_mjsonwp_commands = convert_driver_commands Appium::Core::Commands::COMMANDS_EXTEND_MJSONWP |
| 20 | + @implemented_w3c_commands = convert_driver_commands Appium::Core::Commands::COMMANDS_EXTEND_W3C |
| 21 | + @implemented_core_commands = convert_driver_commands Appium::Core::Commands::COMMANDS |
| 22 | + |
| 23 | + @webdriver_oss_commands = convert_driver_commands Appium::Core::Base::Commands::OSS |
| 24 | + @webdriver_w3c_commands = convert_driver_commands Appium::Core::Base::Commands::W3C |
| 25 | + end |
| 26 | + |
| 27 | + # Get the bellow url's file. |
| 28 | + # https://raw.githubusercontent.com/appium/appium-base-driver/master/lib/mjsonwp/routes.js?raw=1 |
| 29 | + # |
| 30 | + # @param [String] to_path: A file path to routes.js |
| 31 | + # @return [String] The file path in which has saved `routes.js`. |
| 32 | + # |
| 33 | + def get_mjsonwp_routes(to_path = './mjsonwp_routes.js') |
| 34 | + uri = URI 'https://raw.githubusercontent.com/appium/appium-base-driver/master/lib/mjsonwp/routes.js?raw=1' |
| 35 | + result = Net::HTTP.get uri |
| 36 | + |
| 37 | + File.delete to_path |
| 38 | + File.write to_path, result |
| 39 | + to_path |
| 40 | + end |
| 41 | + |
| 42 | + # @private |
| 43 | + HTTP_METHOD_MATCH = /GET:|POST:|DELETE:|PUT:|PATCH:/ |
| 44 | + # @private |
| 45 | + WD_HUB_PREFIX_MATCH = "'/wd/hub/".freeze |
| 46 | + |
| 47 | + # Read routes.js and set the values in @spec_commands |
| 48 | + # |
| 49 | + # @param [String] path: A file path to routes.js |
| 50 | + # @return [Hash] @spec_commands |
| 51 | + # |
| 52 | + def get_all_command_path(path = './mjsonwp_routes.js') |
| 53 | + raise "No file in #{path}" unless File.exist? path |
| 54 | + |
| 55 | + current_command = '' |
| 56 | + @spec_commands = File.read(path).lines.each_with_object({}) do |line, memo| |
| 57 | + if line =~ /#{WD_HUB_PREFIX_MATCH}.+'/ |
| 58 | + current_command = gsub_set(line.slice(/#{WD_HUB_PREFIX_MATCH}.+'/)) |
| 59 | + memo[current_command] = [] |
| 60 | + elsif line =~ HTTP_METHOD_MATCH |
| 61 | + memo[current_command] << line.slice(HTTP_METHOD_MATCH).chop.downcase.to_sym |
| 62 | + end |
| 63 | + memo |
| 64 | + end |
| 65 | + end |
| 66 | + |
| 67 | + # All commands which haven't been implemented in ruby core library yet. |
| 68 | + # @return [Hash] |
| 69 | + # |
| 70 | + def all_diff_commands_mjsonwp |
| 71 | + result = compare_commands(@spec_commands, @implemented_mjsonwp_commands) |
| 72 | + |
| 73 | + white_list.each { |v| result.delete v } |
| 74 | + w3c_spec.each { |v| result.delete v } |
| 75 | + |
| 76 | + result |
| 77 | + end |
| 78 | + |
| 79 | + # All commands which haven't been implemented in ruby core library yet. |
| 80 | + # @return [Hash] |
| 81 | + # |
| 82 | + def all_diff_commands_w3c |
| 83 | + result = compare_commands(@spec_commands, @implemented_w3c_commands) |
| 84 | + white_list.each { |v| result.delete v } |
| 85 | + mjsonwp_spec.each { |v| result.delete v } |
| 86 | + result |
| 87 | + end |
| 88 | + |
| 89 | + # Commands, only this core library, which haven't been implemented in ruby core library yet. |
| 90 | + # @return [Hash] |
| 91 | + # |
| 92 | + def diff_except_for_webdriver |
| 93 | + result = compare_commands(@spec_commands, @implemented_core_commands) |
| 94 | + white_list.each { |v| result.delete v } |
| 95 | + result |
| 96 | + end |
| 97 | + |
| 98 | + def diff_webdriver_oss |
| 99 | + result = compare_commands(@spec_commands, @webdriver_oss_commands) |
| 100 | + white_list.each { |v| result.delete v } |
| 101 | + w3c_spec.each { |v| result.delete v } |
| 102 | + result |
| 103 | + end |
| 104 | + |
| 105 | + def diff_webdriver_w3c |
| 106 | + result = compare_commands(@spec_commands, @webdriver_w3c_commands) |
| 107 | + white_list.each { |v| result.delete v } |
| 108 | + mjsonwp_spec.each { |v| result.delete v } |
| 109 | + result |
| 110 | + end |
| 111 | + |
| 112 | + def compare_commands(command1, with_command2) |
| 113 | + return {} if command1.nil? |
| 114 | + return command1 if with_command2.nil? |
| 115 | + |
| 116 | + result = {} |
| 117 | + command1.each_key do |key| |
| 118 | + if with_command2.key? key |
| 119 | + diff = command1[key] - with_command2[key] |
| 120 | + result[key] = diff unless diff.empty? |
| 121 | + else |
| 122 | + result[key] = command1[key] |
| 123 | + end |
| 124 | + end |
| 125 | + result |
| 126 | + end |
| 127 | + |
| 128 | + private |
| 129 | + |
| 130 | + # rubocop:disable Lint/PercentStringArray |
| 131 | + def white_list |
| 132 | + %w( |
| 133 | + '/wd/hub/session' |
| 134 | + '/wd/hub/sessions' |
| 135 | + ).map { |v| gsub_set(v) } |
| 136 | + end |
| 137 | + |
| 138 | + # https://raw.githubusercontent.com/appium/appium-base-driver/master/lib/mjsonwp/routes.js |
| 139 | + def mjsonwp_spec |
| 140 | + %w( |
| 141 | + '/wd/hub/session/:sessionId/alert_text' |
| 142 | + '/wd/hub/session/:sessionId/accept_alert' |
| 143 | + '/wd/hub/session/:sessionId/dismiss_alert' |
| 144 | + ).map { |v| gsub_set(v) } |
| 145 | + end |
| 146 | + |
| 147 | + def w3c_spec |
| 148 | + %w( |
| 149 | + '/wd/hub/session/:sessionId/alert/text' |
| 150 | + '/wd/hub/session/:sessionId/alert/accept' |
| 151 | + '/wd/hub/session/:sessionId/alert/dismiss' |
| 152 | + '/wd/hub/session/:sessionId/element/:elementId/rect' |
| 153 | + ).map { |v| gsub_set(v) } |
| 154 | + end |
| 155 | + # rubocop:enable Lint/PercentStringArray |
| 156 | + |
| 157 | + def gsub_set(line) |
| 158 | + return nil if line.gsub(/(\A#{WD_HUB_PREFIX_MATCH}|'\z)/, '').nil? |
| 159 | + |
| 160 | + line.gsub(/(\A#{WD_HUB_PREFIX_MATCH}|'\z)/, '') |
| 161 | + .sub(':sessionId', ':session_id') |
| 162 | + .sub('element/:elementId', 'element/:id') |
| 163 | + .sub(':windowhandle', ':window_handle') |
| 164 | + .sub('equals/:otherId', 'equals/:other') |
| 165 | + .sub('css/:propertyName', 'css/:property_name') |
| 166 | + .sub('element/:id/pageIndex', 'element/:id/page_index') |
| 167 | + end |
| 168 | + |
| 169 | + def convert_driver_commands(from) |
| 170 | + from.each_with_object({}) do |command, memo| |
| 171 | + method = command[1][0] |
| 172 | + key = command[1][1] |
| 173 | + |
| 174 | + if memo[key] |
| 175 | + memo[key] << method |
| 176 | + else |
| 177 | + memo[key] = [method] |
| 178 | + end |
| 179 | + |
| 180 | + memo |
| 181 | + end |
| 182 | + end |
| 183 | + end |
| 184 | +end |
0 commit comments