#include "response.h"
#include "errorcodes.h"
#include "logging.h"
namespace webdriver {
Response::Response(void) : error_(""), value_(Json::Value::null), additional_data_(Json::Value::null) {
}
Response::~Response(void) {
}
void Response::Deserialize(const std::string& json) {
LOG(TRACE) << "Entering Response::Deserialize";
Json::Value response_object;
std::string parse_errors;
std::stringstream json_stream;
json_stream.str(json);
Json::parseFromStream(Json::CharReaderBuilder(),
json_stream,
&response_object,
&parse_errors);
Json::Value value_object;
if (response_object.isMember("value")) {
value_object = response_object["value"];
if (value_object.isObject() && value_object.isMember("error")) {
this->error_ = value_object["error"].asString();
this->value_ = value_object["message"].asString();
if (value_object.isMember("data")) {
this->additional_data_ = value_object["data"];
}
} else {
this->error_ = "";
this->value_ = value_object;
}
} else {
this->value_ = Json::Value::null;
}
}
std::string Response::Serialize(void) {
LOG(TRACE) << "Entering Response::Serialize";
Json::Value json_object;
if (this->error_.size() > 0) {
Json::Value error_object;
error_object["error"] = this->error_;
error_object["message"] = this->value_.asString();
error_object["stacktrace"] = "";
if (!this->value_.isNull() && !this->additional_data_.isNull()) {
error_object["data"] = this->additional_data_;
}
json_object["value"] = error_object;
} else {
json_object["value"] = this->value_;
}
Json::StreamWriterBuilder writer;
std::string output(Json::writeString(writer, json_object));
return output;
}
void Response::SetSuccessResponse(const Json::Value& response_value) {
LOG(TRACE) << "Entering Response::SetSuccessResponse";
this->SetResponse("", response_value);
}
void Response::SetResponse(const std::string& error,
const Json::Value& response_value) {
LOG(TRACE) << "Entering Response::SetResponse";
this->error_ = error;
this->value_ = response_value;
}
void Response::SetErrorResponse(const std::string& error,
const std::string& message) {
LOG(TRACE) << "Entering Response::SetErrorResponse";
this->SetResponse(error, message);
}
void Response::SetErrorResponse(const int status_code,
const std::string& message) {
LOG(TRACE) << "Entering Response::SetErrorResponse";
LOG(WARN) << "Error response has status code " << status_code << " and message '" << message << "' message";
this->SetErrorResponse(ConvertErrorCode(status_code), message);
}
void Response::AddAdditionalData(const std::string& data_name,
const std::string& data_value) {
LOG(TRACE) << "Entering Response::AddAdditionalData";
if (this->additional_data_.isNull()) {
Json::Value new_data;
this->additional_data_ = new_data;
}
this->additional_data_[data_name] = data_value;
}
std::string Response::GetSessionId(void) {
if (this->error_.size() == 0) {
return this->value_.get("sessionId", "").asString();
}
return "";
}
int Response::GetHttpResponseCode(void) {
int response_code = 200;
if (this->error_ == ERROR_ELEMENT_CLICK_INTERCEPTED ||
this->error_ == ERROR_ELEMENT_NOT_SELECTABLE ||
this->error_ == ERROR_ELEMENT_NOT_INTERACTABLE ||
this->error_ == ERROR_INSECURE_CERTIFICATE ||
this->error_ == ERROR_INVALID_ARGUMENT ||
this->error_ == ERROR_INVALID_COOKIE_DOMAIN ||
this->error_ == ERROR_INVALID_COORDINATES ||
this->error_ == ERROR_INVALID_ELEMENT_STATE ||
this->error_ == ERROR_INVALID_SELECTOR) {
response_code = 400;
} else if (this->error_ == ERROR_INVALID_SESSION_ID ||
this->error_ == ERROR_NO_SUCH_COOKIE ||
this->error_ == ERROR_NO_SUCH_ALERT ||
this->error_ == ERROR_NO_SUCH_ELEMENT ||
this->error_ == ERROR_NO_SUCH_FRAME ||
this->error_ == ERROR_NO_SUCH_WINDOW ||
this->error_ == ERROR_STALE_ELEMENT_REFERENCE ||
this->error_ == ERROR_UNKNOWN_COMMAND) {
response_code = 404;
} else if (this->error_ == ERROR_UNKNOWN_METHOD) {
response_code = 405;
} else if (this->error_ == ERROR_JAVASCRIPT_ERROR ||
this->error_ == ERROR_MOVE_TARGET_OUT_OF_BOUNDS ||
this->error_ == ERROR_SCRIPT_TIMEOUT ||
this->error_ == ERROR_SESSION_NOT_CREATED ||
this->error_ == ERROR_UNABLE_TO_SET_COOKIE ||
this->error_ == ERROR_UNABLE_TO_CAPTURE_SCREEN ||
this->error_ == ERROR_UNEXPECTED_ALERT_OPEN ||
this->error_ == ERROR_UNKNOWN_ERROR ||
this->error_ == ERROR_UNSUPPORTED_OPERATION ||
this->error_ == ERROR_WEBDRIVER_TIMEOUT) {
response_code = 500;
} else {
response_code = 200;
}
return response_code;
}
std::string Response::ConvertErrorCode(const int error_code) {
if (error_code == WD_SUCCESS) {
return "";
} else if (error_code == ENOSUCHFRAME) {
return ERROR_NO_SUCH_FRAME;
} else if (error_code == ENOSUCHWINDOW) {
return ERROR_NO_SUCH_WINDOW;
} else if (error_code == EOBSOLETEELEMENT) {
return ERROR_STALE_ELEMENT_REFERENCE;
} else if (error_code == EINVALIDSELECTOR) {
return ERROR_INVALID_SELECTOR;
} else if (error_code == ENOSUCHALERT) {
return ERROR_NO_SUCH_ALERT;
} else if (error_code == EUNEXPECTEDALERTOPEN) {
return ERROR_UNEXPECTED_ALERT_OPEN;
} else if (error_code == ENOSUCHCOOKIE) {
return ERROR_NO_SUCH_COOKIE;
} else if (error_code == EELEMENTNOTENABLED) {
return ERROR_INVALID_ELEMENT_STATE;
} else if (error_code == EELEMENTNOTDISPLAYED) {
return ERROR_ELEMENT_NOT_INTERACTABLE;
} else if (error_code == EUNEXPECTEDJSERROR) {
return ERROR_JAVASCRIPT_ERROR;
} else if (error_code == EINVALIDCOOKIEDOMAIN) {
return ERROR_INVALID_COOKIE_DOMAIN;
} else if (error_code == ESCRIPTTIMEOUT) {
return ERROR_SCRIPT_TIMEOUT;
} else if (error_code == EMOVETARGETOUTOFBOUNDS) {
return ERROR_MOVE_TARGET_OUT_OF_BOUNDS;
} else if (error_code == EINVALIDARGUMENT) {
return ERROR_INVALID_ARGUMENT;
} else if (error_code == ENOSUCHELEMENT) {
return ERROR_NO_SUCH_ELEMENT;
} else if (error_code == EUNSUPPORTEDOPERATION) {
return ERROR_UNSUPPORTED_OPERATION;
}
return "";
}
int Response::ConvertStatusToCode(const std::string& status_string) {
if (status_string == "success") {
return WD_SUCCESS;
}
if (status_string == "element not selectable") {
return EELEMENTNOTSELECTED;
}
if (status_string == "element not visible") {
return EELEMENTNOTDISPLAYED;
}
if (status_string == "invalid cookie domain") {
return EINVALIDCOOKIEDOMAIN;
}
if (status_string == "invalid element coordinates") {
return EINVALIDCOORDINATES;
}
if (status_string == "invalid element state") {
return EELEMENTNOTENABLED;
}
if (status_string == "invalid selector") {
return EINVALIDSELECTOR;
}
if (status_string == "javascript error") {
return EUNEXPECTEDJSERROR;
}
if (status_string == "no such alert") {
return ENOSUCHALERT;
}
if (status_string == "no such element") {
return ENOSUCHELEMENT;
}
if (status_string == "no such frame") {
return ENOSUCHFRAME;
}
if (status_string == "no such window") {
return ENOSUCHWINDOW;
}
if (status_string == "script timeout") {
return ESCRIPTTIMEOUT;
}
if (status_string == "stale element reference") {
return EOBSOLETEELEMENT;
}
if (status_string == "timeout") {
return ETIMEOUT;
}
if (status_string == "unable to set cookie") {
return EUNABLETOSETCOOKIE;
}
if (status_string == "unexpected alert open") {
return EUNEXPECTEDALERTOPEN;
}
if (status_string == "unknown command") {
return ENOTIMPLEMENTED;
}
if (status_string == "unknown error") {
return EUNHANDLEDERROR;
}
if (status_string == "unsupported operation") {
return EUNSUPPORTEDOPERATION;
}
return EUNHANDLEDERROR;
}
}