1b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// found in the LICENSE file. 4b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 5b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/console_logger.h" 6b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 7b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/json/json_writer.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/logging.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 10b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/values.h" 11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/devtools_client.h" 12b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/log.h" 13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/status.h" 14b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 15b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)namespace { 16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Translates Console.messageAdded.message.level into Log::Level. 18b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool ConsoleLevelToLogLevel(const std::string& name, Log::Level *out_level) { 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char* const kConsoleLevelNames[] = { 20b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "debug", "log", "warning", "error" 21b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) }; 22b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (size_t i = 0; i < arraysize(kConsoleLevelNames); ++i) { 24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (name == kConsoleLevelNames[i]) { 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK_LE(Log::kDebug + i, static_cast<size_t>(Log::kError)); 26b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) *out_level = static_cast<Log::Level>(Log::kDebug + i); 27b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return true; 28b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 29b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 30b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 32b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 33b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} // namespace 34b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 35b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)ConsoleLogger::ConsoleLogger(Log* log) 36b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) : log_(log) {} 37b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)Status ConsoleLogger::OnConnected(DevToolsClient* client) { 39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::DictionaryValue params; 40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return client->SendCommand("Console.enable", params); 41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Status ConsoleLogger::OnEvent( 44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DevToolsClient* client, 45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const std::string& method, 46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const base::DictionaryValue& params) { 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (method != "Console.messageAdded") 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return Status(kOk); 49b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // If the event has proper structure and fields, log formatted. 51b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Else it's a weird message that we don't know how to format, log full JSON. 52b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const base::DictionaryValue *message_dict = NULL; 53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (params.GetDictionary("message", &message_dict)) { 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string text; 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string level_name; 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Log::Level level = Log::kInfo; 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (message_dict->GetString("text", &text) && !text.empty() && 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) message_dict->GetString("level", &level_name) && 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ConsoleLevelToLogLevel(level_name, &level)) { 60b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char* origin_cstr = "unknown"; 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string origin; 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if ((message_dict->GetString("url", &origin) && !origin.empty()) || 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (message_dict->GetString("source", &origin) && !origin.empty())) { 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) origin_cstr = origin.c_str(); 66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string line_column; 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int line = -1; 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (message_dict->GetInteger("line", &line)) { 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int column = -1; 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (message_dict->GetInteger("column", &column)) { 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::SStringPrintf(&line_column, "%d:%d", line, column); 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::SStringPrintf(&line_column, "%d", line); 76b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // No line number, but print anyway, just to maintain the number of 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // fields in the formatted message in case someone wants to parse it. 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) line_column = "-"; 81b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string source; 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) message_dict->GetString("source", &source); 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) log_->AddEntry(level, source, base::StringPrintf("%s %s %s", 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) origin_cstr, 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) line_column.c_str(), 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) text.c_str())); 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return Status(kOk); 91b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Don't know how to format, log full JSON. 95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) std::string message_json; 96b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::JSONWriter::Write(¶ms, &message_json); 97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) log_->AddEntry(Log::kWarning, message_json); 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return Status(kOk); 99b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 100