blob: 4537f52b224f4a1461bc7d297b9dcbc73652c397 [file] [log] [blame]
import 'dart:convert';
import '../../common/exception.dart';
import '../../common/request.dart';
import '../../common/web_element.dart';
/// Magic constants -- identifiers indicating a value is an element.
/// Source: https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol
const String jsonWireElementStr = 'ELEMENT';
Object? parseJsonWireResponse(WebDriverResponse response,
{bool valueOnly = true}) {
final statusCode = response.statusCode!;
Map<String, dynamic> responseBody;
try {
responseBody = json.decode(response.body!) as Map<String, dynamic>;
} catch (e) {
final rawBody = response.body == null || response.body!.isEmpty
? '<empty response>'
: response.body;
if (statusCode == 405) {
throw UnknownCommandException(statusCode, rawBody);
}
throw WebDriverException(
statusCode, 'Error parsing response body: $rawBody');
}
if (statusCode < 200 ||
statusCode > 299 ||
(responseBody['status'] != null && responseBody['status'] != 0)) {
final status = responseBody['status'] as int?;
final message = responseBody['value']['message'] as String?;
switch (status) {
case 0:
throw StateError('Not a WebDriverError Status: 0 Message: $message');
case 6:
throw NoSuchDriverException(status, message);
case 7:
throw NoSuchElementException(status, message);
case 8:
throw NoSuchFrameException(status, message);
case 9:
throw UnknownCommandException(status, message);
case 10:
throw StaleElementReferenceException(status, message);
case 11:
throw ElementNotVisibleException(status, message);
case 12:
throw InvalidElementStateException(status, message);
case 15:
throw ElementIsNotSelectableException(status, message);
case 17:
throw JavaScriptException(status, message);
case 19:
throw XPathLookupException(status, message);
case 21:
throw TimeoutException(status, message);
case 23:
throw NoSuchWindowException(status, message);
case 24:
throw InvalidCookieDomainException(status, message);
case 25:
throw UnableToSetCookieException(status, message);
case 26:
throw UnexpectedAlertOpenException(status, message);
case 27:
throw NoSuchAlertException(status, message);
case 28:
throw ScriptTimeoutException(status, message);
case 29:
throw InvalidElementCoordinatesException(status, message);
case 30:
throw IMENotAvailableException(status, message);
case 31:
throw IMEEngineActivationFailedException(status, message);
case 32:
throw InvalidSelectorException(status, message);
case 33:
throw SessionNotCreatedException(status, message);
case 34:
throw MoveTargetOutOfBoundsException(status, message);
case 13:
throw UnknownException(status, message);
default:
throw WebDriverException(status, message);
}
}
if (valueOnly) {
return responseBody['value'];
}
return responseBody;
}
/// Prefix to represent element in webdriver uri.
///
/// When [elementId] is null, it means root element.
String elementPrefix(String? elementId) =>
elementId == null ? '' : 'element/$elementId/';
/// Deserializes json object returned by WebDriver server.
///
/// Mainly it handles the element object rebuild.
Object? deserialize(Object? result, dynamic Function(String) createElement) {
if (result is Map) {
if (result.containsKey(jsonWireElementStr)) {
return createElement(result[jsonWireElementStr] as String);
} else {
final newResult = {};
result.forEach((key, value) {
newResult[key] = deserialize(value, createElement);
});
return newResult;
}
} else if (result is List) {
return result.map((item) => deserialize(item, createElement)).toList();
} else {
return result;
}
}
Object? serialize(dynamic obj) {
if (obj is WebElement) {
return {jsonWireElementStr: obj.id};
}
if (obj is Map) {
return <String, dynamic>{
for (var item in obj.entries) item.key as String: serialize(item.value),
};
}
if (obj is List) {
return [for (var item in obj) serialize(item)];
}
return obj;
}