summaryrefslogtreecommitdiff
path: root/services/sync/tests/tps
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /services/sync/tests/tps
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloaduxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'services/sync/tests/tps')
-rw-r--r--services/sync/tests/tps/addons/api/restartless-xpi@tests.mozilla.org.xml27
-rw-r--r--services/sync/tests/tps/addons/api/unsigned-xpi@tests.mozilla.org.xml27
-rw-r--r--services/sync/tests/tps/addons/restartless.xpibin0 -> 485 bytes
-rw-r--r--services/sync/tests/tps/addons/unsigned.xpibin0 -> 452 bytes
-rw-r--r--services/sync/tests/tps/all_tests.json33
-rw-r--r--services/sync/tests/tps/mozmill_sanity.js30
-rw-r--r--services/sync/tests/tps/mozmill_sanity2.js15
-rw-r--r--services/sync/tests/tps/test_addon_nonrestartless_xpi.js105
-rw-r--r--services/sync/tests/tps/test_addon_reconciling.js54
-rw-r--r--services/sync/tests/tps/test_addon_restartless_xpi.js70
-rw-r--r--services/sync/tests/tps/test_addon_sanity.js30
-rw-r--r--services/sync/tests/tps/test_addon_wipe.js35
-rw-r--r--services/sync/tests/tps/test_bookmark_conflict.js143
-rw-r--r--services/sync/tests/tps/test_bookmarks_in_same_named_folder.js69
-rw-r--r--services/sync/tests/tps/test_bug501528.js79
-rw-r--r--services/sync/tests/tps/test_bug530717.js69
-rw-r--r--services/sync/tests/tps/test_bug531489.js62
-rw-r--r--services/sync/tests/tps/test_bug535326.js130
-rw-r--r--services/sync/tests/tps/test_bug538298.js93
-rw-r--r--services/sync/tests/tps/test_bug546807.js54
-rw-r--r--services/sync/tests/tps/test_bug556509.js45
-rw-r--r--services/sync/tests/tps/test_bug562515.js105
-rw-r--r--services/sync/tests/tps/test_bug563989.js107
-rw-r--r--services/sync/tests/tps/test_bug575423.js85
-rw-r--r--services/sync/tests/tps/test_client_wipe.js164
-rw-r--r--services/sync/tests/tps/test_formdata.js97
-rw-r--r--services/sync/tests/tps/test_history.js167
-rw-r--r--services/sync/tests/tps/test_history_collision.js125
-rw-r--r--services/sync/tests/tps/test_mozmill_sanity.js24
-rw-r--r--services/sync/tests/tps/test_passwords.js113
-rw-r--r--services/sync/tests/tps/test_prefs.js57
-rw-r--r--services/sync/tests/tps/test_privbrw_passwords.js104
-rw-r--r--services/sync/tests/tps/test_privbrw_tabs.js87
-rw-r--r--services/sync/tests/tps/test_special_tabs.js78
-rw-r--r--services/sync/tests/tps/test_sync.js424
-rw-r--r--services/sync/tests/tps/test_tabs.js59
36 files changed, 2966 insertions, 0 deletions
diff --git a/services/sync/tests/tps/addons/api/restartless-xpi@tests.mozilla.org.xml b/services/sync/tests/tps/addons/api/restartless-xpi@tests.mozilla.org.xml
new file mode 100644
index 0000000000..6eb153ad19
--- /dev/null
+++ b/services/sync/tests/tps/addons/api/restartless-xpi@tests.mozilla.org.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<searchresults total_results="1">
+ <addon id="5617">
+ <name>Restartless Test XPI</name>
+ <type id="1">Extension</type>
+ <guid>restartless-xpi@tests.mozilla.org</guid>
+ <slug>restartless-xpi</slug>
+ <version>1.0</version>
+
+ <compatible_applications><application>
+ <name>Firefox</name>
+ <application_id>1</application_id>
+ <min_version>3.6</min_version>
+ <max_version>*</max_version>
+ <appID>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</appID>
+ </application></compatible_applications>
+ <all_compatible_os><os>ALL</os></all_compatible_os>
+
+ <install os="ALL" size="485">http://127.0.0.1:4567/addons/restartless.xpi</install>
+ <created epoch="1252903662">
+ 2009-09-14T04:47:42Z
+ </created>
+ <last_updated epoch="1315255329">
+ 2011-09-05T20:42:09Z
+ </last_updated>
+ </addon>
+</searchresults>
diff --git a/services/sync/tests/tps/addons/api/unsigned-xpi@tests.mozilla.org.xml b/services/sync/tests/tps/addons/api/unsigned-xpi@tests.mozilla.org.xml
new file mode 100644
index 0000000000..14a056013b
--- /dev/null
+++ b/services/sync/tests/tps/addons/api/unsigned-xpi@tests.mozilla.org.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<searchresults total_results="1">
+ <addon id="5612">
+ <name>Unsigned Test XPI</name>
+ <type id="1">Extension</type>
+ <guid>unsigned-xpi@tests.mozilla.org</guid>
+ <slug>unsigned-xpi</slug>
+ <version>1.0</version>
+
+ <compatible_applications><application>
+ <name>Firefox</name>
+ <application_id>1</application_id>
+ <min_version>3.6</min_version>
+ <max_version>*</max_version>
+ <appID>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</appID>
+ </application></compatible_applications>
+ <all_compatible_os><os>ALL</os></all_compatible_os>
+
+ <install os="ALL" size="452">http://127.0.0.1:4567/addons/unsigned.xpi</install>
+ <created epoch="1252903662">
+ 2009-09-14T04:47:42Z
+ </created>
+ <last_updated epoch="1315255329">
+ 2011-09-05T20:42:09Z
+ </last_updated>
+ </addon>
+</searchresults>
diff --git a/services/sync/tests/tps/addons/restartless.xpi b/services/sync/tests/tps/addons/restartless.xpi
new file mode 100644
index 0000000000..973bc00cb5
--- /dev/null
+++ b/services/sync/tests/tps/addons/restartless.xpi
Binary files differ
diff --git a/services/sync/tests/tps/addons/unsigned.xpi b/services/sync/tests/tps/addons/unsigned.xpi
new file mode 100644
index 0000000000..51b00475a9
--- /dev/null
+++ b/services/sync/tests/tps/addons/unsigned.xpi
Binary files differ
diff --git a/services/sync/tests/tps/all_tests.json b/services/sync/tests/tps/all_tests.json
new file mode 100644
index 0000000000..ca7031e59a
--- /dev/null
+++ b/services/sync/tests/tps/all_tests.json
@@ -0,0 +1,33 @@
+{ "tests": [
+ "test_bookmark_conflict.js",
+ "test_sync.js",
+ "test_prefs.js",
+ "test_tabs.js",
+ "test_passwords.js",
+ "test_history.js",
+ "test_formdata.js",
+ "test_bug530717.js",
+ "test_bug531489.js",
+ "test_bug538298.js",
+ "test_bug556509.js",
+ "test_bug562515.js",
+ "test_bug563989.js",
+ "test_bug535326.js",
+ "test_bug501528.js",
+ "test_bug575423.js",
+ "test_bug546807.js",
+ "test_history_collision.js",
+ "test_privbrw_passwords.js",
+ "test_privbrw_tabs.js",
+ "test_bookmarks_in_same_named_folder.js",
+ "test_client_wipe.js",
+ "test_special_tabs.js",
+ "test_addon_sanity.js",
+ "test_addon_restartless_xpi.js",
+ "test_addon_nonrestartless_xpi.js",
+ "test_addon_reconciling.js",
+ "test_addon_wipe.js"
+ ]
+}
+
+
diff --git a/services/sync/tests/tps/mozmill_sanity.js b/services/sync/tests/tps/mozmill_sanity.js
new file mode 100644
index 0000000000..fbaed8f257
--- /dev/null
+++ b/services/sync/tests/tps/mozmill_sanity.js
@@ -0,0 +1,30 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+Components.utils.import('resource://tps/tps.jsm');
+
+var setupModule = function(module) {
+ module.controller = mozmill.getBrowserController();
+ assert.ok(true, "SetupModule passes");
+}
+
+var setupTest = function(module) {
+ assert.ok(true, "SetupTest passes");
+}
+
+var testTestStep = function() {
+ assert.ok(true, "test Passes");
+ controller.open("http://www.mozilla.org");
+
+ TPS.Login();
+ TPS.Sync(ACTIONS.ACTION_SYNC_WIPE_CLIENT);
+}
+
+var teardownTest = function () {
+ assert.ok(true, "teardownTest passes");
+}
+
+var teardownModule = function() {
+ assert.ok(true, "teardownModule passes");
+}
diff --git a/services/sync/tests/tps/mozmill_sanity2.js b/services/sync/tests/tps/mozmill_sanity2.js
new file mode 100644
index 0000000000..f0fd0e3d5d
--- /dev/null
+++ b/services/sync/tests/tps/mozmill_sanity2.js
@@ -0,0 +1,15 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var setupModule = function(module) {
+ module.controller = mozmill.getBrowserController();
+};
+
+var testGetNode = function() {
+ controller.open("about:support");
+ controller.waitForPageLoad();
+
+ var appbox = findElement.ID(controller.tabs.activeTab, "application-box");
+ assert.waitFor(() => appbox.getNode().textContent == 'Firefox', 'correct app name');
+};
diff --git a/services/sync/tests/tps/test_addon_nonrestartless_xpi.js b/services/sync/tests/tps/test_addon_nonrestartless_xpi.js
new file mode 100644
index 0000000000..b6c85b3515
--- /dev/null
+++ b/services/sync/tests/tps/test_addon_nonrestartless_xpi.js
@@ -0,0 +1,105 @@
+
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This test verifies that install of extensions that require restart
+// syncs between profiles.
+EnableEngines(["addons"]);
+
+var phases = {
+ "phase01": "profile1",
+ "phase02": "profile1",
+ "phase03": "profile2",
+ "phase04": "profile2",
+ "phase05": "profile1",
+ "phase06": "profile1",
+ "phase07": "profile2",
+ "phase08": "profile2",
+ "phase09": "profile1",
+ "phase10": "profile1",
+ "phase11": "profile2",
+ "phase12": "profile2",
+ "phase13": "profile1",
+ "phase14": "profile1",
+ "phase15": "profile2",
+ "phase16": "profile2"
+};
+
+const id = "unsigned-xpi@tests.mozilla.org";
+
+Phase("phase01", [
+ [Addons.verifyNot, [id]],
+ [Addons.install, [id]],
+ [Sync]
+]);
+Phase("phase02", [
+ [Addons.verify, [id], STATE_ENABLED],
+ [Sync]
+]);
+Phase("phase03", [
+ [Addons.verifyNot, [id]],
+ [Sync]
+]);
+Phase("phase04", [
+ [Addons.verify, [id], STATE_ENABLED],
+ [Sync]
+]);
+
+// Now we disable the add-on
+Phase("phase05", [
+ [EnsureTracking],
+ [Addons.setEnabled, [id], STATE_DISABLED],
+ [Sync]
+]);
+Phase("phase06", [
+ [Addons.verify, [id], STATE_DISABLED],
+ [Sync]
+]);
+Phase("phase07", [
+ [Addons.verify, [id], STATE_ENABLED],
+ [Sync]
+]);
+Phase("phase08", [
+ [Addons.verify, [id], STATE_DISABLED],
+ [Sync]
+]);
+
+// Now we re-enable it again.
+Phase("phase09", [
+ [EnsureTracking],
+ [Addons.setEnabled, [id], STATE_ENABLED],
+ [Sync]
+]);
+Phase("phase10", [
+ [Addons.verify, [id], STATE_ENABLED],
+ [Sync]
+]);
+Phase("phase11", [
+ [Addons.verify, [id], STATE_DISABLED],
+ [Sync]
+]);
+Phase("phase12", [
+ [Addons.verify, [id], STATE_ENABLED],
+ [Sync]
+]);
+
+// And we uninstall it
+
+Phase("phase13", [
+ [EnsureTracking],
+ [Addons.verify, [id], STATE_ENABLED],
+ [Addons.uninstall, [id]],
+ [Sync]
+]);
+Phase("phase14", [
+ [Addons.verifyNot, [id]],
+ [Sync]
+]);
+Phase("phase15", [
+ [Addons.verify, [id], STATE_ENABLED],
+ [Sync]
+]);
+Phase("phase16", [
+ [Addons.verifyNot, [id]],
+ [Sync]
+]);
diff --git a/services/sync/tests/tps/test_addon_reconciling.js b/services/sync/tests/tps/test_addon_reconciling.js
new file mode 100644
index 0000000000..a4244ab03f
--- /dev/null
+++ b/services/sync/tests/tps/test_addon_reconciling.js
@@ -0,0 +1,54 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This test verifies that record reconciling works as expected. It makes
+// similar changes to add-ons in separate profiles and does a sync to verify
+// the proper action is taken.
+EnableEngines(["addons"]);
+
+var phases = {
+ "phase01": "profile1",
+ "phase02": "profile2",
+ "phase03": "profile1",
+ "phase04": "profile2",
+ "phase05": "profile1",
+ "phase06": "profile2"
+};
+
+const id = "restartless-xpi@tests.mozilla.org";
+
+// Install the add-on in 2 profiles.
+Phase("phase01", [
+ [Addons.verifyNot, [id]],
+ [Addons.install, [id]],
+ [Addons.verify, [id], STATE_ENABLED],
+ [Sync]
+]);
+Phase("phase02", [
+ [Addons.verifyNot, [id]],
+ [Sync],
+ [Addons.verify, [id], STATE_ENABLED]
+]);
+
+// Now we disable in one and uninstall in the other.
+Phase("phase03", [
+ [Sync], // Get GUID updates, potentially.
+ [Addons.setEnabled, [id], STATE_DISABLED],
+ // We've changed the state, but don't want this profile to sync until phase5,
+ // so if we ran a validation now we'd be expecting to find errors.
+ [Addons.skipValidation]
+]);
+Phase("phase04", [
+ [EnsureTracking],
+ [Addons.uninstall, [id]],
+ [Sync]
+]);
+
+// When we sync, the uninstall should take precedence because it was newer.
+Phase("phase05", [
+ [Sync]
+]);
+Phase("phase06", [
+ [Sync],
+ [Addons.verifyNot, [id]]
+]);
diff --git a/services/sync/tests/tps/test_addon_restartless_xpi.js b/services/sync/tests/tps/test_addon_restartless_xpi.js
new file mode 100644
index 0000000000..b242c95f0e
--- /dev/null
+++ b/services/sync/tests/tps/test_addon_restartless_xpi.js
@@ -0,0 +1,70 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This test verifies that install of restartless extensions syncs to
+// other profiles.
+EnableEngines(["addons"]);
+
+var phases = {
+ "phase01": "profile1",
+ "phase02": "profile2",
+ "phase03": "profile1",
+ "phase04": "profile2",
+ "phase05": "profile1",
+ "phase06": "profile2",
+ "phase07": "profile1",
+ "phase08": "profile2"
+};
+
+const id = "restartless-xpi@tests.mozilla.org";
+
+// Verify install is synced
+Phase("phase01", [
+ [Addons.verifyNot, [id]],
+ [Addons.install, [id]],
+ [Addons.verify, [id], STATE_ENABLED],
+ [Sync]
+]);
+Phase("phase02", [
+ [Addons.verifyNot, [id]],
+ [Sync],
+ [Addons.verify, [id], STATE_ENABLED]
+]);
+
+// Now disable and see that is is synced.
+Phase("phase03", [
+ [EnsureTracking],
+ [Addons.setEnabled, [id], STATE_DISABLED],
+ [Addons.verify, [id], STATE_DISABLED],
+ [Sync]
+]);
+Phase("phase04", [
+ [Sync],
+ [Addons.verify, [id], STATE_DISABLED]
+]);
+
+// Enable and see it is synced.
+Phase("phase05", [
+ [EnsureTracking],
+ [Addons.setEnabled, [id], STATE_ENABLED],
+ [Addons.verify, [id], STATE_ENABLED],
+ [Sync]
+]);
+Phase("phase06", [
+ [Sync],
+ [Addons.verify, [id], STATE_ENABLED]
+]);
+
+// Uninstall and see it is synced.
+Phase("phase07", [
+ [EnsureTracking],
+ [Addons.verify, [id], STATE_ENABLED],
+ [Addons.uninstall, [id]],
+ [Addons.verifyNot, [id]],
+ [Sync]
+]);
+Phase("phase08", [
+ [Addons.verify, [id], STATE_ENABLED],
+ [Sync],
+ [Addons.verifyNot, [id]]
+]);
diff --git a/services/sync/tests/tps/test_addon_sanity.js b/services/sync/tests/tps/test_addon_sanity.js
new file mode 100644
index 0000000000..2409180949
--- /dev/null
+++ b/services/sync/tests/tps/test_addon_sanity.js
@@ -0,0 +1,30 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+
+EnableEngines(["addons"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile1" };
+
+const id = "unsigned-xpi@tests.mozilla.org";
+
+Phase("phase1", [
+ [Addons.install, [id]],
+ // Non-restartless add-on shouldn't be found after install.
+ [Addons.verifyNot, [id]],
+
+ // But it should be marked for Sync.
+ [Sync]
+]);
+
+Phase("phase2", [
+ // Add-on should be present after restart
+ [Addons.verify, [id], STATE_ENABLED],
+ [Sync] // Sync to ensure everything is initialized enough for the addon validator to run
+]);
diff --git a/services/sync/tests/tps/test_addon_wipe.js b/services/sync/tests/tps/test_addon_wipe.js
new file mode 100644
index 0000000000..60131abc0f
--- /dev/null
+++ b/services/sync/tests/tps/test_addon_wipe.js
@@ -0,0 +1,35 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This test ensures that a client wipe followed by an "initial" sync will
+// restore add-ons. This test should expose flaws in the reconciling logic,
+// specifically around AddonsReconciler. This test is in response to bug
+// 792990.
+
+EnableEngines(["addons"]);
+
+var phases = {
+ "phase01": "profile1",
+ "phase02": "profile1",
+ "phase03": "profile1"
+};
+
+const id1 = "restartless-xpi@tests.mozilla.org";
+const id2 = "unsigned-xpi@tests.mozilla.org";
+
+Phase("phase01", [
+ [Addons.install, [id1]],
+ [Addons.install, [id2]],
+ [Sync]
+]);
+Phase("phase02", [
+ [Addons.verify, [id1], STATE_ENABLED],
+ [Addons.verify, [id2], STATE_ENABLED],
+ [Sync, SYNC_WIPE_CLIENT],
+ [Sync]
+]);
+Phase("phase03", [
+ [Addons.verify, [id1], STATE_ENABLED],
+ [Addons.verify, [id2], STATE_ENABLED],
+ [Sync] // Sync to ensure that the addon validator can run without error
+]);
diff --git a/services/sync/tests/tps/test_bookmark_conflict.js b/services/sync/tests/tps/test_bookmark_conflict.js
new file mode 100644
index 0000000000..cfe9d782e8
--- /dev/null
+++ b/services/sync/tests/tps/test_bookmark_conflict.js
@@ -0,0 +1,143 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["bookmarks"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1",
+ "phase4": "profile2" };
+
+
+// the initial list of bookmarks to add to the browser
+var bookmarksInitial = {
+ "menu": [
+ { folder: "foldera" },
+ { folder: "folderb" },
+ { folder: "folderc" },
+ { folder: "folderd" },
+ ],
+
+ "menu/foldera": [{ uri: "http://www.cnn.com", title: "CNN" }],
+ "menu/folderb": [{ uri: "http://www.apple.com", title: "Apple", tags: [] }],
+ "menu/folderc": [{ uri: "http://www.yahoo.com", title: "Yahoo" }],
+
+ "menu/folderd": []
+};
+
+// a list of bookmarks to delete during a 'delete' action on P2
+var bookmarksToDelete = {
+ "menu": [
+ { folder: "foldera" },
+ { folder: "folderb" },
+ ],
+ "menu/folderc": [{ uri: "http://www.yahoo.com", title: "Yahoo" }],
+};
+
+
+// the modifications to make on P1, after P2 has synced, but before P1 has gotten
+// P2's changes
+var bookmarkMods = {
+ "menu": [
+ { folder: "foldera" },
+ { folder: "folderb" },
+ { folder: "folderc" },
+ { folder: "folderd" },
+ ],
+
+ // we move this child out of its folder (p1), after deleting the folder (p2)
+ // and expect the child to come back to p2 after sync.
+ "menu/foldera": [{
+ uri: "http://www.cnn.com",
+ title: "CNN",
+ changes: { location: "menu/folderd" }
+ }],
+
+ // we rename this child (p1) after deleting the folder (p2), and expect the child
+ // to be moved into great grandparent (menu)
+ "menu/folderb": [{
+ uri: "http://www.apple.com",
+ title: "Apple",
+ tags: [],
+ changes: { title: "Mac" }
+ }],
+
+
+ // we move this child (p1) after deleting the child (p2) and expect it to survive
+ "menu/folderc": [{
+ uri: "http://www.yahoo.com",
+ title: "Yahoo",
+ changes: { location: "menu/folderd" }
+ }],
+
+ "menu/folderd": []
+};
+
+// a list of bookmarks to delete during a 'delete' action
+var bookmarksToDelete = {
+ "menu": [
+ { folder: "foldera" },
+ { folder: "folderb" },
+ ],
+ "menu/folderc": [
+ { uri: "http://www.yahoo.com", title: "Yahoo" },
+ ],
+};
+
+
+
+// expected bookmark state after conflict resolution
+var bookmarksExpected = {
+ "menu": [
+ { folder: "folderc" },
+ { folder: "folderd" },
+ { uri: "http://www.apple.com", title: "Mac", },
+ ],
+
+ "menu/folderc": [],
+
+ "menu/folderd": [
+ { uri: "http://www.cnn.com", title: "CNN" },
+ { uri: "http://www.yahoo.com", title: "Yahoo" }
+ ]
+};
+
+// Add bookmarks to profile1 and sync.
+Phase("phase1", [
+ [Bookmarks.add, bookmarksInitial],
+ [Bookmarks.verify, bookmarksInitial],
+ [Sync],
+ [Bookmarks.verify, bookmarksInitial],
+]);
+
+// Sync to profile2 and verify that the bookmarks are present. Delete
+// bookmarks/folders, verify that it's not present, and sync
+Phase("phase2", [
+ [Sync],
+ [Bookmarks.verify, bookmarksInitial],
+ [Bookmarks.delete, bookmarksToDelete],
+ [Bookmarks.verifyNot, bookmarksToDelete],
+ [Sync]
+]);
+
+// Using profile1, modify the bookmarks, and sync *after* the modification,
+// and then sync again to propagate the reconciliation changes.
+Phase("phase3", [
+ [Bookmarks.verify, bookmarksInitial],
+ [Bookmarks.modify, bookmarkMods],
+ [Sync],
+ [Bookmarks.verify, bookmarksExpected],
+ [Bookmarks.verifyNot, bookmarksToDelete],
+]);
+
+// Back in profile2, do a sync and verify that we're in the expected state
+Phase("phase4", [
+ [Sync],
+ [Bookmarks.verify, bookmarksExpected],
+ [Bookmarks.verifyNot, bookmarksToDelete],
+]);
diff --git a/services/sync/tests/tps/test_bookmarks_in_same_named_folder.js b/services/sync/tests/tps/test_bookmarks_in_same_named_folder.js
new file mode 100644
index 0000000000..e0eb9db53e
--- /dev/null
+++ b/services/sync/tests/tps/test_bookmarks_in_same_named_folder.js
@@ -0,0 +1,69 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// bug 558077
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["bookmarks"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1"};
+
+var bookmarks_initial_1 = {
+ "menu": [
+ { folder: "aaa",
+ description: "foo"
+ },
+ { uri: "http://www.mozilla.com"
+ }
+ ],
+ "menu/aaa": [
+ { uri: "http://www.yahoo.com",
+ title: "testing Yahoo"
+ },
+ { uri: "http://www.google.com",
+ title: "testing Google"
+ }
+ ]
+};
+
+var bookmarks_initial_2 = {
+ "menu": [
+ { folder: "aaa",
+ description: "bar"
+ },
+ { uri: "http://www.mozilla.com"
+ }
+ ],
+ "menu/aaa": [
+ { uri: "http://bugzilla.mozilla.org/show_bug.cgi?id=%s",
+ title: "Bugzilla"
+ },
+ { uri: "http://www.apple.com",
+ tags: [ "apple" ]
+ }
+ ]
+};
+
+Phase('phase1', [
+ [Bookmarks.add, bookmarks_initial_1],
+ [Sync]
+]);
+
+Phase('phase2', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_initial_1],
+ [Bookmarks.add, bookmarks_initial_2],
+ [Sync]
+]);
+
+Phase('phase3', [
+ [Sync],
+ // XXX [Bookmarks.verify, bookmarks_initial_1],
+ [Bookmarks.verify, bookmarks_initial_2]
+]);
diff --git a/services/sync/tests/tps/test_bug501528.js b/services/sync/tests/tps/test_bug501528.js
new file mode 100644
index 0000000000..7b1566c43b
--- /dev/null
+++ b/services/sync/tests/tps/test_bug501528.js
@@ -0,0 +1,79 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["passwords"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1",
+ "phase4": "profile2" };
+
+/*
+ * Password lists
+ */
+
+var passwords_initial = [
+ { hostname: "http://www.example.com",
+ submitURL: "http://login.example.com",
+ username: "joe",
+ password: "secret",
+ usernameField: "uname",
+ passwordField: "pword",
+ changes: {
+ password: "SeCrEt$$$"
+ }
+ },
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "jack",
+ password: "secretlogin"
+ }
+];
+
+var passwords_after_first_update = [
+ { hostname: "http://www.example.com",
+ submitURL: "http://login.example.com",
+ username: "joe",
+ password: "SeCrEt$$$",
+ usernameField: "uname",
+ passwordField: "pword"
+ },
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "jack",
+ password: "secretlogin"
+ }
+];
+
+/*
+ * Test phases
+ */
+
+Phase('phase1', [
+ [Passwords.add, passwords_initial],
+ [Sync]
+]);
+
+Phase('phase2', [
+ [Passwords.add, passwords_initial],
+ [Sync]
+]);
+
+Phase('phase3', [
+ [Sync],
+ [Passwords.verify, passwords_initial],
+ [Passwords.modify, passwords_initial],
+ [Passwords.verify, passwords_after_first_update],
+ [Sync]
+]);
+
+Phase('phase4', [
+ [Sync],
+ [Passwords.verify, passwords_after_first_update],
+]);
+
diff --git a/services/sync/tests/tps/test_bug530717.js b/services/sync/tests/tps/test_bug530717.js
new file mode 100644
index 0000000000..4a11b0a277
--- /dev/null
+++ b/services/sync/tests/tps/test_bug530717.js
@@ -0,0 +1,69 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["prefs"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1"};
+
+/*
+ * Preference lists
+ */
+
+var prefs1 = [
+ { name: "browser.startup.homepage",
+ value: "http://www.getfirefox.com"
+ },
+ { name: "browser.urlbar.maxRichResults",
+ value: 20
+ },
+ { name: "privacy.clearOnShutdown.siteSettings",
+ value: true
+ }
+];
+
+var prefs2 = [
+ { name: "browser.startup.homepage",
+ value: "http://www.mozilla.com"
+ },
+ { name: "browser.urlbar.maxRichResults",
+ value: 18
+ },
+ { name: "privacy.clearOnShutdown.siteSettings",
+ value: false
+ }
+];
+
+/*
+ * Test phases
+ */
+
+// Add prefs to profile1 and sync.
+Phase('phase1', [
+ [Prefs.modify, prefs1],
+ [Prefs.verify, prefs1],
+ [Sync]
+]);
+
+// Sync profile2 and verify same prefs are present.
+Phase('phase2', [
+ [Sync],
+ [Prefs.verify, prefs1]
+]);
+
+// Using profile1, change some prefs, then do another sync with wipe-client.
+// Verify that the cloud's prefs are restored, and the recent local changes
+// discarded.
+Phase('phase3', [
+ [Prefs.modify, prefs2],
+ [Prefs.verify, prefs2],
+ [Sync, SYNC_WIPE_CLIENT],
+ [Prefs.verify, prefs1]
+]);
+
diff --git a/services/sync/tests/tps/test_bug531489.js b/services/sync/tests/tps/test_bug531489.js
new file mode 100644
index 0000000000..aa2de0b3a0
--- /dev/null
+++ b/services/sync/tests/tps/test_bug531489.js
@@ -0,0 +1,62 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["bookmarks"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1"};
+
+/*
+ * Bookmark asset lists: these define bookmarks that are used during the test
+ */
+
+// the initial list of bookmarks to add to the browser
+var bookmarks_initial = {
+ "menu": [
+ { folder: "foldera" },
+ { uri: "http://www.google.com",
+ title: "Google"
+ }
+ ],
+ "menu/foldera": [
+ { uri: "http://www.google.com",
+ title: "Google"
+ }
+ ],
+ "toolbar": [
+ { uri: "http://www.google.com",
+ title: "Google"
+ }
+ ]
+};
+
+/*
+ * Test phases
+ */
+
+// Add three bookmarks with the same url to different locations and sync.
+Phase('phase1', [
+ [Bookmarks.add, bookmarks_initial],
+ [Bookmarks.verify, bookmarks_initial],
+ [Sync]
+]);
+
+// Sync to profile2 and verify that all three bookmarks are present
+Phase('phase2', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_initial]
+]);
+
+// Sync again to profile1 and verify that all three bookmarks are still
+// present.
+Phase('phase3', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_initial]
+]);
+
diff --git a/services/sync/tests/tps/test_bug535326.js b/services/sync/tests/tps/test_bug535326.js
new file mode 100644
index 0000000000..7875e593b5
--- /dev/null
+++ b/services/sync/tests/tps/test_bug535326.js
@@ -0,0 +1,130 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["tabs"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2"};
+
+var tabs1 = [
+ { uri: "data:text/html,<html><head><title>Howdy</title></head><body>Howdy</body></html>",
+ title: "Howdy",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>America</title></head><body>America</body></html>",
+ title: "America",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Apple</title></head><body>Apple</body></html>",
+ title: "Apple",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>This</title></head><body>This</body></html>",
+ title: "This",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Bug</title></head><body>Bug</body></html>",
+ title: "Bug",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>IRC</title></head><body>IRC</body></html>",
+ title: "IRC",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Tinderbox</title></head><body>Tinderbox</body></html>",
+ title: "Tinderbox",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Fox</title></head><body>Fox</body></html>",
+ title: "Fox",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Hello</title></head><body>Hello</body></html>",
+ title: "Hello",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Eagle</title></head><body>Eagle</body></html>",
+ title: "Eagle",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Train</title></head><body>Train</body></html>",
+ title: "Train",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Macbook</title></head><body>Macbook</body></html>",
+ title: "Macbook",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Clock</title></head><body>Clock</body></html>",
+ title: "Clock",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Google</title></head><body>Google</body></html>",
+ title: "Google",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Human</title></head><body>Human</body></html>",
+ title: "Human",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Jetpack</title></head><body>Jetpack</body></html>",
+ title: "Jetpack",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Selenium</title></head><body>Selenium</body></html>",
+ title: "Selenium",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Mozilla</title></head><body>Mozilla</body></html>",
+ title: "Mozilla",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Firefox</title></head><body>Firefox</body></html>",
+ title: "Firefox",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Weave</title></head><body>Weave</body></html>",
+ title: "Weave",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Android</title></head><body>Android</body></html>",
+ title: "Android",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Bye</title></head><body>Bye</body></html>",
+ title: "Bye",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Hi</title></head><body>Hi</body></html>",
+ title: "Hi",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Final</title></head><body>Final</body></html>",
+ title: "Final",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Fennec</title></head><body>Fennec</body></html>",
+ title: "Fennec",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Mobile</title></head><body>Mobile</body></html>",
+ title: "Mobile",
+ profile: "profile1"
+ }
+];
+
+Phase('phase1', [
+ [Tabs.add, tabs1],
+ [Sync]
+]);
+
+Phase('phase2', [
+ [Sync],
+ [Tabs.verify, tabs1]
+]);
+
diff --git a/services/sync/tests/tps/test_bug538298.js b/services/sync/tests/tps/test_bug538298.js
new file mode 100644
index 0000000000..2a6d0c8ded
--- /dev/null
+++ b/services/sync/tests/tps/test_bug538298.js
@@ -0,0 +1,93 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["bookmarks"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1",
+ "phase4": "profile2" };
+
+/*
+ * Bookmark asset lists: these define bookmarks that are used during the test
+ */
+
+// the initial list of bookmarks to add to the browser
+var bookmarks_initial = {
+ "toolbar": [
+ { uri: "http://www.google.com",
+ title: "Google"
+ },
+ { uri: "http://www.cnn.com",
+ title: "CNN",
+ changes: {
+ position: "Google"
+ }
+ },
+ { uri: "http://www.mozilla.com",
+ title: "Mozilla"
+ },
+ { uri: "http://www.firefox.com",
+ title: "Firefox",
+ changes: {
+ position: "Mozilla"
+ }
+ }
+ ]
+};
+
+var bookmarks_after_move = {
+ "toolbar": [
+ { uri: "http://www.cnn.com",
+ title: "CNN"
+ },
+ { uri: "http://www.google.com",
+ title: "Google"
+ },
+ { uri: "http://www.firefox.com",
+ title: "Firefox"
+ },
+ { uri: "http://www.mozilla.com",
+ title: "Mozilla"
+ }
+ ]
+};
+
+/*
+ * Test phases
+ */
+
+// Add four bookmarks to the toolbar and sync.
+Phase('phase1', [
+ [Bookmarks.add, bookmarks_initial],
+ [Bookmarks.verify, bookmarks_initial],
+ [Sync]
+]);
+
+// Sync to profile2 and verify that all four bookmarks are present.
+Phase('phase2', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_initial]
+]);
+
+// Change the order of the toolbar bookmarks, and sync.
+Phase('phase3', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_initial],
+ [Bookmarks.modify, bookmarks_initial],
+ [Bookmarks.verify, bookmarks_after_move],
+ [Sync],
+]);
+
+// Go back to profile2, sync, and verify that the bookmarks are reordered
+// as expected.
+Phase('phase4', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_after_move]
+]);
+
diff --git a/services/sync/tests/tps/test_bug546807.js b/services/sync/tests/tps/test_bug546807.js
new file mode 100644
index 0000000000..873ecf2be2
--- /dev/null
+++ b/services/sync/tests/tps/test_bug546807.js
@@ -0,0 +1,54 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+
+EnableEngines(["tabs"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2"};
+
+/*
+ * Tabs data
+ */
+
+var tabs1 = [
+ { uri: "about:config",
+ profile: "profile1"
+ },
+ { uri: "about:credits",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Apple</title></head><body>Apple</body></html>",
+ title: "Apple",
+ profile: "profile1"
+ }
+];
+
+var tabs_absent = [
+ { uri: "about:config",
+ profile: "profile1"
+ },
+ { uri: "about:credits",
+ profile: "profile1"
+ },
+];
+
+/*
+ * Test phases
+ */
+
+Phase('phase1', [
+ [Tabs.add, tabs1],
+ [Sync]
+]);
+
+Phase('phase2', [
+ [Sync],
+ [Tabs.verifyNot, tabs_absent]
+]);
+
diff --git a/services/sync/tests/tps/test_bug556509.js b/services/sync/tests/tps/test_bug556509.js
new file mode 100644
index 0000000000..a2a5f8fc34
--- /dev/null
+++ b/services/sync/tests/tps/test_bug556509.js
@@ -0,0 +1,45 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["bookmarks"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2"};
+
+
+// the initial list of bookmarks to add to the browser
+var bookmarks_initial = {
+ "menu": [
+ { folder: "testfolder",
+ description: "it's just me, a test folder"
+ }
+ ],
+ "menu/testfolder": [
+ { uri: "http://www.mozilla.com",
+ title: "Mozilla"
+ }
+ ]
+};
+
+/*
+ * Test phases
+ */
+
+// Add a bookmark folder which has a description, and sync.
+Phase('phase1', [
+ [Bookmarks.add, bookmarks_initial],
+ [Bookmarks.verify, bookmarks_initial],
+ [Sync]
+]);
+
+// Sync to profile2 and verify that the bookmark folder is created, along
+// with its description.
+Phase('phase2', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_initial]
+]);
diff --git a/services/sync/tests/tps/test_bug562515.js b/services/sync/tests/tps/test_bug562515.js
new file mode 100644
index 0000000000..380e8ca249
--- /dev/null
+++ b/services/sync/tests/tps/test_bug562515.js
@@ -0,0 +1,105 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["bookmarks"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1",
+ "phase4": "profile2" };
+
+/*
+ * Bookmark lists
+ */
+
+// the initial list of bookmarks to add to the browser
+var bookmarks_initial = {
+ "menu": [
+ { uri: "http://www.google.com",
+ loadInSidebar: true,
+ tags: [ "google", "computers", "internet", "www"]
+ },
+ { uri: "http://bugzilla.mozilla.org/show_bug.cgi?id=%s",
+ title: "Bugzilla",
+ keyword: "bz"
+ },
+ { folder: "foldera" },
+ { uri: "http://www.mozilla.com" },
+ { separator: true },
+ { folder: "folderb" }
+ ],
+ "menu/foldera": [
+ { uri: "http://www.yahoo.com",
+ title: "testing Yahoo"
+ },
+ { uri: "http://www.cnn.com",
+ description: "This is a description of the site a at www.cnn.com"
+ },
+ { livemark: "Livemark1",
+ feedUri: "http://rss.wunderground.com/blog/JeffMasters/rss.xml",
+ siteUri: "http://www.wunderground.com/blog/JeffMasters/show.html"
+ }
+ ],
+ "menu/folderb": [
+ { uri: "http://www.apple.com",
+ tags: [ "apple", "mac" ]
+ }
+ ],
+ "toolbar": [
+ { uri: "place:queryType=0&sort=8&maxResults=10&beginTimeRef=1&beginTime=0",
+ title: "Visited Today"
+ }
+ ]
+};
+
+// a list of bookmarks to delete during a 'delete' action
+var bookmarks_to_delete = {
+ "menu": [
+ { uri: "http://www.google.com",
+ loadInSidebar: true,
+ tags: [ "google", "computers", "internet", "www"]
+ }
+ ],
+ "menu/foldera": [
+ { uri: "http://www.yahoo.com",
+ title: "testing Yahoo"
+ }
+ ]
+};
+
+/*
+ * Test phases
+ */
+
+// add bookmarks to profile1 and sync
+Phase('phase1', [
+ [Bookmarks.add, bookmarks_initial],
+ [Bookmarks.verify, bookmarks_initial],
+ [Sync]
+]);
+
+// sync to profile2 and verify that the bookmarks are present
+Phase('phase2', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_initial]
+]);
+
+// delete some bookmarks from profile1, then sync with "wipe-client"
+// set; finally, verify that the deleted bookmarks were restored.
+Phase('phase3', [
+ [Bookmarks.delete, bookmarks_to_delete],
+ [Bookmarks.verifyNot, bookmarks_to_delete],
+ [Sync, SYNC_WIPE_CLIENT],
+ [Bookmarks.verify, bookmarks_initial]
+]);
+
+// sync profile2 again, verify no bookmarks have been deleted
+Phase('phase4', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_initial]
+]);
diff --git a/services/sync/tests/tps/test_bug563989.js b/services/sync/tests/tps/test_bug563989.js
new file mode 100644
index 0000000000..faf63de659
--- /dev/null
+++ b/services/sync/tests/tps/test_bug563989.js
@@ -0,0 +1,107 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["bookmarks"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1",
+ "phase4": "profile2" };
+
+/*
+ * Bookmark asset lists: these define bookmarks that are used during the test
+ */
+
+// the initial list of bookmarks to add to the browser
+var bookmarks_initial = {
+ "menu": [
+ { uri: "http://www.google.com",
+ loadInSidebar: true,
+ tags: [ "google", "computers", "internet", "www" ]
+ },
+ { uri: "http://bugzilla.mozilla.org/show_bug.cgi?id=%s",
+ title: "Bugzilla",
+ keyword: "bz"
+ },
+ { folder: "foldera" },
+ { uri: "http://www.mozilla.com" },
+ { separator: true },
+ { folder: "folderb" }
+ ],
+ "menu/foldera": [
+ { uri: "http://www.yahoo.com",
+ title: "testing Yahoo"
+ },
+ { uri: "http://www.cnn.com",
+ description: "This is a description of the site a at www.cnn.com"
+ },
+ { livemark: "Livemark1",
+ feedUri: "http://rss.wunderground.com/blog/JeffMasters/rss.xml",
+ siteUri: "http://www.wunderground.com/blog/JeffMasters/show.html"
+ }
+ ],
+ "menu/folderb": [
+ { uri: "http://www.apple.com",
+ tags: [ "apple", "mac" ]
+ }
+ ],
+ "toolbar": [
+ { uri: "place:queryType=0&sort=8&maxResults=10&beginTimeRef=1&beginTime=0",
+ title: "Visited Today"
+ }
+ ]
+};
+
+// a list of bookmarks to delete during a 'delete' action
+var bookmarks_to_delete = {
+ "menu/folderb": [
+ { uri: "http://www.apple.com",
+ tags: [ "apple", "mac" ]
+ }
+ ],
+ "toolbar": [
+ { uri: "place:queryType=0&sort=8&maxResults=10&beginTimeRef=1&beginTime=0",
+ title: "Visited Today"
+ }
+ ]
+};
+
+/*
+ * Test phases
+ */
+
+// Add bookmarks to profile1 and sync.
+Phase('phase1', [
+ [Bookmarks.add, bookmarks_initial],
+ [Bookmarks.verify, bookmarks_initial],
+ [Sync],
+]);
+
+// Sync to profile2 and verify that the bookmarks are present. Delete
+// some bookmarks, and verify that they're not present, but don't sync again.
+Phase('phase2', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_initial],
+ [Bookmarks.delete, bookmarks_to_delete],
+ [Bookmarks.verifyNot, bookmarks_to_delete],
+ [Bookmarks.skipValidation]
+]);
+
+// Using profile1, sync again with wipe-server set to true. Verify our
+// initial bookmarks are still all present.
+Phase('phase3', [
+ [Sync, SYNC_WIPE_REMOTE],
+ [Bookmarks.verify, bookmarks_initial]
+]);
+
+// Back in profile2, do a sync and verify that the bookmarks we had
+// deleted earlier are now restored.
+Phase('phase4', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_initial]
+]);
diff --git a/services/sync/tests/tps/test_bug575423.js b/services/sync/tests/tps/test_bug575423.js
new file mode 100644
index 0000000000..d187c48781
--- /dev/null
+++ b/services/sync/tests/tps/test_bug575423.js
@@ -0,0 +1,85 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+
+EnableEngines(["history"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2"};
+
+/*
+ * History data
+ */
+
+// the history data to add to the browser
+var history1 = [
+ { uri: "http://www.google.com/",
+ title: "Google",
+ visits: [
+ { type: 1,
+ date: 0
+ },
+ { type: 2,
+ date: -1
+ }
+ ]
+ },
+ { uri: "http://www.cnn.com/",
+ title: "CNN",
+ visits: [
+ { type: 1,
+ date: -1
+ },
+ { type: 2,
+ date: -36
+ }
+ ]
+ }
+];
+
+// Another history data to add to the browser
+var history2 = [
+ { uri: "http://www.mozilla.com/",
+ title: "Mozilla",
+ visits: [
+ { type: 1,
+ date: 0
+ },
+ { type: 2,
+ date: -36
+ }
+ ]
+ },
+ { uri: "http://www.google.com/language_tools?hl=en",
+ title: "Language Tools",
+ visits: [
+ { type: 1,
+ date: 0
+ },
+ { type: 2,
+ date: -40
+ }
+ ]
+ }
+];
+
+/*
+ * Test phases
+ */
+Phase('phase1', [
+ [History.add, history1],
+ [Sync],
+ [History.add, history2],
+ [Sync]
+]);
+
+Phase('phase2', [
+ [Sync],
+ [History.verify, history2]
+]);
+
diff --git a/services/sync/tests/tps/test_client_wipe.js b/services/sync/tests/tps/test_client_wipe.js
new file mode 100644
index 0000000000..ba9815db54
--- /dev/null
+++ b/services/sync/tests/tps/test_client_wipe.js
@@ -0,0 +1,164 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1"};
+
+/*
+ * Bookmark lists
+ */
+
+// the initial list of bookmarks to add to the browser
+var bookmarks_initial = {
+ toolbar: [
+ { uri: "http://www.google.com",
+ title: "Google"
+ },
+ { uri: "http://www.cnn.com",
+ title: "CNN",
+ changes: {
+ position: "Google"
+ }
+ },
+ { uri: "http://www.mozilla.com",
+ title: "Mozilla"
+ },
+ { uri: "http://www.firefox.com",
+ title: "Firefox",
+ changes: {
+ position: "Mozilla"
+ }
+ }
+ ]
+};
+
+var bookmarks_after_move = {
+ toolbar: [
+ { uri: "http://www.cnn.com",
+ title: "CNN"
+ },
+ { uri: "http://www.google.com",
+ title: "Google"
+ },
+ { uri: "http://www.firefox.com",
+ title: "Firefox"
+ },
+ { uri: "http://www.mozilla.com",
+ title: "Mozilla"
+ }
+ ]
+};
+
+/*
+ * Password data
+ */
+
+// Initial password data
+var passwords_initial = [
+ { hostname: "http://www.example.com",
+ submitURL: "http://login.example.com",
+ username: "joe",
+ password: "secret",
+ usernameField: "uname",
+ passwordField: "pword",
+ changes: {
+ password: "SeCrEt$$$"
+ }
+ },
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "jack",
+ password: "secretlogin"
+ }
+];
+
+// Password after first modify action has been performed
+var passwords_after_change = [
+ { hostname: "http://www.example.com",
+ submitURL: "http://login.example.com",
+ username: "joe",
+ password: "SeCrEt$$$",
+ usernameField: "uname",
+ passwordField: "pword",
+ changes: {
+ username: "james"
+ }
+ },
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "jack",
+ password: "secretlogin"
+ }
+];
+
+/*
+ * Prefs to use in the test
+ */
+var prefs1 = [
+ { name: "browser.startup.homepage",
+ value: "http://www.getfirefox.com"
+ },
+ { name: "browser.urlbar.maxRichResults",
+ value: 20
+ },
+ { name: "privacy.clearOnShutdown.siteSettings",
+ value: true
+ }
+];
+
+var prefs2 = [
+ { name: "browser.startup.homepage",
+ value: "http://www.mozilla.com"
+ },
+ { name: "browser.urlbar.maxRichResults",
+ value: 18
+ },
+ { name: "privacy.clearOnShutdown.siteSettings",
+ value: false
+ }
+];
+
+/*
+ * Test phases
+ */
+
+// Add prefs,passwords and bookmarks to profile1 and sync.
+Phase('phase1', [
+ [Passwords.add, passwords_initial],
+ [Bookmarks.add, bookmarks_initial],
+ [Prefs.modify, prefs1],
+ [Prefs.verify, prefs1],
+ [Sync]
+]);
+
+// Sync profile2 and verify same prefs,passwords and bookmarks are present.
+Phase('phase2', [
+ [Sync],
+ [Prefs.verify, prefs1],
+ [Passwords.verify, passwords_initial],
+ [Bookmarks.verify, bookmarks_initial]
+]);
+
+// Using profile1, change some prefs,bookmarks and pwds, then do another sync with wipe-client.
+// Verify that the cloud's settings are restored, and the recent local changes
+// discarded.
+Phase('phase3', [
+ [Prefs.modify, prefs2],
+ [Passwords.modify, passwords_initial],
+ [Bookmarks.modify, bookmarks_initial],
+ [Prefs.verify, prefs2],
+ [Passwords.verify, passwords_after_change],
+ [Bookmarks.verify, bookmarks_after_move],
+ [Sync, SYNC_WIPE_CLIENT],
+ [Prefs.verify, prefs1],
+ [Passwords.verify, passwords_initial],
+ [Bookmarks.verify, bookmarks_initial]
+]);
+
diff --git a/services/sync/tests/tps/test_formdata.js b/services/sync/tests/tps/test_formdata.js
new file mode 100644
index 0000000000..decb58dd89
--- /dev/null
+++ b/services/sync/tests/tps/test_formdata.js
@@ -0,0 +1,97 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["forms"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1",
+ "phase4": "profile2" };
+
+/*
+ * Form data asset lists: these define form values that are used in the tests.
+ */
+
+var formdata1 = [
+ { fieldname: "testing",
+ value: "success",
+ date: -1
+ },
+ { fieldname: "testing",
+ value: "failure",
+ date: -2
+ },
+ { fieldname: "username",
+ value: "joe"
+ }
+];
+
+// This is currently pointless - it *looks* like it is trying to check that
+// one of the entries in formdata1 has been removed, but (a) the delete code
+// isn't active (see comments below), and (b) the way the verification works
+// means it would never do the right thing - it only checks all the entries
+// here exist, but not that they are the only entries in the DB.
+var formdata2 = [
+ { fieldname: "testing",
+ value: "success",
+ date: -1
+ },
+ { fieldname: "username",
+ value: "joe"
+ }
+];
+
+var formdata_delete = [
+ { fieldname: "testing",
+ value: "failure"
+ }
+];
+
+var formdata_new = [
+ { fieldname: "new-field",
+ value: "new-value"
+ }
+]
+/*
+ * Test phases
+ */
+
+Phase('phase1', [
+ [Formdata.add, formdata1],
+ [Formdata.verify, formdata1],
+ [Sync]
+]);
+
+Phase('phase2', [
+ [Sync],
+ [Formdata.verify, formdata1],
+]);
+
+/*
+ * Note: Weave does not support syncing deleted form data, so those
+ * tests are disabled below. See bug 568363.
+ */
+
+Phase('phase3', [
+ [Sync],
+ [Formdata.delete, formdata_delete],
+//[Formdata.verifyNot, formdata_delete],
+ [Formdata.verify, formdata2],
+ // add new data after the first Sync, ensuring the tracker works.
+ [Formdata.add, formdata_new],
+ [Sync],
+]);
+
+Phase('phase4', [
+ [Sync],
+ [Formdata.verify, formdata2],
+ [Formdata.verify, formdata_new],
+//[Formdata.verifyNot, formdata_delete]
+]);
+
+
diff --git a/services/sync/tests/tps/test_history.js b/services/sync/tests/tps/test_history.js
new file mode 100644
index 0000000000..5e8bcdb92a
--- /dev/null
+++ b/services/sync/tests/tps/test_history.js
@@ -0,0 +1,167 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["history"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2" };
+
+/*
+ * History asset lists: these define history entries that are used during
+ * the test
+ */
+
+// the initial list of history items to add to the browser
+var history1 = [
+ { uri: "http://www.google.com/",
+ title: "Google",
+ visits: [
+ { type: 1,
+ date: 0
+ },
+ { type: 2,
+ date: -1
+ }
+ ]
+ },
+ { uri: "http://www.cnn.com/",
+ title: "CNN",
+ visits: [
+ { type: 1,
+ date: -1
+ },
+ { type: 2,
+ date: -36
+ }
+ ]
+ },
+ { uri: "http://www.google.com/language_tools?hl=en",
+ title: "Language Tools",
+ visits: [
+ { type: 1,
+ date: 0
+ },
+ { type: 2,
+ date: -40
+ }
+ ]
+ },
+ { uri: "http://www.mozilla.com/",
+ title: "Mozilla",
+ visits: [
+ { type: 1,
+ date: 0
+ },
+ { type: 1,
+ date: -1
+ },
+ { type: 1,
+ date: -20
+ },
+ { type: 2,
+ date: -36
+ }
+ ]
+ }
+];
+
+// a list of items to delete from the history
+var history_to_delete = [
+ { uri: "http://www.cnn.com/" },
+ { begin: -24,
+ end: -1
+ },
+ { host: "www.google.com" }
+];
+
+// a list which reflects items that should be in the history after
+// the above items are deleted
+var history2 = [
+ { uri: "http://www.mozilla.com/",
+ title: "Mozilla",
+ visits: [
+ { type: 1,
+ date: 0
+ },
+ { type: 2,
+ date: -36
+ }
+ ]
+ }
+];
+
+// a list which includes history entries that should not be present
+// after deletion of the history_to_delete entries
+var history_not = [
+ { uri: "http://www.google.com/",
+ title: "Google",
+ visits: [
+ { type: 1,
+ date: 0
+ },
+ { type: 2,
+ date: -1
+ }
+ ]
+ },
+ { uri: "http://www.cnn.com/",
+ title: "CNN",
+ visits: [
+ { type: 1,
+ date: -1
+ },
+ { type: 2,
+ date: -36
+ }
+ ]
+ },
+ { uri: "http://www.google.com/language_tools?hl=en",
+ title: "Language Tools",
+ visits: [
+ { type: 1,
+ date: 0
+ },
+ { type: 2,
+ date: -40
+ }
+ ]
+ },
+ { uri: "http://www.mozilla.com/",
+ title: "Mozilla",
+ visits: [
+ { type: 1,
+ date: -1
+ },
+ { type: 1,
+ date: -20
+ }
+ ]
+ }
+];
+
+/*
+ * Test phases
+ * Note: there is no test phase in which deleted history entries are
+ * synced to other clients. This functionality is not supported by
+ * Sync, see bug 446517.
+ */
+
+Phase('phase1', [
+ [History.add, history1],
+ [Sync],
+]);
+
+Phase('phase2', [
+ [Sync],
+ [History.verify, history1],
+ [History.delete, history_to_delete],
+ [History.verify, history2],
+ [History.verifyNot, history_not],
+ [Sync]
+]);
+
diff --git a/services/sync/tests/tps/test_history_collision.js b/services/sync/tests/tps/test_history_collision.js
new file mode 100644
index 0000000000..625483d5d1
--- /dev/null
+++ b/services/sync/tests/tps/test_history_collision.js
@@ -0,0 +1,125 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["history"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1",
+ "phase4": "profile2" };
+
+/*
+ * History lists
+ */
+
+// the initial list of history to add to the browser
+var history1 = [
+ { uri: "http://www.google.com/",
+ title: "Google",
+ visits: [
+ { type: 1,
+ date: 0
+ }
+ ]
+ },
+ { uri: "http://www.cnn.com/",
+ title: "CNN",
+ visits: [
+ { type: 1,
+ date: -1
+ },
+ { type: 2,
+ date: -36
+ }
+ ]
+ },
+ { uri: "http://www.mozilla.com/",
+ title: "Mozilla",
+ visits: [
+ { type: 1,
+ date: 0
+ },
+ { type: 2,
+ date: -36
+ }
+ ]
+ }
+];
+
+// the history to delete
+var history_to_delete = [
+ { uri: "http://www.cnn.com/",
+ title: "CNN"
+ },
+ { begin: -36,
+ end: -1
+ }
+];
+
+var history_not = [
+ { uri: "http://www.cnn.com/",
+ title: "CNN",
+ visits: [
+ { type: 1,
+ date: -1
+ },
+ { type: 2,
+ date: -36
+ }
+ ]
+ }
+];
+
+var history_after_delete = [
+ { uri: "http://www.google.com/",
+ title: "Google",
+ visits: [
+ { type: 1,
+ date: 0
+ }
+ ]
+ },
+ { uri: "http://www.mozilla.com/",
+ title: "Mozilla",
+ visits: [
+ { type: 1,
+ date: 0
+ }
+ ]
+ }
+];
+
+/*
+ * Test phases
+ */
+
+Phase('phase1', [
+ [History.add, history1],
+ [Sync]
+]);
+
+Phase('phase2', [
+ [History.add, history1],
+ [Sync, SYNC_WIPE_REMOTE]
+]);
+
+Phase('phase3', [
+ [Sync],
+ [History.verify, history1],
+ [History.delete, history_to_delete],
+ [History.verify, history_after_delete],
+ [History.verifyNot, history_not],
+ [Sync]
+]);
+
+Phase('phase4', [
+ [Sync],
+ [History.verify, history_after_delete],
+ [History.verifyNot, history_not]
+]);
+
diff --git a/services/sync/tests/tps/test_mozmill_sanity.js b/services/sync/tests/tps/test_mozmill_sanity.js
new file mode 100644
index 0000000000..57d3d7ad94
--- /dev/null
+++ b/services/sync/tests/tps/test_mozmill_sanity.js
@@ -0,0 +1,24 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2" };
+
+/*
+ * Test phases
+ */
+
+Phase('phase1', [
+ [RunMozmillTest, 'mozmill_sanity.js'],
+]);
+
+Phase('phase2', [
+ [Sync],
+ [RunMozmillTest, 'mozmill_sanity2.js'],
+]);
diff --git a/services/sync/tests/tps/test_passwords.js b/services/sync/tests/tps/test_passwords.js
new file mode 100644
index 0000000000..6a3ce8e1dd
--- /dev/null
+++ b/services/sync/tests/tps/test_passwords.js
@@ -0,0 +1,113 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["passwords"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1",
+ "phase4": "profile2" };
+
+/*
+ * Password asset lists: these define password entries that are used during
+ * the test
+ */
+
+// initial password list to be loaded into the browser
+var passwords_initial = [
+ { hostname: "http://www.example.com",
+ submitURL: "http://login.example.com",
+ username: "joe",
+ password: "SeCrEt123",
+ usernameField: "uname",
+ passwordField: "pword",
+ changes: {
+ password: "zippity-do-dah"
+ }
+ },
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "joe",
+ password: "secretlogin"
+ }
+];
+
+// expected state of passwords after the changes in the above list are applied
+var passwords_after_first_update = [
+ { hostname: "http://www.example.com",
+ submitURL: "http://login.example.com",
+ username: "joe",
+ password: "zippity-do-dah",
+ usernameField: "uname",
+ passwordField: "pword"
+ },
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "joe",
+ password: "secretlogin"
+ }
+];
+
+var passwords_to_delete = [
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "joe",
+ password: "secretlogin"
+ }
+];
+
+var passwords_absent = [
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "joe",
+ password: "secretlogin"
+ }
+];
+
+// expected state of passwords after the delete operation
+var passwords_after_second_update = [
+ { hostname: "http://www.example.com",
+ submitURL: "http://login.example.com",
+ username: "joe",
+ password: "zippity-do-dah",
+ usernameField: "uname",
+ passwordField: "pword"
+ }
+];
+
+/*
+ * Test phases
+ */
+
+Phase('phase1', [
+ [Passwords.add, passwords_initial],
+ [Sync]
+]);
+
+Phase('phase2', [
+ [Sync],
+ [Passwords.verify, passwords_initial],
+ [Passwords.modify, passwords_initial],
+ [Passwords.verify, passwords_after_first_update],
+ [Sync]
+]);
+
+Phase('phase3', [
+ [Sync],
+ [Passwords.verify, passwords_after_first_update],
+ [Passwords.delete, passwords_to_delete],
+ [Passwords.verify, passwords_after_second_update],
+ [Passwords.verifyNot, passwords_absent],
+ [Sync]
+]);
+
+Phase('phase4', [
+ [Sync],
+ [Passwords.verify, passwords_after_second_update],
+ [Passwords.verifyNot, passwords_absent]
+]);
diff --git a/services/sync/tests/tps/test_prefs.js b/services/sync/tests/tps/test_prefs.js
new file mode 100644
index 0000000000..3afff130da
--- /dev/null
+++ b/services/sync/tests/tps/test_prefs.js
@@ -0,0 +1,57 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["prefs"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1"};
+
+var prefs1 = [
+ { name: "browser.startup.homepage",
+ value: "http://www.getfirefox.com"
+ },
+ { name: "browser.urlbar.maxRichResults",
+ value: 20
+ },
+ { name: "privacy.clearOnShutdown.siteSettings",
+ value: true
+ }
+];
+
+var prefs2 = [
+ { name: "browser.startup.homepage",
+ value: "http://www.mozilla.com"
+ },
+ { name: "browser.urlbar.maxRichResults",
+ value: 18
+ },
+ { name: "privacy.clearOnShutdown.siteSettings",
+ value: false
+ }
+];
+
+Phase('phase1', [
+ [Prefs.modify, prefs1],
+ [Prefs.verify, prefs1],
+ [Sync],
+]);
+
+Phase('phase2', [
+ [Sync],
+ [Prefs.verify, prefs1],
+ [Prefs.modify, prefs2],
+ [Prefs.verify, prefs2],
+ [Sync]
+]);
+
+Phase('phase3', [
+ [Sync],
+ [Prefs.verify, prefs2]
+]);
+
diff --git a/services/sync/tests/tps/test_privbrw_passwords.js b/services/sync/tests/tps/test_privbrw_passwords.js
new file mode 100644
index 0000000000..ce90cc12f5
--- /dev/null
+++ b/services/sync/tests/tps/test_privbrw_passwords.js
@@ -0,0 +1,104 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["passwords"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1",
+ "phase4": "profile2" };
+
+/*
+ * Password data
+ */
+
+// Initial password data
+var passwords_initial = [
+ { hostname: "http://www.example.com",
+ submitURL: "http://login.example.com",
+ username: "joe",
+ password: "secret",
+ usernameField: "uname",
+ passwordField: "pword",
+ changes: {
+ password: "SeCrEt$$$"
+ }
+ },
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "jack",
+ password: "secretlogin"
+ }
+];
+
+// Password after first modify action has been performed
+var passwords_after_first_change = [
+ { hostname: "http://www.example.com",
+ submitURL: "http://login.example.com",
+ username: "joe",
+ password: "SeCrEt$$$",
+ usernameField: "uname",
+ passwordField: "pword",
+ changes: {
+ username: "james"
+ }
+ },
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "jack",
+ password: "secretlogin"
+ }
+];
+
+// Password after second modify action has been performed
+var passwords_after_second_change = [
+ { hostname: "http://www.example.com",
+ submitURL: "http://login.example.com",
+ username: "james",
+ password: "SeCrEt$$$",
+ usernameField: "uname",
+ passwordField: "pword"
+ },
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "jack",
+ password: "secretlogin"
+ }
+];
+
+/*
+ * Test phases
+ */
+
+Phase('phase1', [
+ [Passwords.add, passwords_initial],
+ [Sync]
+]);
+
+Phase('phase2', [
+ [Sync],
+ [Passwords.verify, passwords_initial],
+ [Passwords.modify, passwords_initial],
+ [Passwords.verify, passwords_after_first_change],
+ [Sync]
+]);
+
+Phase('phase3', [
+ [Sync],
+ [Windows.add, { private: true }],
+ [Passwords.verify, passwords_after_first_change],
+ [Passwords.modify, passwords_after_first_change],
+ [Passwords.verify, passwords_after_second_change],
+ [Sync]
+]);
+
+Phase('phase4', [
+ [Sync],
+ [Passwords.verify, passwords_after_second_change]
+]);
+
diff --git a/services/sync/tests/tps/test_privbrw_tabs.js b/services/sync/tests/tps/test_privbrw_tabs.js
new file mode 100644
index 0000000000..e7c94e9db9
--- /dev/null
+++ b/services/sync/tests/tps/test_privbrw_tabs.js
@@ -0,0 +1,87 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["tabs"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1",
+ "phase4": "profile2" };
+
+/*
+ * Tabs data
+ */
+
+var tabs1 = [
+ { uri: "data:text/html,<html><head><title>Firefox</title></head><body>Firefox</body></html>",
+ title: "Firefox",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Weave</title></head><body>Weave</body></html>",
+ title: "Weave",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Apple</title></head><body>Apple</body></html>",
+ title: "Apple",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>IRC</title></head><body>IRC</body></html>",
+ title: "IRC",
+ profile: "profile1"
+ }
+];
+
+var tabs2 = [
+ { uri: "data:text/html,<html><head><title>Tinderbox</title></head><body>Tinderbox</body></html>",
+ title: "Tinderbox",
+ profile: "profile2"
+ },
+ { uri: "data:text/html,<html><head><title>Fox</title></head><body>Fox</body></html>",
+ title: "Fox",
+ profile: "profile2"
+ }
+];
+
+var tabs3 = [
+ { uri: "data:text/html,<html><head><title>Jetpack</title></head><body>Jetpack</body></html>",
+ title: "Jetpack",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Selenium</title></head><body>Selenium</body></html>",
+ title: "Selenium",
+ profile: "profile1"
+ }
+];
+
+/*
+ * Test phases
+ */
+
+Phase('phase1', [
+ [Tabs.add, tabs1],
+ [Sync]
+]);
+
+Phase('phase2', [
+ [Sync],
+ [Tabs.verify, tabs1],
+ [Tabs.add, tabs2],
+ [Sync]
+]);
+
+Phase('phase3', [
+ [Sync],
+ [Windows.add, { private: true }],
+ [Tabs.add, tabs3],
+ [Sync]
+]);
+
+Phase('phase4', [
+ [Sync],
+ [Tabs.verifyNot, tabs3]
+]);
diff --git a/services/sync/tests/tps/test_special_tabs.js b/services/sync/tests/tps/test_special_tabs.js
new file mode 100644
index 0000000000..6e709cc1a3
--- /dev/null
+++ b/services/sync/tests/tps/test_special_tabs.js
@@ -0,0 +1,78 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Bug 532173 - Dont sync tabs like about:* , weave firstrun etc
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["tabs"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2" };
+
+var tabs1 = [
+ { uri: "data:text/html,<html><head><title>Firefox</title></head><body>Firefox</body></html>",
+ title: "Firefox",
+ profile: "profile1"
+ },
+ { uri: "about:plugins",
+ title: "About",
+ profile: "profile1"
+ },
+ { uri: "about:credits",
+ title: "Credits",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Mozilla</title></head><body>Mozilla</body></html>",
+ title: "Mozilla",
+ profile: "profile1"
+ },
+ { uri: "http://www.mozilla.com/en-US/firefox/sync/firstrun.html",
+ title: "Firstrun",
+ profile: "profile1"
+ }
+];
+
+var tabs2 = [
+ { uri: "data:text/html,<html><head><title>Firefox</title></head><body>Firefox</body></html>",
+ title: "Firefox",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Mozilla</title></head><body>Mozilla</body></html>",
+ title: "Mozilla",
+ profile: "profile1"
+ }
+];
+
+var tabs3 = [
+ { uri: "http://www.mozilla.com/en-US/firefox/sync/firstrun.html",
+ title: "Firstrun",
+ profile: "profile1"
+ },
+ { uri: "about:plugins",
+ title: "About",
+ profile: "profile1"
+ },
+ { uri: "about:credits",
+ title: "Credits",
+ profile: "profile1"
+ }
+];
+
+/*
+ * Test phases
+ */
+Phase('phase1', [
+ [Tabs.add, tabs1],
+ [Sync]
+]);
+
+Phase('phase2', [
+ [Sync],
+ [Tabs.verify, tabs2],
+ [Tabs.verifyNot, tabs3]
+]);
+
diff --git a/services/sync/tests/tps/test_sync.js b/services/sync/tests/tps/test_sync.js
new file mode 100644
index 0000000000..c9dd89cb5a
--- /dev/null
+++ b/services/sync/tests/tps/test_sync.js
@@ -0,0 +1,424 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1",
+ "phase4": "profile2" };
+
+/*
+ * Bookmark asset lists: these define bookmarks that are used during the test
+ */
+
+// the initial list of bookmarks to be added to the browser
+var bookmarks_initial = {
+ "menu": [
+ { uri: "http://www.google.com",
+ loadInSidebar: true,
+ tags: ["google", "computers", "internet", "www"],
+ changes: {
+ title: "Google",
+ loadInSidebar: false,
+ tags: ["google", "computers", "misc"],
+ }
+ },
+ { uri: "http://bugzilla.mozilla.org/show_bug.cgi?id=%s",
+ title: "Bugzilla",
+ keyword: "bz",
+ changes: {
+ keyword: "bugzilla"
+ }
+ },
+ { folder: "foldera" },
+ { uri: "http://www.mozilla.com" },
+ { separator: true },
+ { folder: "folderb" },
+ ],
+ "menu/foldera": [
+ { uri: "http://www.yahoo.com",
+ title: "testing Yahoo",
+ changes: {
+ location: "menu/folderb"
+ }
+ },
+ { uri: "http://www.cnn.com",
+ description: "This is a description of the site a at www.cnn.com",
+ changes: {
+ uri: "http://money.cnn.com",
+ description: "new description",
+ }
+ },
+ { livemark: "Livemark1",
+ feedUri: "http://rss.wunderground.com/blog/JeffMasters/rss.xml",
+ siteUri: "http://www.wunderground.com/blog/JeffMasters/show.html",
+ changes: {
+ livemark: "LivemarkOne"
+ }
+ },
+ ],
+ "menu/folderb": [
+ { uri: "http://www.apple.com",
+ tags: ["apple", "mac"],
+ changes: {
+ uri: "http://www.apple.com/iphone/",
+ title: "iPhone",
+ location: "menu",
+ position: "Google",
+ tags: []
+ }
+ }
+ ],
+ toolbar: [
+ { uri: "place:queryType=0&sort=8&maxResults=10&beginTimeRef=1&beginTime=0",
+ title: "Visited Today"
+ }
+ ]
+};
+
+// the state of bookmarks after the first 'modify' action has been performed
+// on them
+var bookmarks_after_first_modify = {
+ "menu": [
+ { uri: "http://www.apple.com/iphone/",
+ title: "iPhone",
+ before: "Google",
+ tags: []
+ },
+ { uri: "http://www.google.com",
+ title: "Google",
+ loadInSidebar: false,
+ tags: [ "google", "computers", "misc"]
+ },
+ { uri: "http://bugzilla.mozilla.org/show_bug.cgi?id=%s",
+ title: "Bugzilla",
+ keyword: "bugzilla"
+ },
+ { folder: "foldera" },
+ { uri: "http://www.mozilla.com" },
+ { separator: true },
+ { folder: "folderb",
+ changes: {
+ location: "menu/foldera",
+ folder: "Folder B",
+ description: "folder description"
+ }
+ }
+ ],
+ "menu/foldera": [
+ { uri: "http://money.cnn.com",
+ title: "http://www.cnn.com",
+ description: "new description"
+ },
+ { livemark: "LivemarkOne",
+ feedUri: "http://rss.wunderground.com/blog/JeffMasters/rss.xml",
+ siteUri: "http://www.wunderground.com/blog/JeffMasters/show.html"
+ }
+ ],
+ "menu/folderb": [
+ { uri: "http://www.yahoo.com",
+ title: "testing Yahoo"
+ }
+ ],
+ "toolbar": [
+ { uri: "place:queryType=0&sort=8&maxResults=10&beginTimeRef=1&beginTime=0",
+ title: "Visited Today"
+ }
+ ]
+};
+
+// a list of bookmarks to delete during a 'delete' action
+var bookmarks_to_delete = {
+ "menu": [
+ { uri: "http://www.google.com",
+ title: "Google",
+ loadInSidebar: false,
+ tags: [ "google", "computers", "misc" ]
+ }
+ ]
+};
+
+// the state of bookmarks after the second 'modify' action has been performed
+// on them
+var bookmarks_after_second_modify = {
+ "menu": [
+ { uri: "http://www.apple.com/iphone/",
+ title: "iPhone"
+ },
+ { uri: "http://bugzilla.mozilla.org/show_bug.cgi?id=%s",
+ title: "Bugzilla",
+ keyword: "bugzilla"
+ },
+ { folder: "foldera" },
+ { uri: "http://www.mozilla.com" },
+ { separator: true },
+ ],
+ "menu/foldera": [
+ { uri: "http://money.cnn.com",
+ title: "http://www.cnn.com",
+ description: "new description"
+ },
+ { livemark: "LivemarkOne",
+ feedUri: "http://rss.wunderground.com/blog/JeffMasters/rss.xml",
+ siteUri: "http://www.wunderground.com/blog/JeffMasters/show.html"
+ },
+ { folder: "Folder B",
+ description: "folder description"
+ }
+ ],
+ "menu/foldera/Folder B": [
+ { uri: "http://www.yahoo.com",
+ title: "testing Yahoo"
+ }
+ ]
+};
+
+// a list of bookmarks which should not be present after the last
+// 'delete' and 'modify' actions
+var bookmarks_absent = {
+ "menu": [
+ { uri: "http://www.google.com",
+ title: "Google"
+ },
+ { folder: "folderb" },
+ { folder: "Folder B" }
+ ]
+};
+
+/*
+ * History asset lists: these define history entries that are used during
+ * the test
+ */
+
+// the initial list of history items to add to the browser
+var history_initial = [
+ { uri: "http://www.google.com/",
+ title: "Google",
+ visits: [
+ { type: 1, date: 0 },
+ { type: 2, date: -1 }
+ ]
+ },
+ { uri: "http://www.cnn.com/",
+ title: "CNN",
+ visits: [
+ { type: 1, date: -1 },
+ { type: 2, date: -36 }
+ ]
+ },
+ { uri: "http://www.google.com/language_tools?hl=en",
+ title: "Language Tools",
+ visits: [
+ { type: 1, date: 0 },
+ { type: 2, date: -40 }
+ ]
+ },
+ { uri: "http://www.mozilla.com/",
+ title: "Mozilla",
+ visits: [
+ { type: 1, date: 0 },
+ { type: 1, date: -1 },
+ { type: 1, date: -20 },
+ { type: 2, date: -36 }
+ ]
+ }
+];
+
+// a list of history entries to delete during a 'delete' action
+var history_to_delete = [
+ { uri: "http://www.cnn.com/" },
+ { begin: -24,
+ end: -1 },
+ { host: "www.google.com" }
+];
+
+// the expected history entries after the first 'delete' action
+var history_after_delete = [
+ { uri: "http://www.mozilla.com/",
+ title: "Mozilla",
+ visits: [
+ { type: 1,
+ date: 0
+ },
+ { type: 2,
+ date: -36
+ }
+ ]
+ }
+];
+
+// history entries expected to not exist after a 'delete' action
+var history_absent = [
+ { uri: "http://www.google.com/",
+ title: "Google",
+ visits: [
+ { type: 1,
+ date: 0
+ },
+ { type: 2,
+ date: -1
+ }
+ ]
+ },
+ { uri: "http://www.cnn.com/",
+ title: "CNN",
+ visits: [
+ { type: 1,
+ date: -1
+ },
+ { type: 2,
+ date: -36
+ }
+ ]
+ },
+ { uri: "http://www.google.com/language_tools?hl=en",
+ title: "Language Tools",
+ visits: [
+ { type: 1,
+ date: 0
+ },
+ { type: 2,
+ date: -40
+ }
+ ]
+ },
+ { uri: "http://www.mozilla.com/",
+ title: "Mozilla",
+ visits: [
+ { type: 1,
+ date: -1
+ },
+ { type: 1,
+ date: -20
+ }
+ ]
+ }
+];
+
+/*
+ * Password asset lists: these define password entries that are used during
+ * the test
+ */
+
+// the initial list of passwords to add to the browser
+var passwords_initial = [
+ { hostname: "http://www.example.com",
+ submitURL: "http://login.example.com",
+ username: "joe",
+ password: "SeCrEt123",
+ usernameField: "uname",
+ passwordField: "pword",
+ changes: {
+ password: "zippity-do-dah"
+ }
+ },
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "joe",
+ password: "secretlogin"
+ }
+];
+
+// the expected state of passwords after the first 'modify' action
+var passwords_after_first_modify = [
+ { hostname: "http://www.example.com",
+ submitURL: "http://login.example.com",
+ username: "joe",
+ password: "zippity-do-dah",
+ usernameField: "uname",
+ passwordField: "pword"
+ },
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "joe",
+ password: "secretlogin"
+ }
+];
+
+// a list of passwords to delete during a 'delete' action
+var passwords_to_delete = [
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "joe",
+ password: "secretlogin"
+ }
+];
+
+// a list of passwords expected to be absent after 'delete' and 'modify'
+// actions
+var passwords_absent = [
+ { hostname: "http://www.example.com",
+ realm: "login",
+ username: "joe",
+ password: "secretlogin"
+ }
+];
+
+// the expected state of passwords after the seconds 'modify' action
+var passwords_after_second_modify = [
+ { hostname: "http://www.example.com",
+ submitURL: "http://login.example.com",
+ username: "joe",
+ password: "zippity-do-dah",
+ usernameField: "uname",
+ passwordField: "pword"
+ }
+];
+
+/*
+ * Test phases
+ */
+
+Phase('phase1', [
+ [Bookmarks.add, bookmarks_initial],
+ [Passwords.add, passwords_initial],
+ [History.add, history_initial],
+ [Sync],
+]);
+
+Phase('phase2', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_initial],
+ [Passwords.verify, passwords_initial],
+ [History.verify, history_initial],
+ [Bookmarks.modify, bookmarks_initial],
+ [Passwords.modify, passwords_initial],
+ [History.delete, history_to_delete],
+ [Bookmarks.verify, bookmarks_after_first_modify],
+ [Passwords.verify, passwords_after_first_modify],
+ [History.verify, history_after_delete],
+ [History.verifyNot, history_absent],
+ [Sync],
+]);
+
+Phase('phase3', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_after_first_modify],
+ [Passwords.verify, passwords_after_first_modify],
+ [History.verify, history_after_delete],
+ [Bookmarks.modify, bookmarks_after_first_modify],
+ [Passwords.modify, passwords_after_first_modify],
+ [Bookmarks.delete, bookmarks_to_delete],
+ [Passwords.delete, passwords_to_delete],
+ [Bookmarks.verify, bookmarks_after_second_modify],
+ [Passwords.verify, passwords_after_second_modify],
+ [Bookmarks.verifyNot, bookmarks_absent],
+ [Passwords.verifyNot, passwords_absent],
+ [Sync],
+]);
+
+Phase('phase4', [
+ [Sync],
+ [Bookmarks.verify, bookmarks_after_second_modify],
+ [Passwords.verify, passwords_after_second_modify],
+ [Bookmarks.verifyNot, bookmarks_absent],
+ [Passwords.verifyNot, passwords_absent],
+ [History.verifyNot, history_absent],
+]);
+
+
diff --git a/services/sync/tests/tps/test_tabs.js b/services/sync/tests/tps/test_tabs.js
new file mode 100644
index 0000000000..03f2777092
--- /dev/null
+++ b/services/sync/tests/tps/test_tabs.js
@@ -0,0 +1,59 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * The list of phases mapped to their corresponding profiles. The object
+ * here must be in strict JSON format, as it will get parsed by the Python
+ * testrunner (no single quotes, extra comma's, etc).
+ */
+EnableEngines(["tabs"]);
+
+var phases = { "phase1": "profile1",
+ "phase2": "profile2",
+ "phase3": "profile1"};
+
+/*
+ * Tab lists.
+ */
+
+var tabs1 = [
+ { uri: "http://mozqa.com/data/firefox/layout/mozilla.html",
+ title: "Mozilla",
+ profile: "profile1"
+ },
+ { uri: "data:text/html,<html><head><title>Hello</title></head><body>Hello</body></html>",
+ title: "Hello",
+ profile: "profile1"
+ }
+];
+
+var tabs2 = [
+ { uri: "http://mozqa.com/data/firefox/layout/mozilla_community.html",
+ title: "Mozilla Community",
+ profile: "profile2"
+ },
+ { uri: "data:text/html,<html><head><title>Bye</title></head><body>Bye</body></html>",
+ profile: "profile2"
+ }
+];
+
+/*
+ * Test phases
+ */
+
+Phase('phase1', [
+ [Tabs.add, tabs1],
+ [Sync]
+]);
+
+Phase('phase2', [
+ [Sync],
+ [Tabs.verify, tabs1],
+ [Tabs.add, tabs2],
+ [Sync]
+]);
+
+Phase('phase3', [
+ [Sync],
+ [Tabs.verify, tabs2]
+]);