diff --git a/src/lib/blocks.js b/src/lib/blocks.js index 39a8c70e6209d3682f615f3804c1a2bdfd7426ca..bbaf7a61157e7ad1322e7ea760def67b84bbe92c 100644 --- a/src/lib/blocks.js +++ b/src/lib/blocks.js @@ -67,7 +67,11 @@ export default function (vm) { const cloneMenu = function () { if (vm.editingTarget && vm.editingTarget.isStage) { - return spriteMenu(); + const menu = spriteMenu(); + if (menu.length === 0) { + return [['', '']]; // Empty menu matches Scratch 2 behavior + } + return menu; } return [['myself', '_myself_']].concat(spriteMenu()); }; diff --git a/test/integration/test.js b/test/integration/test.js index 57feb8e085effb080c5bd20731116e2ae7d46b37..eaf11ead1fc769ba407cb07c373db13865946d2b 100644 --- a/test/integration/test.js +++ b/test/integration/test.js @@ -163,4 +163,18 @@ describe('costumes, sounds and variables', () => { const logs = await getLogs(errorWhitelist); await expect(logs).toEqual([]); }); + + test('Deleting only sprite does not crash', async () => { + const spriteTileContext = '*[starts-with(@class,"react-contextmenu-wrapper")]'; + await loadUri(uri); + await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation + await rightClickText('Sprite1', spriteTileContext); + await clickText('delete', spriteTileContext); + await driver.switchTo().alert() + .accept(); + // Confirm that the stage has been switched to + await findByText('Stage selected: no motion blocks'); + const logs = await getLogs(errorWhitelist); + await expect(logs).toEqual([]); + }); });