| import 'dart:convert'; |
| |
| import 'package:webdriver/src/common/web_element.dart'; |
| |
| import '../../common/exception.dart'; |
| import '../../common/request.dart'; |
| |
| // Source: https://www.w3.org/TR/webdriver/#elements |
| const String w3cElementStr = 'element-6066-11e4-a52e-4f735466cecf'; |
| |
| dynamic parseW3cResponse(WebDriverResponse response) { |
| final int statusCode = response.statusCode; |
| Map responseBody; |
| try { |
| responseBody = json.decode(response.body); |
| } catch (e) { |
| final rawBody = response.body == null || response.body.isEmpty |
| ? '<empty response>' |
| : response.body; |
| throw WebDriverException( |
| statusCode, 'Error parsing response body: $rawBody'); |
| } |
| |
| if (statusCode < 200 || statusCode > 299) { |
| final Map value = responseBody['value']; |
| final String message = value['message']; |
| |
| // See https://www.w3.org/TR/webdriver/#handling-errors |
| switch (value['error']) { |
| case 'element click intercepted': |
| throw ElementClickInterceptedException(statusCode, message); |
| |
| case 'element not interactable': |
| throw ElementNotInteractableException(statusCode, message); |
| |
| case 'insecure certificate': |
| throw InsecureCertificateException(statusCode, message); |
| |
| case 'invalid argument': |
| throw InvalidArgumentException(statusCode, message); |
| |
| case 'invalid cookie domain': |
| throw InvalidCookieDomainException(statusCode, message); |
| |
| case 'invalid element state': |
| throw InvalidElementStateException(statusCode, message); |
| |
| case 'invalid selector': |
| throw InvalidSelectorException(statusCode, message); |
| |
| case 'invalid session id': |
| throw InvalidSessionIdException(statusCode, message); |
| |
| case 'javascript error': |
| throw JavaScriptException(statusCode, message); |
| |
| case 'move target out of bounds': |
| throw MoveTargetOutOfBoundsException(statusCode, message); |
| |
| case 'no such alert': |
| throw NoSuchAlertException(statusCode, message); |
| |
| case 'no such cookie': |
| throw NoSuchCookieException(statusCode, message); |
| |
| case 'no such element': |
| throw NoSuchElementException(statusCode, message); |
| |
| case 'no such frame': |
| throw NoSuchFrameException(statusCode, message); |
| |
| case 'no such window': |
| throw NoSuchWindowException(statusCode, message); |
| |
| case 'script timeout': |
| throw ScriptTimeoutException(statusCode, message); |
| |
| case 'session not created': |
| throw SessionNotCreatedException(statusCode, message); |
| |
| case 'stale element reference': |
| throw StaleElementReferenceException(statusCode, message); |
| |
| case 'timeout': |
| throw TimeoutException(statusCode, message); |
| |
| case 'unable to set cookie': |
| throw UnableToSetCookieException(statusCode, message); |
| |
| case 'unable to capture screen': |
| throw UnableToCaptureScreenException(statusCode, message); |
| |
| case 'unexpected alert open': |
| throw UnexpectedAlertOpenException(statusCode, message); |
| |
| case 'unknown command': |
| throw UnknownCommandException(statusCode, message); |
| |
| case 'unknown error': |
| throw UnknownException(statusCode, message); |
| |
| case 'unknown method': |
| throw UnknownMethodException(statusCode, message); |
| |
| case 'unsupported operation': |
| throw UnsupportedOperationException(statusCode, message); |
| |
| default: |
| throw WebDriverException(statusCode, message); |
| } |
| } |
| |
| return responseBody == null ? null : responseBody['value']; |
| } |
| |
| /// Prefix to represent element in webdriver uri. |
| /// |
| /// When [elementId] is null, it means root element. |
| String elementPrefix(String elementId) => |
| elementId == null ? '' : 'element/$elementId/'; |
| |
| dynamic deserialize(result, dynamic Function(String) createElement) { |
| if (result is Map) { |
| if (result.containsKey(w3cElementStr)) { |
| return createElement(result[w3cElementStr]); |
| } 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; |
| } |
| } |
| |
| dynamic serialize(dynamic obj) { |
| if (obj is WebElement) { |
| return {w3cElementStr: obj.id}; |
| } |
| |
| if (obj is Map) { |
| final newResult = <String, dynamic>{}; |
| for (final item in obj.entries) { |
| newResult[item.key] = serialize(item.value); |
| } |
| |
| return newResult; |
| } |
| |
| if (obj is List) { |
| return obj.map(serialize).toList(); |
| } |
| |
| return obj; |
| } |