diff --git a/spec/features/logging_spec.cr b/spec/features/logging_spec.cr new file mode 100644 index 0000000..8516e21 --- /dev/null +++ b/spec/features/logging_spec.cr @@ -0,0 +1,31 @@ +require "../spec_helper" + +module Selenium::Command + describe "logging", tags: ["feature", "chrome"] do + it "#available_log_types" do + TestServer.route "/home", "" + + with_session do |session| + session.navigate_to("http://localhost:3002/home") + + available_log_types = session.available_log_types + available_log_types.should eq(["browser", "driver"]) + end + end + + it "#log" do + TestServer.route "/home", <<-HTML + + HTML + + with_session do |session| + session.navigate_to("http://localhost:3002/home") + + logs = session.log("browser") + logs.any? { |log| log.level == "WARNING" && log.message.ends_with?("\"Hello, Console!\"") }.should be_truthy + end + end + end +end diff --git a/spec/version_spec.cr b/spec/version_spec.cr index 41d621c..17858df 100644 --- a/spec/version_spec.cr +++ b/spec/version_spec.cr @@ -6,7 +6,7 @@ describe Selenium do file.gets_to_end end - version = /version\:(.*?)\n/.match(content).not_nil![1].strip + version = /version\:(.*?)\n/.match!(content)[1].strip version.should eq Selenium::VERSION end end diff --git a/src/selenium/chrome/capabilities.cr b/src/selenium/chrome/capabilities.cr index 21bbfc9..537cc45 100644 --- a/src/selenium/chrome/capabilities.cr +++ b/src/selenium/chrome/capabilities.cr @@ -4,6 +4,19 @@ class Selenium::Chrome::Capabilities < Selenium::Capabilities @[JSON::Field(key: "goog:chromeOptions")] property chrome_options = ChromeOptions.new + # Enable logging + # + # ``` + # capabilities = Selenium::Chrome::Capabilities.new + # capabilities.logging_prefs = { + # "browser" => "ALL", + # "driver" => "ALL", + # "performance" => "ALL", + # } + # ``` + @[JSON::Field(key: "goog:loggingPrefs")] + property logging_prefs : Hash(String, String)? + class ChromeOptions include JSON::Serializable diff --git a/src/selenium/chrome/command_handler.cr b/src/selenium/chrome/command_handler.cr new file mode 100644 index 0000000..aa14ff3 --- /dev/null +++ b/src/selenium/chrome/command_handler.cr @@ -0,0 +1,10 @@ +class Selenium::Chrome::CommandHandler < Selenium::CommandHandler + CHROME_COMMANDS = { + get_available_log_types: {:get, "/session/:session_id/se/log/types"}, + get_log: {:post, "/session/:session_id/se/log"}, + } + + def commands + DEFAULT_COMMANDS.merge(CHROME_COMMANDS) + end +end diff --git a/src/selenium/chrome/driver.cr b/src/selenium/chrome/driver.cr index 8b87987..89d8b1c 100644 --- a/src/selenium/chrome/driver.cr +++ b/src/selenium/chrome/driver.cr @@ -3,6 +3,10 @@ class Selenium::Chrome::Driver < Selenium::Driver super(capabilities) end + private def command_handler + Chrome::CommandHandler.new(@http_client) + end + def create_session(args : Array(String)) : Session capabilities = Chrome::Capabilities.new capabilities.chrome_options.args = args diff --git a/src/selenium/chrome/log_entry.cr b/src/selenium/chrome/log_entry.cr new file mode 100644 index 0000000..d85bc36 --- /dev/null +++ b/src/selenium/chrome/log_entry.cr @@ -0,0 +1,8 @@ +class Selenium::Chrome::LogEntry + include JSON::Serializable + + property level : String + property message : String + property source : String? + property timestamp : Int64 +end diff --git a/src/selenium/command_handler.cr b/src/selenium/command_handler.cr index dadebe6..abb26dc 100644 --- a/src/selenium/command_handler.cr +++ b/src/selenium/command_handler.cr @@ -1,12 +1,17 @@ class Selenium::CommandHandler include DefaultCommands + getter http_client : HttpClient def initialize(@http_client) end + def commands + DEFAULT_COMMANDS + end + def execute(command, path_variables : Hash(String, String) = {} of String => String, parameters = {} of String => String) : JSON::Any - method, path = DEFAULT_COMMANDS[command] + method, path = commands[command] full_path = path_variables.reduce(path) { |acc, entry| acc.sub(entry.first, entry.last) } execute(method, full_path, parameters.to_json) diff --git a/src/selenium/session.cr b/src/selenium/session.cr index 080c141..8b1bae1 100644 --- a/src/selenium/session.cr +++ b/src/selenium/session.cr @@ -143,6 +143,24 @@ class Selenium::Session perform_actions([sequence]) end + # Get available log types + def available_log_types : Array(String) + data = command_handler.execute(:get_available_log_types, path_variables) + + data["value"].as_a.map(&.as_s) + end + + # Get the log for a given log type. Log buffer is reset after each request + # + # List of common log types: "client", "driver", "browser", "server" + def log(type : String) : Array(Selenium::Chrome::LogEntry) + data = command_handler.execute(:get_log, path_variables, {"type" => type}) + + data.as_h["value"].as_a.map do |log| + Selenium::Chrome::LogEntry.from_json(log.to_json) + end + end + private def path_variables {":session_id" => id} end