Merge pull request #823 from xodio/fix-818-delete-patch

Fix crashing of IDE on patch delete
This commit is contained in:
Kirill Shumilov
2017-10-20 12:31:39 +03:00
committed by GitHub
4 changed files with 107 additions and 58 deletions

View File

@@ -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
//-----------------------------------------------------------------------------
@@ -174,6 +205,12 @@ function assertActiveTabHasTitle(client, expectedTitle) {
);
}
function assertTabWithTitleDoesNotExist(client, expectedTitle) {
return assert.eventually.isFalse(
client.isExisting(`.tab-name=${expectedTitle}`)
);
}
//-----------------------------------------------------------------------------
// API
//-----------------------------------------------------------------------------
@@ -182,8 +219,10 @@ function assertActiveTabHasTitle(client, expectedTitle) {
const API = {
addNode,
assertActiveTabHasTitle,
assertTabWithTitleDoesNotExist,
assertNoPopups,
assertNodeAvailableInProjectBrowser,
assertNodeUnavailableInProjectBrowser,
assertPatchGroupCollapsed,
assertPatchGroupExpanded,
assertPatchSelected,
@@ -194,6 +233,7 @@ const API = {
clickAddNodeButton,
clickAddPatch,
confirmPopup,
closePopup,
dragNode,
findInspectorWidget,
findLink,
@@ -205,6 +245,8 @@ const API = {
scrollTo,
scrollToPatchInProjectBrowser,
selectPatchInProjectBrowser,
openPatchFromProjectBrowser,
deletePatch,
};
/**

View File

@@ -176,5 +176,18 @@ describe('IDE', () => {
.then(() => page.getCodeboxValue())
.then(code => assert.strictEqual(code, expectedCpp, 'Actual and expected C++ dont match'))
);
it('closes show code popup', () =>
page.closePopup()
);
});
describe('deleting a patch', () => {
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'))
);
});
});

View File

@@ -229,21 +229,26 @@ 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(
(tabId, state) => {
if (!isTabOpened(tabId, state)) return state;
const tabToClose = getTabById(tabId, state);
const isDebuggerTabClosing = () => (tabToClose.type === TAB_TYPES.DEBUGGER);
@@ -254,6 +259,7 @@ const closeTabById = R.curry(
);
const openOriginalPatch = patchPath => R.compose(
clearSelection,
R.converge(
setTabOffset(tabToClose.offset),
[
@@ -265,10 +271,6 @@ const closeTabById = R.curry(
);
return R.compose(
R.when(
isCurrentDebuggerTabClosing,
clearSelection
),
R.cond([
[isCurrentDebuggerTabClosing, openOriginalPatch(tabToClose.patchPath)],
[isCurrentTabClosing, openLatestOpenedTab],
@@ -279,10 +281,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);

View File

@@ -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 },