mirror of
https://github.com/xodio/xod.git
synced 2026-03-24 17:46:56 +01:00
Merge pull request #823 from xodio/fix-818-delete-patch
Fix crashing of IDE on patch delete
This commit is contained in:
@@ -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,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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('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'))
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 },
|
||||
|
||||
Reference in New Issue
Block a user