diff --git a/library/test/selenium/readme.md b/library/test/selenium/readme.md new file mode 100644 index 00000000..88828519 --- /dev/null +++ b/library/test/selenium/readme.md @@ -0,0 +1,27 @@ +Eiffel Selenium binding +================================================= + +## Overview + +This client is a binding for the REST API interface defined in the WebDriver protocol http://code.google.com/p/selenium/wiki/JsonWireProtocol. + +WARNING this API is still under development, and maybe it will change + +## Requirements + +* Get the server selenium-server-standalone-#.jar file provided here: http://code.google.com/p/selenium/downloads/list + +* Download and run that file, replacing # with the current server version. + + java -jar selenium-server-standalone-#.jar + (it only has a Firefox WebDriver by default) + + But you can add other drivers doing something like that (change PATH_TO to the corresponding value in your environment) + java -jar selenium-server-standalone-2.32.0.jar + -Dwebdriver.chrome.driver=%PATH_TO%\chromedriver.exe -Dwebdriver.ie.driver=%PATH_TO%\IEDriverServer.exe + +## Getting Started + +TODO + + diff --git a/library/test/selenium/selenium-safe.ecf b/library/test/selenium/selenium-safe.ecf new file mode 100644 index 00000000..b09d84cf --- /dev/null +++ b/library/test/selenium/selenium-safe.ecf @@ -0,0 +1,19 @@ + + + + + + + + + + + /EIFGENs$ + /CVS$ + /.svn$ + + + + diff --git a/library/test/selenium/src.rc b/library/test/selenium/src.rc new file mode 100644 index 00000000..b0ec159c --- /dev/null +++ b/library/test/selenium/src.rc @@ -0,0 +1,6 @@ +#include + +STRINGTABLE +BEGIN + 1 "This Program was made using EiffelStudio using Visual Studio C++" +END diff --git a/library/test/selenium/src/command_executor.e b/library/test/selenium/src/command_executor.e new file mode 100644 index 00000000..961a60ab --- /dev/null +++ b/library/test/selenium/src/command_executor.e @@ -0,0 +1,120 @@ +note + description: "{COMMAND_EXECUTOR} object that execute a command in the JSONWireProtocol" + author: "" + date: "$Date$" + revision: "$Revision$" + EIS: "name=SELINIUM", "protocol=JSONWireProtocol", "src=https://code.google.com/p/selenium/wiki/JsonWireProtocol#Commands" + +class + COMMAND_EXECUTOR +inherit + JSON_HELPER + SE_JSON_WIRE_PROTOCOL_COMMANDS + +create + make + +feature -- Initialization + make (a_host : STRING_32) + do + host := a_host + end + +feature -- Status Report + is_available : BOOLEAN + -- Is the Seleniun server up and running? + local + resp: HTTP_CLIENT_RESPONSE + do +-- resp := execute_get (cmd_ping) +-- if resp.status = 200 then +-- Result := True +-- end + Result := true + end +feature -- Commands + + status : SE_RESPONSE + require + selinum_server_available : is_available + local + resp: HTTP_CLIENT_RESPONSE + do + create Result.make_empty + resp := execute_get (cmd_status) + if attached resp.body as l_body then + Result := build_response (l_body) + end + end + + new_session (capabilities : STRING_32) : SE_RESPONSE + require + selinum_server_available : is_available + local + resp: HTTP_CLIENT_RESPONSE + do + create Result.make_empty + resp := execute_post (cmd_new_session, capabilities) + if attached resp.body as l_body then + Result := build_response(l_body) + end + end + + sessions : SE_RESPONSE + require + selinum_server_available : is_available + local + resp: HTTP_CLIENT_RESPONSE + do + create Result.make_empty + resp := execute_get (cmd_sessions) + if attached resp.body as l_body then + Result := build_response(l_body) + end + end + + +feature {NONE} -- Implementation + execute_get (command_name:STRING_32) : HTTP_CLIENT_RESPONSE + local + h: LIBCURL_HTTP_CLIENT + http_session : HTTP_CLIENT_SESSION + do + create h.make + http_session := h.new_session (host) + Result := http_session.get (command_name, context_executor) + end + + execute_post (command_name:STRING_32; data: STRING_32) : HTTP_CLIENT_RESPONSE + local + h: LIBCURL_HTTP_CLIENT + http_session : HTTP_CLIENT_SESSION + do + create h.make + http_session := h.new_session (host) + Result := http_session.post (command_name, context_executor, data) + + end + + + build_response (a_message : STRING_32) : SE_RESPONSE + do + create Result.make_empty + initialize_converters (json) + if attached {SE_RESPONSE} json.object_from_json (a_message, "SE_RESPONSE") as l_response then + Result := l_response + end + Result.set_json_response (a_message) + end + + + context_executor : HTTP_CLIENT_REQUEST_CONTEXT + -- request context for each request + once + create Result.make + Result.headers.put ("application/json;charset=UTF-8", "Content-Type") + Result.headers.put ("application/json;charset=UTF-8", "Accept") + end + + host : STRING_32 +end diff --git a/library/test/selenium/src/converter/se_build_value_json_converter.e b/library/test/selenium/src/converter/se_build_value_json_converter.e new file mode 100644 index 00000000..9c55d318 --- /dev/null +++ b/library/test/selenium/src/converter/se_build_value_json_converter.e @@ -0,0 +1,72 @@ +note + description: "Summary description for {SE_BUILD_VALUE_JSON_CONVERTER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_BUILD_VALUE_JSON_CONVERTER +inherit + SE_JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make + do + create object.make_empty + end + +feature -- Access + + object: SE_BUILD_VALUE + +feature -- Conversion + + from_json (j: like to_json): detachable like object + do + create Result.make_empty + if attached {STRING_32} json_to_object (j.item (version_key),Void) as l_item then + Result.set_version(l_item) + end + if attached {STRING_32} json_to_object (j.item (revision_key), Void) as l_item then + Result.set_revision(l_item) + end + if attached {STRING_32} json_to_object (j.item (time_key),Void) as l_item then + Result.set_time(l_item) + end + + + + end + + to_json (o: like object): JSON_OBJECT + do + create Result.make + Result.put (json.value (o.version), version_key) + Result.put (json.value (o.revision), revision_key) + Result.put (json.value (o.time), time_key) + end + +feature {NONE} -- Implementation + + + + version_key: JSON_STRING + once + create Result.make_json ("version") + end + + time_key: JSON_STRING + once + create Result.make_json ("time") + end + + revision_key: JSON_STRING + once + create Result.make_json ("revision") + end + +end diff --git a/library/test/selenium/src/converter/se_capabilities_json_converter.e b/library/test/selenium/src/converter/se_capabilities_json_converter.e new file mode 100644 index 00000000..29349de4 --- /dev/null +++ b/library/test/selenium/src/converter/se_capabilities_json_converter.e @@ -0,0 +1,185 @@ +note + description: "Summary description for {SE_CAPABILITIES_JSON_CONVERTER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_CAPABILITIES_JSON_CONVERTER + +inherit + + SE_JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make + do + create object.make + end + +feature -- Access + + object: SE_CAPABILITIES + +feature -- Conversion + + from_json (j: like to_json): detachable like object + do + create Result.make + if attached {STRING_32} json_to_object (j.item (browser_name_key), Void) as l_item then + Result.set_browser_name(l_item) + end + if attached {STRING_32} json_to_object (j.item (version_key), Void) as l_item then + Result.set_version(l_item) + end + if attached {STRING_32} json_to_object (j.item (platform_key), Void) as l_item then + Result.set_platform(l_item) + end + if attached {BOOLEAN} json_to_object (j.item (javascriptenabled_key), Void) as l_item then + Result.set_javascript_enabled(l_item) + end + if attached {BOOLEAN} json_to_object (j.item (takesscreenshot_key), Void) as l_item then + Result.set_takes_screenshot(l_item) + end + if attached {BOOLEAN} json_to_object (j.item (handlesalerts_key ), Void) as l_item then + Result.set_handles_alerts(l_item) + end + if attached {BOOLEAN} json_to_object (j.item (locationcontextenabled_key ), Void) as l_item then + Result.set_location_context_enabled (l_item) + end + if attached {BOOLEAN} json_to_object (j.item (applicationcacheenabled_key ), Void) as l_item then + Result.set_application_cache_enabled (l_item) + end + if attached {BOOLEAN} json_to_object (j.item (browserconnectionenabled_key ), Void) as l_item then + Result.set_browser_connection_enabled (l_item) + end + if attached {BOOLEAN} json_to_object (j.item (cssselectorsenabled_key ), Void) as l_item then + Result.set_css_selectors_enabled (l_item) + end + if attached {BOOLEAN} json_to_object (j.item (webstorageenabled_key ), Void) as l_item then + Result.set_web_storage_enabled (l_item) + end + if attached {BOOLEAN} json_to_object (j.item (rotatable_key ), Void) as l_item then + Result.set_rotatable (l_item) + end + if attached {BOOLEAN} json_to_object (j.item (acceptsslcerts_key ), Void) as l_item then + Result.set_accept_ssl_certs (l_item) + end + if attached {BOOLEAN} json_to_object (j.item (nativeevents_key ), Void) as l_item then + Result.set_native_events (l_item) + end + +-- if attached {WEB_DRIVER_PROXY} json_to_object (j.item (proxy_key), {WEB_DRIVER_PROXY}) as lv then +-- Result.set_proxy(lv) +-- end + + end + + to_json (o: like object): JSON_OBJECT + do + create Result.make + Result.put (json.value (o.browser_name),browser_name_key) + Result.put (json.value (o.version),version_key) + Result.put (json.value (o.platform),platform_key) + Result.put (json.value (o.is_javascript_enabled),javascriptenabled_key) + Result.put (json.value (o.takes_screenshot),takesscreenshot_key) + Result.put (json.value (o.handles_alerts),handlesalerts_key) + Result.put (json.value (o.is_database_enabled),databaseenabled_key) + Result.put (json.value (o.is_location_context_enabled),locationcontextenabled_key) + Result.put (json.value (o.is_application_cache_enabled),applicationcacheenabled_key) + Result.put (json.value (o.is_browser_connection_enabled),browserconnectionenabled_key) + Result.put (json.value (o.is_css_selectors_enabled),cssselectorsenabled_key) + Result.put (json.value (o.is_web_storage_enabled),webstorageenabled_key) + Result.put (json.value (o.is_rotatable),rotatable_key) + Result.put (json.value (o.accept_ssl_certs),acceptsslcerts_key) + Result.put (json.value (o.native_events),nativeevents_key) + --Result.put (json.value (o.proxy),proxy_key) + end + +feature {NONE} -- Implementation + + browser_name_key: JSON_STRING + once + create Result.make_json ("browserName") + end + + version_key: JSON_STRING + once + create Result.make_json ("version") + end + + platform_key: JSON_STRING + once + create Result.make_json ("platform") + end + + javascriptEnabled_key: JSON_STRING + once + create Result.make_json ("javascriptEnabled") + end + + takesScreenshot_key: JSON_STRING + once + create Result.make_json ("takesScreenshot") + end + + handlesAlerts_key: JSON_STRING + once + create Result.make_json ("handlesAlerts") + end + + databaseEnabled_key: JSON_STRING + once + create Result.make_json ("databaseEnabled") + end + + locationContextEnabled_key: JSON_STRING + once + create Result.make_json ("locationContextEnabled") + end + + applicationCacheEnabled_key: JSON_STRING + once + create Result.make_json ("applicationCacheEnabled") + end + + browserConnectionEnabled_key: JSON_STRING + once + create Result.make_json ("browserConnectionEnabled") + end + + cssSelectorsEnabled_key: JSON_STRING + once + create Result.make_json ("cssSelectorsEnabled") + end + + webStorageEnabled_key: JSON_STRING + once + create Result.make_json ("webStorageEnabled") + end + + rotatable_key: JSON_STRING + once + create Result.make_json ("rotatable") + end + + acceptSslCerts_key: JSON_STRING + once + create Result.make_json ("acceptSslCerts") + end + + nativeEvents_key: JSON_STRING + once + create Result.make_json ("nativeEvents") + end + + proxy_key: JSON_STRING + once + create Result.make_json ("proxy") + end + +end diff --git a/library/test/selenium/src/converter/se_java_value_json_converter.e b/library/test/selenium/src/converter/se_java_value_json_converter.e new file mode 100644 index 00000000..2385a42d --- /dev/null +++ b/library/test/selenium/src/converter/se_java_value_json_converter.e @@ -0,0 +1,51 @@ +note + description: "Summary description for {SE_JAVA_VALUE_JSON_CONVERTER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_JAVA_VALUE_JSON_CONVERTER +inherit + SE_JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make + do + create object.make_empty + end + +feature -- Access + + object: SE_JAVA_VALUE + +feature -- Conversion + + from_json (j: like to_json): detachable like object + do + create Result.make_empty + if attached {STRING_32} json_to_object (j.item (version_key), Void) as l_item then + Result.set_version(l_item) + end + end + + to_json (o: like object): JSON_OBJECT + do + create Result.make + Result.put (json.value (o.version), version_key) + end + +feature {NONE} -- Implementation + + + + version_key: JSON_STRING + once + create Result.make_json ("version") + end + +end diff --git a/library/test/selenium/src/converter/se_json_converter.e b/library/test/selenium/src/converter/se_json_converter.e new file mode 100644 index 00000000..24c3b45b --- /dev/null +++ b/library/test/selenium/src/converter/se_json_converter.e @@ -0,0 +1,27 @@ +note + description: "Summary description for {SE_JSON_CONVERTER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + SE_JSON_CONVERTER + +inherit + JSON_CONVERTER + +feature -- Convertion + + json_to_object (j: detachable JSON_VALUE; a_type: detachable TYPE [detachable ANY]): detachable ANY + local + l_classname: detachable STRING + do + if a_type /= Void then + l_classname := a_type.name + if l_classname.item (1) = '!' then + l_classname := l_classname.substring (2, l_classname.count) + end + end + Result := json.object (j, l_classname) + end +end diff --git a/library/test/selenium/src/converter/se_os_value_json_converter.e b/library/test/selenium/src/converter/se_os_value_json_converter.e new file mode 100644 index 00000000..6da07888 --- /dev/null +++ b/library/test/selenium/src/converter/se_os_value_json_converter.e @@ -0,0 +1,73 @@ +note + description: "Summary description for {SE_OS_VALUE_JSON_CONVERTER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_OS_VALUE_JSON_CONVERTER +inherit + SE_JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make + do + create object.make_empty + end + +feature -- Access + + object: SE_OS_VALUE + +feature -- Conversion + + from_json (j: like to_json): detachable like object + do + create Result.make_empty + if attached {STRING_32} json_to_object (j.item (version_key), Void) as l_item then + Result.set_version(l_item) + end + if attached {STRING_32} json_to_object (j.item (name_key), Void) as l_item then + Result.set_name(l_item) + end + if attached {STRING_32} json_to_object (j.item (architecture_key), Void) as l_item then + Result.set_architecture(l_item) + end + + + + end + + to_json (o: like object): JSON_OBJECT + do + create Result.make + Result.put (json.value (o.architecture), architecture_key) + Result.put (json.value (o.name), name_key) + Result.put (json.value (o.version), version_key) + end + +feature {NONE} -- Implementation + + + + version_key: JSON_STRING + once + create Result.make_json ("version") + end + + name_key: JSON_STRING + once + create Result.make_json ("name") + end + + architecture_key: JSON_STRING + once + create Result.make_json ("arch") + end + + +end diff --git a/library/test/selenium/src/converter/se_response_json_converter.e b/library/test/selenium/src/converter/se_response_json_converter.e new file mode 100644 index 00000000..4e28414f --- /dev/null +++ b/library/test/selenium/src/converter/se_response_json_converter.e @@ -0,0 +1,73 @@ +note + description: "Summary description for {SE_RESPONSE_JSON_CONVERTER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_RESPONSE_JSON_CONVERTER +inherit + SE_JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make + do + create object.make_empty + end + +feature -- Access + + object: SE_RESPONSE + +feature -- Conversion + + from_json (j: like to_json): detachable like object + do + create Result.make_empty + if attached {STRING_32} json_to_object (j.item (session_key), Void) as l_item then + Result.set_session_id(l_item) + end + if attached {INTEGER_32} json_to_object (j.item (status_key), Void) as l_item then + Result.set_status(l_item) + end + if attached {JSON_VALUE} j.item (value_key) as l_item then + Result.set_value(l_item.representation) + end + + + + end + + to_json (o: like object): JSON_OBJECT + do + create Result.make + Result.put (json.value (o.session_id),session_key) + Result.put (json.value (o.status), status_key) + Result.put (json.value (o.value), value_key) + end + +feature {NONE} -- Implementation + + + + session_key: JSON_STRING + once + create Result.make_json ("sessionId") + end + + status_key: JSON_STRING + once + create Result.make_json ("status") + end + + value_key: JSON_STRING + once + create Result.make_json ("value") + end + + +end diff --git a/library/test/selenium/src/converter/se_status_json_converter.e b/library/test/selenium/src/converter/se_status_json_converter.e new file mode 100644 index 00000000..ae1c379e --- /dev/null +++ b/library/test/selenium/src/converter/se_status_json_converter.e @@ -0,0 +1,101 @@ +note + description: "A converter for SE_STATUS" + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_STATUS_JSON_CONVERTER + +inherit + SE_JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make + do + create object + end + +feature -- Access + + object: SE_STATUS + +feature -- Conversion + + from_json (j: like to_json): detachable like object + do + create Result + if attached {INTEGER_8} json_to_object (j.item (status_key), Void) as l_ucs then + Result.set_status (l_ucs.out) + end + if attached {STRING_32} json_to_object (j.item (session_id_key), Void) as l_ucs then + Result.set_session_id (l_ucs) + end + if attached {STRING_32} json_to_object (j.item (state_key), Void) as l_ucs then + Result.set_state (l_ucs) + end + if attached {STRING_32} json_to_object (j.item (class_name_key), Void) as l_ucs then + Result.set_class_name (l_ucs) + end + if attached {INTEGER_32} json_to_object (j.item (hash_code_key), Void) as l_ucs then + Result.set_hash_code (l_ucs.out) + end + if attached {SE_STATUS_VALUE} json_to_object (j.item (value_key), {SE_STATUS_VALUE}) as lv then + Result.set_value(lv) + end + end + + to_json (o: like object): JSON_OBJECT + do + create Result.make + Result.put (json.value (o.status), status_key) + Result.put (json.value (o.session_id), session_id_key) + Result.put (json.value (o.value), value_key) + Result.put (json.value (o.state), state_key) + Result.put (json.value (o.class_name), class_name_key) + Result.put (json.value (o.hash_code), hash_code_key) + end + +feature {NONE} -- Implementation + + + + + status_key: JSON_STRING + once + create Result.make_json ("status") + end + + session_id_key: JSON_STRING + once + create Result.make_json ("sessionId") + end + + value_key: JSON_STRING + once + create Result.make_json ("value") + end + + state_key: JSON_STRING + once + create Result.make_json ("state") + end + + class_name_key: JSON_STRING + once + create Result.make_json ("class") + end + + hash_code_key : JSON_STRING + once + create Result.make_json ("hCode") + end + +note + copyright: "2011-2012, Javier Velilla, Jocelyn Fiat and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" +end diff --git a/library/test/selenium/src/converter/se_status_value_json_converter.e b/library/test/selenium/src/converter/se_status_value_json_converter.e new file mode 100644 index 00000000..2f8ad543 --- /dev/null +++ b/library/test/selenium/src/converter/se_status_value_json_converter.e @@ -0,0 +1,70 @@ +note + description: "Summary description for {SE_STATUS_VALUE_JSON_CONVERTER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_STATUS_VALUE_JSON_CONVERTER +inherit + SE_JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make + do + create object.make_empty + end + +feature -- Access + + object: SE_STATUS_VALUE + +feature -- Conversion + + from_json (j: like to_json): detachable like object + do + create Result.make_empty + if attached {SE_OS_VALUE} json_to_object (j.item (os_key), {SE_OS_VALUE}) as l_item then + Result.set_os_value(l_item) + end + if attached {SE_JAVA_VALUE} json_to_object (j.item (java_key), {SE_JAVA_VALUE}) as l_item then + Result.set_java_value(l_item) + end + if attached {SE_BUILD_VALUE} json_to_object (j.item (build_key), {SE_BUILD_VALUE}) as l_item then + Result.set_build_value(l_item) + end + + end + + to_json (o: like object): JSON_OBJECT + do + create Result.make + Result.put (json.value (o.os_value), os_key) + Result.put (json.value (o.java_value), java_key) + Result.put (json.value (o.build_value), build_key) + end + +feature {NONE} -- Implementation + + + + os_key: JSON_STRING + once + create Result.make_json ("os") + end + + java_key: JSON_STRING + once + create Result.make_json ("java") + end + + build_key: JSON_STRING + once + create Result.make_json ("build") + end + +end diff --git a/library/test/selenium/src/helpers/json_helper.e b/library/test/selenium/src/helpers/json_helper.e new file mode 100644 index 00000000..88b8fb3f --- /dev/null +++ b/library/test/selenium/src/helpers/json_helper.e @@ -0,0 +1,72 @@ +note + description: "Summary description for {JSON_HELPER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + JSON_HELPER +inherit + + SHARED_EJSON + +feature -- Access + to_json (an_object : ANY) :detachable JSON_VALUE + local + parser: JSON_PARSER + do + initialize_converters (json) + if attached json.value (an_object) as lv then + Result := lv + end + end + + string_to_json ( str: STRING_32): detachable JSON_VALUE + local + parser: JSON_PARSER + do + initialize_converters (json) + create parser.make_parser (str) + if attached parser.parse_object as st and parser.is_parsed then + Result := st + end + end + + json_to_se_status (post: STRING_32): detachable SE_STATUS + local + parser: JSON_PARSER + do + initialize_converters (json) + create parser.make_parser (post) + if attached parser.parse_object as st and parser.is_parsed then + if attached {SE_STATUS} json.object (st, "SE_STATUS") as l_status then + Result := l_status + end + end + end + + json_to_se_capabilities (post: STRING_32): detachable SE_CAPABILITIES + local + parser: JSON_PARSER + do + initialize_converters (json) + create parser.make_parser (post) + if attached parser.parse_object as st and parser.is_parsed then + if attached {SE_CAPABILITIES} json.object (st, "SE_CAPABILITIES") as l_capabilities then + Result := l_capabilities + end + end + end + + initialize_converters (j: like json) + -- Initialize json converters + do + j.add_converter (create {SE_STATUS_JSON_CONVERTER}.make) + j.add_converter (create {SE_BUILD_VALUE_JSON_CONVERTER}.make) + j.add_converter (create {SE_JAVA_VALUE_JSON_CONVERTER}.make) + j.add_converter (create {SE_OS_VALUE_JSON_CONVERTER}.make) + j.add_converter (create {SE_STATUS_VALUE_JSON_CONVERTER}.make) + j.add_converter (create {SE_CAPABILITIES_JSON_CONVERTER}.make) + j.add_converter (create {SE_RESPONSE_JSON_CONVERTER}.make) + end +end diff --git a/library/test/selenium/src/protocol/se_json_wire_protocol.e b/library/test/selenium/src/protocol/se_json_wire_protocol.e new file mode 100644 index 00000000..dca15c36 --- /dev/null +++ b/library/test/selenium/src/protocol/se_json_wire_protocol.e @@ -0,0 +1,162 @@ +note + description: "Summary description for {SE_JSON_WIRE_PROTOCOL}." + author: "" + date: "$Date$" + revision: "$Revision$" + EIS: "name=SELINIUM", "protocol=http", "src=https://code.google.com/p/selenium/wiki/JsonWireProtocol" + +class + SE_JSON_WIRE_PROTOCOL + +inherit + + JSON_HELPER + + SE_JSON_WIRE_PROTOCOL_COMMANDS + +create + make, make_with_host + +feature -- Initialization + + make + -- + local + h: LIBCURL_HTTP_CLIENT + do + create h.make + host := "http://127.0.0.1:4444/wd/hub/" + initialize_executor + end + + make_with_host (a_host: STRING_32) + -- + local + h: LIBCURL_HTTP_CLIENT + do + create h.make + host := a_host + initialize_executor + end + +feature -- Commands + + status: detachable SE_STATUS + -- GET /status + -- Query the server's current status. + -- The server should respond with a general "HTTP 200 OK" response if it is alive and accepting commands. + -- The response body should be a JSON object describing the state of the server. + -- All server implementations should return two basic objects describing the server's current platform and when the server was built. + -- All fields are optional; if omitted, the client should assume the value is uknown. + -- Furthermore, server implementations may include additional fields not listed here. + local + response : SE_RESPONSE + do + if commnad_executor.is_available then + + response := commnad_executor.status + if attached response.json_response as l_response then + Result := json_to_se_status (l_response) + end + else + -- TODO log the error. + -- Handling error + -- the Selenium server is not running or not it is reachable + end + end + + create_session_with_desired_capabilities (capabilities: SE_CAPABILITIES): detachable SE_SESSION + -- POST /session + -- Create a new session. + -- The server should attempt to create a session that most closely matches the desired and required capabilities. + -- Required capabilities have higher priority than desired capabilities and must be set for the session to be created. + -- JSON Parameters: + -- desiredCapabilities - {object} An object describing the session's desired capabilities. + -- requiredCapabilities - {object} An object describing the session's required capabilities (Optional). + -- Returns: + -- A 302 See Other redirect to /session/:sessionId, where :sessionId is the ID of the newly created session. + -- Potential Errors: + -- SessionNotCreatedException - If a required capability could not be set. + local + response : SE_RESPONSE + do + -- TODO, update the status of the server + -- SE_STATUS + -- SE_ERROR + -- create an COMMAND_EXECUTOR + if commnad_executor.is_available then + + if attached to_json (capabilities) as l_json then + response := commnad_executor.new_session(desired_capabilities (l_json.representation)) + if attached response.json_response as r_value then + Result := build_session (r_value) + end + end + else + end + end + + + sessions : detachable LIST[SE_SESSION] + -- GET /sessions + -- Returns a list of the currently active sessions. Each session will be returned as a list of JSON objects with the following keys: + -- id string The session ID. + -- capabilities object An object describing the session's capabilities. + local + response : SE_RESPONSE + index : INTEGER + do + if commnad_executor.is_available then + response := commnad_executor.sessions + if attached response.value as l_value and then attached {JSON_ARRAY} string_to_json (l_value) as l_json_array then + create {ARRAYED_LIST[SE_SESSION]} Result.make (10) + from + index := 1 + until + index > l_json_array.count + loop + if attached {JSON_OBJECT} l_json_array.i_th (index) as json_obj then + if attached build_session (json_obj.representation) as l_session then + Result.force ( l_session) + end + end + index := index + 1 + end + end + else + -- TODO handle error + end + + end + +feature {NONE} -- Implementation + initialize_executor + do + create commnad_executor.make ( host ) + end + + host: STRING_32 + + desired_capabilities (capabilites: STRING_32): STRING_32 + do + create Result.make_from_string (desired_capabilities_template) + Result.replace_substring_all ("$DESIRED_CAPABILITIES", capabilites) + end + + desired_capabilities_template: STRING = "[ + { + "desiredCapabilities": $DESIRED_CAPABILITIES + } + ]" + + commnad_executor : COMMAND_EXECUTOR + + build_session (value : STRING_32): detachable SE_SESSION + do + if attached {JSON_OBJECT} string_to_json (value) as l_value then + if attached l_value.item ("sessionId") as ls and then attached l_value.item ("value") as lv and then attached json_to_se_capabilities (lv.representation) as lc then + create Result.make (ls.representation, lc) + end + end + end +end diff --git a/library/test/selenium/src/protocol/se_json_wire_protocol_commands.e b/library/test/selenium/src/protocol/se_json_wire_protocol_commands.e new file mode 100644 index 00000000..243fc733 --- /dev/null +++ b/library/test/selenium/src/protocol/se_json_wire_protocol_commands.e @@ -0,0 +1,116 @@ +note + description: "Summary description for {SE_JSON_WIRE_PROTOCOL_COMMANDS}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_JSON_WIRE_PROTOCOL_COMMANDS + + +feature + cmd_ping : STRING = "" + --GET / expected a 200 ok + + cmd_status : STRING = "status" + --GET /status Query the server's current status. + + cmd_new_session : STRING = "session" + --POST /session Create a new session. + cmd_sessions : STRING = "sessions" + --GET /sessions Returns a list of the currently active sessions. +--GET /session/:sessionId Retrieve the capabilities of the specified session. +--DELETE /session/:sessionId Delete the session. +--POST /session/:sessionId/timeouts Configure the amount of time that a particular type of operation can execute for before they are aborted and a |Timeout| error is returned to the client. +--POST /session/:sessionId/timeouts/async_script Set the amount of time, in milliseconds, that asynchronous scripts executed by /session/:sessionId/execute_async are permitted to run before they are aborted and a |Timeout| error is returned to the client. +--POST /session/:sessionId/timeouts/implicit_wait Set the amount of time the driver should wait when searching for elements. +--GET /session/:sessionId/window_handle Retrieve the current window handle. +--GET /session/:sessionId/window_handles Retrieve the list of all window handles available to the session. +--GET /session/:sessionId/url Retrieve the URL of the current page. +--POST /session/:sessionId/url Navigate to a new URL. +--POST /session/:sessionId/forward Navigate forwards in the browser history, if possible. +--POST /session/:sessionId/back Navigate backwards in the browser history, if possible. +--POST /session/:sessionId/refresh Refresh the current page. +--POST /session/:sessionId/execute Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. +--POST /session/:sessionId/execute_async Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. +--GET /session/:sessionId/screenshot Take a screenshot of the current page. +--GET /session/:sessionId/ime/available_engines List all available engines on the machine. +--GET /session/:sessionId/ime/active_engine Get the name of the active IME engine. +--GET /session/:sessionId/ime/activated Indicates whether IME input is active at the moment (not if it's available. +--POST /session/:sessionId/ime/deactivate De-activates the currently-active IME engine. +--POST /session/:sessionId/ime/activate Make an engines that is available (appears on the listreturned by getAvailableEngines) active. +--POST /session/:sessionId/frame Change focus to another frame on the page. +--POST /session/:sessionId/window Change focus to another window. +--DELETE /session/:sessionId/window Close the current window. +--POST /session/:sessionId/window/:windowHandle/size Change the size of the specified window. +--GET /session/:sessionId/window/:windowHandle/size Get the size of the specified window. +--POST /session/:sessionId/window/:windowHandle/position Change the position of the specified window. +--GET /session/:sessionId/window/:windowHandle/position Get the position of the specified window. +--POST /session/:sessionId/window/:windowHandle/maximize Maximize the specified window if not already maximized. +--GET /session/:sessionId/cookie Retrieve all cookies visible to the current page. +--POST /session/:sessionId/cookie Set a cookie. +--DELETE /session/:sessionId/cookie Delete all cookies visible to the current page. +--DELETE /session/:sessionId/cookie/:name Delete the cookie with the given name. +--GET /session/:sessionId/source Get the current page source. +--GET /session/:sessionId/title Get the current page title. +--POST /session/:sessionId/element Search for an element on the page, starting from the document root. +--POST /session/:sessionId/elements Search for multiple elements on the page, starting from the document root. +--POST /session/:sessionId/element/active Get the element on the page that currently has focus. +--GET /session/:sessionId/element/:id Describe the identified element. +--POST /session/:sessionId/element/:id/element Search for an element on the page, starting from the identified element. +--POST /session/:sessionId/element/:id/elements Search for multiple elements on the page, starting from the identified element. +--POST /session/:sessionId/element/:id/click Click on an element. +--POST /session/:sessionId/element/:id/submit Submit a FORM element. +--GET /session/:sessionId/element/:id/text Returns the visible text for the element. +--POST /session/:sessionId/element/:id/value Send a sequence of key strokes to an element. +--POST /session/:sessionId/keys Send a sequence of key strokes to the active element. +--GET /session/:sessionId/element/:id/name Query for an element's tag name. +--POST /session/:sessionId/element/:id/clear Clear a TEXTAREA or text INPUT element's value. +--GET /session/:sessionId/element/:id/selected Determine if an OPTION element, or an INPUT element of type checkbox or radiobutton is currently selected. +--GET /session/:sessionId/element/:id/enabled Determine if an element is currently enabled. +--GET /session/:sessionId/element/:id/attribute/:name Get the value of an element's attribute. +--GET /session/:sessionId/element/:id/equals/:other Test if two element IDs refer to the same DOM element. +--GET /session/:sessionId/element/:id/displayed Determine if an element is currently displayed. +--GET /session/:sessionId/element/:id/location Determine an element's location on the page. +--GET /session/:sessionId/element/:id/location_in_view Determine an element's location on the screen once it has been scrolled into view. +--GET /session/:sessionId/element/:id/size Determine an element's size in pixels. +--GET /session/:sessionId/element/:id/css/:propertyName Query the value of an element's computed CSS property. +--GET /session/:sessionId/orientation Get the current browser orientation. +--POST /session/:sessionId/orientation Set the browser orientation. +--GET /session/:sessionId/alert_text Gets the text of the currently displayed JavaScript alert(), confirm(), or prompt() dialog. +--POST /session/:sessionId/alert_text Sends keystrokes to a JavaScript prompt() dialog. +--POST /session/:sessionId/accept_alert Accepts the currently displayed alert dialog. +--POST /session/:sessionId/dismiss_alert Dismisses the currently displayed alert dialog. +--POST /session/:sessionId/moveto Move the mouse by an offset of the specificed element. +--POST /session/:sessionId/click Click any mouse button (at the coordinates set by the last moveto command). +--POST /session/:sessionId/buttondown Click and hold the left mouse button (at the coordinates set by the last moveto command). +--POST /session/:sessionId/buttonup Releases the mouse button previously held (where the mouse is currently at). +--POST /session/:sessionId/doubleclick Double-clicks at the current mouse coordinates (set by moveto). +--POST /session/:sessionId/touch/click Single tap on the touch enabled device. +--POST /session/:sessionId/touch/down Finger down on the screen. +--POST /session/:sessionId/touch/up Finger up on the screen. +--POST /session/:sessionId/touch/move Finger move on the screen. +--POST /session/:sessionId/touch/scroll Scroll on the touch screen using finger based motion events. +--POST /session/:sessionId/touch/scroll Scroll on the touch screen using finger based motion events. +--POST /session/:sessionId/touch/doubleclick Double tap on the touch screen using finger motion events. +--POST /session/:sessionId/touch/longclick Long press on the touch screen using finger motion events. +--POST /session/:sessionId/touch/flick Flick on the touch screen using finger motion events. +--POST /session/:sessionId/touch/flick Flick on the touch screen using finger motion events. +--GET /session/:sessionId/location Get the current geo location. +--POST /session/:sessionId/location Set the current geo location. +--GET /session/:sessionId/local_storage Get all keys of the storage. +--POST /session/:sessionId/local_storage Set the storage item for the given key. +--DELETE /session/:sessionId/local_storage Clear the storage. +--GET /session/:sessionId/local_storage/key/:key Get the storage item for the given key. +--DELETE /session/:sessionId/local_storage/key/:key Remove the storage item for the given key. +--GET /session/:sessionId/local_storage/size Get the number of items in the storage. +--GET /session/:sessionId/session_storage Get all keys of the storage. +--POST /session/:sessionId/session_storage Set the storage item for the given key. +--DELETE /session/:sessionId/session_storage Clear the storage. +--GET /session/:sessionId/session_storage/key/:key Get the storage item for the given key. +--DELETE /session/:sessionId/session_storage/key/:key Remove the storage item for the given key. +--GET /session/:sessionId/session_storage/size Get the number of items in the storage. +--POST /session/:sessionId/log Get the log for a given log type. +--GET /session/:sessionId/log/types Get available log types. +--GET /session/:sessionId/application_cache/status Get the status of the html5 application cache. +end diff --git a/library/test/selenium/src/response/se_build_value.e b/library/test/selenium/src/response/se_build_value.e new file mode 100644 index 00000000..f0cd4dfd --- /dev/null +++ b/library/test/selenium/src/response/se_build_value.e @@ -0,0 +1,63 @@ +note + description: "Object that describe the build information from the current server" + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_BUILD_VALUE + +create + make, + make_empty + +feature{NONE} -- Initialization + make ( a_version : STRING_32; a_revision: STRING_32; a_time: STRING_32) + do + set_version(a_version) + set_revision (a_revision) + set_time (a_time) + end + + make_empty + do + + end + +feature -- Access + version : detachable STRING_32 + -- A generic release label (i.e. "2.0rc3") + + revision : detachable STRING_32 + --The revision of the local source control client from which the server was built + + time : detachable STRING_32 + --A timestamp from when the server was built. + +feature -- Change Element + set_version (a_version : STRING_32) + -- Set version with `a_version' + do + version := a_version + ensure + version_assigned : version ~ a_version + end + + + set_revision (a_revision : STRING_32) + -- Set revision with `a_revision' + do + revision := a_revision + ensure + revision_assigned : revision ~ a_revision + end + + + set_time (a_time : STRING_32) + -- Set time with `a_time' + do + time := a_time + ensure + time_assigned : time ~ a_time + end +end diff --git a/library/test/selenium/src/response/se_java_value.e b/library/test/selenium/src/response/se_java_value.e new file mode 100644 index 00000000..3daffd14 --- /dev/null +++ b/library/test/selenium/src/response/se_java_value.e @@ -0,0 +1,36 @@ +note + description: "Object that describe the current verion of Java" + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_JAVA_VALUE + +create + make, + make_empty + +feature -- Initialization + make ( a_version : STRING_32) + do + set_version (a_version) + end + make_empty + do + + end + +feature -- Access + version : detachable STRING_32 + -- current Java version + +feature -- Change Element + set_version (a_version: STRING_32) + --Set version with `a_version' + do + version := a_version + ensure + version_assigned : version ~ a_version + end +end diff --git a/library/test/selenium/src/response/se_os_value.e b/library/test/selenium/src/response/se_os_value.e new file mode 100644 index 00000000..13d44843 --- /dev/null +++ b/library/test/selenium/src/response/se_os_value.e @@ -0,0 +1,64 @@ +note + description: "Object that describe the OS information from the current server" + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_OS_VALUE + +create + make, + make_empty + + +feature{NONE} -- Initialization + make ( an_architecture : STRING_32; a_name: STRING_32; a_version: STRING_32) + do + set_version(a_version) + set_name (a_name) + set_architecture (an_architecture) + end + + make_empty + do + + end + +feature -- Access + architecture : detachable STRING_32 + -- The current system architecture. + + name : detachable STRING_32 + -- The name of the operating system the server is currently running on: "windows", "linux", etc. + + version : detachable STRING_32 + --The operating system version. + +feature -- Change Element + set_version (a_version : STRING_32) + -- Set version with `a_version' + do + version := a_version + ensure + version_assigned : version ~ a_version + end + + + set_name (a_name : STRING_32) + -- Set name with `a_name' + do + name := a_name + ensure + name_assigned : name ~ a_name + end + + + set_architecture (an_architecture : STRING_32) + -- Set architecture with `an_architecture' + do + architecture := an_architecture + ensure + architecture_assigned : architecture ~ an_architecture + end +end diff --git a/library/test/selenium/src/response/se_response.e b/library/test/selenium/src/response/se_response.e new file mode 100644 index 00000000..8e444e63 --- /dev/null +++ b/library/test/selenium/src/response/se_response.e @@ -0,0 +1,61 @@ +note + description: "Object that represent Command responses from Seleniun JSONWireProtocol" + author: "" + date: "$Date$" + revision: "$Revision$" + EIS: "name=SELINIUM", "protocol=JsonWireProtocol", "src=https://code.google.com/p/selenium/wiki/JsonWireProtocol#Responses" + +class + SE_RESPONSE + +create + make, + make_empty + +feature -- Initialization + make (a_session_id : STRING_32; a_status: INTEGER_32; a_value : STRING_32) + do + session_id := a_session_id + status := a_status + value := a_value + end + + make_empty + do + + end +feature -- Access + session_id : detachable STRING_32 + -- An opaque handle used by the server to determine where to route session-specific commands. + -- This ID should be included in all future session-commands in place of the :sessionId path segment variable. + + status : INTEGER_32 + -- A status code summarizing the result of the command. A non-zero value indicates that the command failed. + + value : detachable STRING_32 + -- The response JSON value. + +feature -- Change Element + set_session_id ( a_session_id : STRING_32) + do + session_id := a_session_id + end + + set_status ( a_status : INTEGER_32) + do + status := a_status + end + + set_value (a_value : STRING_32) + do + value := a_value + end + +feature -- JSON Response + json_response : detachable STRING_32 + + set_json_response ( a_response : STRING_32) + do + json_response := a_response + end +end diff --git a/library/test/selenium/src/response/se_status.e b/library/test/selenium/src/response/se_status.e new file mode 100644 index 00000000..ecc8b060 --- /dev/null +++ b/library/test/selenium/src/response/se_status.e @@ -0,0 +1,99 @@ +note + description: "Object representation of JSON response describing the state of the server" + author: "" + date: "$Date$" + revision: "$Revision$" + EIS: "name=status", "protocol=http", "src=https://code.google.com/p/selenium/wiki/JsonWireProtocol#GET_/status" + +class + SE_STATUS +inherit + ANY + redefine + out + end + +feature -- Access + status: detachable STRING_32 + session_id: detachable STRING_32 + state: detachable STRING_32 + class_name: detachable STRING_32 + value : detachable SE_STATUS_VALUE + hash_code: detachable STRING_32 + +feature -- Change Element + set_status (a_status : STRING_32) + do + status := a_status + end + + set_session_id (a_session_id : STRING_32) + do + session_id := a_session_id + end + + set_state (a_state : STRING_32) + do + state := a_state + end + + set_class_name (a_class_name : STRING_32) + do + class_name := a_class_name + end + + set_value (a_value : SE_STATUS_VALUE) + do + value := a_value + end + + set_hash_code (a_hash_code : STRING_32) + do + hash_code := a_hash_code + end + + out : STRING + do + create Result.make_from_string ("Response : ") + if attached status as l_satus then + Result.append ("[Status:") + Result.append (l_satus.out) + Result.append ("]") + Result.append (" ") + end + if attached session_id as l_session_id then + Result.append ("[SessionId:") + Result.append (l_session_id.out) + Result.append ("]") + Result.append (" ") + end + if attached state as l_state then + Result.append ("[State:") + Result.append (l_state.out) + Result.append ("]") + Result.append (" ") + end + if attached value as l_value then + Result.append ("[value:") + Result.append (l_value.out) + Result.append ("]") + Result.append (" ") + end + + if attached class_name as l_class_name then + Result.append ("[Class Name:") + Result.append (l_class_name.out) + Result.append ("]") + Result.append (" ") + end + + if attached hash_code as l_hash_code then + Result.append ("[hCode:") + Result.append (l_hash_code.out) + Result.append ("]") + Result.append (" ") + end + + + end +end diff --git a/library/test/selenium/src/response/se_status_value.e b/library/test/selenium/src/response/se_status_value.e new file mode 100644 index 00000000..8a785740 --- /dev/null +++ b/library/test/selenium/src/response/se_status_value.e @@ -0,0 +1,53 @@ +note + description: "Summary description for {STATUS}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_STATUS_VALUE +create + make, + make_empty + +feature {NONE}-- Initialization + make (an_os_value : SE_OS_VALUE; a_java_value :SE_JAVA_VALUE; a_build_value: SE_BUILD_VALUE ) + do + set_os_value (an_os_value) + set_java_value (a_java_value) + set_build_value (a_build_value) + end + + make_empty + do + + end +feature -- Access + os_value: detachable SE_OS_VALUE + + java_value : detachable SE_JAVA_VALUE + + build_value : detachable SE_BUILD_VALUE + +feature -- Change Element + set_os_value (an_os_value : SE_OS_VALUE) + -- Set os_value with `an_os_value' + do + os_value := an_os_value + end + + set_build_value (a_build_value : SE_BUILD_VALUE) + -- Set build_value with `a_build_value' + do + build_value := a_build_value + end + + set_java_value (a_java_value : SE_JAVA_VALUE) + -- Set java_value with `a_java_value' + do + + java_value := a_java_value + end + + +end diff --git a/library/test/selenium/src/se_capabilities.e b/library/test/selenium/src/se_capabilities.e new file mode 100644 index 00000000..e551b1b4 --- /dev/null +++ b/library/test/selenium/src/se_capabilities.e @@ -0,0 +1,149 @@ +note + description: "Object that describe available features a client can submit in a WebDriver session. Not all server implementations will support every WebDriver feature." + author: "" + date: "$Date$" + revision: "$Revision$" + EIS: "name=Capabilities", "protocl=http", "src=https://code.google.com/p/selenium/wiki/JsonWireProtocol#Desired_Capabilities" +class + SE_CAPABILITIES + +create + make +feature -- Initialization + make + -- defaults initializations + do + end + +feature -- Access + browser_name : detachable STRING_32 + --The name of the browser being used; should be one of {chrome|firefox|htmlunit|internet explorer|iphone} + + version : detachable STRING_32 + -- The browser version, or the empty string if unknown. + + platform : detachable STRING_32 + -- A key specifying which platform the browser is running on. This value should be one of {WINDOWS|XP|VISTA|MAC|LINUX|UNIX}. + -- When requesting a new session, the client may specify ANY to indicate any available platform may be used. + + is_javascript_enabled : BOOLEAN + --Whether the session supports executing user supplied JavaScript in the context of the current page. + + takes_screenshot : BOOLEAN + --Whether the session supports taking screenshots of the current page. + + handles_alerts : BOOLEAN + --Whether the session can interact with modal popups, such as window.alert and window.confirm. + + is_database_enabled : BOOLEAN + --Whether the session can interact database storage. + + is_location_context_enabled : BOOLEAN + --Whether the session can set and query the browser's location context. + + is_application_cache_enabled : BOOLEAN + --Whether the session can interact with the application cache. + + is_browser_connection_enabled : BOOLEAN + --Whether the session can query for the browser's connectivity and disable it if desired. + + is_css_selectors_enabled : BOOLEAN + --Whether the session supports CSS selectors when searching for elements. + + is_web_storage_enabled : BOOLEAN + --Whether the session supports interactions with storage objects. + + is_rotatable : BOOLEAN + --Whether the session can rotate the current page's current layout between portrait and landscape orientations (only applies to mobile platforms). + + accept_ssl_certs : BOOLEAN + --Whether the session should accept all SSL certs by default. + + native_events : BOOLEAN + --Whether the session is capable of generating native events when simulating user input. + + proxy : detachable WEB_DRIVER_PROXY + --Details of any proxy to use. If no proxy is specified, whatever the system's current or default state is used. The format is specified under Proxy JSON Object. + +feature -- Change Elemenet + set_browser_name (a_browser_name : STRING_32) + do + browser_name := a_browser_name + end + + set_version (a_version : STRING_32) + do + version := a_version + end + + set_platform (a_platform : STRING_32) + do + platform := a_platform + end + + set_javascript_enabled ( value : BOOLEAN) + do + is_javascript_enabled := value + end + + set_takes_screenshot (value : BOOLEAN) + do + takes_screenshot := value + end + + set_handles_alerts ( value: BOOLEAN) + do + handles_alerts := value + end + + set_database_enabled (value : BOOLEAN) + do + is_database_enabled := value + end + + set_location_context_enabled (value:BOOLEAN) + do + is_location_context_enabled := value + end + + set_application_cache_enabled (value : BOOLEAN) + do + is_application_cache_enabled := value + end + + set_browser_connection_enabled (value : BOOLEAN) + do + is_browser_connection_enabled := value + end + + set_css_selectors_enabled (value : BOOLEAN) + do + is_css_selectors_enabled := value + end + + set_web_storage_enabled (value : BOOLEAN) + do + is_web_storage_enabled := value + end + + set_rotatable (value : BOOLEAN) + do + is_rotatable := value + end + + set_accept_ssl_certs (value : BOOLEAN) + do + accept_ssl_certs := value + end + + set_native_events ( value : BOOLEAN) + do + native_events := value + end + + set_proxy ( a_proxy : WEB_DRIVER_PROXY) + do + proxy := a_proxy + end + +end diff --git a/library/test/selenium/src/se_error.e b/library/test/selenium/src/se_error.e new file mode 100644 index 00000000..42236c89 --- /dev/null +++ b/library/test/selenium/src/se_error.e @@ -0,0 +1,24 @@ +note + description: "Summary description for {SE_ERROR}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_ERROR + +create + make +feature -- Initialization + make (a_code : INTEGER_32; a_summary : STRING_32; a_detail : STRING_32) + do + code := a_code + summary := a_summary + detail := a_detail + end + +feature -- Access + code : INTEGER_32 + summary : STRING_32 + detail : STRING_32 +end diff --git a/library/test/selenium/src/se_session.e b/library/test/selenium/src/se_session.e new file mode 100644 index 00000000..66ed2fce --- /dev/null +++ b/library/test/selenium/src/se_session.e @@ -0,0 +1,27 @@ +note + description: "Object that represent an active session" + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SE_SESSION + +create + make +feature -- Initializaton + make (a_session_id : STRING_32; a_capabilities: SE_CAPABILITIES) + do + session_id := a_session_id + capabilities := a_capabilities + end + +feature -- Access + + session_id : STRING_32 + -- The session id. + + capabilities : SE_CAPABILITIES + -- An object describing the session's capabilities. + +end diff --git a/library/test/selenium/src/web_driver_cookie.e b/library/test/selenium/src/web_driver_cookie.e new file mode 100644 index 00000000..311a5bdb --- /dev/null +++ b/library/test/selenium/src/web_driver_cookie.e @@ -0,0 +1,69 @@ +note + description: "Object that describe a cookie. When returning Cookie objects, the server should only omit an optional field if it is incapable of providing the information." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WEB_DRIVER_COOKIE + +create + make +feature {NONE}-- Initialization + make (a_name : STRING_32; a_value: STRING_32) + do + set_name (a_name) + set_value (a_value) + end + +feature -- Access + name : STRING_32 + --The name of the cookie. + + value : STRING_32 + -- The cookie value. + + path : detachable STRING_32 + --(Optional) The cookie path + + domain : detachable STRING_32 + --(Optional) The domain the cookie is visible to. + + secure : BOOLEAN + --(Optional) Whether the cookie is a secure cookie + + expiry : NATURAL_32 + -- (Optional) When the cookie expires, specified in seconds since midnight, January 1, 1970 UTC.1 + +feature -- Change Element + set_name (a_name:STRING_32) + do + name := a_name + end + + set_value (a_value:STRING_32) + do + value := a_value + end + + set_path (a_path : STRING_32) + do + path := a_path + end + + set_domain (a_domain : STRING_32) + do + domain := a_domain + end + + set_secure (a_value : BOOLEAN) + do + secure := a_value + end + + set_expiry ( a_value : NATURAL_32) + do + expiry := a_value + end + +end diff --git a/library/test/selenium/src/web_driver_log.e b/library/test/selenium/src/web_driver_log.e new file mode 100644 index 00000000..1c2924c9 --- /dev/null +++ b/library/test/selenium/src/web_driver_log.e @@ -0,0 +1,26 @@ +note + description: "Object describing a log entry" + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WEB_DRIVER_LOG +feature + + timestamp : NATURAL_32 + --The timestamp of the entry. + + level : detachable STRING_32 + --The log level of the entry, for example, "INFO" (see log levels). + --ALL All log messages. Used for fetching of logs and configuration of logging. + --DEBUG Messages for debugging. + --INFO Messages with user information. + --WARNING Messages corresponding to non-critical problems. + --SEVERE Messages corresponding to critical errors. + --OFF No log messages. Used for configuration of logging. + + message : detachable STRING_32 + --The log message. + +end diff --git a/library/test/selenium/src/web_driver_proxy.e b/library/test/selenium/src/web_driver_proxy.e new file mode 100644 index 00000000..1aacaca8 --- /dev/null +++ b/library/test/selenium/src/web_driver_proxy.e @@ -0,0 +1,47 @@ +note + description: "A JSON object describing a Proxy configuration." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WEB_DRIVER_PROXY +create + make + +feature -- Initialization + make (a_proxy_type : STRING_32) + do + set_proxy_type(a_proxy_type) + end +feature -- Access + + proxy_type: STRING_32 + --(Required) The type of proxy being used. + --Possible values are: + -- direct - A direct connection - + -- no proxy in use, + -- manual - Manual proxy settings configured, + -- e.g. setting a proxy for HTTP, a proxy for FTP, etc, + -- pac - Proxy autoconfiguration from a URL), + -- autodetect (proxy autodetection, probably with WPAD, + -- system - Use system settings + + proxy_auto_config_url : detachable STRING_32 + --(Required if proxyType == pac, Ignored otherwise) + -- Specifies the URL to be used for proxy autoconfiguration. Expected format example: http://hostname.com:1234/pacfile + + ftp_proxy : detachable STRING_32 + http_proxy: detachable STRING_32 + ssl_Proxy : detachable STRING_32 + --(Optional, Ignored if proxyType != manual) Specifies the proxies to be used for FTP, HTTP and HTTPS requests respectively. + --Behaviour is undefined if a request is made, where the proxy for the particular protocol is undefined, if proxyType is manual. + --Expected format example: hostname.com:1234 + + +feature -- Element Change + set_proxy_type (a_proxy_type : STRING_32) + do + proxy_type := a_proxy_type + end +end diff --git a/library/test/selenium/src/web_element.e b/library/test/selenium/src/web_element.e new file mode 100644 index 00000000..7147d82e --- /dev/null +++ b/library/test/selenium/src/web_element.e @@ -0,0 +1,10 @@ +note + description: "An object in the WebDriver API that represents a DOM element on the page." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WEB_ELEMENT + +end diff --git a/library/test/selenium/test/application.e b/library/test/selenium/test/application.e new file mode 100644 index 00000000..a27397ae --- /dev/null +++ b/library/test/selenium/test/application.e @@ -0,0 +1,82 @@ +note + description : "test application root class" + date : "$Date$" + revision : "$Revision$" + +class + APPLICATION + +inherit + ARGUMENTS + +create + make + +feature {NONE} -- Initialization + + make + local + web_driver: SE_JSON_WIRE_PROTOCOL + capabilities : SE_CAPABILITIES + do + -- check if the selenium Remote WebDriver is up and running. + create web_driver.make + if attached web_driver.status as l_status then + print (l_status) + + -- retrieve sessions + if attached web_driver.sessions as l_session then + across l_session as item loop + print (item) + end + end + + -- create a new session + create capabilities.make + capabilities.set_browser_name ("chrome") + if attached web_driver.create_session_with_desired_capabilities (capabilities) as l_session then + print ("%NSessionId:" + l_session.session_id) + end + + + -- retrieve sessions + if attached web_driver.sessions as l_session then + across l_session as item loop + print (item) + end + end + + else + print ("The selenium server is not accesible") + end + + end + + test_session + local + h: LIBCURL_HTTP_CLIENT + session: HTTP_CLIENT_SESSION + resp : detachable HTTP_CLIENT_RESPONSE + l_location : detachable READABLE_STRING_8 + body : STRING + context : HTTP_CLIENT_REQUEST_CONTEXT + s: READABLE_STRING_8 + do + create h.make + s := "[ + { + "desiredCapabilities" : { + "browserName":"firefox" + } + } + ]" + + + session := h.new_session ("http://localhost:4444/wd/hub/") + create context.make + context.headers.put ("application/json;charset=UTF-8", "Content-Type") + context.headers.put ("application/json;charset=UTF-8", "Accept") + resp := session.post ("session", context,s) + print(resp) + end +end diff --git a/library/test/selenium/test/test-safe.ecf b/library/test/selenium/test/test-safe.ecf new file mode 100644 index 00000000..de82f16f --- /dev/null +++ b/library/test/selenium/test/test-safe.ecf @@ -0,0 +1,20 @@ + + + + + + + + + + + + /EIFGENs$ + /CVS$ + /.svn$ + + + + diff --git a/library/test/selenium/test/test.rc b/library/test/selenium/test/test.rc new file mode 100644 index 00000000..b0ec159c --- /dev/null +++ b/library/test/selenium/test/test.rc @@ -0,0 +1,6 @@ +#include + +STRINGTABLE +BEGIN + 1 "This Program was made using EiffelStudio using Visual Studio C++" +END