[common][appcontrol][add webapp to support operation pick] 14/306514/1
authorchen <chen89.chen@samsung.com>
Thu, 22 Feb 2024 09:31:46 +0000 (17:31 +0800)
committerchen <chen89.chen@samsung.com>
Thu, 22 Feb 2024 09:31:56 +0000 (17:31 +0800)
Change-Id: I2c2e113f3e101fa2d7c536a37e877c4bbb26c6c8
Signed-off-by: chen <chen89.chen@samsung.com>
31 files changed:
common/tct-appcontrol-tizen-tests/appcontrol/AppControl_select_file.html
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_exit.html [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_launch.html [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_launch_explicit.html [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_reply_failure.html [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_reply_result.html [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_reply_result_with_data.html [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_run_test.html [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/config.xml [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/css/style.css [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/icon.png [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/index.html [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/manifest.json [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/COPYING [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/testharness.css [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/testharness.js [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/testharnessreport.js [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/unitcommon.js [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/Application_getRequestedAppControl.js [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/Application_getRequestedAppControl_extra_argument.js [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/Application_hide.js [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/Application_hide_extra_argument.js [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_appControl_attribute.js [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_callerAppId_attribute.js [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_extend.js [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_replyFailure_exist.js [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_replyResult_data_TypeMismatch.js [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_replyResult_exist.js [new file with mode: 0755]
common/tct-appcontrol-tizen-tests/appcontrol/support/appcontrol_common.js
common/tct-appcontrol-tizen-tests/inst.wgt.py
common/tct-appcontrol-tizen-tests/suite.json

index db328f080feaebe1a9f62429b618d0f0e55b76dc..98222520370ec020ba22718ac919d045bf20f52a 100755 (executable)
@@ -1,54 +1,54 @@
-<!DOCTYPE html>
-<!--
-Copyright (c) 2013 Samsung Electronics Co., Ltd.
-
-Licensed under the Apache License, Version 2.0 (the License);
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-
-Authors:
-        Piotr Szydelko <p.szydelko@samsung.com>
-        JungHyuk, Park <junghyuk.park@samsung.com>
-
--->
-<html>
-<head>
-<title>AppControl_select_file</title>
-<meta charset="utf-8"/>
-<script src="support/unitcommon.js"></script>
-<script src="support/appcontrol_common.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-//==== TEST: AppControl_select_file
-//==== LABEL Check if application for selecting a file is available
-//==== PRIORITY P1
-//==== SPEC Tizen Web API:Application:Application:ApplicationManager:findAppControl M
-//==== SPEC_URL https://developer.tizen.org/help/topic/org.tizen.web.device.apireference/tizen/application.html
-//==== TEST_CRITERIA MR
-
-var t = async_test(document.title), appcontrol1;
-
-t.step(function () {
-    // Use case: Select a file
-
-    // operation: http://tizen.org/appcontrol/operation/view
-    appcontrol1 = new tizen.ApplicationControl(
-        "http://tizen.org/appcontrol/operation/pick");
-
-    checkAppControls(t, [appcontrol1]);
-});
-
-</script>
-</body>
-</html>
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+\r
+Authors:\r
+        Piotr Szydelko <p.szydelko@samsung.com>\r
+        JungHyuk, Park <junghyuk.park@samsung.com>\r
+\r
+-->\r
+<html>\r
+<head>\r
+<title>AppControl_select_file</title>\r
+<meta charset="utf-8"/>\r
+<script src="support/unitcommon.js"></script>\r
+<script src="support/appcontrol_common.js"></script>\r
+</head>\r
+<body>\r
+<div id="log"></div>\r
+<script>\r
+//==== TEST: AppControl_select_file\r
+//==== LABEL Check if application for selecting a file is available\r
+//==== PRIORITY P1\r
+//==== SPEC Tizen Web API:Application:Application:ApplicationManager:findAppControl M\r
+//==== SPEC_URL https://developer.tizen.org/help/topic/org.tizen.web.device.apireference/tizen/application.html\r
+//==== TEST_CRITERIA MR\r
+\r
+var t = async_test(document.title), appcontrol1;\r
+\r
+t.step(function () {\r
+    // Use case: Select a file\r
+\r
+    // operation: http://tizen.org/appcontrol/operation/view\r
+    appcontrol1 = new tizen.ApplicationControl(\r
+        "http://tizen.org/appcontrol/operation/pick");\r
+\r
+    checkAppControls(t, [appcontrol1]);\r
+});\r
+\r
+</script>\r
+</body>\r
+</html>\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_exit.html b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_exit.html
new file mode 100755 (executable)
index 0000000..6c8142e
--- /dev/null
@@ -0,0 +1,70 @@
+<!DOCTYPE html>\r
+\r
+<!--\r
+\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+\r
+\r
+Authors:\r
+        Junghyuk Park <junghyuk.park@samsung.com>\r
+\r
+\r
+-->\r
+\r
+<html>\r
+<head>\r
+<meta charset="utf-8" />\r
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">\r
+<meta name="description" content="tct-application-tizen-tests"/>\r
+\r
+<title>TCTAppControl</title>\r
+\r
+    <link rel="stylesheet" type="text/css" href="css/style.css"/>\r
+</head>\r
+\r
+<body>\r
+<header>\r
+    <hgroup>\r
+      <h1>TCTAppControl</h1>\r
+      <h2>appcontrol_exit.html</h2>\r
+      <h3 id="info"></h3>\r
+    </hgroup>\r
+</header>\r
+\r
+<script type="text/javascript">\r
+var application, request, timeout = 1000;\r
+\r
+application = tizen.application.getCurrentApplication();\r
+request = application.getRequestedAppControl();\r
+\r
+if (request) {\r
+    if (request.appControl.data[0].key === "timeout") {\r
+        timeout = parseInt(request.appControl.data[0].value[0]);\r
+    }\r
+\r
+    request.replyResult();\r
+\r
+    setTimeout(function () {\r
+        application.exit();\r
+    }, timeout);\r
+\r
+} else  {\r
+    document.getElementById("info").innerHTML="RequestedAppControl not found";\r
+}\r
+\r
+</script>\r
+</body>\r
+</html>\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_launch.html b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_launch.html
new file mode 100755 (executable)
index 0000000..35fbebd
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE html>\r
+\r
+<!--\r
+\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+\r
+\r
+Authors:\r
+            Junghyuk Park <junghyuk.park@samsung.com>\r
+\r
+\r
+-->\r
+\r
+<html>\r
+<head>\r
+    <meta charset="utf-8" />\r
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">\r
+    <meta name="description" content="tct-application-tizen-tests"/>\r
+\r
+    <title>TCTAppControl</title>\r
+\r
+    <link rel="stylesheet" type="text/css" href="css/style.css"/>\r
+</head>\r
+<script>\r
+var init = function () {\r
+    // add eventListener for tizenhwkey\r
+    document.addEventListener('tizenhwkey', function(e) {\r
+        if(e.keyName == "back") {\r
+            try {\r
+                tizen.application.getCurrentApplication().exit();\r
+            } catch (error) {\r
+                console.error("getCurrentApplication(): " + error.message);\r
+            }\r
+        }\r
+    });\r
+};\r
+window.onload = init;\r
+</script>\r
+<body>\r
+  <header>\r
+    <hgroup>\r
+      <h1>TCTAppControl</h1>\r
+      <h2>appcontrol_launch.html</h2>\r
+    </hgroup>\r
+  </header>\r
+</body>\r
+</html>\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_launch_explicit.html b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_launch_explicit.html
new file mode 100755 (executable)
index 0000000..870fc86
--- /dev/null
@@ -0,0 +1,46 @@
+<!DOCTYPE html>\r
+\r
+<!--\r
+\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+\r
+\r
+Authors:\r
+            Junghyuk Park <junghyuk.park@samsung.com>\r
+\r
+\r
+-->\r
+\r
+<html>\r
+<head>\r
+    <meta charset="utf-8" />\r
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">\r
+    <meta name="description" content="tct-application-tizen-tests"/>\r
+\r
+    <title>TCTAppControl</title>\r
+\r
+    <link rel="stylesheet" type="text/css" href="css/style.css"/>\r
+</head>\r
+\r
+<body>\r
+  <header>\r
+    <hgroup>\r
+      <h1>TCTAppControl</h1>\r
+      <h2>appcontrol_launch.html</h2>\r
+    </hgroup>\r
+  </header>\r
+</body>\r
+</html>\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_reply_failure.html b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_reply_failure.html
new file mode 100755 (executable)
index 0000000..de800de
--- /dev/null
@@ -0,0 +1,77 @@
+<!DOCTYPE html>\r
+\r
+<!--\r
+\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+\r
+\r
+Authors:\r
+            Junghyuk Park <junghyuk.park@samsung.com>\r
+\r
+\r
+-->\r
+\r
+<html>\r
+<head>\r
+    <meta charset="utf-8" />\r
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">\r
+    <meta name="description" content="tct-application-tizen-tests"/>\r
+\r
+    <title>TCTAppControl</title>\r
+\r
+    <link rel="stylesheet" type="text/css" href="css/style.css"/>\r
+</head>\r
+\r
+<body>\r
+  <header>\r
+    <hgroup>\r
+      <h1>TCTAppControl</h1>\r
+      <h2>appcontrol_reply_failure.html</h2>\r
+      <h3 id="info"></h3>\r
+    </hgroup>\r
+  </header>\r
+\r
+<script type="text/javascript">\r
+    var application, request, dataArray, tests = {};\r
+\r
+    tests["RequestedApplicationControl_replyFailure"] = function (request) {\r
+        request.replyFailure();\r
+    };\r
+\r
+    // check only null because not able to invoke replyFailure() multiple times\r
+    tests["RequestedApplicationControl_replyFailure_extra_argument"] = function (request) {\r
+        request.replyFailure(null);\r
+    };\r
+\r
+    application = tizen.application.getCurrentApplication();\r
+    request = application.getRequestedAppControl();\r
+\r
+    if (request) {\r
+        dataArray = request.appControl.data;\r
+\r
+        if (dataArray.length > 0 && dataArray[0].key === "testName") {\r
+            tests[dataArray[0].value[0]](request);\r
+        } else {\r
+            request.replyFailure();\r
+        }\r
+    } else  {\r
+        document.getElementById("info").innerHTML="RequestedAppControl not found";\r
+    }\r
+\r
+</script>  \r
+\r
+</body>\r
+</html>\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_reply_result.html b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_reply_result.html
new file mode 100755 (executable)
index 0000000..47bda16
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE html>\r
+\r
+<!--\r
+\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+\r
+\r
+Authors:\r
+            Junghyuk Park <junghyuk.park@samsung.com>\r
+\r
+\r
+-->\r
+\r
+<html>\r
+<head>\r
+    <meta charset="utf-8" />\r
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">\r
+    <meta name="description" content="tct-application-tizen-tests"/>\r
+\r
+    <title>TCTAppControl</title>\r
+\r
+    <link rel="stylesheet" type="text/css" href="css/style.css"/>\r
+</head>\r
+\r
+<body>\r
+  <header>\r
+    <hgroup>\r
+      <h1>TCTAppControl</h1>\r
+      <h2>appcontrol_reply_result.html</h2>\r
+      <h3 id="info"></h3>\r
+    </hgroup>\r
+  </header>\r
+\r
+<script type="text/javascript">\r
+    var application, request;\r
+    application = tizen.application.getCurrentApplication();\r
+    request = application.getRequestedAppControl();\r
+\r
+    if (request) {\r
+        request.replyResult();\r
+    } else  {\r
+        document.getElementById("info").innerHTML="RequestedAppControl not found";\r
+    }\r
+</script>  \r
+\r
+</body>\r
+</html>\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_reply_result_with_data.html b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_reply_result_with_data.html
new file mode 100755 (executable)
index 0000000..480bbea
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE html>\r
+\r
+<!--\r
+\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+\r
+\r
+Authors:\r
+            Junghyuk Park <junghyuk.park@samsung.com>\r
+\r
+\r
+-->\r
+\r
+<html>\r
+<head>\r
+    <meta charset="utf-8" />\r
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">\r
+    <meta name="description" content="tct-application-tizen-tests"/>\r
+\r
+    <title>TCTAppControl</title>\r
+\r
+    <link rel="stylesheet" type="text/css" href="css/style.css"/>\r
+</head>\r
+\r
+<body>\r
+  <header>\r
+    <hgroup>\r
+      <h1>TCTAppControl</h1>\r
+      <h2>appcontrol_reply_result_with_data.html</h2>\r
+      <h3 id="info"></h3>\r
+    </hgroup>\r
+  </header>\r
+\r
+<script type="text/javascript">\r
+    var application, request;\r
+    application = tizen.application.getCurrentApplication();\r
+    request = application.getRequestedAppControl();\r
+\r
+    if (request) {\r
+        request.replyResult(request.appControl.data);\r
+    } else  {\r
+        document.getElementById("info").innerHTML="RequestedAppControl not found";\r
+    }\r
+</script>  \r
+\r
+</body>\r
+</html>\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_run_test.html b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/appcontrol_run_test.html
new file mode 100755 (executable)
index 0000000..1ac1813
--- /dev/null
@@ -0,0 +1,63 @@
+<!DOCTYPE html>\r
+\r
+<!--\r
+\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+\r
+\r
+Authors:\r
+            Junghyuk Park <junghyuk.park@samsung.com>\r
+\r
+\r
+-->\r
+\r
+<html>\r
+<head>\r
+    <meta charset="utf-8" />\r
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">\r
+    <meta name="description" content="tct-application-tizen-tests"/>\r
+\r
+    <title>appcontrol_run_test</title>\r
+\r
+    <link rel="stylesheet" type="text/css" href="css/style.css"/>\r
+    <script src="resources/testharness.js"></script>\r
+    <script src="resources/testharnessreport.js"></script>\r
+    <script src="resources/unitcommon.js"></script>\r
+</head>\r
+\r
+<body>\r
+<div id="log"></div>\r
+<script type="text/javascript">\r
+\r
+var application, requestedAppControl, testName, resultData;\r
+\r
+add_result_callback(function (result) {\r
+    resultData = [\r
+        new tizen.ApplicationControlData("status", [result.status]),\r
+        new tizen.ApplicationControlData("message", [result.message])\r
+    ];\r
+\r
+    requestedAppControl.replyResult(resultData);\r
+});\r
+\r
+application = tizen.application.getCurrentApplication();\r
+requestedAppControl = application.getRequestedAppControl();\r
+testName = requestedAppControl.appControl.uri.substring("tct://".length);\r
+\r
+document.write("<script language=\"javascript\" src=\"tests/" + testName + ".js\"><\/script>");\r
+</script>\r
+</body>\r
+</html>\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/config.xml b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/config.xml
new file mode 100755 (executable)
index 0000000..3b917c7
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets" id="http://tizen.org/TCTAppControl" version="1.0.0" viewmodes="maximized">
+    <access origin="*" subdomains="true"/>
+    <tizen:app-control>
+        <tizen:src name="appcontrol_launch.html"/>
+        <tizen:operation name="http://tizen.org/appcontrol/operation/tct/launch"/>
+    </tizen:app-control>
+    <tizen:app-control>
+        <tizen:src name="appcontrol_launch.html"/>
+        <tizen:operation name="http://tizen.org/appcontrol/operation/tct/launch"/>
+        <tizen:uri name="tct"/>
+    </tizen:app-control>
+    <tizen:app-control>
+        <tizen:src name="appcontrol_launch.html"/>
+        <tizen:operation name="http://tizen.org/appcontrol/operation/tct/launch"/>
+        <tizen:mime name="text/html"/>
+    </tizen:app-control>
+    <tizen:app-control>
+        <tizen:src name="appcontrol_launch.html"/>
+        <tizen:operation name="http://tizen.org/appcontrol/operation/tct/launch"/>
+        <tizen:uri name="tct"/>
+        <tizen:mime name="text/html"/>
+    </tizen:app-control>
+    <tizen:app-control>
+        <tizen:src name="appcontrol_launch_explicit.html"/>
+        <tizen:operation name="http://tizen.org/appcontrol/operation/tct/launch/explicit"/>
+        <tizen:uri name="tct"/>
+        <tizen:mime name="text/html"/>
+    </tizen:app-control>
+    <tizen:app-control>
+        <tizen:src name="appcontrol_reply_result.html"/>
+        <tizen:operation name="http://tizen.org/appcontrol/operation/tct/reply_result"/>
+    </tizen:app-control>
+    <tizen:app-control>
+        <tizen:src name="appcontrol_reply_result_with_data.html"/>
+        <tizen:operation name="http://tizen.org/appcontrol/operation/tct/reply_result/data"/>
+    </tizen:app-control>
+    <tizen:app-control>
+        <tizen:src name="appcontrol_reply_failure.html"/>
+        <tizen:operation name="http://tizen.org/appcontrol/operation/tct/reply_failure"/>
+    </tizen:app-control>
+    <tizen:app-control>
+        <tizen:src name="appcontrol_run_test.html"/>
+        <tizen:operation name="http://tizen.org/appcontrol/operation/tct/run_test"/>
+        <tizen:uri name="tct"/>
+        <tizen:mime name="application/javascript"/>
+    </tizen:app-control>
+    <tizen:app-control>
+        <tizen:src name="appcontrol_exit.html"/>
+        <tizen:operation name="http://tizen.org/appcontrol/operation/tct/exit"/>
+    </tizen:app-control>
+    <tizen:app-control>
+       <tizen:src name="appcontrol_launch.html"/>
+        <operation name="http://tizen.org/appcontrol/operation/pick"/>
+    </tizen:app-control>
+    <tizen:app-control>
+        <tizen:src name="appcontrol_launch.html"/>
+        <operation name="http://tizen.org/appcontrol/operation/pick"/>
+        <mime name="image/*"/>
+    </tizen:app-control>
+    <tizen:app-control>
+        <tizen:src name="appcontrol_launch.html"/>
+        <operation name="http://tizen.org/appcontrol/operation/pick"/>
+        <mime name="video/*"/>
+    </tizen:app-control>
+    <tizen:privilege name="http://tizen.org/privilege/application.info"/>
+    <tizen:privilege name="http://tizen.org/privilege/appmanager.kill"/>
+    <tizen:application id="api1appli1.TCTAppControl" package="api1appli1" required_version="9.0"/>
+    <content src="index.html"/>
+    <icon src="icon.png"/>
+    <name>TCTAppControl</name>
+    <tizen:metadata key="testKey1" value="testValue1"/>
+    <tizen:metadata key="testKey2" value="testValue2"/>
+    <tizen:setting screen-orientation="landscape" background-support="enable"/>
+</widget>
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/css/style.css b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/css/style.css
new file mode 100755 (executable)
index 0000000..5fd52e2
--- /dev/null
@@ -0,0 +1,99 @@
+/*\r
+\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+\r
+\r
+Authors:\r
+            Junghyuk Park <junghyuk.park@samsung.com>\r
+\r
+\r
+*/\r
+\r
+* {\r
+    font-family: Lucida Sans, Arial, Helvetica, sans-serif;\r
+}\r
+\r
+body {\r
+    margin: 0px auto;\r
+}\r
+\r
+header h1 {\r
+    font-size: 36px;\r
+    margin: 0px;\r
+}\r
+\r
+header h2 {\r
+    font-size: 18px;\r
+    margin: 0px;\r
+    color: #888;\r
+    font-style: italic;\r
+}\r
+\r
+nav ul {\r
+    list-style: none;\r
+    padding: 0px;\r
+    display: block;\r
+    clear: right;\r
+    background-color: #666;\r
+    padding-left: 4px;\r
+    height: 24px;\r
+}\r
+\r
+nav ul li {\r
+    display: inline;\r
+    padding: 0px 20px 5px 10px;\r
+    height: 24px;\r
+    border-right: 1px solid #ccc;\r
+}\r
+\r
+nav ul li a {\r
+    color: #EFD3D3;\r
+    text-decoration: none;\r
+    font-size: 13px;\r
+    font-weight: bold;\r
+}\r
+\r
+nav ul li a:hover {\r
+    color: #fff;\r
+}\r
+\r
+article > header h1 {\r
+    font-size: 20px;\r
+    margin-left: 14px;\r
+}\r
+\r
+article > header h1 a {\r
+    color: #993333;\r
+}\r
+\r
+article > header h1 img {\r
+    vertical-align:middle;\r
+}\r
+\r
+article > section header h1 {\r
+    font-size: 16px;\r
+}\r
+\r
+article p {\r
+    clear: both;\r
+}\r
+\r
+footer p {\r
+    text-align: center;\r
+    font-size: 12px;\r
+    color: #888;\r
+    margin-top: 24px;\r
+}\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/icon.png b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/icon.png
new file mode 100755 (executable)
index 0000000..c22cfa8
Binary files /dev/null and b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/icon.png differ
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/index.html b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/index.html
new file mode 100755 (executable)
index 0000000..89c40d4
--- /dev/null
@@ -0,0 +1,46 @@
+<!DOCTYPE html>\r
+\r
+<!--\r
+\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+\r
+\r
+Authors:\r
+            Junghyuk Park <junghyuk.park@samsung.com>\r
+\r
+\r
+-->\r
+\r
+<html>\r
+<head>\r
+    <meta charset="utf-8" />\r
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">\r
+    <meta name="description" content="tct-application-tizen-tests"/>\r
+\r
+    <title>TCTAppControl</title>\r
+\r
+    <link rel="stylesheet" type="text/css" href="css/style.css"/>\r
+</head>\r
+\r
+<body bgcolor="FFFFFF" >\r
+  <header>\r
+    <hgroup>\r
+      <h1>TCTAppControl</h1>\r
+      <h2>index.html</h2>\r
+    </hgroup>\r
+  </header>\r
+</body>\r
+</html>\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/manifest.json b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/manifest.json
new file mode 100755 (executable)
index 0000000..ce32ce3
--- /dev/null
@@ -0,0 +1,22 @@
+{\r
+    "app": {\r
+        "launch": {\r
+            "local_path": "index.html"\r
+        }\r
+    }, \r
+    "description": "TCTAppControl", \r
+    "file_name": "manifest.json", \r
+    "icons": {\r
+        "128": "icon.png"\r
+    }, \r
+    "name": "TCTAppControl", \r
+    "permissions": [\r
+        "tabs", \r
+        "unlimited_storage", \r
+        "notifications", \r
+        "http://*/*", \r
+        "https://*/*"\r
+    ], \r
+    "version": "2.2.1", \r
+    "webapimanager": true\r
+}
\ No newline at end of file
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/COPYING b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/COPYING
new file mode 100755 (executable)
index 0000000..7aa743b
--- /dev/null
@@ -0,0 +1,12 @@
+All test files under this folder except COPYING, Makefile.am and blacklist.* come from\r
+https://github.com/w3c/testharness.js (commit 81649066b179216eed02dfb58f631eb8bb6c7629)\r
+without any modification besides the necessary adjustment on reference path to test harness\r
+\r
+These tests are copyright by W3C and/or the author listed in the test\r
+file. The tests are dual-licensed under the W3C Test Suite License:\r
+http://www.w3.org/Consortium/Legal/2008/04-testsuite-license\r
+and the BSD 3-clause License:\r
+http://www.w3.org/Consortium/Legal/2008/03-bsd-license\r
+under W3C's test suite licensing policy:\r
+http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright\r
+\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/testharness.css b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/testharness.css
new file mode 100755 (executable)
index 0000000..721dce3
--- /dev/null
@@ -0,0 +1,92 @@
+html {\r
+    font-family:DejaVu Sans, Bitstream Vera Sans, Arial, Sans;\r
+}\r
+\r
+#log .warning,\r
+#log .warning a {\r
+  color: black;\r
+  background: yellow;\r
+}\r
+\r
+#log .error,\r
+#log .error a {\r
+  color: white;\r
+  background: red;\r
+}\r
+\r
+#log pre {\r
+  border: 1px solid black;\r
+  padding: 1em;\r
+}\r
+\r
+section#summary {\r
+    margin-bottom:1em;\r
+}\r
+\r
+table#results {\r
+    border-collapse:collapse;\r
+    table-layout:fixed;\r
+    width:100%;\r
+}\r
+\r
+table#results th:first-child,\r
+table#results td:first-child {\r
+    width:4em;\r
+}\r
+\r
+table#results th:last-child,\r
+table#results td:last-child {\r
+    width:50%;\r
+}\r
+\r
+table#results.assertions th:last-child,\r
+table#results.assertions td:last-child {\r
+    width:35%;\r
+}\r
+\r
+table#results th {\r
+    padding:0;\r
+    padding-bottom:0.5em;\r
+    border-bottom:medium solid black;\r
+}\r
+\r
+table#results td {\r
+    padding:1em;\r
+    padding-bottom:0.5em;\r
+    border-bottom:thin solid black;\r
+}\r
+\r
+tr.pass > td:first-child {\r
+    color:green;\r
+}\r
+\r
+tr.fail > td:first-child {\r
+    color:red;\r
+}\r
+\r
+tr.timeout > td:first-child {\r
+    color:red;\r
+}\r
+\r
+tr.notrun > td:first-child {\r
+    color:blue;\r
+}\r
+\r
+.pass > td:first-child, .fail > td:first-child, .timeout > td:first-child, .notrun > td:first-child {\r
+    font-variant:small-caps;\r
+}\r
+\r
+table#results span {\r
+    display:block;\r
+}\r
+\r
+table#results span.expected {\r
+    font-family:DejaVu Sans Mono, Bitstream Vera Sans Mono, Monospace;\r
+    white-space:pre;\r
+}\r
+\r
+table#results span.actual {\r
+    font-family:DejaVu Sans Mono, Bitstream Vera Sans Mono, Monospace;\r
+    white-space:pre;\r
+}\r
+\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/testharness.js b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/testharness.js
new file mode 100755 (executable)
index 0000000..5f92be5
--- /dev/null
@@ -0,0 +1,2237 @@
+/*\r
+Distributed under both the W3C Test Suite License [1] and the W3C\r
+3-clause BSD License [2]. To contribute to a W3C Test Suite, see the\r
+policies and contribution forms [3].\r
+\r
+[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license\r
+[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license\r
+[3] http://www.w3.org/2004/10/27-testcases\r
+*/\r
+\r
+/*\r
+ * == Introduction ==\r
+ *\r
+ * This file provides a framework for writing testcases. It is intended to\r
+ * provide a convenient API for making common assertions, and to work both\r
+ * for testing synchronous and asynchronous DOM features in a way that\r
+ * promotes clear, robust, tests.\r
+ *\r
+ * == Basic Usage ==\r
+ *\r
+ * To use this file, import the script and the testharnessreport script into\r
+ * the test document:\r
+ * <script src="/resources/testharness.js"></script>\r
+ * <script src="/resources/testharnessreport.js"></script>\r
+ *\r
+ * Within each file one may define one or more tests. Each test is atomic\r
+ * in the sense that a single test has a single result (pass/fail/timeout).\r
+ * Within each test one may have a number of asserts. The test fails at the\r
+ * first failing assert, and the remainder of the test is (typically) not run.\r
+ *\r
+ * If the file containing the tests is a HTML file with an element of id "log"\r
+ * this will be populated with a table containing the test results after all\r
+ * the tests have run.\r
+ *\r
+ * NOTE: By default tests must be created before the load event fires. For ways\r
+ *       to create tests after the load event, see "Determining when all tests\r
+ *       are complete", below\r
+ *\r
+ * == Synchronous Tests ==\r
+ *\r
+ * To create a synchronous test use the test() function:\r
+ *\r
+ * test(test_function, name, properties)\r
+ *\r
+ * test_function is a function that contains the code to test. For example a\r
+ * trivial passing test would be:\r
+ *\r
+ * test(function() {assert_true(true)}, "assert_true with true")\r
+ *\r
+ * The function passed in is run in the test() call.\r
+ *\r
+ * properties is an object that overrides default test properties. The\r
+ * recognised properties are:\r
+ *    timeout - the test timeout in ms\r
+ *\r
+ * e.g.\r
+ * test(test_function, "Sample test", {timeout:1000})\r
+ *\r
+ * would run test_function with a timeout of 1s.\r
+ *\r
+ * Additionally, test-specific metadata can be passed in the properties. These\r
+ * are used when the individual test has different metadata from that stored \r
+ * in the <head>.\r
+ * The recognized metadata properties are:\r
+ *\r
+ *    help - The url of the part of the specification being tested\r
+ *\r
+ *    assert - A human readable description of what the test is attempting \r
+ *             to prove\r
+ *\r
+ *    author - Name and contact information for the author of the test in the\r
+ *             format: "Name <email_addr>" or "Name http://contact/url"\r
+ *\r
+ * == Asynchronous Tests ==\r
+ *\r
+ * Testing asynchronous features is somewhat more complex since the result of\r
+ * a test may depend on one or more events or other callbacks. The API provided\r
+ * for testing these features is indended to be rather low-level but hopefully\r
+ * applicable to many situations.\r
+ *\r
+ * To create a test, one starts by getting a Test object using async_test:\r
+ *\r
+ * async_test(name, properties)\r
+ *\r
+ * e.g.\r
+ * var t = async_test("Simple async test")\r
+ *\r
+ * Assertions can be added to the test by calling the step method of the test\r
+ * object with a function containing the test assertions:\r
+ *\r
+ * t.step(function() {assert_true(true)});\r
+ *\r
+ * When all the steps are complete, the done() method must be called:\r
+ *\r
+ * t.done();\r
+ *\r
+ * As a convenience, async_test can also takes a function as first argument.\r
+ * This function is called with the test object as both its `this` object and\r
+ * first argument. The above example can be rewritten as:\r
+ *\r
+ * async_test(function(t) {\r
+ *     object.some_event = function() {\r
+ *         t.step(function (){assert_true(true); t.done();});\r
+ *     };\r
+ * }, "Simple async test");\r
+ *\r
+ * which avoids cluttering the global scope with references to async\r
+ * tests instances.\r
+ *\r
+ * The properties argument is identical to that for test().\r
+ *\r
+ * In many cases it is convenient to run a step in response to an event or a\r
+ * callback. A convenient method of doing this is through the step_func method\r
+ * which returns a function that, when called runs a test step. For example\r
+ *\r
+ * object.some_event = t.step_func(function(e) {assert_true(e.a)});\r
+ *\r
+ * == Making assertions ==\r
+ *\r
+ * Functions for making assertions start assert_\r
+ * The best way to get a list is to look in this file for functions names\r
+ * matching that pattern. The general signature is\r
+ *\r
+ * assert_something(actual, expected, description)\r
+ *\r
+ * although not all assertions precisely match this pattern e.g. assert_true\r
+ * only takes actual and description as arguments.\r
+ *\r
+ * The description parameter is used to present more useful error messages when\r
+ * a test fails\r
+ *\r
+ * NOTE: All asserts must be located in a test() or a step of an async_test().\r
+ *       asserts outside these places won't be detected correctly by the harness\r
+ *       and may cause a file to stop testing.\r
+ *\r
+ * == Setup ==\r
+ *\r
+ * Sometimes tests require non-trivial setup that may fail. For this purpose\r
+ * there is a setup() function, that may be called with one or two arguments.\r
+ * The two argument version is:\r
+ *\r
+ * setup(func, properties)\r
+ *\r
+ * The one argument versions may omit either argument.\r
+ * func is a function to be run synchronously. setup() becomes a no-op once\r
+ * any tests have returned results. Properties are global properties of the test\r
+ * harness. Currently recognised properties are:\r
+ *\r
+ * timeout - The time in ms after which the harness should stop waiting for\r
+ *           tests to complete (this is different to the per-test timeout\r
+ *           because async tests do not start their timer until .step is called)\r
+ *\r
+ * explicit_done - Wait for an explicit call to done() before declaring all\r
+ *                 tests complete (see below)\r
+ *\r
+ * output_document - The document to which results should be logged. By default\r
+ *                   this is the current document but could be an ancestor\r
+ *                   document in some cases e.g. a SVG test loaded in an HTML\r
+ *                   wrapper\r
+ *\r
+ * explicit_timeout - disable file timeout; only stop waiting for results\r
+ *                    when the timeout() function is called (typically for\r
+ *                    use when integrating with some existing test framework\r
+ *                    that has its own timeout mechanism).\r
+ *\r
+ * == Determining when all tests are complete ==\r
+ *\r
+ * By default the test harness will assume there are no more results to come\r
+ * when:\r
+ * 1) There are no Test objects that have been created but not completed\r
+ * 2) The load event on the document has fired\r
+ *\r
+ * This behaviour can be overridden by setting the explicit_done property to\r
+ * true in a call to setup(). If explicit_done is true, the test harness will\r
+ * not assume it is done until the global done() function is called. Once done()\r
+ * is called, the two conditions above apply like normal.\r
+ *\r
+ * == Generating tests ==\r
+ *\r
+ * NOTE: this functionality may be removed\r
+ *\r
+ * There are scenarios in which is is desirable to create a large number of\r
+ * (synchronous) tests that are internally similar but vary in the parameters\r
+ * used. To make this easier, the generate_tests function allows a single\r
+ * function to be called with each set of parameters in a list:\r
+ *\r
+ * generate_tests(test_function, parameter_lists, properties)\r
+ *\r
+ * For example:\r
+ *\r
+ * generate_tests(assert_equals, [\r
+ *     ["Sum one and one", 1+1, 2],\r
+ *     ["Sum one and zero", 1+0, 1]\r
+ *     ])\r
+ *\r
+ * Is equivalent to:\r
+ *\r
+ * test(function() {assert_equals(1+1, 2)}, "Sum one and one")\r
+ * test(function() {assert_equals(1+0, 1)}, "Sum one and zero")\r
+ *\r
+ * Note that the first item in each parameter list corresponds to the name of\r
+ * the test.\r
+ *\r
+ * The properties argument is identical to that for test(). This may be a \r
+ * single object (used for all generated tests) or an array.\r
+ *\r
+ * == Callback API ==\r
+ *\r
+ * The framework provides callbacks corresponding to 3 events:\r
+ *\r
+ * start - happens when the first Test is created\r
+ * result - happens when a test result is recieved\r
+ * complete - happens when all results are recieved\r
+ *\r
+ * The page defining the tests may add callbacks for these events by calling\r
+ * the following methods:\r
+ *\r
+ *   add_start_callback(callback) - callback called with no arguments\r
+ *   add_result_callback(callback) - callback called with a test argument\r
+ *   add_completion_callback(callback) - callback called with an array of tests\r
+ *                                       and an status object\r
+ *\r
+ * tests have the following properties:\r
+ *   status: A status code. This can be compared to the PASS, FAIL, TIMEOUT and\r
+ *           NOTRUN properties on the test object\r
+ *   message: A message indicating the reason for failure. In the future this\r
+ *            will always be a string\r
+ *\r
+ *  The status object gives the overall status of the harness. It has the\r
+ *  following properties:\r
+ *    status: Can be compared to the OK, ERROR and TIMEOUT properties\r
+ *    message: An error message set when the status is ERROR\r
+ *\r
+ * == External API ==\r
+ *\r
+ * In order to collect the results of multiple pages containing tests, the test\r
+ * harness will, when loaded in a nested browsing context, attempt to call\r
+ * certain functions in each ancestor and opener browsing context:\r
+ *\r
+ * start - start_callback\r
+ * result - result_callback\r
+ * complete - completion_callback\r
+ *\r
+ * These are given the same arguments as the corresponding internal callbacks\r
+ * described above.\r
+ *\r
+ * == External API through cross-document messaging ==\r
+ *\r
+ * Where supported, the test harness will also send messages using\r
+ * cross-document messaging to each ancestor and opener browsing context. Since\r
+ * it uses the wildcard keyword (*), cross-origin communication is enabled and\r
+ * script on different origins can collect the results.\r
+ *\r
+ * This API follows similar conventions as those described above only slightly\r
+ * modified to accommodate message event API. Each message is sent by the harness\r
+ * is passed a single vanilla object, available as the `data` property of the\r
+ * event object. These objects are structures as follows:\r
+ *\r
+ * start - { type: "start" }\r
+ * result - { type: "result", test: Test }\r
+ * complete - { type: "complete", tests: [Test, ...], status: TestsStatus }\r
+ *\r
+ * == List of assertions ==\r
+ *\r
+ * assert_true(actual, description)\r
+ *   asserts that /actual/ is strictly true\r
+ *\r
+ * assert_false(actual, description)\r
+ *   asserts that /actual/ is strictly false\r
+ *\r
+ * assert_equals(actual, expected, description)\r
+ *   asserts that /actual/ is the same value as /expected/\r
+ *\r
+ * assert_not_equals(actual, expected, description)\r
+ *   asserts that /actual/ is a different value to /expected/. Yes, this means\r
+ *   that "expected" is a misnomer\r
+ *\r
+ * assert_in_array(actual, expected, description)\r
+ *   asserts that /expected/ is an Array, and /actual/ is equal to one of the\r
+ *   members -- expected.indexOf(actual) != -1\r
+ *\r
+ * assert_array_equals(actual, expected, description)\r
+ *   asserts that /actual/ and /expected/ have the same length and the value of\r
+ *   each indexed property in /actual/ is the strictly equal to the corresponding\r
+ *   property value in /expected/\r
+ *\r
+ * assert_approx_equals(actual, expected, epsilon, description)\r
+ *   asserts that /actual/ is a number within +/- /epsilon/ of /expected/\r
+ *\r
+ * assert_less_than(actual, expected, description)\r
+ *   asserts that /actual/ is a number less than /expected/\r
+ *\r
+ * assert_greater_than(actual, expected, description)\r
+ *   asserts that /actual/ is a number greater than /expected/\r
+ *\r
+ * assert_less_than_equal(actual, expected, description)\r
+ *   asserts that /actual/ is a number less than or equal to /expected/\r
+ *\r
+ * assert_greater_than_equal(actual, expected, description)\r
+ *   asserts that /actual/ is a number greater than or equal to /expected/\r
+ *\r
+ * assert_regexp_match(actual, expected, description)\r
+ *   asserts that /actual/ matches the regexp /expected/\r
+ *\r
+ * assert_class_string(object, class_name, description)\r
+ *   asserts that the class string of /object/ as returned in\r
+ *   Object.prototype.toString is equal to /class_name/.\r
+ *\r
+ * assert_own_property(object, property_name, description)\r
+ *   assert that object has own property property_name\r
+ *\r
+ * assert_inherits(object, property_name, description)\r
+ *   assert that object does not have an own property named property_name\r
+ *   but that property_name is present in the prototype chain for object\r
+ *\r
+ * assert_idl_attribute(object, attribute_name, description)\r
+ *   assert that an object that is an instance of some interface has the\r
+ *   attribute attribute_name following the conditions specified by WebIDL\r
+ *\r
+ * assert_readonly(object, property_name, description)\r
+ *   assert that property property_name on object is readonly\r
+ *\r
+ * assert_throws(code, func, description)\r
+ *   code - the expected exception:\r
+ *     o string: the thrown exception must be a DOMException with the given\r
+ *               name, e.g., "TimeoutError" (for compatibility with existing\r
+ *               tests, a constant is also supported, e.g., "TIMEOUT_ERR")\r
+ *     o object: the thrown exception must have a property called "name" that\r
+ *               matches code.name\r
+ *     o null:   allow any exception (in general, one of the options above\r
+ *               should be used)\r
+ *   func - a function that should throw\r
+ *\r
+ * assert_unreached(description)\r
+ *   asserts if called. Used to ensure that some codepath is *not* taken e.g.\r
+ *   an event does not fire.\r
+ *\r
+ * assert_any(assert_func, actual, expected_array, extra_arg_1, ... extra_arg_N)\r
+ *   asserts that one assert_func(actual, expected_array_N, extra_arg1, ..., extra_arg_N)\r
+ *   is true for some expected_array_N in expected_array. This only works for assert_func\r
+ *   with signature assert_func(actual, expected, args_1, ..., args_N). Note that tests\r
+ *   with multiple allowed pass conditions are bad practice unless the spec specifically\r
+ *   allows multiple behaviours. Test authors should not use this method simply to hide \r
+ *   UA bugs.\r
+ *\r
+ * assert_exists(object, property_name, description)\r
+ *   *** deprecated ***\r
+ *   asserts that object has an own property property_name\r
+ *\r
+ * assert_not_exists(object, property_name, description)\r
+ *   *** deprecated ***\r
+ *   assert that object does not have own property property_name\r
+ */\r
+\r
+(function ()\r
+{\r
+    var debug = false;\r
+    // default timeout is 5 seconds, test can override if needed\r
+    var settings = {\r
+      output:true,\r
+      timeout:5000,\r
+      test_timeout:2000\r
+    };\r
+\r
+    var xhtml_ns = "http://www.w3.org/1999/xhtml";\r
+\r
+    // script_prefix is used by Output.prototype.show_results() to figure out\r
+    // where to get testharness.css from.  It's enclosed in an extra closure to\r
+    // not pollute the library's namespace with variables like "src".\r
+    var script_prefix = null;\r
+    (function ()\r
+    {\r
+        var scripts = document.getElementsByTagName("script");\r
+        for (var i = 0; i < scripts.length; i++)\r
+        {\r
+            if (scripts[i].src)\r
+            {\r
+                var src = scripts[i].src;\r
+            }\r
+            else if (scripts[i].href)\r
+            {\r
+                //SVG case\r
+                var src = scripts[i].href.baseVal;\r
+            }\r
+            if (src && src.slice(src.length - "testharness.js".length) === "testharness.js")\r
+            {\r
+                script_prefix = src.slice(0, src.length - "testharness.js".length);\r
+                break;\r
+            }\r
+        }\r
+    })();\r
+\r
+    /*\r
+     * API functions\r
+     */\r
+\r
+    var name_counter = 0;\r
+    function next_default_name()\r
+    {\r
+        //Don't use document.title to work around an Opera bug in XHTML documents\r
+        var prefix = document.getElementsByTagName("title").length > 0 ?\r
+                         document.getElementsByTagName("title")[0].firstChild.data :\r
+                         "Untitled";\r
+        var suffix = name_counter > 0 ? " " + name_counter : "";\r
+        name_counter++;\r
+        return prefix + suffix;\r
+    }\r
+\r
+    function test(func, name, properties)\r
+    {\r
+        var test_name = name ? name : next_default_name();\r
+        properties = properties ? properties : {};\r
+        var test_obj = new Test(test_name, properties);\r
+        test_obj.step(func);\r
+        if (test_obj.status === test_obj.NOTRUN) {\r
+            test_obj.done();\r
+        }\r
+    }\r
+\r
+    function async_test(func, name, properties)\r
+    {\r
+        if (typeof func !== "function") {\r
+            properties = name;\r
+            name = func;\r
+            func = null;\r
+        }\r
+        var test_name = name ? name : next_default_name();\r
+        properties = properties ? properties : {};\r
+        var test_obj = new Test(test_name, properties);\r
+        if (func) {\r
+            test_obj.step(func, test_obj, test_obj);\r
+        }\r
+        return test_obj;\r
+    }\r
+\r
+    function setup(func_or_properties, maybe_properties)\r
+    {\r
+        var func = null;\r
+        var properties = {};\r
+        if (arguments.length === 2) {\r
+            func = func_or_properties;\r
+            properties = maybe_properties;\r
+        } else if (func_or_properties instanceof Function){\r
+            func = func_or_properties;\r
+        } else {\r
+            properties = func_or_properties;\r
+        }\r
+        tests.setup(func, properties);\r
+        output.setup(properties);\r
+    }\r
+\r
+    function done() {\r
+        tests.end_wait();\r
+    }\r
+\r
+    function generate_tests(func, args, properties) {\r
+        forEach(args, function(x, i)\r
+                {\r
+                    var name = x[0];\r
+                    test(function()\r
+                         {\r
+                             func.apply(this, x.slice(1));\r
+                         }, \r
+                         name, \r
+                         Array.isArray(properties) ? properties[i] : properties);\r
+                });\r
+    }\r
+\r
+    function on_event(object, event, callback)\r
+    {\r
+      object.addEventListener(event, callback, false);\r
+    }\r
+\r
+    expose(test, 'test');\r
+    expose(async_test, 'async_test');\r
+    expose(generate_tests, 'generate_tests');\r
+    expose(setup, 'setup');\r
+    expose(done, 'done');\r
+    expose(on_event, 'on_event');\r
+\r
+    /*\r
+     * Return a string truncated to the given length, with ... added at the end\r
+     * if it was longer.\r
+     */\r
+    function truncate(s, len)\r
+    {\r
+        if (s.length > len) {\r
+            return s.substring(0, len - 3) + "...";\r
+        }\r
+        return s;\r
+    }\r
+\r
+    /*\r
+     * Convert a value to a nice, human-readable string\r
+     */\r
+    function format_value(val)\r
+    {\r
+        if (Array.isArray(val))\r
+        {\r
+            return "[" + val.map(format_value).join(", ") + "]";\r
+        }\r
+\r
+        switch (typeof val)\r
+        {\r
+        case "string":\r
+            val = val.replace("\\", "\\\\");\r
+            for (var i = 0; i < 32; i++)\r
+            {\r
+                var replace = "\\";\r
+                switch (i) {\r
+                case 0: replace += "0"; break;\r
+                case 1: replace += "x01"; break;\r
+                case 2: replace += "x02"; break;\r
+                case 3: replace += "x03"; break;\r
+                case 4: replace += "x04"; break;\r
+                case 5: replace += "x05"; break;\r
+                case 6: replace += "x06"; break;\r
+                case 7: replace += "x07"; break;\r
+                case 8: replace += "b"; break;\r
+                case 9: replace += "t"; break;\r
+                case 10: replace += "n"; break;\r
+                case 11: replace += "v"; break;\r
+                case 12: replace += "f"; break;\r
+                case 13: replace += "r"; break;\r
+                case 14: replace += "x0e"; break;\r
+                case 15: replace += "x0f"; break;\r
+                case 16: replace += "x10"; break;\r
+                case 17: replace += "x11"; break;\r
+                case 18: replace += "x12"; break;\r
+                case 19: replace += "x13"; break;\r
+                case 20: replace += "x14"; break;\r
+                case 21: replace += "x15"; break;\r
+                case 22: replace += "x16"; break;\r
+                case 23: replace += "x17"; break;\r
+                case 24: replace += "x18"; break;\r
+                case 25: replace += "x19"; break;\r
+                case 26: replace += "x1a"; break;\r
+                case 27: replace += "x1b"; break;\r
+                case 28: replace += "x1c"; break;\r
+                case 29: replace += "x1d"; break;\r
+                case 30: replace += "x1e"; break;\r
+                case 31: replace += "x1f"; break;\r
+                }\r
+                val = val.replace(RegExp(String.fromCharCode(i), "g"), replace);\r
+            }\r
+            return '"' + val.replace(/"/g, '\\"') + '"';\r
+        case "boolean":\r
+        case "undefined":\r
+            return String(val);\r
+        case "number":\r
+            // In JavaScript, -0 === 0 and String(-0) == "0", so we have to\r
+            // special-case.\r
+            if (val === -0 && 1/val === -Infinity)\r
+            {\r
+                return "-0";\r
+            }\r
+            return String(val);\r
+        case "object":\r
+            if (val === null)\r
+            {\r
+                return "null";\r
+            }\r
+\r
+            // Special-case Node objects, since those come up a lot in my tests.  I\r
+            // ignore namespaces.  I use duck-typing instead of instanceof, because\r
+            // instanceof doesn't work if the node is from another window (like an\r
+            // iframe's contentWindow):\r
+            // http://www.w3.org/Bugs/Public/show_bug.cgi?id=12295\r
+            if ("nodeType" in val\r
+            && "nodeName" in val\r
+            && "nodeValue" in val\r
+            && "childNodes" in val)\r
+            {\r
+                switch (val.nodeType)\r
+                {\r
+                case Node.ELEMENT_NODE:\r
+                    var ret = "<" + val.tagName.toLowerCase();\r
+                    for (var i = 0; i < val.attributes.length; i++)\r
+                    {\r
+                        ret += " " + val.attributes[i].name + '="' + val.attributes[i].value + '"';\r
+                    }\r
+                    ret += ">" + val.innerHTML + "</" + val.tagName.toLowerCase() + ">";\r
+                    return "Element node " + truncate(ret, 60);\r
+                case Node.TEXT_NODE:\r
+                    return 'Text node "' + truncate(val.data, 60) + '"';\r
+                case Node.PROCESSING_INSTRUCTION_NODE:\r
+                    return "ProcessingInstruction node with target " + format_value(truncate(val.target, 60)) + " and data " + format_value(truncate(val.data, 60));\r
+                case Node.COMMENT_NODE:\r
+                    return "Comment node <!--" + truncate(val.data, 60) + "-->";\r
+                case Node.DOCUMENT_NODE:\r
+                    return "Document node with " + val.childNodes.length + (val.childNodes.length == 1 ? " child" : " children");\r
+                case Node.DOCUMENT_TYPE_NODE:\r
+                    return "DocumentType node";\r
+                case Node.DOCUMENT_FRAGMENT_NODE:\r
+                    return "DocumentFragment node with " + val.childNodes.length + (val.childNodes.length == 1 ? " child" : " children");\r
+                default:\r
+                    return "Node object of unknown type";\r
+                }\r
+            }\r
+\r
+            // Fall through to default\r
+        default:\r
+            return typeof val + ' "' + truncate(String(val), 60) + '"';\r
+        }\r
+    }\r
+    expose(format_value, "format_value");\r
+\r
+    /*\r
+     * Assertions\r
+     */\r
+\r
+    function assert_true(actual, description)\r
+    {\r
+        assert(actual === true, "assert_true", description,\r
+                                "expected true got ${actual}", {actual:actual});\r
+    };\r
+    expose(assert_true, "assert_true");\r
+\r
+    function assert_false(actual, description)\r
+    {\r
+        assert(actual === false, "assert_false", description,\r
+                                 "expected false got ${actual}", {actual:actual});\r
+    };\r
+    expose(assert_false, "assert_false");\r
+\r
+    function same_value(x, y) {\r
+        if (y !== y)\r
+        {\r
+            //NaN case\r
+            return x !== x;\r
+        }\r
+        else if (x === 0 && y === 0) {\r
+            //Distinguish +0 and -0\r
+            return 1/x === 1/y;\r
+        }\r
+        else\r
+        {\r
+            //typical case\r
+            return x === y;\r
+        }\r
+    }\r
+\r
+    function assert_equals(actual, expected, description)\r
+    {\r
+         /*\r
+          * Test if two primitives are equal or two objects\r
+          * are the same object\r
+          */\r
+        if (typeof actual != typeof expected)\r
+        {\r
+            assert(false, "assert_equals", description,\r
+                          "expected (" + typeof expected + ") ${expected} but got (" + typeof actual + ") ${actual}",\r
+                          {expected:expected, actual:actual});\r
+            return;\r
+        }\r
+        assert(same_value(actual, expected), "assert_equals", description,\r
+                                             "expected ${expected} but got ${actual}",\r
+                                             {expected:expected, actual:actual});\r
+    };\r
+    expose(assert_equals, "assert_equals");\r
+\r
+    function assert_not_equals(actual, expected, description)\r
+    {\r
+         /*\r
+          * Test if two primitives are unequal or two objects\r
+          * are different objects\r
+          */\r
+        assert(!same_value(actual, expected), "assert_not_equals", description,\r
+                                              "got disallowed value ${actual}",\r
+                                              {actual:actual});\r
+    };\r
+    expose(assert_not_equals, "assert_not_equals");\r
+\r
+    function assert_in_array(actual, expected, description)\r
+    {\r
+        assert(expected.indexOf(actual) != -1, "assert_in_array", description,\r
+                                               "value ${actual} not in array ${expected}",\r
+                                               {actual:actual, expected:expected});\r
+    }\r
+    expose(assert_in_array, "assert_in_array");\r
+\r
+    function assert_object_equals(actual, expected, description)\r
+    {\r
+         //This needs to be improved a great deal\r
+         function check_equal(actual, expected, stack)\r
+         {\r
+             stack.push(actual);\r
+\r
+             var p;\r
+             for (p in actual)\r
+             {\r
+                 assert(expected.hasOwnProperty(p), "assert_object_equals", description,\r
+                                                    "unexpected property ${p}", {p:p});\r
+\r
+                 if (typeof actual[p] === "object" && actual[p] !== null)\r
+                 {\r
+                     if (stack.indexOf(actual[p]) === -1)\r
+                     {\r
+                         check_equal(actual[p], expected[p], stack);\r
+                     }\r
+                 }\r
+                 else\r
+                 {\r
+                     assert(same_value(actual[p], expected[p]), "assert_object_equals", description,\r
+                                                       "property ${p} expected ${expected} got ${actual}",\r
+                                                       {p:p, expected:expected, actual:actual});\r
+                 }\r
+             }\r
+             for (p in expected)\r
+             {\r
+                 assert(actual.hasOwnProperty(p),\r
+                        "assert_object_equals", description,\r
+                        "expected property ${p} missing", {p:p});\r
+             }\r
+             stack.pop();\r
+         }\r
+         check_equal(actual, expected, []);\r
+    };\r
+    expose(assert_object_equals, "assert_object_equals");\r
+\r
+    function assert_array_equals(actual, expected, description)\r
+    {\r
+        assert(actual.length === expected.length,\r
+               "assert_array_equals", description,\r
+               "lengths differ, expected ${expected} got ${actual}",\r
+               {expected:expected.length, actual:actual.length});\r
+\r
+        for (var i=0; i < actual.length; i++)\r
+        {\r
+            assert(actual.hasOwnProperty(i) === expected.hasOwnProperty(i),\r
+                   "assert_array_equals", description,\r
+                   "property ${i}, property expected to be $expected but was $actual",\r
+                   {i:i, expected:expected.hasOwnProperty(i) ? "present" : "missing",\r
+                   actual:actual.hasOwnProperty(i) ? "present" : "missing"});\r
+            assert(same_value(expected[i], actual[i]),\r
+                   "assert_array_equals", description,\r
+                   "property ${i}, expected ${expected} but got ${actual}",\r
+                   {i:i, expected:expected[i], actual:actual[i]});\r
+        }\r
+    }\r
+    expose(assert_array_equals, "assert_array_equals");\r
+\r
+    function assert_approx_equals(actual, expected, epsilon, description)\r
+    {\r
+        /*\r
+         * Test if two primitive numbers are equal withing +/- epsilon\r
+         */\r
+        assert(typeof actual === "number",\r
+               "assert_approx_equals", description,\r
+               "expected a number but got a ${type_actual}",\r
+               {type_actual:typeof actual});\r
+\r
+        assert(Math.abs(actual - expected) <= epsilon,\r
+               "assert_approx_equals", description,\r
+               "expected ${expected} +/- ${epsilon} but got ${actual}",\r
+               {expected:expected, actual:actual, epsilon:epsilon});\r
+    };\r
+    expose(assert_approx_equals, "assert_approx_equals");\r
+\r
+    function assert_less_than(actual, expected, description)\r
+    {\r
+        /*\r
+         * Test if a primitive number is less than another\r
+         */\r
+        assert(typeof actual === "number",\r
+               "assert_less_than", description,\r
+               "expected a number but got a ${type_actual}",\r
+               {type_actual:typeof actual});\r
+\r
+        assert(actual < expected,\r
+               "assert_less_than", description,\r
+               "expected a number less than ${expected} but got ${actual}",\r
+               {expected:expected, actual:actual});\r
+    };\r
+    expose(assert_less_than, "assert_less_than");\r
+\r
+    function assert_greater_than(actual, expected, description)\r
+    {\r
+        /*\r
+         * Test if a primitive number is greater than another\r
+         */\r
+        assert(typeof actual === "number",\r
+               "assert_greater_than", description,\r
+               "expected a number but got a ${type_actual}",\r
+               {type_actual:typeof actual});\r
+\r
+        assert(actual > expected,\r
+               "assert_greater_than", description,\r
+               "expected a number greater than ${expected} but got ${actual}",\r
+               {expected:expected, actual:actual});\r
+    };\r
+    expose(assert_greater_than, "assert_greater_than");\r
+\r
+    function assert_less_than_equal(actual, expected, description)\r
+    {\r
+        /*\r
+         * Test if a primitive number is less than or equal to another\r
+         */\r
+        assert(typeof actual === "number",\r
+               "assert_less_than_equal", description,\r
+               "expected a number but got a ${type_actual}",\r
+               {type_actual:typeof actual});\r
+\r
+        assert(actual <= expected,\r
+               "assert_less_than", description,\r
+               "expected a number less than or equal to ${expected} but got ${actual}",\r
+               {expected:expected, actual:actual});\r
+    };\r
+    expose(assert_less_than_equal, "assert_less_than_equal");\r
+\r
+    function assert_greater_than_equal(actual, expected, description)\r
+    {\r
+        /*\r
+         * Test if a primitive number is greater than or equal to another\r
+         */\r
+        assert(typeof actual === "number",\r
+               "assert_greater_than_equal", description,\r
+               "expected a number but got a ${type_actual}",\r
+               {type_actual:typeof actual});\r
+\r
+        assert(actual >= expected,\r
+               "assert_greater_than_equal", description,\r
+               "expected a number greater than or equal to ${expected} but got ${actual}",\r
+               {expected:expected, actual:actual});\r
+    };\r
+    expose(assert_greater_than_equal, "assert_greater_than_equal");\r
+\r
+    function assert_regexp_match(actual, expected, description) {\r
+        /*\r
+         * Test if a string (actual) matches a regexp (expected)\r
+         */\r
+        assert(expected.test(actual),\r
+               "assert_regexp_match", description,\r
+               "expected ${expected} but got ${actual}",\r
+               {expected:expected, actual:actual});\r
+    }\r
+    expose(assert_regexp_match, "assert_regexp_match");\r
+\r
+    function assert_class_string(object, class_string, description) {\r
+        assert_equals({}.toString.call(object), "[object " + class_string + "]",\r
+                      description);\r
+    }\r
+    expose(assert_class_string, "assert_class_string");\r
+\r
+\r
+    function _assert_own_property(name) {\r
+        return function(object, property_name, description)\r
+        {\r
+            assert(property_name in object,\r
+                   name, description,\r
+                   "expected property ${p} missing", {p:property_name});\r
+        };\r
+    }\r
+    expose(_assert_own_property("assert_exists"), "assert_exists");\r
+    expose(_assert_own_property("assert_own_property"), "assert_own_property");\r
+\r
+    function assert_not_exists(object, property_name, description)\r
+    {\r
+        assert(!object.hasOwnProperty(property_name),\r
+               "assert_not_exists", description,\r
+               "unexpected property ${p} found", {p:property_name});\r
+    };\r
+    expose(assert_not_exists, "assert_not_exists");\r
+\r
+    function _assert_inherits(name) {\r
+        return function (object, property_name, description)\r
+        {\r
+            assert(typeof object === "object",\r
+                   name, description,\r
+                   "provided value is not an object");\r
+\r
+            assert("hasOwnProperty" in object,\r
+                   name, description,\r
+                   "provided value is an object but has no hasOwnProperty method");\r
+\r
+            assert(!object.hasOwnProperty(property_name),\r
+                   name, description,\r
+                   "property ${p} found on object expected in prototype chain",\r
+                   {p:property_name});\r
+\r
+            assert(property_name in object,\r
+                   name, description,\r
+                   "property ${p} not found in prototype chain",\r
+                   {p:property_name});\r
+        };\r
+    }\r
+    expose(_assert_inherits("assert_inherits"), "assert_inherits");\r
+    expose(_assert_inherits("assert_idl_attribute"), "assert_idl_attribute");\r
+\r
+    function assert_readonly(object, property_name, description)\r
+    {\r
+         var initial_value = object[property_name];\r
+         try {\r
+             //Note that this can have side effects in the case where\r
+             //the property has PutForwards\r
+             object[property_name] = initial_value + "a"; //XXX use some other value here?\r
+             assert(same_value(object[property_name], initial_value),\r
+                    "assert_readonly", description,\r
+                    "changing property ${p} succeeded",\r
+                    {p:property_name});\r
+         }\r
+         finally\r
+         {\r
+             object[property_name] = initial_value;\r
+         }\r
+    };\r
+    expose(assert_readonly, "assert_readonly");\r
+\r
+    function assert_throws(code, func, description)\r
+    {\r
+        try\r
+        {\r
+            func.call(this);\r
+            assert(false, "assert_throws", description,\r
+                   "${func} did not throw", {func:func});\r
+        }\r
+        catch(e)\r
+        {\r
+            if (e instanceof AssertionError) {\r
+                throw(e);\r
+            }\r
+            if (code === null)\r
+            {\r
+                return;\r
+            }\r
+            if (typeof code === "object")\r
+            {\r
+                assert(typeof e == "object" && "name" in e && e.name == code.name,\r
+                       "assert_throws", description,\r
+                       "${func} threw ${actual} (${actual_name}) expected ${expected} (${expected_name})",\r
+                                    {func:func, actual:e, actual_name:e.name,\r
+                                     expected:code,\r
+                                     expected_name:code.name});\r
+                return;\r
+            }\r
+\r
+            var code_name_map = {\r
+                INDEX_SIZE_ERR: 'IndexSizeError',\r
+                HIERARCHY_REQUEST_ERR: 'HierarchyRequestError',\r
+                WRONG_DOCUMENT_ERR: 'WrongDocumentError',\r
+                INVALID_CHARACTER_ERR: 'InvalidCharacterError',\r
+                NO_MODIFICATION_ALLOWED_ERR: 'NoModificationAllowedError',\r
+                NOT_FOUND_ERR: 'NotFoundError',\r
+                NOT_SUPPORTED_ERR: 'NotSupportedError',\r
+                INVALID_STATE_ERR: 'InvalidStateError',\r
+                SYNTAX_ERR: 'SyntaxError',\r
+                INVALID_MODIFICATION_ERR: 'InvalidModificationError',\r
+                NAMESPACE_ERR: 'NamespaceError',\r
+                INVALID_ACCESS_ERR: 'InvalidAccessError',\r
+                TYPE_MISMATCH_ERR: 'TypeMismatchError',\r
+                SECURITY_ERR: 'SecurityError',\r
+                NETWORK_ERR: 'NetworkError',\r
+                ABORT_ERR: 'AbortError',\r
+                URL_MISMATCH_ERR: 'URLMismatchError',\r
+                QUOTA_EXCEEDED_ERR: 'QuotaExceededError',\r
+                TIMEOUT_ERR: 'TimeoutError',\r
+                INVALID_NODE_TYPE_ERR: 'InvalidNodeTypeError',\r
+                DATA_CLONE_ERR: 'DataCloneError'\r
+            };\r
+\r
+            var name = code in code_name_map ? code_name_map[code] : code;\r
+\r
+            var name_code_map = {\r
+                IndexSizeError: 1,\r
+                HierarchyRequestError: 3,\r
+                WrongDocumentError: 4,\r
+                InvalidCharacterError: 5,\r
+                NoModificationAllowedError: 7,\r
+                NotFoundError: 8,\r
+                NotSupportedError: 9,\r
+                InvalidStateError: 11,\r
+                SyntaxError: 12,\r
+                InvalidModificationError: 13,\r
+                NamespaceError: 14,\r
+                InvalidAccessError: 15,\r
+                TypeMismatchError: 17,\r
+                SecurityError: 18,\r
+                NetworkError: 19,\r
+                AbortError: 20,\r
+                URLMismatchError: 21,\r
+                QuotaExceededError: 22,\r
+                TimeoutError: 23,\r
+                InvalidNodeTypeError: 24,\r
+                DataCloneError: 25,\r
+\r
+                UnknownError: 0,\r
+                ConstraintError: 0,\r
+                DataError: 0,\r
+                TransactionInactiveError: 0,\r
+                ReadOnlyError: 0,\r
+                VersionError: 0\r
+            };\r
+\r
+            if (!(name in name_code_map))\r
+            {\r
+                throw new AssertionError('Test bug: unrecognized DOMException code "' + code + '" passed to assert_throws()');\r
+            }\r
+\r
+            var required_props = { code: name_code_map[name] };\r
+\r
+            if (required_props.code === 0\r
+            || ("name" in e && e.name !== e.name.toUpperCase() && e.name !== "DOMException"))\r
+            {\r
+                // New style exception: also test the name property.\r
+                required_props.name = name;\r
+            }\r
+\r
+            //We'd like to test that e instanceof the appropriate interface,\r
+            //but we can't, because we don't know what window it was created\r
+            //in.  It might be an instanceof the appropriate interface on some\r
+            //unknown other window.  TODO: Work around this somehow?\r
+\r
+            assert(typeof e == "object",\r
+                   "assert_throws", description,\r
+                   "${func} threw ${e} with type ${type}, not an object",\r
+                   {func:func, e:e, type:typeof e});\r
+\r
+            for (var prop in required_props)\r
+            {\r
+                assert(typeof e == "object" && prop in e && e[prop] == required_props[prop],\r
+                       "assert_throws", description,\r
+                       "${func} threw ${e} that is not a DOMException " + code + ": property ${prop} is equal to ${actual}, expected ${expected}",\r
+                       {func:func, e:e, prop:prop, actual:e[prop], expected:required_props[prop]});\r
+            }\r
+        }\r
+    }\r
+    expose(assert_throws, "assert_throws");\r
+\r
+    function assert_unreached(description) {\r
+         assert(false, "assert_unreached", description,\r
+                "Reached unreachable code");\r
+    }\r
+    expose(assert_unreached, "assert_unreached");\r
+\r
+    function assert_any(assert_func, actual, expected_array) \r
+    {\r
+        var args = [].slice.call(arguments, 3)\r
+        var errors = []\r
+        var passed = false;\r
+        forEach(expected_array, \r
+                function(expected)\r
+                {\r
+                    try {\r
+                        assert_func.apply(this, [actual, expected].concat(args))\r
+                        passed = true;\r
+                    } catch(e) {\r
+                        errors.push(e.message);\r
+                    }\r
+                });\r
+        if (!passed) {\r
+            throw new AssertionError(errors.join("\n\n"));\r
+        }\r
+    }\r
+    expose(assert_any, "assert_any");\r
+\r
+    function Test(name, properties)\r
+    {\r
+        this.name = name;\r
+        this.status = this.NOTRUN;\r
+        this.timeout_id = null;\r
+        this.is_done = false;\r
+\r
+        this.properties = properties;\r
+        this.timeout_length = properties.timeout ? properties.timeout : settings.test_timeout;\r
+\r
+        this.message = null;\r
+\r
+        var this_obj = this;\r
+        this.steps = [];\r
+\r
+        tests.push(this);\r
+    }\r
+\r
+    Test.statuses = {\r
+        PASS:0,\r
+        FAIL:1,\r
+        TIMEOUT:2,\r
+        NOTRUN:3\r
+    };\r
+\r
+    Test.prototype = merge({}, Test.statuses);\r
+\r
+    Test.prototype.structured_clone = function()\r
+    {\r
+        if(!this._structured_clone)\r
+        {\r
+            var msg = this.message;\r
+            msg = msg ? String(msg) : msg;\r
+            this._structured_clone = merge({\r
+                name:String(this.name),\r
+                status:this.status,\r
+                message:msg\r
+            }, Test.statuses);\r
+        }\r
+        return this._structured_clone;\r
+    };\r
+\r
+    Test.prototype.step = function(func, this_obj)\r
+    {\r
+        //In case the test has already failed\r
+        if (this.status !== this.NOTRUN)\r
+        {\r
+          return;\r
+        }\r
+\r
+        tests.started = true;\r
+\r
+        if (this.timeout_id === null) {\r
+            this.set_timeout();\r
+        }\r
+\r
+        this.steps.push(func);\r
+\r
+        if (arguments.length === 1)\r
+        {\r
+            this_obj = this;\r
+        }\r
+\r
+        try\r
+        {\r
+            return func.apply(this_obj, Array.prototype.slice.call(arguments, 2));\r
+        }\r
+        catch(e)\r
+        {\r
+            //This can happen if something called synchronously invoked another\r
+            //step\r
+            if (this.status !== this.NOTRUN)\r
+            {\r
+                return;\r
+            }\r
+            this.status = this.FAIL;\r
+            this.message = (typeof e === "object" && e !== null) ? e.message : e;\r
+            if (typeof e.stack != "undefined" && typeof e.message == "string") {\r
+                //Try to make it more informative for some exceptions, at least\r
+                //in Gecko and WebKit.  This results in a stack dump instead of\r
+                //just errors like "Cannot read property 'parentNode' of null"\r
+                //or "root is null".  Makes it a lot longer, of course.\r
+                this.message += "(stack: " + e.stack + ")";\r
+            }\r
+            this.done();\r
+            if (debug && e.constructor !== AssertionError) {\r
+                throw e;\r
+            }\r
+        }\r
+    };\r
+\r
+    Test.prototype.step_func = function(func, this_obj)\r
+    {\r
+        var test_this = this;\r
+\r
+        if (arguments.length === 1)\r
+        {\r
+            this_obj = test_this;\r
+        }\r
+\r
+        return function()\r
+        {\r
+            test_this.step.apply(test_this, [func, this_obj].concat(\r
+                Array.prototype.slice.call(arguments)));\r
+        };\r
+    };\r
+\r
+    Test.prototype.step_func_done = function(func, this_obj)\r
+    {\r
+        var test_this = this;\r
+\r
+        if (arguments.length === 1)\r
+        {\r
+            this_obj = test_this;\r
+        }\r
+\r
+        return function()\r
+        {\r
+            test_this.step.apply(test_this, [func, this_obj].concat(\r
+                Array.prototype.slice.call(arguments)));\r
+            test_this.done();\r
+        };\r
+    };\r
+\r
+    Test.prototype.set_timeout = function()\r
+    {\r
+        var this_obj = this;\r
+        this.timeout_id = setTimeout(function()\r
+                                     {\r
+                                         this_obj.timeout();\r
+                                     }, this.timeout_length);\r
+    };\r
+\r
+    Test.prototype.timeout = function()\r
+    {\r
+        this.status = this.TIMEOUT;\r
+        this.timeout_id = null;\r
+        this.message = "Test timed out";\r
+        this.done();\r
+    };\r
+\r
+    Test.prototype.done = function()\r
+    {\r
+        if (this.is_done) {\r
+            return;\r
+        }\r
+        clearTimeout(this.timeout_id);\r
+        if (this.status === this.NOTRUN)\r
+        {\r
+            this.status = this.PASS;\r
+        }\r
+        this.is_done = true;\r
+        tests.result(this);\r
+    };\r
+\r
+\r
+    /*\r
+     * Harness\r
+     */\r
+\r
+    function TestsStatus()\r
+    {\r
+        this.status = null;\r
+        this.message = null;\r
+    }\r
+\r
+    TestsStatus.statuses = {\r
+        OK:0,\r
+        ERROR:1,\r
+        TIMEOUT:2\r
+    };\r
+\r
+    TestsStatus.prototype = merge({}, TestsStatus.statuses);\r
+\r
+    TestsStatus.prototype.structured_clone = function()\r
+    {\r
+        if(!this._structured_clone)\r
+        {\r
+            var msg = this.message;\r
+            msg = msg ? String(msg) : msg;\r
+            this._structured_clone = merge({\r
+                status:this.status,\r
+                message:msg\r
+            }, TestsStatus.statuses);\r
+        }\r
+        return this._structured_clone;\r
+    };\r
+\r
+    function Tests()\r
+    {\r
+        this.tests = [];\r
+        this.num_pending = 0;\r
+\r
+        this.phases = {\r
+            INITIAL:0,\r
+            SETUP:1,\r
+            HAVE_TESTS:2,\r
+            HAVE_RESULTS:3,\r
+            COMPLETE:4\r
+        };\r
+        this.phase = this.phases.INITIAL;\r
+\r
+        this.properties = {};\r
+\r
+        //All tests can't be done until the load event fires\r
+        this.all_loaded = false;\r
+        this.wait_for_finish = false;\r
+        this.processing_callbacks = false;\r
+\r
+        this.timeout_length = settings.timeout;\r
+        this.timeout_id = null;\r
+\r
+        this.start_callbacks = [];\r
+        this.test_done_callbacks = [];\r
+        this.all_done_callbacks = [];\r
+\r
+        this.status = new TestsStatus();\r
+\r
+        var this_obj = this;\r
+\r
+        on_event(window, "load",\r
+                 function()\r
+                 {\r
+                     this_obj.all_loaded = true;\r
+                     if (this_obj.all_done())\r
+                     {\r
+                         this_obj.complete();\r
+                     }\r
+                 });\r
+\r
+        this.set_timeout();\r
+    }\r
+\r
+    Tests.prototype.setup = function(func, properties)\r
+    {\r
+        if (this.phase >= this.phases.HAVE_RESULTS)\r
+        {\r
+            return;\r
+        }\r
+        if (this.phase < this.phases.SETUP)\r
+        {\r
+            this.phase = this.phases.SETUP;\r
+        }\r
+\r
+        for (var p in properties)\r
+        {\r
+            if (properties.hasOwnProperty(p))\r
+            {\r
+                this.properties[p] = properties[p];\r
+            }\r
+        }\r
+\r
+        if (properties.timeout)\r
+        {\r
+            this.timeout_length = properties.timeout;\r
+        }\r
+        if (properties.explicit_done)\r
+        {\r
+            this.wait_for_finish = true;\r
+        }\r
+        if (properties.explicit_timeout) {\r
+            this.timeout_length = null;\r
+        }\r
+\r
+        if (func)\r
+        {\r
+            try\r
+            {\r
+                func();\r
+            } catch(e)\r
+            {\r
+                this.status.status = this.status.ERROR;\r
+                this.status.message = e;\r
+            };\r
+        }\r
+        this.set_timeout();\r
+    };\r
+\r
+    Tests.prototype.set_timeout = function()\r
+    {\r
+        var this_obj = this;\r
+        clearTimeout(this.timeout_id);\r
+        if (this.timeout_length !== null)\r
+        {\r
+            this.timeout_id = setTimeout(function() {\r
+                                             this_obj.timeout();\r
+                                         }, this.timeout_length);\r
+        }\r
+    };\r
+\r
+    Tests.prototype.timeout = function() {\r
+        this.status.status = this.status.TIMEOUT;\r
+        this.complete();\r
+    };\r
+\r
+    Tests.prototype.end_wait = function()\r
+    {\r
+        this.wait_for_finish = false;\r
+        if (this.all_done()) {\r
+            this.complete();\r
+        }\r
+    };\r
+\r
+    Tests.prototype.push = function(test)\r
+    {\r
+        if (this.phase < this.phases.HAVE_TESTS) {\r
+            this.start();\r
+        }\r
+        this.num_pending++;\r
+        this.tests.push(test);\r
+    };\r
+\r
+    Tests.prototype.all_done = function() {\r
+        return (this.all_loaded && this.num_pending === 0 &&\r
+                !this.wait_for_finish && !this.processing_callbacks);\r
+    };\r
+\r
+    Tests.prototype.start = function() {\r
+        this.phase = this.phases.HAVE_TESTS;\r
+        this.notify_start();\r
+    };\r
+\r
+    Tests.prototype.notify_start = function() {\r
+        var this_obj = this;\r
+        forEach (this.start_callbacks,\r
+                 function(callback)\r
+                 {\r
+                     callback(this_obj.properties);\r
+                 });\r
+        forEach_windows(\r
+                function(w, is_same_origin)\r
+                {\r
+                    if(is_same_origin && w.start_callback)\r
+                    {\r
+                        try\r
+                        {\r
+                            w.start_callback(this_obj.properties);\r
+                        }\r
+                        catch(e)\r
+                        {\r
+                            if (debug)\r
+                            {\r
+                                throw(e);\r
+                            }\r
+                        }\r
+                    }\r
+                    if (supports_post_message(w) && w !== self)\r
+                    {\r
+                        w.postMessage({\r
+                            type: "start",\r
+                            properties: this_obj.properties\r
+                        }, "*");\r
+                    }\r
+                });\r
+    };\r
+\r
+    Tests.prototype.result = function(test)\r
+    {\r
+        if (this.phase > this.phases.HAVE_RESULTS)\r
+        {\r
+            return;\r
+        }\r
+        this.phase = this.phases.HAVE_RESULTS;\r
+        this.num_pending--;\r
+        this.notify_result(test);\r
+    };\r
+\r
+    Tests.prototype.notify_result = function(test) {\r
+        var this_obj = this;\r
+        this.processing_callbacks = true;\r
+        forEach(this.test_done_callbacks,\r
+                function(callback)\r
+                {\r
+                    callback(test, this_obj);\r
+                });\r
+\r
+        forEach_windows(\r
+                function(w, is_same_origin)\r
+                {\r
+                    if(is_same_origin && w.result_callback)\r
+                    {\r
+                        try\r
+                        {\r
+                            w.result_callback(test);\r
+                        }\r
+                        catch(e)\r
+                        {\r
+                            if(debug) {\r
+                                throw e;\r
+                            }\r
+                        }\r
+                    }\r
+                    if (supports_post_message(w) && w !== self)\r
+                    {\r
+                        w.postMessage({\r
+                            type: "result",\r
+                            test: test.structured_clone()\r
+                        }, "*");\r
+                    }\r
+                });\r
+        this.processing_callbacks = false;\r
+        if (this_obj.all_done())\r
+        {\r
+            this_obj.complete();\r
+        }\r
+    };\r
+\r
+    Tests.prototype.complete = function() {\r
+        if (this.phase === this.phases.COMPLETE) {\r
+            return;\r
+        }\r
+        this.phase = this.phases.COMPLETE;\r
+        var this_obj = this;\r
+        this.tests.forEach(\r
+            function(x)\r
+            {\r
+                if(x.status === x.NOTRUN)\r
+                {\r
+                    this_obj.notify_result(x);\r
+                }\r
+            }\r
+        );\r
+        this.notify_complete();\r
+    };\r
+\r
+    Tests.prototype.notify_complete = function()\r
+    {\r
+        clearTimeout(this.timeout_id);\r
+        var this_obj = this;\r
+        var tests = map(this_obj.tests,\r
+                        function(test)\r
+                        {\r
+                            return test.structured_clone();\r
+                        });\r
+        if (this.status.status === null)\r
+        {\r
+            this.status.status = this.status.OK;\r
+        }\r
+\r
+        forEach (this.all_done_callbacks,\r
+                 function(callback)\r
+                 {\r
+                     callback(this_obj.tests, this_obj.status);\r
+                 });\r
+\r
+        forEach_windows(\r
+                function(w, is_same_origin)\r
+                {\r
+                    if(is_same_origin && w.completion_callback)\r
+                    {\r
+                        try\r
+                        {\r
+                            w.completion_callback(this_obj.tests, this_obj.status);\r
+                        }\r
+                        catch(e)\r
+                        {\r
+                            if (debug)\r
+                            {\r
+                                throw e;\r
+                            }\r
+                        }\r
+                    }\r
+                    if (supports_post_message(w) && w !== self)\r
+                    {\r
+                        w.postMessage({\r
+                            type: "complete",\r
+                            tests: tests,\r
+                            status: this_obj.status.structured_clone()\r
+                        }, "*");\r
+                    }\r
+                });\r
+    };\r
+\r
+    var tests = new Tests();\r
+\r
+    function timeout() {\r
+        if (tests.timeout_length === null)\r
+        {\r
+            tests.timeout();\r
+        }\r
+    }\r
+    expose(timeout, 'timeout');\r
+\r
+    function add_start_callback(callback) {\r
+        tests.start_callbacks.push(callback);\r
+    }\r
+\r
+    function add_result_callback(callback)\r
+    {\r
+        tests.test_done_callbacks.push(callback);\r
+    }\r
+\r
+    function add_completion_callback(callback)\r
+    {\r
+       tests.all_done_callbacks.push(callback);\r
+    }\r
+\r
+    expose(add_start_callback, 'add_start_callback');\r
+    expose(add_result_callback, 'add_result_callback');\r
+    expose(add_completion_callback, 'add_completion_callback');\r
+\r
+    /*\r
+     * Output listener\r
+    */\r
+\r
+    function Output() {\r
+      this.output_document = document;\r
+      this.output_node = null;\r
+      this.done_count = 0;\r
+      this.enabled = settings.output;\r
+      this.phase = this.INITIAL;\r
+    }\r
+\r
+    Output.prototype.INITIAL = 0;\r
+    Output.prototype.STARTED = 1;\r
+    Output.prototype.HAVE_RESULTS = 2;\r
+    Output.prototype.COMPLETE = 3;\r
+\r
+    Output.prototype.setup = function(properties) {\r
+        if (this.phase > this.INITIAL) {\r
+            return;\r
+        }\r
+\r
+        //If output is disabled in testharnessreport.js the test shouldn't be\r
+        //able to override that\r
+        this.enabled = this.enabled && (properties.hasOwnProperty("output") ?\r
+                                        properties.output : settings.output);\r
+    };\r
+\r
+    Output.prototype.init = function(properties)\r
+    {\r
+        if (this.phase >= this.STARTED) {\r
+            return;\r
+        }\r
+        if (properties.output_document) {\r
+            this.output_document = properties.output_document;\r
+        } else {\r
+            this.output_document = document;\r
+        }\r
+        this.phase = this.STARTED;\r
+    };\r
+\r
+    Output.prototype.resolve_log = function()\r
+    {\r
+        var output_document;\r
+        if (typeof this.output_document === "function")\r
+        {\r
+            output_document = this.output_document.apply(undefined);\r
+        } else\r
+        {\r
+            output_document = this.output_document;\r
+        }\r
+        if (!output_document)\r
+        {\r
+            return;\r
+        }\r
+        var node = output_document.getElementById("log");\r
+        if (node)\r
+        {\r
+            this.output_document = output_document;\r
+            this.output_node = node;\r
+        }\r
+    };\r
+\r
+    Output.prototype.show_status = function(test)\r
+    {\r
+        if (this.phase < this.STARTED)\r
+        {\r
+            this.init();\r
+        }\r
+        if (!this.enabled)\r
+        {\r
+            return;\r
+        }\r
+        if (this.phase < this.HAVE_RESULTS)\r
+        {\r
+            this.resolve_log();\r
+            this.phase = this.HAVE_RESULTS;\r
+        }\r
+        this.done_count++;\r
+        if (this.output_node)\r
+        {\r
+            if (this.done_count < 100\r
+            || (this.done_count < 1000 && this.done_count % 100 == 0)\r
+            || this.done_count % 1000 == 0) {\r
+                this.output_node.textContent = "Running, "\r
+                    + this.done_count + " complete, "\r
+                    + tests.num_pending + " remain";\r
+            }\r
+        }\r
+    };\r
+\r
+    Output.prototype.show_results = function (tests, harness_status)\r
+    {\r
+        if (this.phase >= this.COMPLETE) {\r
+            return;\r
+        }\r
+        if (!this.enabled)\r
+        {\r
+            return;\r
+        }\r
+        if (!this.output_node) {\r
+            this.resolve_log();\r
+        }\r
+        this.phase = this.COMPLETE;\r
+\r
+        var log = this.output_node;\r
+        if (!log)\r
+        {\r
+            return;\r
+        }\r
+        var output_document = this.output_document;\r
+\r
+        while (log.lastChild)\r
+        {\r
+            log.removeChild(log.lastChild);\r
+        }\r
+\r
+        if (script_prefix != null) {\r
+            var stylesheet = output_document.createElementNS(xhtml_ns, "link");\r
+            stylesheet.setAttribute("rel", "stylesheet");\r
+            stylesheet.setAttribute("href", script_prefix + "testharness.css");\r
+            var heads = output_document.getElementsByTagName("head");\r
+            if (heads.length) {\r
+                heads[0].appendChild(stylesheet);\r
+            }\r
+        }\r
+\r
+        var status_text = {};\r
+        status_text[Test.prototype.PASS] = "Pass";\r
+        status_text[Test.prototype.FAIL] = "Fail";\r
+        status_text[Test.prototype.TIMEOUT] = "Timeout";\r
+        status_text[Test.prototype.NOTRUN] = "Not Run";\r
+\r
+        var status_number = {};\r
+        forEach(tests, function(test) {\r
+                    var status = status_text[test.status];\r
+                    if (status_number.hasOwnProperty(status))\r
+                    {\r
+                        status_number[status] += 1;\r
+                    } else {\r
+                        status_number[status] = 1;\r
+                    }\r
+                });\r
+\r
+        function status_class(status)\r
+        {\r
+            return status.replace(/\s/g, '').toLowerCase();\r
+        }\r
+\r
+        var summary_template = ["section", {"id":"summary"},\r
+                                ["h2", {}, "Summary"],\r
+                                ["p", {}, "Found ${num_tests} tests"],\r
+                                function(vars) {\r
+                                    var rv = [["div", {}]];\r
+                                    var i=0;\r
+                                    while (status_text.hasOwnProperty(i)) {\r
+                                        if (status_number.hasOwnProperty(status_text[i])) {\r
+                                            var status = status_text[i];\r
+                                            rv[0].push(["div", {"class":status_class(status)},\r
+                                                        ["label", {},\r
+                                                         ["input", {type:"checkbox", checked:"checked"}],\r
+                                                         status_number[status] + " " + status]]);\r
+                                        }\r
+                                        i++;\r
+                                    }\r
+                                    return rv;\r
+                                }];\r
+\r
+        log.appendChild(render(summary_template, {num_tests:tests.length}, output_document));\r
+\r
+        forEach(output_document.querySelectorAll("section#summary label"),\r
+                function(element)\r
+                {\r
+                    on_event(element, "click",\r
+                             function(e)\r
+                             {\r
+                                 if (output_document.getElementById("results") === null)\r
+                                 {\r
+                                     e.preventDefault();\r
+                                     return;\r
+                                 }\r
+                                 var result_class = element.parentNode.getAttribute("class");\r
+                                 var style_element = output_document.querySelector("style#hide-" + result_class);\r
+                                 var input_element = element.querySelector("input");\r
+                                 if (!style_element && !input_element.checked) {\r
+                                     style_element = output_document.createElementNS(xhtml_ns, "style");\r
+                                     style_element.id = "hide-" + result_class;\r
+                                     style_element.textContent = "table#results > tbody > tr."+result_class+"{display:none}";\r
+                                     output_document.body.appendChild(style_element);\r
+                                 } else if (style_element && input_element.checked) {\r
+                                     style_element.parentNode.removeChild(style_element);\r
+                                 }\r
+                             });\r
+                });\r
+\r
+        // This use of innerHTML plus manual escaping is not recommended in\r
+        // general, but is necessary here for performance.  Using textContent\r
+        // on each individual <td> adds tens of seconds of execution time for\r
+        // large test suites (tens of thousands of tests).\r
+        function escape_html(s)\r
+        {\r
+            return s.replace(/\&/g, "&amp;")\r
+                .replace(/</g, "&lt;")\r
+                .replace(/"/g, "&quot;")\r
+                .replace(/'/g, "&#39;");\r
+        }\r
+\r
+        function has_assertions()\r
+        {\r
+            for (var i = 0; i < tests.length; i++) {\r
+                if (tests[i].properties.hasOwnProperty("assert")) {\r
+                    return true;\r
+                }\r
+            }\r
+            return false;\r
+        }\r
+        \r
+        function get_assertion(test)\r
+        {\r
+            if (test.properties.hasOwnProperty("assert")) {\r
+                if (Array.isArray(test.properties.assert)) {\r
+                    return test.properties.assert.join(' ');\r
+                }\r
+                return test.properties.assert;\r
+            }\r
+            return '';\r
+        }\r
+        \r
+        log.appendChild(document.createElementNS(xhtml_ns, "section"));\r
+        var assertions = has_assertions();\r
+        var html = "<h2>Details</h2><table id='results' " + (assertions ? "class='assertions'" : "" ) + ">"\r
+            + "<thead><tr><th>Result</th><th>Test Name</th>"\r
+            + (assertions ? "<th>Assertion</th>" : "")\r
+            + "<th>Message</th></tr></thead>"\r
+            + "<tbody>";\r
+        for (var i = 0; i < tests.length; i++) {\r
+            html += '<tr class="'\r
+                + escape_html(status_class(status_text[tests[i].status]))\r
+                + '"><td>'\r
+                + escape_html(status_text[tests[i].status])\r
+                + "</td><td>"\r
+                + escape_html(tests[i].name)\r
+                + "</td><td>"\r
+                + (assertions ? escape_html(get_assertion(tests[i])) + "</td><td>" : "")\r
+                + escape_html(tests[i].message ? tests[i].message : " ")\r
+                + "</td></tr>";\r
+        }\r
+        html += "</tbody></table>";\r
+        try {\r
+            log.lastChild.innerHTML = html;\r
+        } catch (e) {\r
+            log.appendChild(document.createElementNS(xhtml_ns, "p"))\r
+               .textContent = "Setting innerHTML for the log threw an exception.";\r
+            log.appendChild(document.createElementNS(xhtml_ns, "pre"))\r
+               .textContent = html;\r
+        }\r
+    };\r
+\r
+    var output = new Output();\r
+    add_start_callback(function (properties) {output.init(properties);});\r
+    add_result_callback(function (test) {output.show_status(tests);});\r
+    add_completion_callback(function (tests, harness_status) {output.show_results(tests, harness_status);});\r
+\r
+    /*\r
+     * Template code\r
+     *\r
+     * A template is just a javascript structure. An element is represented as:\r
+     *\r
+     * [tag_name, {attr_name:attr_value}, child1, child2]\r
+     *\r
+     * the children can either be strings (which act like text nodes), other templates or\r
+     * functions (see below)\r
+     *\r
+     * A text node is represented as\r
+     *\r
+     * ["{text}", value]\r
+     *\r
+     * String values have a simple substitution syntax; ${foo} represents a variable foo.\r
+     *\r
+     * It is possible to embed logic in templates by using a function in a place where a\r
+     * node would usually go. The function must either return part of a template or null.\r
+     *\r
+     * In cases where a set of nodes are required as output rather than a single node\r
+     * with children it is possible to just use a list\r
+     * [node1, node2, node3]\r
+     *\r
+     * Usage:\r
+     *\r
+     * render(template, substitutions) - take a template and an object mapping\r
+     * variable names to parameters and return either a DOM node or a list of DOM nodes\r
+     *\r
+     * substitute(template, substitutions) - take a template and variable mapping object,\r
+     * make the variable substitutions and return the substituted template\r
+     *\r
+     */\r
+\r
+    function is_single_node(template)\r
+    {\r
+        return typeof template[0] === "string";\r
+    }\r
+\r
+    function substitute(template, substitutions)\r
+    {\r
+        if (typeof template === "function") {\r
+            var replacement = template(substitutions);\r
+            if (replacement)\r
+            {\r
+                var rv = substitute(replacement, substitutions);\r
+                return rv;\r
+            }\r
+            else\r
+            {\r
+                return null;\r
+            }\r
+        }\r
+        else if (is_single_node(template))\r
+        {\r
+            return substitute_single(template, substitutions);\r
+        }\r
+        else\r
+        {\r
+            return filter(map(template, function(x) {\r
+                                  return substitute(x, substitutions);\r
+                              }), function(x) {return x !== null;});\r
+        }\r
+    }\r
+\r
+    function substitute_single(template, substitutions)\r
+    {\r
+        var substitution_re = /\${([^ }]*)}/g;\r
+\r
+        function do_substitution(input) {\r
+            var components = input.split(substitution_re);\r
+            var rv = [];\r
+            for (var i=0; i<components.length; i+=2)\r
+            {\r
+                rv.push(components[i]);\r
+                if (components[i+1])\r
+                {\r
+                    rv.push(String(substitutions[components[i+1]]));\r
+                }\r
+            }\r
+            return rv;\r
+        }\r
+\r
+        var rv = [];\r
+        rv.push(do_substitution(String(template[0])).join(""));\r
+\r
+        if (template[0] === "{text}") {\r
+            substitute_children(template.slice(1), rv);\r
+        } else {\r
+            substitute_attrs(template[1], rv);\r
+            substitute_children(template.slice(2), rv);\r
+        }\r
+\r
+        function substitute_attrs(attrs, rv)\r
+        {\r
+            rv[1] = {};\r
+            for (var name in template[1])\r
+            {\r
+                if (attrs.hasOwnProperty(name))\r
+                {\r
+                    var new_name = do_substitution(name).join("");\r
+                    var new_value = do_substitution(attrs[name]).join("");\r
+                    rv[1][new_name] = new_value;\r
+                };\r
+            }\r
+        }\r
+\r
+        function substitute_children(children, rv)\r
+        {\r
+            for (var i=0; i<children.length; i++)\r
+            {\r
+                if (children[i] instanceof Object) {\r
+                    var replacement = substitute(children[i], substitutions);\r
+                    if (replacement !== null)\r
+                    {\r
+                        if (is_single_node(replacement))\r
+                        {\r
+                            rv.push(replacement);\r
+                        }\r
+                        else\r
+                        {\r
+                            extend(rv, replacement);\r
+                        }\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    extend(rv, do_substitution(String(children[i])));\r
+                }\r
+            }\r
+            return rv;\r
+        }\r
+\r
+        return rv;\r
+    }\r
+\r
+ function make_dom_single(template, doc)\r
+ {\r
+     var output_document = doc || document;\r
+     if (template[0] === "{text}")\r
+     {\r
+         var element = output_document.createTextNode("");\r
+         for (var i=1; i<template.length; i++)\r
+         {\r
+             element.data += template[i];\r
+         }\r
+     }\r
+     else\r
+     {\r
+         var element = output_document.createElementNS(xhtml_ns, template[0]);\r
+         for (var name in template[1]) {\r
+             if (template[1].hasOwnProperty(name))\r
+             {\r
+                 element.setAttribute(name, template[1][name]);\r
+             }\r
+         }\r
+         for (var i=2; i<template.length; i++)\r
+         {\r
+             if (template[i] instanceof Object)\r
+             {\r
+                 var sub_element = make_dom(template[i]);\r
+                 element.appendChild(sub_element);\r
+             }\r
+             else\r
+             {\r
+                 var text_node = output_document.createTextNode(template[i]);\r
+                 element.appendChild(text_node);\r
+             }\r
+         }\r
+     }\r
+\r
+     return element;\r
+ }\r
+\r
+\r
+\r
+ function make_dom(template, substitutions, output_document)\r
+    {\r
+        if (is_single_node(template))\r
+        {\r
+            return make_dom_single(template, output_document);\r
+        }\r
+        else\r
+        {\r
+            return map(template, function(x) {\r
+                           return make_dom_single(x, output_document);\r
+                       });\r
+        }\r
+    }\r
+\r
+ function render(template, substitutions, output_document)\r
+    {\r
+        return make_dom(substitute(template, substitutions), output_document);\r
+    }\r
+\r
+    /*\r
+     * Utility funcions\r
+     */\r
+    function assert(expected_true, function_name, description, error, substitutions)\r
+    {\r
+        if (expected_true !== true)\r
+        {\r
+            throw new AssertionError(make_message(function_name, description,\r
+                                                  error, substitutions));\r
+        }\r
+    }\r
+\r
+    function AssertionError(message)\r
+    {\r
+        this.message = message;\r
+    }\r
+\r
+    function make_message(function_name, description, error, substitutions)\r
+    {\r
+        for (var p in substitutions) {\r
+            if (substitutions.hasOwnProperty(p)) {\r
+                substitutions[p] = format_value(substitutions[p]);\r
+            }\r
+        }\r
+        var node_form = substitute(["{text}", "${function_name}: ${description}" + error],\r
+                                   merge({function_name:function_name,\r
+                                          description:(description?description + " ":"")},\r
+                                          substitutions));\r
+        return node_form.slice(1).join("");\r
+    }\r
+\r
+    function filter(array, callable, thisObj) {\r
+        var rv = [];\r
+        for (var i=0; i<array.length; i++)\r
+        {\r
+            if (array.hasOwnProperty(i))\r
+            {\r
+                var pass = callable.call(thisObj, array[i], i, array);\r
+                if (pass) {\r
+                    rv.push(array[i]);\r
+                }\r
+            }\r
+        }\r
+        return rv;\r
+    }\r
+\r
+    function map(array, callable, thisObj)\r
+    {\r
+        var rv = [];\r
+        rv.length = array.length;\r
+        for (var i=0; i<array.length; i++)\r
+        {\r
+            if (array.hasOwnProperty(i))\r
+            {\r
+                rv[i] = callable.call(thisObj, array[i], i, array);\r
+            }\r
+        }\r
+        return rv;\r
+    }\r
+\r
+    function extend(array, items)\r
+    {\r
+        Array.prototype.push.apply(array, items);\r
+    }\r
+\r
+    function forEach (array, callback, thisObj)\r
+    {\r
+        for (var i=0; i<array.length; i++)\r
+        {\r
+            if (array.hasOwnProperty(i))\r
+            {\r
+                callback.call(thisObj, array[i], i, array);\r
+            }\r
+        }\r
+    }\r
+\r
+    function merge(a,b)\r
+    {\r
+        var rv = {};\r
+        var p;\r
+        for (p in a)\r
+        {\r
+            rv[p] = a[p];\r
+        }\r
+        for (p in b) {\r
+            rv[p] = b[p];\r
+        }\r
+        return rv;\r
+    }\r
+\r
+    function expose(object, name)\r
+    {\r
+        var components = name.split(".");\r
+        var target = window;\r
+        for (var i=0; i<components.length - 1; i++)\r
+        {\r
+            if (!(components[i] in target))\r
+            {\r
+                target[components[i]] = {};\r
+            }\r
+            target = target[components[i]];\r
+        }\r
+        target[components[components.length - 1]] = object;\r
+    }\r
+\r
+    function forEach_windows(callback) {\r
+        // Iterate of the the windows [self ... top, opener]. The callback is passed\r
+        // two objects, the first one is the windows object itself, the second one\r
+        // is a boolean indicating whether or not its on the same origin as the\r
+        // current window.\r
+        var cache = forEach_windows.result_cache;\r
+        if (!cache) {\r
+            cache = [[self, true]];\r
+            var w = self;\r
+            var i = 0;\r
+            var so;\r
+            var origins = location.ancestorOrigins;\r
+            while (w != w.parent)\r
+            {\r
+                w = w.parent;\r
+                // In WebKit, calls to parent windows' properties that aren't on the same\r
+                // origin cause an error message to be displayed in the error console but\r
+                // don't throw an exception. This is a deviation from the current HTML5\r
+                // spec. See: https://bugs.webkit.org/show_bug.cgi?id=43504\r
+                // The problem with WebKit's behavior is that it pollutes the error console\r
+                // with error messages that can't be caught.\r
+                //\r
+                // This issue can be mitigated by relying on the (for now) proprietary\r
+                // `location.ancestorOrigins` property which returns an ordered list of\r
+                // the origins of enclosing windows. See:\r
+                // http://trac.webkit.org/changeset/113945.\r
+                if(origins) {\r
+                    so = (location.origin == origins[i]);\r
+                }\r
+                else\r
+                {\r
+                    so = is_same_origin(w);\r
+                }\r
+                cache.push([w, so]);\r
+                i++;\r
+            }\r
+            w = window.opener;\r
+            if(w)\r
+            {\r
+                // window.opener isn't included in the `location.ancestorOrigins` prop.\r
+                // We'll just have to deal with a simple check and an error msg on WebKit\r
+                // browsers in this case.\r
+                cache.push([w, is_same_origin(w)]);\r
+            }\r
+            forEach_windows.result_cache = cache;\r
+        }\r
+\r
+        forEach(cache,\r
+                function(a)\r
+                {\r
+                    callback.apply(null, a);\r
+                });\r
+    }\r
+\r
+    function is_same_origin(w) {\r
+        try {\r
+            'random_prop' in w;\r
+            return true;\r
+        } catch(e) {\r
+            return false;\r
+        }\r
+    }\r
+\r
+    function supports_post_message(w)\r
+    {\r
+        var supports;\r
+        var type;\r
+        // Given IE  implements postMessage across nested iframes but not across\r
+        // windows or tabs, you can't infer cross-origin communication from the presence\r
+        // of postMessage on the current window object only.\r
+        //\r
+        // Touching the postMessage prop on a window can throw if the window is\r
+        // not from the same origin AND post message is not supported in that\r
+        // browser. So just doing an existence test here won't do, you also need\r
+        // to wrap it in a try..cacth block.\r
+        try\r
+        {\r
+            type = typeof w.postMessage;\r
+            if (type === "function")\r
+            {\r
+                supports = true;\r
+            }\r
+            // IE8 supports postMessage, but implements it as a host object which\r
+            // returns "object" as its `typeof`.\r
+            else if (type === "object")\r
+            {\r
+                supports = true;\r
+            }\r
+            // This is the case where postMessage isn't supported AND accessing a\r
+            // window property across origins does NOT throw (e.g. old Safari browser).\r
+            else\r
+            {\r
+                supports = false;\r
+            }\r
+        }\r
+        catch(e) {\r
+            // This is the case where postMessage isn't supported AND accessing a\r
+            // window property across origins throws (e.g. old Firefox browser).\r
+            supports = false;\r
+        }\r
+        return supports;\r
+    }\r
+})();\r
+\r
+/*\r
+ *For blacklist\r
+ */\r
+\r
+function is_platform_supported(name)\r
+{\r
+    var ret = true;\r
+\r
+    if (not_support_list.indexOf(name) >= 0)\r
+        ret = false;\r
+\r
+    return ret;\r
+}\r
+\r
+// vim: set expandtab shiftwidth=4 tabstop=4:\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/testharnessreport.js b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/testharnessreport.js
new file mode 100755 (executable)
index 0000000..8305f7b
--- /dev/null
@@ -0,0 +1,380 @@
+/*\r
+ * This file is intended for vendors to implement\r
+ * code needed to integrate testharness.js tests with their own test systems.\r
+ *\r
+ * The default implementation extracts metadata from the tests and validates \r
+ * it against the cached version that should be present in the test source \r
+ * file. If the cache is not found or is out of sync, source code suitable for\r
+ * caching the metadata is optionally generated.\r
+ *\r
+ * The cached metadata is present for extraction by test processing tools that\r
+ * are unable to execute javascript.\r
+ *\r
+ * Metadata is attached to tests via the properties parameter in the test\r
+ * constructor. See testharness.js for details.\r
+ *\r
+ * Typically test system integration will attach callbacks when each test has\r
+ * run, using add_result_callback(callback(test)), or when the whole test file\r
+ * has completed, using \r
+ * add_completion_callback(callback(tests, harness_status)).\r
+ *\r
+ * For more documentation about the callback functions and the\r
+ * parameters they are called with see testharness.js\r
+ */\r
+\r
+\r
+\r
+var metadata_generator = {\r
+\r
+    currentMetadata: {},\r
+    cachedMetadata: false,\r
+    metadataProperties: ['help', 'assert', 'author'],\r
+    \r
+    error: function(message) {\r
+        var messageElement = document.createElement('p');\r
+        messageElement.setAttribute('class', 'error');\r
+        this.appendText(messageElement, message);\r
+        \r
+        var summary = document.getElementById('summary');\r
+        if (summary) {\r
+            summary.parentNode.insertBefore(messageElement, summary);\r
+        }\r
+        else {\r
+            document.body.appendChild(messageElement);\r
+        }\r
+    },\r
+\r
+    /**\r
+     * Ensure property value has contact information\r
+     */\r
+    validateContact: function(test, propertyName) {\r
+        var result = true;\r
+        var value = test.properties[propertyName];\r
+        var values = Array.isArray(value) ? value : [value];\r
+        for (var index = 0; index < values.length; index++) {\r
+            value = values[index];\r
+            var re = /(\S+)(\s*)<(.*)>(.*)/;\r
+            if (! re.test(value)) {\r
+                re = /(\S+)(\s+)(http[s]?:\/\/)(.*)/\r
+                if (! re.test(value)) {\r
+                    this.error('Metadata property "' + propertyName + \r
+                        '" for test: "' + test.name +\r
+                        '" must have name and contact information ' +\r
+                        '("name <email>" or "name http(s)://")');\r
+                    result = false;\r
+                }\r
+            }\r
+        }\r
+        return result;\r
+    },\r
+    \r
+    /**\r
+     * Extract metadata from test object\r
+     */\r
+    extractFromTest: function(test) {\r
+        var testMetadata = {};\r
+        // filter out metadata from other properties in test\r
+        for (var metaIndex = 0; metaIndex < this.metadataProperties.length;\r
+             metaIndex++) {\r
+            var meta = this.metadataProperties[metaIndex];\r
+            if (test.properties.hasOwnProperty(meta)) {\r
+                if ('author' == meta) {\r
+                    this.validateContact(test, meta);\r
+                }\r
+                testMetadata[meta] = test.properties[meta];\r
+            }\r
+        }\r
+        return testMetadata;\r
+    },\r
+    \r
+    /**\r
+     * Compare cached metadata to extracted metadata\r
+     */\r
+    validateCache: function() {\r
+        for (var testName in this.currentMetadata) {\r
+            if (! this.cachedMetadata.hasOwnProperty(testName)) {\r
+                return false;\r
+            }\r
+            var testMetadata = this.currentMetadata[testName];\r
+            var cachedTestMetadata = this.cachedMetadata[testName];\r
+            delete this.cachedMetadata[testName];\r
+            \r
+            for (var metaIndex = 0; metaIndex < this.metadataProperties.length;\r
+                 metaIndex++) {\r
+                var meta = this.metadataProperties[metaIndex];\r
+                if (cachedTestMetadata.hasOwnProperty(meta) && \r
+                    testMetadata.hasOwnProperty(meta)) {\r
+                    if (Array.isArray(cachedTestMetadata[meta])) {\r
+                      if (! Array.isArray(testMetadata[meta])) {\r
+                          return false;\r
+                      }\r
+                      if (cachedTestMetadata[meta].length == \r
+                          testMetadata[meta].length) {\r
+                          for (var index = 0; \r
+                               index < cachedTestMetadata[meta].length; \r
+                               index++) {\r
+                              if (cachedTestMetadata[meta][index] != \r
+                                  testMetadata[meta][index]) {\r
+                                  return false;\r
+                              }\r
+                          }\r
+                      }\r
+                      else {\r
+                          return false;\r
+                      }\r
+                    }\r
+                    else {\r
+                      if (Array.isArray(testMetadata[meta])) {\r
+                        return false;\r
+                      }\r
+                      if (cachedTestMetadata[meta] != testMetadata[meta]) {\r
+                        return false;\r
+                      }\r
+                    }\r
+                }\r
+                else if (cachedTestMetadata.hasOwnProperty(meta) || \r
+                         testMetadata.hasOwnProperty(meta)) {\r
+                    return false;\r
+                }\r
+            }\r
+        }\r
+        for (var testName in this.cachedMetadata) {\r
+            return false;\r
+        }\r
+        return true;\r
+    },\r
+  \r
+    appendText: function(elemement, text) {\r
+        elemement.appendChild(document.createTextNode(text));\r
+    },\r
+  \r
+    jsonifyArray: function(arrayValue, indent) {\r
+        var output = '[';\r
+\r
+        if (1 == arrayValue.length) {\r
+            output += JSON.stringify(arrayValue[0]);\r
+        }\r
+        else {\r
+            for (var index = 0; index < arrayValue.length; index++) {\r
+                if (0 < index) {\r
+                    output += ',\n  ' + indent;\r
+                }\r
+                output += JSON.stringify(arrayValue[index]);\r
+            }\r
+        }\r
+        output += ']';\r
+        return output;\r
+    },\r
+    \r
+    jsonifyObject: function(objectValue, indent) {\r
+        var output = '{';\r
+        \r
+        var count = 0;\r
+        for (var property in objectValue) {\r
+            ++count;\r
+            if (Array.isArray(objectValue[property]) || \r
+                ('object' == typeof(value))) {\r
+                ++count;\r
+            }\r
+        }\r
+        if (1 == count) {\r
+            for (var property in objectValue) {\r
+                output += ' "' + property + '": '\r
+                          + JSON.stringify(objectValue[property])\r
+                          + ' ';\r
+            }\r
+        }\r
+        else {\r
+            var first = true;\r
+            for (var property in objectValue) {\r
+                if (! first) {\r
+                    output += ',';\r
+                }\r
+                first = false;\r
+                output += '\n  ' + indent + '"' + property + '": ';\r
+                var value = objectValue[property];\r
+                if (Array.isArray(value)) {\r
+                    output += this.jsonifyArray(value, indent + \r
+                        '                '.substr(0, 5 + property.length));\r
+                }\r
+                else if ('object' == typeof(value)) {\r
+                    output += this.jsonifyObject(value, indent + '  ');\r
+                }\r
+                else {\r
+                    output += JSON.stringify(value);\r
+                }\r
+            }\r
+            if (1 < output.length) {\r
+                output += '\n' + indent;\r
+            }\r
+        }\r
+        output += '}';\r
+        return output;\r
+    },\r
+  \r
+    /**\r
+     * Generate javascript source code for captured metadata\r
+     * Metadata is in pretty-printed JSON format\r
+     */\r
+    generateSource: function() {\r
+        var source = \r
+            '<script id="metadata_cache">/*\n' + \r
+            this.jsonifyObject(this.currentMetadata, '') + '\n' + \r
+            '*/</script>\n';\r
+        return source;\r
+    },\r
+    \r
+    /**\r
+     * Add element containing metadata source code\r
+     */\r
+    addSourceElement: function(event) {\r
+        var sourceWrapper = document.createElement('div');\r
+        sourceWrapper.setAttribute('id', 'metadata_source');\r
+\r
+        var instructions = document.createElement('p');\r
+        if (this.cachedMetadata) {\r
+            this.appendText(instructions, \r
+                'Replace the existing <script id="metadata_cache"> element ' + \r
+                'in the test\'s <head> with the following:');\r
+        }\r
+        else {\r
+            this.appendText(instructions, \r
+                'Copy the following into the <head> element of the test ' +\r
+                'or the test\'s metadata sidecar file:');\r
+        }\r
+        sourceWrapper.appendChild(instructions);\r
+        \r
+        var sourceElement = document.createElement('pre');\r
+        this.appendText(sourceElement, this.generateSource());\r
+\r
+        sourceWrapper.appendChild(sourceElement);\r
+        \r
+        var messageElement = document.getElementById('metadata_issue');\r
+        messageElement.parentNode.insertBefore(sourceWrapper, \r
+                                               messageElement.nextSibling);\r
+        messageElement.parentNode.removeChild(messageElement);\r
+\r
+        (event.preventDefault) ? event.preventDefault() : \r
+                                 event.returnValue = false;\r
+    },\r
+    \r
+    /**\r
+     * Extract the metadata cache from the cache element if present\r
+     */\r
+    getCachedMetadata: function() {\r
+        var cacheElement = document.getElementById('metadata_cache');\r
+        \r
+        if (cacheElement) {\r
+            var cacheText = cacheElement.firstChild.nodeValue;\r
+            var openBrace = cacheText.indexOf('{');\r
+            var closeBrace = cacheText.lastIndexOf('}');\r
+            if ((-1 < openBrace) && (-1 < closeBrace)) {\r
+                cacheText = cacheText.slice(openBrace, closeBrace + 1);\r
+                try {\r
+                    this.cachedMetadata = JSON.parse(cacheText);\r
+                }\r
+                catch (exc) {\r
+                    this.cachedMetadata = 'Invalid JSON in Cached metadata. ';\r
+                }\r
+            }\r
+            else {\r
+                this.cachedMetadata = 'Metadata not found in cache element. ';\r
+            }\r
+        }\r
+    },\r
+    \r
+    /**\r
+     * Main entry point, extract metadata from tests, compare to cached version\r
+     * if present.\r
+     * If cache not present or differs from extrated metadata, generate an error\r
+     */\r
+    process: function(tests, harness_status) {\r
+        for (var index = 0; index < tests.length; index++) {\r
+            var test = tests[index];\r
+            if (this.currentMetadata.hasOwnProperty(test.name)) {\r
+                this.error('Duplicate test name: ' + test.name);\r
+            }\r
+            else {\r
+                this.currentMetadata[test.name] = this.extractFromTest(test);\r
+            }\r
+        }\r
+\r
+        this.getCachedMetadata();\r
+        \r
+        var message = null;\r
+        var messageClass = 'warning';\r
+        var showSource = false;\r
+        \r
+        if (0 == tests.length) {\r
+            if (this.cachedMetadata) {\r
+                message = 'Cached metadata present but no tests. ';\r
+            }\r
+        }\r
+        else if (1 == tests.length) {\r
+            if (this.cachedMetadata) {\r
+                message = 'Single test files should not have cached metadata. ';\r
+            }\r
+            else {\r
+                var testMetadata = this.currentMetadata[tests[0].name];\r
+                var hasMetadata = false;\r
+                for (var meta in testMetadata) {\r
+                    hasMetadata |= testMetadata.hasOwnProperty(meta);\r
+                }\r
+                if (hasMetadata) {\r
+                    message = 'Single tests should not have metadata. ' +\r
+                              'Move metadata to <head>. ';\r
+                }\r
+            }\r
+        }\r
+        else {\r
+            if (this.cachedMetadata) {\r
+                messageClass = 'error';\r
+                if ('string' == typeof(this.cachedMetadata)) {\r
+                    message = this.cachedMetadata;\r
+                    showSource = true;\r
+                }\r
+                else if (! this.validateCache()) {\r
+                    message = 'Cached metadata out of sync. ';\r
+                    showSource = true;\r
+                }\r
+            }\r
+        }\r
+        \r
+        if (message) {\r
+            var messageElement = document.createElement('p');\r
+            messageElement.setAttribute('id', 'metadata_issue');\r
+            messageElement.setAttribute('class', messageClass);\r
+            this.appendText(messageElement, message);\r
+            \r
+            if (showSource) {\r
+                var link = document.createElement('a');\r
+                this.appendText(link, 'Click for source code.');\r
+                link.setAttribute('href', '#');\r
+                link.setAttribute('onclick', \r
+                                  'metadata_generator.addSourceElement(event)');\r
+                messageElement.appendChild(link);\r
+            }\r
+            \r
+            var summary = document.getElementById('summary');\r
+            if (summary) {\r
+                summary.parentNode.insertBefore(messageElement, summary);\r
+            }\r
+            else {\r
+                var log = document.getElementById('log');\r
+                if (log) {\r
+                    log.appendChild(messageElement);\r
+                }\r
+            }\r
+        }\r
+    },\r
+\r
+    setup: function() {\r
+        add_completion_callback(\r
+            function (tests, harness_status) { \r
+                metadata_generator.process(tests, harness_status)\r
+            });\r
+    }\r
+}\r
+\r
+metadata_generator.setup();\r
+// vim: set expandtab shiftwidth=4 tabstop=4:\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/unitcommon.js b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/resources/unitcommon.js
new file mode 100755 (executable)
index 0000000..73b96f6
--- /dev/null
@@ -0,0 +1,562 @@
+/*\r
+\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+\r
+\r
+Authors:\r
+\r
+ */\r
+\r
+\r
+MIN_BYTE = -128;\r
+MAX_BYTE = 127;\r
+MIN_OCTET = 0;\r
+MAX_OCTET = 255;\r
+MIN_SHORT = -32768;\r
+MAX_SHORT = 32767;\r
+MIN_UNSIGNED_SHORT = 0;\r
+MAX_UNSIGNED_SHORT = 65535;\r
+MIN_LONG = -2147483648;\r
+MAX_LONG = 2147483647;\r
+MIN_UNSIGNED_LONG = 0;\r
+MAX_UNSIGNED_LONG = 4294967295;\r
+MIN_LONG_LONG = -9223372036854775808;\r
+MAX_LONG_LONG = 9223372036854775807;\r
+MIN_UNSIGNED_LONG_LONG = 0;\r
+MAX_UNSIGNED_LONG_LONG = 18446744073709551615;\r
+\r
+TYPE_MISMATCH_EXCEPTION = {name: 'TypeMismatchError'};\r
+NOT_FOUND_EXCEPTION = {name: 'NotFoundError'};\r
+INVALID_VALUES_EXCEPTION = {name: 'InvalidValuesError'};\r
+IO_EXCEPTION = {name: 'IOError'};\r
+SECURITY_EXCEPTION = {name: 'SecurityError'};\r
+\r
+\r
+(function () {\r
+   var head_src = document.head.innerHTML;\r
+   if (head_src.search(/\/testharness.js\W/) === -1) {\r
+       document.write('<script language="javascript" src="../resources/testharness.js"></script>\n');\r
+   }\r
+   if (head_src.search(/\/testharnessreport.js\W/) === -1) {\r
+       document.write('<script language="javascript" src="../resources/testharnessreport.js"></script>\n');\r
+   }\r
+})();\r
+\r
+var _registered_types = {};\r
+\r
+function _resolve_registered_type(type) {\r
+    while (type in _registered_types) {\r
+        type = _registered_types[type];\r
+    }\r
+    return type;\r
+}\r
+\r
+/**\r
+ * Method checks extra argument for none argument method.\r
+ * The only check is that method will not throw an exception.\r
+ * Example usage:\r
+ * checkExtraArgument(tizen.notification, "removeAll");\r
+ *\r
+ * @param object object\r
+ * @param methodName string - name of the method\r
+ */\r
+function checkExtraArgument(object, methodName) {\r
+    var extraArgument = [\r
+        null,\r
+        undefined,\r
+        "Tizen",\r
+        1,\r
+        false,\r
+        ["one", "two"],\r
+        {argument: 1},\r
+        function () {}\r
+    ], i;\r
+\r
+    for (i = 0; i < extraArgument.length; i++) {\r
+        object[methodName](extraArgument[i]);\r
+    }\r
+}\r
+\r
+/**\r
+ * Method to validate conversion.\r
+ * Example usage:\r
+ *   conversionTable = getTypeConversionExceptions("functionObject", true);\r
+ *   for(i = 0; i < conversionTable.length; i++) {\r
+ *       errorCallback = conversionTable[i][0];\r
+ *       exceptionName = conversionTable[i][1];\r
+ *\r
+ *       assert_throws({name : exceptionName},\r
+ *       function () {\r
+ *           tizen.systemsetting.setProperty("HOME_SCREEN",\r
+ *               propertyValue, successCallback, errorCallback);\r
+ *       }, exceptionName + " should be thrown - given incorrect errorCallback.");\r
+ *   }\r
+ *\r
+ * @param conversionType\r
+ * @param isOptional\r
+ * @returns table of tables which contain value (index 0) and exceptionName (index 1)\r
+ *\r
+ */\r
+function getTypeConversionExceptions(conversionType, isOptional) {\r
+    var exceptionName = "TypeMismatchError",\r
+        conversionTable;\r
+    switch (conversionType) {\r
+        case "enum":\r
+            conversionTable = [\r
+                [undefined, exceptionName],\r
+                [null, exceptionName],\r
+                [0, exceptionName],\r
+                [true, exceptionName],\r
+                ["dummyInvalidEnumValue", exceptionName],\r
+                [{ }, exceptionName]\r
+            ];\r
+            break;\r
+        case "double":\r
+            conversionTable = [\r
+                [undefined, exceptionName],\r
+                [NaN, exceptionName],\r
+                [Number.POSITIVE_INFINITY, exceptionName],\r
+                [Number.NEGATIVE_INFINITY, exceptionName],\r
+                ["TIZEN", exceptionName],\r
+                [{ name : "TIZEN" }, exceptionName],\r
+                [function () { }, exceptionName]\r
+            ];\r
+            break;\r
+        case "object":\r
+            conversionTable = [\r
+                [true, exceptionName],\r
+                [false, exceptionName],\r
+                [NaN, exceptionName],\r
+                [0, exceptionName],\r
+                ["", exceptionName],\r
+                ["TIZEN", exceptionName],\r
+                [undefined, exceptionName]\r
+            ];\r
+            if (!isOptional) {\r
+                conversionTable.push([null, exceptionName]);\r
+            }\r
+            break;\r
+        case "functionObject":\r
+            conversionTable = [\r
+                [true, exceptionName],\r
+                [false, exceptionName],\r
+                [NaN, exceptionName],\r
+                [0, exceptionName],\r
+                ["", exceptionName],\r
+                ["TIZEN", exceptionName],\r
+                [[], exceptionName],\r
+                [{ }, exceptionName],\r
+                [undefined, exceptionName]\r
+            ];\r
+            if (!isOptional) {\r
+                conversionTable.push([null, exceptionName]);\r
+            }\r
+            break;\r
+        case "array":\r
+            conversionTable = [\r
+                [true, exceptionName],\r
+                [false, exceptionName],\r
+                [NaN, exceptionName],\r
+                [0, exceptionName],\r
+                ["", exceptionName],\r
+                ["TIZEN", exceptionName],\r
+                [{ }, exceptionName],\r
+                [function () { }, exceptionName],\r
+                [undefined, exceptionName]\r
+            ];\r
+            if (!isOptional) {\r
+                conversionTable.push([null, exceptionName]);\r
+            }\r
+            break;\r
+        case "dictionary":\r
+            conversionTable = [\r
+                [true, exceptionName],\r
+                [false, exceptionName],\r
+                [NaN, exceptionName],\r
+                [0, exceptionName],\r
+                ["", exceptionName],\r
+                ["TIZEN", exceptionName],\r
+                [undefined, exceptionName]\r
+            ];\r
+            if (!isOptional) {\r
+                conversionTable.push([null, exceptionName]);\r
+            }\r
+            break;\r
+        default:\r
+            assert_unreached("Fix your test. Wrong conversionType '" + conversionType + "'.");\r
+    };\r
+\r
+    return conversionTable;\r
+}\r
+\r
+\r
+function assert_type(obj, type, description) {\r
+    var org_type = type, prop_name, prop_type, prop_value;\r
+\r
+    type = _resolve_registered_type(type);\r
+\r
+    if (typeof (type) === 'string') {\r
+        type = type.toLowerCase();\r
+        switch (type) {\r
+            case 'object':\r
+            case 'string':\r
+            case 'number':\r
+            case 'function':\r
+            case 'boolean':\r
+            case 'undefined':\r
+            case 'xml':\r
+                assert_equals(typeof (obj), type, description);\r
+                break;\r
+            case 'null':\r
+                assert_true(obj === null, description);\r
+                break;\r
+            case 'array':\r
+                assert_true(Array.isArray(obj), description);\r
+                break;\r
+            case 'date':\r
+                assert_true(obj instanceof Date, description);\r
+                break;\r
+            case 'byte':\r
+                assert_equals(typeof (obj), 'number', description);\r
+                assert_greater_than_equal(obj, MIN_BYTE, description + " - value too low.");\r
+                assert_less_than_equal(obj, MAX_BYTE, description + " - value too high.");\r
+                assert_equals(Math.abs(obj % 1), 0, description + " - value is not an integer.");\r
+                break;\r
+            case 'octet':\r
+                assert_equals(typeof (obj), 'number', description);\r
+                assert_greater_than_equal(obj, MIN_OCTET, description + " - value too low.");\r
+                assert_less_than_equal(obj, MAX_OCTET, description + " - value too high.");\r
+                assert_equals(obj % 1, 0, description + " - value is not an integer.");\r
+                break;\r
+            case 'short':\r
+                assert_equals(typeof (obj), 'number', description);\r
+                assert_greater_than_equal(obj, MIN_SHORT, description + " - value too low.");\r
+                assert_less_than_equal(obj, MAX_SHORT, description + " - value too high.");\r
+                assert_equals(Math.abs(obj % 1), 0, description + " - value is not an integer.");\r
+                break;\r
+            case 'unsigned short':\r
+                assert_equals(typeof (obj), 'number', description);\r
+                assert_greater_than_equal(obj, MIN_UNSIGNED_SHORT, description + " - value too low.");\r
+                assert_less_than_equal(obj, MAX_UNSIGNED_SHORT, description + " - value too high.");\r
+                assert_equals(obj % 1, 0, description + " - value is not an integer.");\r
+                break;\r
+            case 'long':\r
+                assert_equals(typeof (obj), 'number', description);\r
+                assert_greater_than_equal(obj, MIN_LONG, description + " - value too low.");\r
+                assert_less_than_equal(obj, MAX_LONG, description + " - value too high.");\r
+                assert_equals(Math.abs(obj % 1), 0, description + " - value is not an integer.");\r
+                break;\r
+            case 'unsigned long':\r
+                assert_equals(typeof (obj), 'number', description);\r
+                assert_greater_than_equal(obj, MIN_UNSIGNED_LONG, description + " - value too low.");\r
+                assert_less_than_equal(obj, MAX_UNSIGNED_LONG, description + " - value too high.");\r
+                assert_equals(obj % 1, 0, description + " - value is not an integer.");\r
+                break;\r
+            case 'long long':\r
+                assert_equals(typeof (obj), 'number', description);\r
+                assert_greater_than_equal(obj, MIN_LONG_LONG, description + " - value too low.");\r
+                assert_less_than_equal(obj, MAX_LONG_LONG, description + " - value too high.");\r
+                assert_equals(Math.abs(obj % 1), 0, description + " - value is not an integer.");\r
+                break;\r
+            case 'unsigned long long':\r
+                assert_equals(typeof (obj), 'number', description);\r
+                assert_greater_than_equal(obj, MIN_UNSIGNED_LONG_LONG, description + " - value too low.");\r
+                assert_less_than_equal(obj, MAX_UNSIGNED_LONG_LONG, description + " - value too high.");\r
+                assert_equals(obj % 1, 0, description + " - value is not an integer.");\r
+                break;\r
+            case 'double':\r
+                assert_equals(typeof (obj), 'number', description);\r
+                break;\r
+            default:\r
+                assert_unreached('Fix your test. Wrong type \'' + org_type + '\'');\r
+        }\r
+    } else if (typeof (type) === 'function') {\r
+        assert_true(obj instanceof type, description);\r
+    } else if (typeof (type) === 'object') {\r
+        for (prop_name in type) {\r
+            prop_type = type[prop_name];\r
+            if (prop_type === 'function') {\r
+                assert_inherits(obj, prop_name);\r
+                assert_equals(typeof obj[prop_name], prop_type, 'Object should have method ' + prop_name);\r
+            } else {\r
+                assert_own_property(obj, prop_name);\r
+            }\r
+        }\r
+    } else {\r
+        assert_unreached('Fix your test. Wrong type ' + org_type);\r
+    }\r
+}\r
+\r
+function register_type(alias, type_spec) {\r
+    _registered_types[alias] = type_spec;\r
+}\r
+\r
+/**\r
+ * Method to check if attribute is const.\r
+ * Example usage:\r
+ * check_const(tizen.bluetooth.deviceMinor, 'TOY_DOLL', 0x03, 'number', 0x29B);\r
+ *\r
+ * @param obj  object to test which  has const attribute\r
+ * @param attributeName attribute name.\r
+ * @param expectedValue expected value of provided attribute name\r
+ * @param expectedType expected type of provided attribute name\r
+ * @param valueToAssign value to assign in order to check if attribute value can be modified\r
+ */\r
+function check_const(obj, attributeName, expectedValue, expectedType, valueToAssign) {\r
+    var tmp;\r
+    if (expectedValue === valueToAssign) {\r
+        assert_unreached("Fix your test. The same values given for "  + attributeName +\r
+            " in 'value' and 'valueToSet' arguments.");\r
+    }\r
+    if (typeof (attributeName) === "string") {\r
+        assert_true(attributeName in obj, "Name " + attributeName + " doesn't exist in provided object.");\r
+        assert_equals(obj[attributeName], expectedValue, "Value of " + attributeName + " is diffrent.");\r
+        if (typeof (expectedType) !== "undefined") {\r
+            if (expectedValue === null) {\r
+                assert_type(obj[attributeName], "object", "Type of " + attributeName + " is different.");\r
+            } else {\r
+                assert_type(obj[attributeName], expectedType, "Type of " + attributeName + " is different.");\r
+            }\r
+        } else {\r
+            assert_unreached("Fix your test. Wrong type " + expectedType);\r
+        }\r
+        tmp = obj[attributeName];\r
+        obj[attributeName] = valueToAssign;\r
+        assert_equals(obj[attributeName], tmp, attributeName + " can be modified.");\r
+    } else {\r
+        assert_unreached("Fix your test. Wrong type of name " + typeof (attributeName));\r
+    }\r
+}\r
+\r
+/**\r
+ * Method to check if attribute is readonly.\r
+ * Example usage:\r
+ * check_readonly(statusNotification, "postedTime", null, 'object', new Date());\r
+ *\r
+ * @param obj  object to test which  has readonly attribute\r
+ * @param attributeName attribute name.\r
+ * @param expectedValue expected value of provided attribute name\r
+ * @param expectedType expected type of provided attribute name\r
+ * @param valueToAssign value to assign in order to check if attribute value can be modified\r
+ */\r
+function check_readonly(obj, attributeName, expectedValue, expectedType, valueToAssign) {\r
+    check_const(obj, attributeName, expectedValue, expectedType, valueToAssign);\r
+}\r
+\r
+/**\r
+ * Method to check if attribute can be set to null.\r
+ * Example usage:\r
+ * check_not_nullable(syncInfo, "mode");\r
+ *\r
+ * @param obj object to test which has not nullable attribute\r
+ * @param attributeName attribute name.\r
+ */\r
+function check_not_nullable(obj, attributeName)\r
+{   var old_value = obj[attributeName];\r
+    obj[attributeName] = null;\r
+    assert_not_equals(obj[attributeName], null, "Attribute " + attributeName + " can be set to null.");\r
+    obj[attributeName] = old_value;\r
+}\r
+\r
+/**\r
+ * Method to check NoInterfaceObject\r
+ * Example usage:\r
+ * check_no_interface_object("BluetoothAdapter")\r
+ *\r
+ * @param interfaceName interface name\r
+ */\r
+function check_no_interface_object(interfaceName) {\r
+    assert_throws({name: "TypeError"}, function () {\r
+        tizen[interfaceName]();\r
+    },"Wrong call as a function");\r
+    assert_throws({name: "TypeError"}, function () {\r
+        new tizen[interfaceName]();\r
+    },"Wrong call as a new function");\r
+    assert_throws({name: "TypeError"}, function () {\r
+        ({}) instanceof tizen[interfaceName];\r
+    },"instanceof exception");\r
+    assert_equals(tizen[interfaceName], undefined, interfaceName + " is not undefined.");\r
+}\r
+\r
+\r
+/**\r
+ * Method to check Constructors\r
+ * Example usage:\r
+ * check_constructor("BluetoothAdapter")\r
+ *\r
+ * @param constructorName constructor name\r
+ */\r
+\r
+function check_constructor(constructorName) {\r
+    assert_true(constructorName in tizen, "No " + constructorName + " in tizen.");\r
+    assert_false({} instanceof tizen[constructorName],"Custom object is not instance of " + constructorName);\r
+    assert_throws({\r
+        name: "TypeError"\r
+    }, function () {\r
+        tizen[constructorName]();\r
+    }, "Constructor called as function.");\r
+}\r
+\r
+/**\r
+ * Method to check if given method can be overridden in a given object - (TEMPORARY REMOVED).\r
+ * That method also checks if given method exists in a given object.\r
+ * Example usage:\r
+ * check_method_exists(tizen.notification, "get");\r
+ *\r
+ * @param obj object with method\r
+ * @param methodName name of the method to check.\r
+ */\r
+function check_method_exists(obj, methodName) {\r
+    assert_type(obj[methodName], 'function', "Method does not exist.");\r
+}\r
+\r
+/**\r
+ * Method to check extensibility of given object.\r
+ * Method checks if new attribute and method can be added.\r
+ * Example usage:\r
+ * check_extensibility(tizen.notification);\r
+ *\r
+ * @param obj object to check\r
+ */\r
+function check_extensibility(obj) {\r
+    var dummyAttribute = "dummyAttributeValue", dummyMethodResult = "dummyMethodResultValue";\r
+    obj.newDummyMethod = function() {\r
+        return dummyMethodResult;\r
+    }\r
+    assert_equals(obj.newDummyMethod(), dummyMethodResult, "Incorrect result from added method.");\r
+\r
+    obj.newDummyAttribute = dummyAttribute;\r
+    assert_equals(obj.newDummyAttribute, dummyAttribute, "Incorrect result from added attribute.");\r
+}\r
+\r
+/**\r
+ * Method to check if attribute can be modify.\r
+ * Example usage:\r
+ * check_attr(downloadRequest, "fileName", default_val, "string", "file_name.html");\r
+ *\r
+ * @param obj  object to test which has not readonly attribute\r
+ * @param attributeName attribute name.\r
+ * @param expectedValue expected value of provided attribute name\r
+ * @param expectedType expected type of provided attribute name\r
+ * @param valueToAssign value to assign in order to check if attribute value can be modified\r
+ */\r
+function check_attribute(obj, attributeName, expectedValue, expectedType, valueToAssign) {\r
+    if (expectedValue === valueToAssign) {\r
+        assert_unreached("Fix your test. The same values given for "  + attributeName +\r
+            " in 'value' and 'valueToSet' arguments.");\r
+    }\r
+    if (typeof (attributeName) === "string") {\r
+        assert_true(attributeName in obj, "Name " + attributeName + " doesn't exist in provided object.");\r
+        assert_equals(obj[attributeName], expectedValue, "Value of " + attributeName + " is diffrent.");\r
+        if (typeof (expectedType) !== "undefined") {\r
+            if (expectedValue === null) {\r
+                assert_type(obj[attributeName], "object", "Type of " + attributeName + " is different.");\r
+            } else {\r
+                assert_type(obj[attributeName], expectedType, "Type of " + attributeName + " is different.");\r
+            }\r
+        } else {\r
+            assert_unreached("Fix your test. Wrong type " + expectedType);\r
+        }\r
+        obj[attributeName] = valueToAssign;\r
+        assert_equals(obj[attributeName], valueToAssign, attributeName + " can be modified.");\r
+    } else {\r
+        assert_unreached("Fix your test. Wrong type of name " + typeof (attributeName));\r
+    }\r
+}\r
+\r
+/**\r
+ * Method to check if whole array can be overwritten with an invalid value.\r
+ * Sample usage:\r
+ * check_invalid_array_assignments(message, "to", false);\r
+ *\r
+ * @param obj object which has the array as its property\r
+ * @param array name of the array to check\r
+ * @param isNullable indicates if the array can be null\r
+ */\r
+function check_invalid_array_assignments(obj, array, isNullable) {\r
+    var args = [undefined, true, false, NaN, 0, "TIZEN", {}, function () {}],\r
+        val = obj[array], i;\r
+\r
+    if (!isNullable) {\r
+        obj[array] = null;\r
+        assert_not_equals(obj[array], null, "Non-nullable array was set to null");\r
+        assert_type(obj[array], "array", "Non-nullable array type changed after assigning null");\r
+        assert_equals(obj[array].toString(), val.toString(), "Non-nullable array contents changed after assigning null");\r
+    }\r
+\r
+    for (i = 0 ; i < args.length ; i++) {\r
+        obj[array] = args[i];\r
+        assert_type(obj[array], "array", "Array type changed after assigning an invalid value");\r
+        assert_equals(obj[array].toString(), val.toString(), "Array contents changed after assigning an invalid value");\r
+    }\r
+}\r
+\r
+/**\r
+ * Method to check if an object can be overwritten with an invalid value.\r
+ * Sample usage:\r
+ * check_invalid_object_assignments(message, "body", false);\r
+ *\r
+ * @param parentObj object which has the 'obj' object as its property\r
+ * @param obj name of the object to check\r
+ * @param isNullable indicates if the object can be null\r
+ */\r
+function check_invalid_obj_assignments(parentObj, obj, isNullable) {\r
+    var args = [undefined, true, false, NaN, 0, "TIZEN", function () {}],\r
+        val = parentObj[obj], i;\r
+\r
+    if (!isNullable) {\r
+        parentObj[obj] = null;\r
+        assert_equals(parentObj[obj], val, "Non-nullable obj was modified after assigning null");\r
+    }\r
+\r
+    for (i = 0 ; i < args.length ; i++) {\r
+        parentObj[obj] = args[i];\r
+        assert_equals(parentObj[obj], val, "The object was set to " + args[i]);\r
+    }\r
+}\r
+\r
+/**\r
+ * Method to validate conversion for listeners.\r
+ * Example usage:\r
+ * incorrectListeners = getListenerConversionExceptions(["oninstalled", "onupdated", "onuninstalled"]);\r
+ * for(i = 0; i < incorrectListeners.length; i++) {\r
+ *     packageInformationEventCallback  = incorrectListeners[i][0];\r
+ *     exceptionName = incorrectListeners[i][1];\r
+ *     assert_throws({name : exceptionName},\r
+ *        function () {\r
+ *             tizen.package.setPackageInfoEventListener(packageInformationEventCallback);\r
+ *         }, exceptionName + " should be thrown - given incorrect successCallback.");\r
+ * }\r
+ *\r
+ *\r
+ * @param callbackNames Array with names\r
+ * @returns {Array} table of tables which contain incorrect listener (index 0) and exceptionName (index 1)\r
+ *\r
+ */\r
+function getListenerConversionExceptions(callbackNames) {\r
+    var result = [], conversionTable, i, j, listenerName;\r
+    conversionTable = getTypeConversionExceptions("functionObject", false);\r
+\r
+    for (i = 0; i < callbackNames.length; i++) {\r
+        for (j = 0; j < conversionTable.length; j++) {\r
+            listenerName = {};\r
+            listenerName[callbackNames[i]] = conversionTable[j][0];\r
+            result.push([listenerName, conversionTable[j][1]]);\r
+        }\r
+    }\r
+\r
+    return result;\r
+}\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/Application_getRequestedAppControl.js b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/Application_getRequestedAppControl.js
new file mode 100755 (executable)
index 0000000..eabd4e1
--- /dev/null
@@ -0,0 +1,54 @@
+/*\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+Authors:\r
+        Krzysztof Lachacz <k.lachacz@samsung.com>\r
+        Junghyuk Park <junghyuk.park@samsung.com>\r
+\r
+*/\r
+\r
+test(function () {\r
+    var reqAppControl = tizen.application.getCurrentApplication().getRequestedAppControl(),\r
+        appControl;\r
+\r
+    assert_true("appControl" in reqAppControl, "RequestedApplicationControl should have appControl attribute");\r
+\r
+    appControl = reqAppControl.appControl;\r
+    assert_type(appControl, "object", "incorrect type of appControl");\r
+    assert_true("operation" in appControl, "ApplicationControl should have operation attribute");\r
+    assert_true("uri" in appControl, "ApplicationControl should have uri attribute");\r
+    assert_true("mime" in appControl, "ApplicationControl should have mime attribute");\r
+    assert_true("category" in appControl, "ApplicationControl should have category attribute");\r
+    assert_true("data" in appControl, "ApplicationControl should have data attribute");\r
+\r
+    reqAppControl.appControl = {\r
+        operation: "dummy",\r
+        uri: "dummy",\r
+        mime: "dummy",\r
+        category: "dummy",\r
+        data: []\r
+    };\r
+\r
+    assert_equals(reqAppControl.appControl.operation, appControl.operation, "appControl is not readonly");\r
+    assert_equals(reqAppControl.appControl.uri, appControl.uri, "appControl is not readonly");\r
+    assert_equals(reqAppControl.appControl.mime, appControl.mime, "appControl is not readonly");\r
+    assert_equals(reqAppControl.appControl.category, appControl.category, "appControl is not readonly");\r
+    if(appControl.data) {\r
+        assert_equals(reqAppControl.appControl.data.length, appControl.data.length, "appControl is not readonly");\r
+    } else {\r
+        assert_equals(reqAppControl.appControl.data, appControl.data, "appControl is not readonly");\r
+    }\r
+\r
+}, "Application_getRequestedAppControl");\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/Application_getRequestedAppControl_extra_argument.js b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/Application_getRequestedAppControl_extra_argument.js
new file mode 100755 (executable)
index 0000000..c3c0c43
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+Authors:\r
+        Krzysztof Lachacz <k.lachacz@samsung.com>\r
+        Junghyuk Park <junghyuk.park@samsung.com>\r
+\r
+*/\r
+\r
+test(function () {\r
+    var i, argumentsList = [null, undefined, "string", 1, false, ["one", "two"], {arg: 1}, function () {}],\r
+        reqAppControl, appControl;\r
+\r
+    for (i = 0; i < argumentsList.length; i++) {\r
+        reqAppControl = tizen.application.getCurrentApplication().getRequestedAppControl(argumentsList[i]),\r
+        assert_true("appControl" in reqAppControl, "RequestedApplicationControl should have appControl attribute");\r
+\r
+        appControl = reqAppControl.appControl;\r
+        assert_type(appControl, "object", "incorrect type of appControl");\r
+        assert_true("operation" in appControl, "ApplicationControl should have operation attribute");\r
+        assert_true("uri" in appControl, "ApplicationControl should have uri attribute");\r
+        assert_true("mime" in appControl, "ApplicationControl should have mime attribute");\r
+        assert_true("category" in appControl, "ApplicationControl should have category attribute");\r
+        assert_true("data" in appControl, "ApplicationControl should have data attribute");\r
+\r
+        reqAppControl.appControl = new tizen.ApplicationControl(\r
+            "operation",\r
+            "uri",\r
+            "mime",\r
+            "category",\r
+            [ new tizen.ApplicationControlData("key", [ "value" ]) ]\r
+        );\r
+\r
+        assert_equals(reqAppControl.appControl.operation, appControl.operation, "appControl is not readonly");\r
+        assert_equals(reqAppControl.appControl.uri, appControl.uri, "appControl is not readonly");\r
+        assert_equals(reqAppControl.appControl.mime, appControl.mime, "appControl is not readonly");\r
+        assert_equals(reqAppControl.appControl.category, appControl.category, "appControl is not readonly");\r
+        if(appControl.data) {\r
+            assert_equals(reqAppControl.appControl.data.length, appControl.data.length, "appControl is not readonly");\r
+        } else {\r
+            assert_equals(reqAppControl.appControl.data, appControl.data, "appControl is not readonly");\r
+        }\r
+    }\r
+\r
+}, "Application_getRequestedAppControl_extra_argument");\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/Application_hide.js b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/Application_hide.js
new file mode 100755 (executable)
index 0000000..b4de287
--- /dev/null
@@ -0,0 +1,28 @@
+/*\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+Authors:\r
+        Krzysztof Lachacz <k.lachacz@samsung.com>\r
+        Mariusz Polasinski <m.polasinski@samsung.com>\r
+\r
+*/\r
+\r
+test(function () {\r
+    var retVal, currentApplication = tizen.application.getCurrentApplication();\r
+\r
+    retVal = currentApplication.hide();\r
+    assert_equals(retVal, undefined, "wrong returned value");\r
+\r
+}, "Application_hide");\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/Application_hide_extra_argument.js b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/Application_hide_extra_argument.js
new file mode 100755 (executable)
index 0000000..b4c0415
--- /dev/null
@@ -0,0 +1,26 @@
+/*\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+Authors:\r
+        Krzysztof Lachacz <k.lachacz@samsung.com>\r
+\r
+*/\r
+\r
+test(function () {\r
+    var currentApplication = tizen.application.getCurrentApplication();\r
+\r
+    checkExtraArgument(currentApplication, "hide");\r
+\r
+}, "Application_hide_extra_argument");\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_appControl_attribute.js b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_appControl_attribute.js
new file mode 100755 (executable)
index 0000000..10adb3b
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+Authors:\r
+        Krzysztof Lachacz <k.lachacz@samsung.com>\r
+\r
+*/\r
+\r
+test(function () {\r
+    var reqAppControl = tizen.application.getCurrentApplication().getRequestedAppControl(),\r
+        appControl;\r
+\r
+    assert_true("appControl" in reqAppControl, "RequestedApplicationControl should have appControl attribute");\r
+\r
+    appControl = reqAppControl.appControl;\r
+    assert_type(appControl, "object", "incorrect type of appControl");\r
+    assert_true("operation" in appControl, "ApplicationControl should have operation attribute");\r
+    assert_true("uri" in appControl, "ApplicationControl should have uri attribute");\r
+    assert_true("mime" in appControl, "ApplicationControl should have mime attribute");\r
+    assert_true("category" in appControl, "ApplicationControl should have category attribute");\r
+    assert_true("data" in appControl, "ApplicationControl should have data attribute");\r
+\r
+    reqAppControl.appControl = {\r
+        operation: "dummy",\r
+        uri: "dummy",\r
+        mime: "dummy",\r
+        category: "dummy",\r
+        data: []\r
+    };\r
+\r
+    assert_equals(reqAppControl.appControl.operation, appControl.operation, "appControl is not readonly");\r
+    assert_equals(reqAppControl.appControl.uri, appControl.uri, "appControl is not readonly");\r
+    assert_equals(reqAppControl.appControl.mime, appControl.mime, "appControl is not readonly");\r
+    assert_equals(reqAppControl.appControl.category, appControl.category, "appControl is not readonly");\r
+    if(appControl.data) {\r
+        assert_equals(reqAppControl.appControl.data.length, appControl.data.length, "appControl is not readonly");\r
+    } else {\r
+        assert_equals(reqAppControl.appControl.data, appControl.data, "appControl is not readonly");\r
+    }\r
+\r
+}, "RequestedApplicationControl_appControl_attribute");\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_callerAppId_attribute.js b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_callerAppId_attribute.js
new file mode 100755 (executable)
index 0000000..0bab554
--- /dev/null
@@ -0,0 +1,27 @@
+/*\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+Authors:\r
+        Krzysztof Lachacz <k.lachacz@samsung.com>\r
+\r
+*/\r
+\r
+test(function () {\r
+    var reqAppControl = tizen.application.getCurrentApplication().getRequestedAppControl();\r
+\r
+    assert_true("callerAppId" in reqAppControl, "RequestedApplicationControl should have callerAppId attribute");\r
+    check_readonly(reqAppControl, "callerAppId", reqAppControl.callerAppId, "string", "dummy");\r
+\r
+}, "RequestedApplicationControl_callerAppId_attribute");\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_extend.js b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_extend.js
new file mode 100755 (executable)
index 0000000..f640627
--- /dev/null
@@ -0,0 +1,24 @@
+/*\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+Authors:\r
+        Krzysztof Lachacz <k.lachacz@samsung.com>\r
+\r
+*/\r
+\r
+test(function () {\r
+    var reqAppControl = tizen.application.getCurrentApplication().getRequestedAppControl();\r
+    check_extensibility(reqAppControl);\r
+}, "RequestedApplicationControl_extend");\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_replyFailure_exist.js b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_replyFailure_exist.js
new file mode 100755 (executable)
index 0000000..891e066
--- /dev/null
@@ -0,0 +1,24 @@
+/*\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+Authors:\r
+        Krzysztof Lachacz <k.lachacz@samsung.com>\r
+\r
+*/\r
+\r
+test(function () {\r
+    var reqAppControl = tizen.application.getCurrentApplication().getRequestedAppControl();\r
+    check_method_exists(reqAppControl, "replyFailure");\r
+}, "RequestedApplicationControl_replyFailure_exist");\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_replyResult_data_TypeMismatch.js b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_replyResult_data_TypeMismatch.js
new file mode 100755 (executable)
index 0000000..c0fa2f4
--- /dev/null
@@ -0,0 +1,36 @@
+/*\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+Authors:\r
+        Krzysztof Lachacz <k.lachacz@samsung.com>\r
+\r
+*/\r
+\r
+test(function () {\r
+    var reqAppControl = tizen.application.getCurrentApplication().getRequestedAppControl(),\r
+        conversionTable, exceptionName, i, data;\r
+\r
+    conversionTable = getTypeConversionExceptions("array", true);\r
+\r
+    for(i = 0; i < conversionTable.length; i++) {\r
+        data = conversionTable[i][0];\r
+        exceptionName = conversionTable[i][1];\r
+\r
+        assert_throws({name: exceptionName},\r
+            function () {\r
+                reqAppControl.replyResult(data);\r
+            }, exceptionName + " should be thrown.");\r
+    }\r
+}, "RequestedApplicationControl_replyResult_data_TypeMismatch");\r
diff --git a/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_replyResult_exist.js b/common/tct-appcontrol-tizen-tests/appcontrol/support/TCTAppControl/tests/RequestedApplicationControl_replyResult_exist.js
new file mode 100755 (executable)
index 0000000..76de5d4
--- /dev/null
@@ -0,0 +1,28 @@
+/*\r
+Copyright (c) 2013 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+Authors:\r
+        Krzysztof Lachacz <k.lachacz@samsung.com>\r
+\r
+*/\r
+\r
+test(function () {\r
+    var reqAppControl = tizen.application.getCurrentApplication().getRequestedAppControl();\r
+\r
+    assert_true("replyResult" in reqAppControl, "reqAppControl should have replyResult method");\r
+    assert_type(reqAppControl.replyResult, "function", "incorrect type of replyResult");\r
+\r
+    check_method_exists(reqAppControl, "replyResult");\r
+}, "RequestedApplicationControl_replyResult_exist");\r
index 5823e58a6393c4b68cf92585e9c09978fd80922b..86a531a6bb96a2380bbeb4bbb4bf0d6b047b3475 100755 (executable)
@@ -1,62 +1,62 @@
-/*
-Copyright (c) 2014 Samsung Electronics Co., Ltd.
-
-Licensed under the Apache License, Version 2.0 (the License);
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Authors:
-        Piotr Szydelko <p.szydelko@samsung.com>
-        Mohammad Ashekur Rahman <ashek.rahman@samsung.com>
-
-*/
-
-var TEST_DIR = "";
-var TEST_URL_HTTP = "http://www.tizen.org";
-var TEST_URL_HTTPS = "https://www.tizen.org";
-
-var TEST_FILE_IMAGE_BMP = "";
-var TEST_FILE_IMAGE_JPEG = "";
-var TEST_FILE_IMAGE_GIF = "";
-var TEST_FILE_IMAGE_PNG = "";
-var TEST_FILE_SOUND_AAC = "";
-var TEST_FILE_SOUND_AMR = "";
-var TEST_FILE_SOUND_MP3 = "";
-var TEST_FILE_SOUND_WAV = "";
-var TEST_FILE_VIDEO_MP4 = "";
-var TEST_FILE_VIDEO_3GPP = "";
-
-function checkAppControls(this_test, appControls) {
-    var onSuccess, onError, currentAppControl, appControlDesc;
-
-    onSuccess = this_test.step_func(function(informationArray, appControl) {
-        assert_true(Array.isArray(informationArray), "informationArray should be Array");
-        assert_not_equals(informationArray.length, 0, "Number of application found for: " + appControlDesc);
-
-        // check next from the list or report success if list is empty
-        if(appControls.length === 0) {
-            return this_test.done();
-        } else {
-            checkAppControls(this_test, appControls);
-        }
-    });
-
-    onError = this_test.step_func(function(error) {
-        assert_unreached("onError: " + error.message);
-    });
-
-    currentAppControl = appControls.shift();
-    appControlDesc = '(' + currentAppControl.operation + " " + currentAppControl.uri + " " + currentAppControl.mime + ')';
-
-    tizen.application.findAppControl(currentAppControl, onSuccess, onError);
-}
-document.write('<script src="../webrunner/jquery-1.10.2.min.js"></script>');
-document.write('<script src="support/getJsonConf.js"></script>');
+/*\r
+Copyright (c) 2014 Samsung Electronics Co., Ltd.\r
+\r
+Licensed under the Apache License, Version 2.0 (the License);\r
+you may not use this file except in compliance with the License.\r
+You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+Unless required by applicable law or agreed to in writing, software\r
+distributed under the License is distributed on an "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+See the License for the specific language governing permissions and\r
+limitations under the License.\r
+\r
+Authors:\r
+        Piotr Szydelko <p.szydelko@samsung.com>\r
+        Mohammad Ashekur Rahman <ashek.rahman@samsung.com>\r
+\r
+*/\r
+\r
+var TEST_DIR = "";\r
+var TEST_URL_HTTP = "http://www.tizen.org";\r
+var TEST_URL_HTTPS = "https://www.tizen.org";\r
+\r
+var TEST_FILE_IMAGE_BMP = "";\r
+var TEST_FILE_IMAGE_JPEG = "";\r
+var TEST_FILE_IMAGE_GIF = "";\r
+var TEST_FILE_IMAGE_PNG = "";\r
+var TEST_FILE_SOUND_AAC = "";\r
+var TEST_FILE_SOUND_AMR = "";\r
+var TEST_FILE_SOUND_MP3 = "";\r
+var TEST_FILE_SOUND_WAV = "";\r
+var TEST_FILE_VIDEO_MP4 = "";\r
+var TEST_FILE_VIDEO_3GPP = "";\r
+\r
+function checkAppControls(this_test, appControls) {\r
+    var onSuccess, onError, currentAppControl, appControlDesc;\r
+\r
+    onSuccess = this_test.step_func(function(informationArray, appControl) {\r
+        assert_true(Array.isArray(informationArray), "informationArray should be Array");\r
+        assert_not_equals(informationArray.length, 0, "Number of application found for: " + appControlDesc);\r
+\r
+        // check next from the list or report success if list is empty\r
+        if(appControls.length === 0) {\r
+            return this_test.done();\r
+        } else {\r
+            checkAppControls(this_test, appControls);\r
+        }\r
+    });\r
+\r
+    onError = this_test.step_func(function(error) {\r
+        assert_unreached("onError: " + error.message);\r
+    });\r
+\r
+    currentAppControl = appControls.shift();\r
+    appControlDesc = '(' + currentAppControl.operation + " " + currentAppControl.uri + " " + currentAppControl.mime + ')';\r
+\r
+    tizen.application.findAppControl(currentAppControl, onSuccess, onError);\r
+}\r
+document.write('<script src="../webrunner/jquery-1.10.2.min.js"></script>');\r
+document.write('<script src="support/getJsonConf.js"></script>');\r
index b72850d63dbd293fed9df13eaab0dd8c4298025b..9b91907fb69cc28fa15976beb112f08104e5c771 100755 (executable)
@@ -10,7 +10,6 @@ import string
 from optparse import OptionParser, make_option
 import configparser
 
-
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
 PKG_NAME = os.path.basename(SCRIPT_DIR)
 PARAMETERS = None
index 945e536b35f6501e22f7745b6c0d0884f4241ccb..07d433181d16ff2eefb5e2d8abd09a1c97fffae4 100755 (executable)
@@ -1,55 +1,75 @@
-{
-    "pkg-blacklist": [
-        "config.xml",
-        "pack.py",
-        "testcase.xsl",
-        "testresult.xsl",
-        "tests.css",
-        "icon.png",
-        "manifest.json",
-        "suite.json",
-        "inst.*"
-    ],
-    "pkg-list": {
-        "wgt": {
-            "blacklist": [
-                "appcontrol",
-                "COPYING",
-                "LICENSE.*",
-                "NOTICE",
-                "resources",
-                "tests.full.xml",
-                "webrunner"
-            ],
-            "copylist": {
-                "inst.wgt.py": "inst.py",
-                "tests.xml": "tests.xml"
-            },
-            "pkg-app": {
-                "blacklist": [],
-                "sign-flag": "true",
-                "sign-flag": "true"
-            }
-        },
-        "xpk": {
-            "blacklist": [
-                "appcontrol",
-                "COPYING",
-                "LICENSE.*",
-                "NOTICE",
-                "resources",
-                "tests.full.xml",
-                "webrunner"
-            ],
-            "copylist": {
-                "inst.xpk.py": "inst.py",
-                "tests.xml": "tests.xml"
-            },
-            "pkg-app": {
-                "blacklist": [],
-                "sign-flag": "true"
-            }
-        }
-    },
-    "pkg-name": "tct-appcontrol-tizen-tests"
+{\r
+    "pkg-blacklist": [\r
+        "config.xml",\r
+        "pack.py",\r
+        "testcase.xsl",\r
+        "testresult.xsl",\r
+        "tests.css",\r
+        "icon.png",\r
+        "manifest.json",\r
+        "suite.json",\r
+        "inst.*"\r
+    ],\r
+    "pkg-list": {\r
+        "wgt": {\r
+            "blacklist": [\r
+                "appcontrol",\r
+                "COPYING",\r
+                "LICENSE.*",\r
+                "NOTICE",\r
+                "resources",\r
+                "tests.full.xml",\r
+                "webrunner"\r
+            ],\r
+            "copylist": {\r
+                "inst.wgt.py": "inst.py",\r
+                "tests.xml": "tests.xml"\r
+            },\r
+            "subapp-list": {\r
+                "appcontrol/support/TCTAppControl": {\r
+                    "app-name": "TCTAppControl",\r
+                    "blacklist": [\r
+                        "manifest.json"\r
+                    ],\r
+                    "install-path": "apps",\r
+                    "sign-flag": "true"\r
+                }\r
+            },\r
+            "pkg-app": {\r
+                "blacklist": [],\r
+                "sign-flag": "true",\r
+                "sign-flag": "true"\r
+            }\r
+        },\r
+        "xpk": {\r
+            "blacklist": [\r
+                "appcontrol",\r
+                "COPYING",\r
+                "LICENSE.*",\r
+                "NOTICE",\r
+                "resources",\r
+                "tests.full.xml",\r
+                "webrunner"\r
+            ],\r
+            "subapp-list": {\r
+                "appcontrol/support/TCTAppControl": {\r
+                    "app-name": "TCTAppControl",\r
+                    "blacklist": [\r
+                        "manifest.json"\r
+                    ],\r
+                    "install-path": "apps",\r
+                    "sign-flag": "true"\r
+                }\r
+            },\r
+            "copylist": {\r
+                "inst.xpk.py": "inst.py",\r
+                "tests.xml": "tests.xml"\r
+            },\r
+            "pkg-app": {\r
+                "blacklist": [],\r
+                "sign-flag": "true"\r
+            }\r
+        }\r
+    },\r
+    "pkg-name": "tct-appcontrol-tizen-tests"\r
 }
\ No newline at end of file