This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resource-editor.git
commit 72b6b7bf0f2360f48a4aa82f0caebfbf1269cca1 Author: Sandro Boehme <[email protected]> AuthorDate: Tue May 12 16:35:04 2015 +0000 SLING-4555 Resource Editor: Added initial end to end tests. Now with the actual content. :-) git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1678999 13f79535-47bb-0310-9956-ffa450edef68 --- README | 3 +- .../js/tree/AddNodeController.js | 7 +- .../js/tree/JSTreeAdapter.js | 6 +- .../js/tree/TreeController.js | 9 +- .../SLING-INF/libs/sling/resource-editor/html.jsp | 2 +- src/test/javascript/e2e/spec/e2e_spec.js | 215 +++++++++++++++++---- src/test/javascript/spec/resource_editor_spec.js | 3 +- 7 files changed, 201 insertions(+), 44 deletions(-) diff --git a/README b/README index ac4e114..3695033 100644 --- a/README +++ b/README @@ -14,10 +14,11 @@ o To run the build on your local machine call './grunt desktop_build' within the o To have the less sources automatically compiled on change call `./grunt watch:less` in the frontend directory. Press Ctrl-Z to stop watching. o To have the 'desktop_build' target triggered on changes in the frontend tests, less sources, JavaScript files and JSP sources use `./grunt watch:all` in the frontend directory and also press Ctrl-Z to stop watching. o To get the end to end tests triggered by changes use './grunt watch:e2e' in the frontend directory and also press Ctrl-Z to stop watching. +o If you don't use 'localhost' as server and '8080' as port you can specify your values by using the environment variables 'SLING_SERVER' 'SLING_PORT'. ++ Debugging the the end to end tests ++ o You can still use 'console.log()' and JSON.stringify(display) to inspect JSON values of a test spec. -o You can use 'client.pause([milliseconds]);' in you test spec to pause and also inspect the browser status. +o You can use 'client.pause([milliseconds]);' in your test spec to pause and also inspect the browser status. o To set breakpoints in a test spec you can use a JavaScript IDE like 'Webstorm' diff --git a/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/AddNodeController.js b/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/AddNodeController.js index 76d8566..3c2571e 100644 --- a/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/AddNodeController.js +++ b/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/AddNodeController.js @@ -237,6 +237,7 @@ org.apache.sling.reseditor.AddNodeController = (function() { $("#nodeType").select2({ placeholder: "Select a node type", allowClear: true, + dropdownCssClass: "node_type_dd_container", selectOnBlur: true, data: function() { return { results: thatAddNodeController.nodeTypeObjects } ; // Use the global variable to populate the list @@ -261,6 +262,7 @@ org.apache.sling.reseditor.AddNodeController = (function() { var select2 = $("#resourceType").select2({ placeholder: "Enter or select a resource type", allowClear: true, + dropdownCssClass: "resource_type_dd_container", selectOnBlur: true, data: data, createSearchChoice: function(searchTerm){ @@ -268,9 +270,8 @@ org.apache.sling.reseditor.AddNodeController = (function() { return {id:searchTerm, text:searchTerm}; } }).data("select2"); - $("#resourceType").on("select2-loaded", function() { - $('#addNodeDialog').append('<div class="add-node-finished"></div>'); - }); + $('#addNodeDialog').addClass('add-node-finished'); +// $('#addNodeDialog').append('<div id="add-node-finished"></div>'); }); } diff --git a/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/JSTreeAdapter.js b/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/JSTreeAdapter.js index 26da7e0..b7338d4 100644 --- a/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/JSTreeAdapter.js +++ b/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/JSTreeAdapter.js @@ -122,11 +122,9 @@ $(document).ready(function() { "dnd" : { "drop_finish" : function () { console.log("drop"); - alert("DROP"); }, "drag_finish" : function (data) { console.log("drag"); - alert("DRAG OK"); } }, // the `plugins` array allows you to configure the active plugins on this instance @@ -167,6 +165,10 @@ $(document).ready(function() { treeController.configureKeyListeners(e); }).on('select_node.jstree', function (e, data) { ; + }).on('after_open.jstree', function(e, data){ + treeController.afterOpen(data.node); + }).on('close_node.jstree', function(e, data){ + treeController.beforeClose(data.node); }); }); diff --git a/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/TreeController.js b/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/TreeController.js index 2bd9c28..9a90bf4 100644 --- a/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/TreeController.js +++ b/src/main/resources/SLING-INF/libs/sling/resource-editor-static-content/js/tree/TreeController.js @@ -81,7 +81,14 @@ org.apache.sling.reseditor.TreeController = (function() { } } - + + TreeController.prototype.afterOpen = function(node) { + $('#'+node.id).addClass("opened"); + } + + TreeController.prototype.beforeClose = function(node) { + $('#'+node.id).removeClass("opened"); + } TreeController.prototype.openNodeTarget = function(e) { var url = $(e.target).parent().attr("href"); diff --git a/src/main/resources/SLING-INF/libs/sling/resource-editor/html.jsp b/src/main/resources/SLING-INF/libs/sling/resource-editor/html.jsp index de96aba..170e0e0 100644 --- a/src/main/resources/SLING-INF/libs/sling/resource-editor/html.jsp +++ b/src/main/resources/SLING-INF/libs/sling/resource-editor/html.jsp @@ -329,7 +329,7 @@ new org.apache.sling.reseditor.JSTreeAdapter(jsTreeAdapterSettings, treeControll <label for="nodeType">Node Type - <span class="nt-dependency-description">applicable together with node name</span> (<a class="nt-toggle" href="javascript:void(0)">show generally applicable</a>)</label> <input name="jcr:primaryType" type="hidden" id="nodeType"> </div> - <div class="form-group"> + <div class="form-group resource-type"> <label for="resourceType">Sling Resource Type</label> <input name="sling:resourceType" type="hidden" id="resourceType"> <span class="resource-type-not-allowed help-block" style="display:none;">The selected node type does not allow the resulting node to have a Sling resource type property.</span> diff --git a/src/test/javascript/e2e/spec/e2e_spec.js b/src/test/javascript/e2e/spec/e2e_spec.js index aed1721..fb9d379 100644 --- a/src/test/javascript/e2e/spec/e2e_spec.js +++ b/src/test/javascript/e2e/spec/e2e_spec.js @@ -21,59 +21,204 @@ var assert = require('assert'); -describe('A user of the Apache Sling Resource Editor', function() { - var homeURL = 'http://localhost:8080/reseditor/.html'; +describe('A user of the Apache Sling Resource Editor', function() { + // see http://stackoverflow.com/questions/29370075/how-to-pass-parameters-from-the-gruntfile-js-to-the-webdriverio-spec + var homeURL = 'http://'+process.env.SLING_SERVER+':'+process.env.SLING_PORT+'/reseditor/.html'; var client = browser.url(homeURL); - // TODO: Find a way to specify the host and the port via grunt. See - // http://stackoverflow.com/questions/29370075/how-to-pass-parameters-from-the-gruntfile-js-to-the-webdriverio-spec - client.timeouts("script", 500); + + client.timeouts("script", 1000); + client.timeouts("implicit", 1000); + client.timeouts("page load", 1000); describe('can open the add node dialog with', function() { it('the icon', function(done) { - client = client.url(homeURL); - client.waitForExist('#last-element', function(err) { - client.click('#root_anchor i.add-icon', function(err, res) { - client.waitForVisible('#addNodeDialog', function(err) { - client.getCssProperty('#addNodeDialog', 'display', function(err, display) { - assert(typeof err === "undefined" || err === null); - assert(display.value === "block"); - }); - }); - }) + client.url(homeURL).waitForExist('#last-element'). + click('#root_anchor i.add-icon').waitForVisible('#addNodeDialog', function(err, visible) { + assert(typeof err === "undefined" || err === null); + assert(true === visible); }) .call(done); }); it('the shortcut', function(done) { - client = client.url(homeURL); - client.waitForExist('#last-element', function(err) { - client.click('#root_anchor i.add-icon', function(err, res) { - client.keys("a", function(err) { - client.waitForVisible('#addNodeDialog', function(err) { - client.getCssProperty('#addNodeDialog', 'display', function(err, display) { - assert(typeof err === "undefined" || err === null); - assert(display.value === "block"); - }); - }); - }); - }) + client.url(homeURL).waitForExist('#last-element') + .click('#root_anchor i.jstree-themeicon') + .keys("c").waitForVisible('#addNodeDialog', function(err, visible) { + assert(typeof err === "undefined" || err === null); + assert(true === visible); }) .call(done); }); }); + it('can login as admin', function(done) { + client.url(homeURL).waitForExist('#last-element') + .click('#login_tab').waitForVisible('#login_submit') + .setValue('#login_form input[name="j_username"]', 'admin') + .setValue('#login_form input[name="j_password"]', 'admin') + .click('#login_submit').waitForExist('#login .logout') + .getText('#login_tab', function(err, text) { + assert(typeof err === "undefined" || err === null); + assert("Logout admin" === text); + }) + .call(done); + }); + it('can add an unstructured node to the root node', function(done) { + client.url(homeURL).waitForExist('#last-element') + .click("#root i.add-icon").waitForVisible('#addNodeDialog.add-node-finished .node_name_dd_container input') + .setValue('.node_name_dd_container input', "aTestNode") + .addValue('.node_name_dd_container input', 'Return') // presses the 'return' key + .click('#addNodeDialog .btn.btn-primary.submit').waitForExist("#root li[nodename=\"aTestNode\"]", function(err, existed) { + assert(typeof err === "undefined" || err === null); + assert(existed === true); + }) + .call(done); + }); + + it('can add a node with an encoded name on the second level ', function(done) { + client.url(homeURL).waitForExist('#last-element') + .click("#root li[nodename=\"aTestNode\"] i.add-icon").waitForVisible('#addNodeDialog.add-node-finished .node_name_dd_container input') + .setValue('.node_name_dd_container input', "täßt ?<>") + .addValue('.node_name_dd_container input', 'Return') // presses the 'return' key + .click('#addNodeDialog .btn.btn-primary.submit').waitForExist("#root li[nodename=\"aTestNode\"].opened li[nodename=\"täßt ?<>\"]", function(err, existed) { + assert(typeof err === "undefined" || err === null); + assert(existed === true); + }) + .call(done); + }); + + it('can link to a node with an encoded name', function(done) { + var encodedNodeNameSelector = '#root li[nodename="aTestNode"].opened li[nodename="täßt ?<>"]'; + var encodedNodeNameOpenSelector = encodedNodeNameSelector +' i.open-icon'; + client.url(homeURL).waitForExist('#last-element') + .click("#root li[nodename=\"aTestNode\"] i.jstree-ocl").waitForExist(encodedNodeNameOpenSelector) + .click(encodedNodeNameOpenSelector).waitForExist(encodedNodeNameSelector+' a.jstree-clicked', function(err, existed) { + assert(typeof err === "undefined" || err === null); + assert(existed === true); + }) + .call(done); + }); + + + it('can add a node with a specific node type ', function(done) { + client.url(homeURL); + client.waitForExist('#last-element').click("#root li[nodename=\"aTestNode\"] i.add-icon").waitForVisible('#addNodeDialog.add-node-finished .node_name_dd_container', 1000) + .setValue('.node_name_dd_container input', "aFolder") + .addValue('.node_name_dd_container input', 'Return') + .click(".form-group.node-type .select2-chosen").waitForExist('.node_type_dd_container input') + .setValue('.node_type_dd_container input', "sling:Folder") + .addValue('.node_type_dd_container input', 'Return') + .click('#addNodeDialog .btn.btn-primary.submit').waitForExist('#root li[nodename="aTestNode"] li[nodename="aFolder"][nodetype="sling:Folder"]', function(err, existed) { + assert(typeof err === "undefined" || err === null); + assert(existed === true); + }) + .call(done); + }); + + it('can add a node with a resource type on the second level ', function(done) { + var nodeName = "a node with a resource type"; + var resourceType = "test/resource-editor/resource-type"; + var resourceTypeSelector = '#root li[nodename="aTestNode"].opened li[nodename="a node with a resource type"] span.node-type'; + client.url(homeURL); + client.waitForExist('#last-element').click("#root li[nodename=\"aTestNode\"] i.add-icon") + .waitForVisible('#addNodeDialog.add-node-finished .node_name_dd_container', 1000) + .setValue('.node_name_dd_container input', nodeName) + .addValue('.node_name_dd_container input', 'Return') // presses the 'return' key + .click(".form-group.resource-type .select2-chosen").waitForExist('.resource_type_dd_container input', 1000) + .setValue('.resource_type_dd_container input', resourceType) + .addValue('.resource_type_dd_container input', 'Return') // presses the 'return' key + .click('#addNodeDialog .btn.btn-primary.submit').waitForExist(resourceTypeSelector, 1000) + .getText(resourceTypeSelector, function(err, text) { + assert(typeof err === "undefined" || err === null); + assert(text === resourceType); + }) + .call(done); + }); + + it('can rename a node with an encoded name', function(done) { + client = client.url(homeURL); + client.waitForExist('#last-element', function(err) { + client.click("#root li[nodename=\"aTestNode\"] i.jstree-ocl", function(err, res) { + var encodedNodeNameSelector = '#root li[nodename="aTestNode"].opened li[nodename="täßt ?<>"]'; + var encodedNodeNameAnchorSelector = encodedNodeNameSelector +' a .node-type'; +// The open node animation will take longer than 500ms thus setting 2000ms as max. + client.waitForExist(encodedNodeNameAnchorSelector, 2000, function(err, existed) { + client.doubleClick(encodedNodeNameAnchorSelector, function(err) { + var encodedNodeNameInputSelector = encodedNodeNameSelector+' input.jstree-rename-input'; + client.waitForExist(encodedNodeNameInputSelector, function(err, existed) { + client.setValue(encodedNodeNameInputSelector, 'täßt2& <>'); + client.execute(function() { + $('#root li[nodename="aTestNode"] li[nodename="täßt ?<>"] input.jstree-rename-input').blur(); + $('#root li[nodename="aTestNode"] li[nodename="täßt ?<>"] input.jstree-rename-input').blur(); + }); + client.waitForExist('#root li[nodename="aTestNode"].opened li[nodename="täßt2& <>"]', 2000, function(err, existed) { + assert(typeof err === "undefined" || err === null); + assert(true === existed); + + }); + }); + }); + }) + }) + }) + .call(done); + }); + it('can delete nodes via multi selection and shortcut', function(done) { + client = client.url(homeURL); + client + .waitForExist('#last-element').click("#root li[nodename=\"aTestNode\"] i.add-icon") + .waitForVisible('#addNodeDialog.add-node-finished').click('#addNodeDialog .btn.btn-primary.submit') + // The open node animation will take longer than 500ms thus setting 2000ms as max. + .waitForExist('#root li[nodename="aTestNode"].opened', 2000).elements('#root li[nodename="aTestNode"].opened li a .jstree-themeicon', function(err, res) { + client + .moveTo(res.value[0].ELEMENT, 0, 0) + .buttonPress('left') + .keys('Shift') + .moveTo(res.value[1].ELEMENT, 0, 0) + .buttonPress('left'); + + client.keys('Shift'); // release the Shift key + + // On Mac the ctrl key opens the context menu in the browser + // this is why the Cmd key should be used in this case. + if ('darwin' === process.platform){ + client.keys('Command'); + } else { + client.keys('Control'); + } + + client.moveTo(res.value[3].ELEMENT, 0, 0) + .buttonPress('left'); + client.keys('NULL'); // release all keys + }); + var confirmationOkBtn = 'div.bootbox-confirm div.modal-footer button[data-bb-handler="confirm"]'; + var openTestNodeIcon = '#root li[nodename=\"aTestNode\"] i.open-icon'; + client.keys('Delete') + .waitForVisible(confirmationOkBtn) + .click(confirmationOkBtn) + .waitForVisible(openTestNodeIcon) + .click(openTestNodeIcon) + .waitForExist('#last-element').elements('#root li[nodename="aTestNode"] li a .jstree-themeicon', function(err, res) { + assert(typeof err === "undefined" || err === null); + assert(1 === res.value.length); + }); + client.call(done); + + }); + + it('can delete a node with the icon', function(done) { client = client.url(homeURL); client.waitForExist('#last-element', function(err) { - client.click('#root_anchor i.add-icon', function(err, res) { - client.waitForVisible('#addNodeDialog .add-node-finished', function(err) { - client.setValue('.node_name_dd_container input', 'testnode'); - client.addValue('.node_name_dd_container input', 'Return'); // presses the 'return' key - client.click('#addNodeDialog .btn.btn-primary.submit', function(err, res) { - client.pause(3000); + client.click('li[nodetype="rep:root"] li[nodename="aTestNode"] a i.remove-icon', function(err, res) { + client.waitForText('div.bootbox-confirm div.bootbox-body', function(err, result, third, fourth){ + client.click('div.bootbox-confirm div.modal-footer button[data-bb-handler="confirm"]', function(err, res) { + client.waitForExist('li[nodetype="rep:root"] li[nodename="aTestNode"]', true/*reverse*/, function(err, existed) { + assert(typeof err === "undefined" || err === null); + assert(existed === false); + }); }); - }); - + }); }) }) .call(done); diff --git a/src/test/javascript/spec/resource_editor_spec.js b/src/test/javascript/spec/resource_editor_spec.js index 636d888..f53a5f1 100644 --- a/src/test/javascript/spec/resource_editor_spec.js +++ b/src/test/javascript/spec/resource_editor_spec.js @@ -21,9 +21,10 @@ describe('The Resource Editor', function() { it('\'s MainController', function() { // it('can encode a URL', function() { + // Mock it! // var ntManager = new de.sandroboehme.NodeTypeManager(); var mainControllerSettings = { - contextPath: "/", + contextPath: "/"//, // nodeTypes: ntManager.getNodeTypeNames() }; var mainController = new org.apache.sling.reseditor.MainController(mainControllerSettings, null); -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
