From b035c2eb67f33c9de9a20eaf96e9dda852841d71 Mon Sep 17 00:00:00 2001 From: Kirill Shumilov Date: Wed, 18 Oct 2017 16:39:54 +0300 Subject: [PATCH 1/4] fix(xod-client): fix deleting of patch --- packages/xod-client/src/editor/reducer.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/xod-client/src/editor/reducer.js b/packages/xod-client/src/editor/reducer.js index bf6388e8..c1204bd7 100644 --- a/packages/xod-client/src/editor/reducer.js +++ b/packages/xod-client/src/editor/reducer.js @@ -70,6 +70,11 @@ const getCurrentTab = R.converge( ] ); +const getCurrentPatchPath = R.compose( + R.prop('patchPath'), + getCurrentTab +); + const getBreadcrumbs = R.compose( R.prop('breadcrumbs'), getCurrentTab @@ -244,6 +249,8 @@ const openLatestOpenedTab = R.converge( const closeTabById = R.curry( (tabId, state) => { + if (!isTabOpened(tabId, state)) return state; + const tabToClose = getTabById(tabId, state); const isDebuggerTabClosing = () => (tabToClose.type === TAB_TYPES.DEBUGGER); @@ -254,6 +261,7 @@ const closeTabById = R.curry( ); const openOriginalPatch = patchPath => R.compose( + clearSelection, R.converge( setTabOffset(tabToClose.offset), [ @@ -265,10 +273,6 @@ const closeTabById = R.curry( ); return R.compose( - R.when( - isCurrentDebuggerTabClosing, - clearSelection - ), R.cond([ [isCurrentDebuggerTabClosing, openOriginalPatch(tabToClose.patchPath)], [isCurrentTabClosing, openLatestOpenedTab], @@ -279,10 +283,12 @@ const closeTabById = R.curry( } ); -const closeTabByPatchPath = (patchPath, state) => { - const tabIdToClose = getTabIdbyPatchPath(patchPath, state); - return closeTabById(tabIdToClose, state); -}; +const closeTabByPatchPath = R.curry( + (patchPath, state) => { + const tabIdToClose = getTabIdbyPatchPath(patchPath, state); + return closeTabById(tabIdToClose, state); + } +); const renamePatchInTabs = (newPatchPath, oldPatchPath, state) => { const tabIdToRename = getTabIdbyPatchPath(oldPatchPath, state); From 10921e6a3427d879f6dc42c05b273775c31dffae Mon Sep 17 00:00:00 2001 From: Kirill Shumilov Date: Wed, 18 Oct 2017 18:55:07 +0300 Subject: [PATCH 2/4] test(xod-client-electron): add functional test for deleting patch --- .../test-func/pageObject.js | 93 +++++++++++++------ .../test-func/suite.spec.js | 13 +++ 2 files changed, 77 insertions(+), 29 deletions(-) diff --git a/packages/xod-client-electron/test-func/pageObject.js b/packages/xod-client-electron/test-func/pageObject.js index 9d54f3d1..7ecf217f 100644 --- a/packages/xod-client-electron/test-func/pageObject.js +++ b/packages/xod-client-electron/test-func/pageObject.js @@ -17,6 +17,37 @@ function scrollTo(client, containerSelector, childSelector) { }, containerSelector, childSelector); } + +// ----------------------------------------------------------------------------- +// Popup dialogs +//----------------------------------------------------------------------------- +function findPopup(client) { + return client.element('.PopupPrompt'); +} + +function assertPopupShown(client, title) { + return Promise.all([ + assert.eventually.isTrue(findPopup(client).isVisible()), + assert.eventually.strictEqual(findPopup(client).getText('h2'), title), + ]); +} + +function assertNoPopups(client) { + return assert.eventually.isFalse(findPopup(client).isVisible()); +} + +function confirmPopup(client) { + return findPopup(client).click('button.Button--primary'); +} + +function getCodeboxValue(client) { + return client.getValue('.Codebox'); +} + +function closePopup(client) { + return client.element('.skylight-close-button').click(); +} + //----------------------------------------------------------------------------- // Project browser //----------------------------------------------------------------------------- @@ -37,20 +68,30 @@ function findPatchGroup(client, groupTitle) { function assertPatchGroupCollapsed(client, groupTitle) { return assert.eventually.include( findPatchGroup(client, groupTitle).getAttribute('class'), - 'is-closed' + 'is-closed', + `Expected patch group "${groupTitle}" to be collapsed, but it's expanded` ); } function assertPatchGroupExpanded(client, groupTitle) { return assert.eventually.include( findPatchGroup(client, groupTitle).getAttribute('class'), - 'is-open' + 'is-open', + `Expected patch group "${groupTitle}" to be expanded, but it's collapsed` ); } function assertNodeAvailableInProjectBrowser(client, nodeName) { return assert.eventually.isTrue( - findProjectBrowser(client).isVisible(getSelectorForPatchInProjectBrowser(nodeName)) + findProjectBrowser(client).isVisible(getSelectorForPatchInProjectBrowser(nodeName)), + `Expected node "${nodeName}" to be available in the project browser` + ); +} + +function assertNodeUnavailableInProjectBrowser(client, nodeName) { + return assert.eventually.isFalse( + findProjectBrowser(client).isVisible(getSelectorForPatchInProjectBrowser(nodeName)), + `Expected node "${nodeName}" to be unavailable in the project browser` ); } @@ -66,6 +107,14 @@ function selectPatchInProjectBrowser(client, name) { return client.click(getSelectorForPatchInProjectBrowser(name)); } +function openPatchFromProjectBrowser(client, name) { + return client.doubleClick(getSelectorForPatchInProjectBrowser(name)); +} + +function clickDeletePatchButton(client, name) { + return client.click(`${getSelectorForPatchInProjectBrowser(name)} span[title="Delete patch"]`); +} + function assertPatchSelected(client, name) { return assert.eventually.include( client.element(getSelectorForPatchInProjectBrowser(name)).getAttribute('class'), @@ -107,6 +156,14 @@ function addNode(client, type, dragX, dragY) { .then(() => dragNode(client, type, dragX, dragY)); } +function deletePatch(client, type) { + return client.waitForVisible(getSelectorForPatchInProjectBrowser(type)) + .then(() => scrollToPatchInProjectBrowser(client, type)) + .then(() => selectPatchInProjectBrowser(client, type)) + .then(() => clickDeletePatchButton(client, type)) + .then(() => findProjectBrowser(client).click('.PopupConfirm button.Button--primary')); +} + function assertPinIsSelected(client, nodeType, pinLabel) { return assert.eventually.include( findPin(client, nodeType, pinLabel).getAttribute('class'), @@ -138,32 +195,6 @@ function bindValue(client, nodeType, pinLabel, value) { ); } -// ----------------------------------------------------------------------------- -// Popup dialogs -//----------------------------------------------------------------------------- -function findPopup(client) { - return client.element('.PopupPrompt'); -} - -function assertPopupShown(client, title) { - return Promise.all([ - assert.eventually.isTrue(findPopup(client).isVisible()), - assert.eventually.strictEqual(findPopup(client).getText('h2'), title), - ]); -} - -function assertNoPopups(client) { - return assert.eventually.isFalse(findPopup(client).isVisible()); -} - -function confirmPopup(client) { - return findPopup(client).click('button.Button--primary'); -} - -function getCodeboxValue(client) { - return client.getValue('.Codebox'); -} - //----------------------------------------------------------------------------- // Tabs //----------------------------------------------------------------------------- @@ -184,6 +215,7 @@ const API = { assertActiveTabHasTitle, assertNoPopups, assertNodeAvailableInProjectBrowser, + assertNodeUnavailableInProjectBrowser, assertPatchGroupCollapsed, assertPatchGroupExpanded, assertPatchSelected, @@ -194,6 +226,7 @@ const API = { clickAddNodeButton, clickAddPatch, confirmPopup, + closePopup, dragNode, findInspectorWidget, findLink, @@ -205,6 +238,8 @@ const API = { scrollTo, scrollToPatchInProjectBrowser, selectPatchInProjectBrowser, + openPatchFromProjectBrowser, + deletePatch, }; /** diff --git a/packages/xod-client-electron/test-func/suite.spec.js b/packages/xod-client-electron/test-func/suite.spec.js index 29f9e089..5bfded70 100644 --- a/packages/xod-client-electron/test-func/suite.spec.js +++ b/packages/xod-client-electron/test-func/suite.spec.js @@ -176,5 +176,18 @@ describe('IDE', () => { .then(() => page.getCodeboxValue()) .then(code => assert.strictEqual(code, expectedCpp, 'Actual and expected C++ don’t match')) ); + it('closes show code popup', () => + page.closePopup() + ); + }); + + describe('deleting a patch', () => { + it('opens patch from xod/core', () => + page.openPatchFromProjectBrowser('clock') + .then(() => page.findPatchGroup('welcome-to-xod').click()) + .then(() => page.assertPatchGroupExpanded('welcome-to-xod')) + .then(() => page.deletePatch('my-blink')) + .then(() => page.assertNodeUnavailableInProjectBrowser('my-blink')) + ); }); }); From f391af87c530b0024f7c1d27b9401d2ef4e0ac5c Mon Sep 17 00:00:00 2001 From: Kirill Shumilov Date: Thu, 19 Oct 2017 13:23:37 +0300 Subject: [PATCH 3/4] feat(xod-client): make possible to delete current patch, and it will close current tab too --- packages/xod-client/src/editor/reducer.js | 30 +++++++++---------- .../xod-client/src/projectBrowser/actions.js | 10 ------- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/packages/xod-client/src/editor/reducer.js b/packages/xod-client/src/editor/reducer.js index c1204bd7..2ebaa990 100644 --- a/packages/xod-client/src/editor/reducer.js +++ b/packages/xod-client/src/editor/reducer.js @@ -70,11 +70,6 @@ const getCurrentTab = R.converge( ] ); -const getCurrentPatchPath = R.compose( - R.prop('patchPath'), - getCurrentTab -); - const getBreadcrumbs = R.compose( R.prop('breadcrumbs'), getCurrentTab @@ -234,17 +229,20 @@ const openPatchByPath = R.curry( } ); -const openLatestOpenedTab = R.converge( - R.assoc('currentTabId'), - [ - R.compose( // get patch id from last of remaining tabs - R.propOr(null, 'id'), - R.last, - R.values, - R.prop('tabs') - ), - R.identity, - ] +const openLatestOpenedTab = R.compose( + clearSelection, + R.converge( + R.assoc('currentTabId'), + [ + R.compose( // get patch id from last of remaining tabs + R.propOr(null, 'id'), + R.last, + R.values, + R.prop('tabs') + ), + R.identity, + ] + ) ); const closeTabById = R.curry( diff --git a/packages/xod-client/src/projectBrowser/actions.js b/packages/xod-client/src/projectBrowser/actions.js index 4583f464..61421a85 100644 --- a/packages/xod-client/src/projectBrowser/actions.js +++ b/packages/xod-client/src/projectBrowser/actions.js @@ -11,13 +11,9 @@ import { import { getSelectedPatchPath } from './selectors'; import { isPatchEmpty } from './utils'; -import { getCurrentPatchPath } from '../editor/selectors'; -import { addError } from '../messages/actions'; import { deletePatch } from '../project/actions'; -import { PROJECT_BROWSER_ERRORS } from '../messages/constants'; - export const requestCreatePatch = () => ({ type: PATCH_CREATE_REQUESTED, }); @@ -40,12 +36,6 @@ export const requestDeletePatch = patchPath => (dispatch, getState) => { return; } - const currentPatchPath = getCurrentPatchPath(state); - if (selectedPatchPath === currentPatchPath) { - dispatch(addError(PROJECT_BROWSER_ERRORS.CANT_DELETE_CURRENT_PATCH)); - return; - } - dispatch({ type: PATCH_DELETE_REQUESTED, payload: { patchPath: selectedPatchPath }, From 50d56c999ac1a1843d6f21fe5578a92416e74a8e Mon Sep 17 00:00:00 2001 From: Kirill Shumilov Date: Thu, 19 Oct 2017 13:24:28 +0300 Subject: [PATCH 4/4] test(xod-client-electron): tweak func test for deleting patch, that checks that tab is removed too --- packages/xod-client-electron/test-func/pageObject.js | 7 +++++++ packages/xod-client-electron/test-func/suite.spec.js | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/xod-client-electron/test-func/pageObject.js b/packages/xod-client-electron/test-func/pageObject.js index 7ecf217f..ebffa087 100644 --- a/packages/xod-client-electron/test-func/pageObject.js +++ b/packages/xod-client-electron/test-func/pageObject.js @@ -205,6 +205,12 @@ function assertActiveTabHasTitle(client, expectedTitle) { ); } +function assertTabWithTitleDoesNotExist(client, expectedTitle) { + return assert.eventually.isFalse( + client.isExisting(`.tab-name=${expectedTitle}`) + ); +} + //----------------------------------------------------------------------------- // API //----------------------------------------------------------------------------- @@ -213,6 +219,7 @@ function assertActiveTabHasTitle(client, expectedTitle) { const API = { addNode, assertActiveTabHasTitle, + assertTabWithTitleDoesNotExist, assertNoPopups, assertNodeAvailableInProjectBrowser, assertNodeUnavailableInProjectBrowser, diff --git a/packages/xod-client-electron/test-func/suite.spec.js b/packages/xod-client-electron/test-func/suite.spec.js index 5bfded70..d54b44b6 100644 --- a/packages/xod-client-electron/test-func/suite.spec.js +++ b/packages/xod-client-electron/test-func/suite.spec.js @@ -182,12 +182,12 @@ describe('IDE', () => { }); describe('deleting a patch', () => { - it('opens patch from xod/core', () => - page.openPatchFromProjectBrowser('clock') - .then(() => page.findPatchGroup('welcome-to-xod').click()) + it('deletes "my-blink" patch', () => + page.findPatchGroup('welcome-to-xod').click() .then(() => page.assertPatchGroupExpanded('welcome-to-xod')) .then(() => page.deletePatch('my-blink')) .then(() => page.assertNodeUnavailableInProjectBrowser('my-blink')) + .then(() => page.assertTabWithTitleDoesNotExist('my-blink')) ); }); });