1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Merge pull request #2475 from kazuhitoyokoi/master-adduitest

Add UI test case for error handling
This commit is contained in:
Nick O'Leary 2020-02-25 14:10:38 +00:00 committed by GitHub
commit 3d6170be5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 341 additions and 5 deletions

View File

@ -18,11 +18,16 @@ var idMap = {
// common
"inject": ".red-ui-palette-node[data-palette-type='inject']",
"debug": ".red-ui-palette-node[data-palette-type='debug']",
"complete": ".red-ui-palette-node[data-palette-type='complete']",
"catch": ".red-ui-palette-node[data-palette-type='catch']",
"status": ".red-ui-palette-node[data-palette-type='status']",
"comment": ".red-ui-palette-node[data-palette-type='comment']",
// function
"function": ".red-ui-palette-node[data-palette-type='function']",
"change": ".red-ui-palette-node[data-palette-type='change']",
"range": ".red-ui-palette-node[data-palette-type='range']",
"template": ".red-ui-palette-node[data-palette-type='template']",
"delay": ".red-ui-palette-node[data-palette-type='delay']",
// network
"mqttIn": ".red-ui-palette-node[data-palette-type='mqtt in']",
"mqttOut": ".red-ui-palette-node[data-palette-type='mqtt out']",
@ -30,8 +35,9 @@ var idMap = {
"httpResponse": ".red-ui-palette-node[data-palette-type='http response']",
"httpRequest": ".red-ui-palette-node[data-palette-type='http request']",
// sequence
"join": ".red-ui-palette-node[data-palette-type='join']",
"split": ".red-ui-palette-node[data-palette-type='split']",
"join": ".red-ui-palette-node[data-palette-type='join']",
"batch": ".red-ui-palette-node[data-palette-type='batch']",
// parser
"csv": ".red-ui-palette-node[data-palette-type='csv']",
"html": ".red-ui-palette-node[data-palette-type='html']",

View File

@ -33,6 +33,8 @@ debugNode.prototype.setOutput = function (complete) {
// Select the "msg" type.
browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options")][1]/a[1]');
// Input the path in msg.
browser.clickWithWait('//*[contains(@class, "red-ui-typedInput-input")]/input');
browser.keys(Array('payload'.length).fill('Backspace'));
browser.setValue('//*[contains(@class, "red-ui-typedInput-input")]/input', complete);
} else {
// Select the "complete msg object" type.

View File

@ -0,0 +1,47 @@
/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var util = require('util');
var nodePage = require('../../node_page');
function completeNode(id) {
nodePage.call(this, id);
}
util.inherits(completeNode, nodePage);
completeNode.prototype.setScope = function (scope) {
if (scope) {
browser.clickWithWait('//*[@id="node-input-complete-target-select"]');
browser.pause(1000);
if (Array.isArray(scope)) {
for (var i = 0; i < scope.length; i++) {
browser.moveToObject(scope[i].id);
browser.buttonDown();
browser.buttonUp();
}
} else {
browser.moveToObject(scope.id);
browser.buttonDown();
browser.buttonUp();
}
browser.clickWithWait('//*[contains(@class, "red-ui-notification")]/div/button[2]');
browser.pause(1000);
}
}
module.exports = completeNode;

View File

@ -0,0 +1,48 @@
/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var util = require('util');
var nodePage = require('../../node_page');
function catchNode(id) {
nodePage.call(this, id);
}
util.inherits(catchNode, nodePage);
catchNode.prototype.setScope = function (scope) {
if (scope) {
browser.selectWithWait('#node-input-scope-select', 'target');
browser.clickWithWait('//*[@id="node-input-catch-target-select"]');
browser.pause(1000);
if (Array.isArray(scope)) {
for (var i = 0; i < scope.length; i++) {
browser.moveToObject(scope[i].id);
browser.buttonDown();
browser.buttonUp();
}
} else {
browser.moveToObject(scope.id);
browser.buttonDown();
browser.buttonUp();
}
browser.clickWithWait('//*[contains(@class, "red-ui-notification")]/div/button[2]');
browser.pause(1000);
}
}
module.exports = catchNode;

View File

@ -0,0 +1,48 @@
/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var util = require('util');
var nodePage = require('../../node_page');
function statusNode(id) {
nodePage.call(this, id);
}
util.inherits(statusNode, nodePage);
statusNode.prototype.setScope = function (scope) {
if (scope) {
browser.selectWithWait('#node-input-scope-select', 'target');
browser.clickWithWait('//*[@id="node-input-status-target-select"]');
browser.pause(1000);
if (Array.isArray(scope)) {
for (var i = 0; i < scope.length; i++) {
browser.moveToObject(scope[i].id);
browser.buttonDown();
browser.buttonUp();
}
} else {
browser.moveToObject(scope.id);
browser.buttonDown();
browser.buttonUp();
}
browser.clickWithWait('//*[contains(@class, "red-ui-notification")]/div/button[2]');
browser.pause(1000);
}
}
module.exports = statusNode;

View File

@ -0,0 +1,27 @@
/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var util = require('util');
var nodePage = require('../../node_page');
function commentNode(id) {
nodePage.call(this, id);
}
util.inherits(commentNode, nodePage);
module.exports = commentNode;

View File

@ -0,0 +1,33 @@
/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var util = require("util");
var nodePage = require("../../node_page");
var keyPage = require("../../../util/key_page");
function delayNode(id) {
nodePage.call(this, id);
}
util.inherits(delayNode, nodePage);
delayNode.prototype.setTimeout = function (timeout) {
browser.setValue('//*[@id="node-input-timeout"]', timeout);
}
module.exports = delayNode;

View File

@ -18,13 +18,13 @@ var util = require('util');
var nodePage = require('../../node_page');
function joinNode(id) {
function splitNode(id) {
nodePage.call(this, id);
}
util.inherits(joinNode, nodePage);
util.inherits(splitNode, nodePage);
module.exports = joinNode;
module.exports = splitNode;
function joinNode(id) {
nodePage.call(this, id);

View File

@ -0,0 +1,39 @@
/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var util = require('util');
var nodePage = require('../../node_page');
function batchNode(id) {
nodePage.call(this, id);
}
batchNode.prototype.setMode = function (mode) {
browser.selectWithWait('#node-input-mode', mode);
}
batchNode.prototype.setCount = function (count) {
browser.setValue('#node-input-count', count);
}
batchNode.prototype.setOverlap = function (overlap) {
browser.setValue('#node-input-overlap', overlap);
}
util.inherits(batchNode, nodePage);
module.exports = batchNode;

View File

@ -16,10 +16,15 @@
var injectNode = require('./core/common/20-inject_page');
var debugNode = require('./core/common/21-debug_page');
var completeNode = require('./core/common/24-complete_page');
var catchNode = require('./core/common/25-catch_page');
var statusNode = require('./core/common/25-status_page');
var commentNode = require('./core/common/90-comment_page');
var functionNode = require('./core/function/10-function_page');
var changeNode = require('./core/function/15-change_page');
var rangeNode = require('./core/function/16-range_page');
var templateNode = require('./core/function/80-template_page');
var delayNode = require('./core/function/89-delay_page');
var mqttInNode = require('./core/network/10-mqttin_page');
var mqttOutNode = require('./core/network/10-mqttout_page');
var httpInNode = require('./core/network/21-httpin_page');
@ -27,6 +32,7 @@ var httpResponseNode = require('./core/network/21-httpresponse_page');
var httpRequestNode = require('./core/network/21-httprequest_page');
var splitNode = require('./core/sequence/17-split_page');
var joinNode = require('./core/sequence/17-split_page');
var batchNode = require('./core/sequence/19-batch_page');
var csvNode = require('./core/parsers/70-CSV_page');
var htmlNode = require('./core/parsers/70-HTML_page');
var jsonNode = require('./core/parsers/70-JSON_page');
@ -38,11 +44,16 @@ var nodeCatalog = {
// common
"inject": injectNode,
"debug": debugNode,
"complete": completeNode,
"catch": catchNode,
"status": statusNode,
"comment": commentNode,
// function
"function": functionNode,
"change": changeNode,
"range": rangeNode,
"template": templateNode,
"delay": delayNode,
// network
"mqttIn": mqttInNode,
"mqttOut": mqttOutNode,
@ -52,6 +63,7 @@ var nodeCatalog = {
// sequence
"split": splitNode,
"join": joinNode,
"batch": batchNode,
// parser
"csv": csvNode,
"html": htmlNode,

View File

@ -0,0 +1,74 @@
/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var when = require('when');
var should = require('should');
var fs = require('fs-extra');
var helper = require('../../editor_helper');
var debugTab = require('../../pageobjects/editor/debugTab_page');
var workspace = require('../../pageobjects/editor/workspace_page');
var specUtil = require('../../pageobjects/util/spec_util_page');
var httpNodeRoot = '/api';
// https://cookbook.nodered.org/
describe('cookbook', function () {
beforeEach(function () {
workspace.init();
});
before(function () {
helper.startServer();
});
after(function () {
helper.stopServer();
});
describe('messages', function () {
it('trigger a flow when a node throws an error', function () {
var injectNode = workspace.addNode('inject');
var functionNode = workspace.addNode('function');
var catchNode = workspace.addNode('catch', 0 , 80);
var debugNode = workspace.addNode('debug');
functionNode.edit();
functionNode.setFunction('node.error("an example error", msg);');
functionNode.clickOk();
catchNode.edit();
catchNode.setScope(functionNode);
catchNode.clickOk();
debugNode.edit();
debugNode.setOutput('error');
debugNode.clickOk();
injectNode.connect(functionNode);
catchNode.connect(debugNode);
workspace.deploy();
debugTab.open();
injectNode.clickLeftButton();
debugTab.getMessage().should.eql(['"an example error"', 'function']);
});
// skip this case since the flow outputs random results.
it.skip('automatically retry an action after an error');
});
});

View File

@ -190,7 +190,7 @@ describe('cookbook', function () {
httpRequestNode.clickOk();
debugNode.edit();
debugNode.setOutput('.title');
debugNode.setOutput('payload.title');
debugNode.clickOk();
injectNode.connect(changeNodeSetPost);