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