diff --git a/package.json b/package.json
index e6ef75b48fa2c4d5088cf11f88ad7a0dc3208a2b..5532e798bbba4df7ed6393ebae9a6be11814e523 100644
--- a/package.json
+++ b/package.json
@@ -37,7 +37,7 @@
     "babel-preset-es2015": "^6.22.0",
     "babel-preset-react": "^6.22.0",
     "buffer-loader": "0.0.1",
-    "chromedriver": "2.34.1",
+    "chromedriver": "2.35.0",
     "classnames": "2.2.5",
     "copy-webpack-plugin": "^4.3.0",
     "css-loader": "^0.28.7",
diff --git a/test/helpers/selenium-helper.js b/test/helpers/selenium-helper.js
index 44064d5bda1effd5d29eb51f06aab0a5fec6d81f..c8ead90725e7197bf1ab966e94d05a7145ae88e5 100644
--- a/test/helpers/selenium-helper.js
+++ b/test/helpers/selenium-helper.js
@@ -21,6 +21,17 @@ class SeleniumHelper {
         ]);
     }
 
+    get scope () {
+        // List of useful xpath scopes for finding elements
+        return {
+            blocksTab: "*[@id='react-tabs-1']",
+            modal: '*[@class="ReactModalPortal"]',
+            reportedValue: '*[@class="blocklyDropDownContent"]',
+            soundsTab: "*[@id='react-tabs-5']",
+            spriteTile: '*[starts-with(@class,"react-contextmenu-wrapper")]'
+        };
+    }
+
     getDriver () {
         this.driver = new webdriver.Builder()
             .forBrowser('chrome')
@@ -70,6 +81,12 @@ class SeleniumHelper {
     }
 
     getLogs (whitelist) {
+        if (!whitelist) {
+            // Default whitelist
+            whitelist = [
+                'The play() request was interrupted by a call to pause()'
+            ];
+        }
         return this.driver.manage()
             .logs()
             .get('browser')
diff --git a/test/integration/blocks.test.js b/test/integration/blocks.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..9f073648882d6e3cad7eb8915edb72bbc3410c95
--- /dev/null
+++ b/test/integration/blocks.test.js
@@ -0,0 +1,106 @@
+import path from 'path';
+import SeleniumHelper from '../helpers/selenium-helper';
+
+const {
+    clickText,
+    clickButton,
+    clickXpath,
+    findByText,
+    findByXpath,
+    getDriver,
+    getLogs,
+    loadUri,
+    scope
+} = new SeleniumHelper();
+
+const uri = path.resolve(__dirname, '../../build/index.html');
+
+let driver;
+
+describe('Working with the blocks', () => {
+    beforeAll(() => {
+        driver = getDriver();
+    });
+
+    afterAll(async () => {
+        await driver.quit();
+    });
+
+    test('Blocks report when clicked in the toolbox', async () => {
+        await loadUri(uri);
+        await clickXpath('//button[@title="tryit"]');
+        await clickText('Blocks');
+        await clickText('Operators', scope.blocksTab);
+        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
+        await clickText('join', scope.blocksTab); // Click "join <hello> <world>" block
+        await findByText('helloworld', scope.reportedValue); // Tooltip with result
+        const logs = await getLogs();
+        await expect(logs).toEqual([]);
+    });
+
+    test('Switching sprites updates the block menus', async () => {
+        await loadUri(uri);
+        await clickXpath('//button[@title="tryit"]');
+        await clickText('Sound', scope.blocksTab);
+        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
+        // "Meow" sound block should be visible
+        await findByText('Meow', scope.blocksTab);
+        await clickText('Backdrops'); // Switch to the backdrop
+        // Now "pop" sound block should be visible and motion blocks hidden
+        await findByText('pop', scope.blocksTab);
+        await clickText('Motion', scope.blocksTab);
+        await findByText('Stage selected: no motion blocks');
+
+        const logs = await getLogs();
+        await expect(logs).toEqual([]);
+    });
+
+    test('Creating variables', async () => {
+        await loadUri(uri);
+        await clickXpath('//button[@title="tryit"]');
+        await clickText('Blocks');
+        await clickText('Variables', scope.blocksTab);
+        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
+
+        // Expect a default variable "my variable" to be visible
+        await clickText('my\u00A0variable', scope.blocksTab);
+        await findByText('0', scope.reportedValue);
+
+        await clickText('Make a Variable');
+        let el = await findByXpath("//input[@placeholder='']");
+        await el.sendKeys('score');
+        await clickButton('OK');
+        await clickText('Make a Variable');
+        el = await findByXpath("//input[@placeholder='']");
+        await el.sendKeys('second variable');
+        await clickButton('OK');
+
+        // Make sure reporting works on a new variable
+        await clickText('Variables', scope.blocksTab);
+        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
+        await clickText('score', scope.blocksTab);
+        await findByText('0', scope.reportedValue); // Tooltip with result
+
+        const logs = await getLogs();
+        await expect(logs).toEqual([]);
+    });
+
+    test('Custom procedures', async () => {
+        await loadUri(uri);
+        await clickXpath('//button[@title="tryit"]');
+        await clickText('My Blocks');
+        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
+        await clickText('Make a Block');
+        // Click on the "add an input" buttons
+        await clickText('number or text', scope.modal);
+        await clickText('boolean', scope.modal);
+        await clickText('Add a label', scope.modal);
+        await clickText('OK', scope.modal);
+
+        // Make sure a "define" block has been added to the workspace
+        await findByText('define', scope.blocksTab);
+
+        const logs = await getLogs();
+        await expect(logs).toEqual([]);
+    });
+});
diff --git a/test/integration/costumes.test.js b/test/integration/costumes.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..b19576bf2ff8ae6313b595c6b56f628fe11a762a
--- /dev/null
+++ b/test/integration/costumes.test.js
@@ -0,0 +1,49 @@
+import path from 'path';
+import SeleniumHelper from '../helpers/selenium-helper';
+
+const {
+    clickText,
+    clickXpath,
+    findByXpath,
+    getDriver,
+    getLogs,
+    loadUri
+} = new SeleniumHelper();
+
+const uri = path.resolve(__dirname, '../../build/index.html');
+
+let driver;
+
+describe('Working with costumes', () => {
+    beforeAll(() => {
+        driver = getDriver();
+    });
+
+    afterAll(async () => {
+        await driver.quit();
+    });
+
+    test('Adding a costume', async () => {
+        await loadUri(uri);
+        await clickXpath('//button[@title="tryit"]');
+        await clickText('Costumes');
+        await clickText('Add Costume');
+        const el = await findByXpath("//input[@placeholder='what are you looking for?']");
+        await el.sendKeys('abb');
+        await clickText('Abby-a'); // Should close the modal, then click the costumes in the selector
+        await findByXpath("//input[@value='Abby-a']"); // Should show editor for new costume
+        const logs = await getLogs();
+        await expect(logs).toEqual([]);
+    });
+
+    test('Adding a backdrop', async () => {
+        await loadUri(uri);
+        await clickXpath('//button[@title="tryit"]');
+        await clickText('Add Backdrop');
+        const el = await findByXpath("//input[@placeholder='what are you looking for?']");
+        await el.sendKeys('blue');
+        await clickText('Blue Sky'); // Should close the modal
+        const logs = await getLogs();
+        await expect(logs).toEqual([]);
+    });
+});
diff --git a/test/integration/examples.test.js b/test/integration/examples.test.js
index 1bf2c0f5ba539269ff7889b6d032b478be538d60..f745dc24d2c0101582e5901d581d7dd901f717d7 100644
--- a/test/integration/examples.test.js
+++ b/test/integration/examples.test.js
@@ -13,10 +13,6 @@ const {
     loadUri
 } = new SeleniumHelper();
 
-const errorWhitelist = [
-    'The play() request was interrupted by a call to pause()'
-];
-
 let driver;
 
 describe('player example', () => {
@@ -37,7 +33,7 @@ describe('player example', () => {
         await clickXpath('//img[@title="Go"]');
         await new Promise(resolve => setTimeout(resolve, 2000));
         await clickXpath('//img[@title="Stop"]');
-        const logs = await getLogs(errorWhitelist);
+        const logs = await getLogs();
         await expect(logs).toEqual([]);
     });
 });
@@ -60,7 +56,7 @@ describe('blocks example', () => {
         await clickXpath('//img[@title="Go"]');
         await new Promise(resolve => setTimeout(resolve, 2000));
         await clickXpath('//img[@title="Stop"]');
-        const logs = await getLogs(errorWhitelist);
+        const logs = await getLogs();
         await expect(logs).toEqual([]);
     });
 
@@ -82,7 +78,7 @@ describe('blocks example', () => {
         el = await findByXpath("//input[@placeholder='']");
         await el.sendKeys('second variable');
         await clickButton('OK');
-        const logs = await getLogs(errorWhitelist);
+        const logs = await getLogs();
         await expect(logs).toEqual([]);
     });
 });
diff --git a/test/integration/localization.test.js b/test/integration/localization.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..b99066a3541211ae27fac253396a31a6d206951e
--- /dev/null
+++ b/test/integration/localization.test.js
@@ -0,0 +1,49 @@
+import path from 'path';
+import SeleniumHelper from '../helpers/selenium-helper';
+
+const {
+    clickText,
+    clickXpath,
+    findByText,
+    getDriver,
+    getLogs,
+    loadUri,
+    scope
+} = new SeleniumHelper();
+
+const uri = path.resolve(__dirname, '../../build/index.html');
+
+let driver;
+
+describe('Localization', () => {
+    beforeAll(() => {
+        driver = getDriver();
+    });
+
+    afterAll(async () => {
+        await driver.quit();
+    });
+
+    // Skipped temporarily while the language selector is marked as
+    // "Coming Soon"
+    test.skip('Localization', async () => {
+        await loadUri(uri);
+        await clickXpath('//button[@title="tryit"]');
+        await clickText('Blocks');
+        await clickText('Extensions');
+        await clickText('Pen', scope.modal); // Modal closes
+        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
+        await clickText('English');
+        await clickText('Deutsch');
+        await new Promise(resolve => setTimeout(resolve, 1000)); // wait for blocks refresh
+        await clickText('Pen'); // will need to be updated when 'Pen' is translated
+
+        // Make sure "Add Sprite" has changed to "Figur hinzufügen"
+        await findByText('Figur hinzufügen');
+        // Find the stamp block in German
+        await findByText('Abdruck');
+
+        const logs = await getLogs();
+        await expect(logs).toEqual([]);
+    });
+});
diff --git a/test/integration/project-loading.test.js b/test/integration/project-loading.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..3bc4ecde03dde48b261da3fc1e9f816db8e1f6e2
--- /dev/null
+++ b/test/integration/project-loading.test.js
@@ -0,0 +1,60 @@
+import path from 'path';
+import SeleniumHelper from '../helpers/selenium-helper';
+
+const {
+    clickXpath,
+    getDriver,
+    getLogs,
+    loadUri
+} = new SeleniumHelper();
+
+const uri = path.resolve(__dirname, '../../build/index.html');
+
+let driver;
+
+describe('Loading projects by ID', () => {
+    beforeAll(() => {
+        driver = getDriver();
+    });
+
+    afterAll(async () => {
+        await driver.quit();
+    });
+
+    test('Load a project by ID', async () => {
+        const projectId = '96708228';
+        await loadUri(`${uri}#${projectId}`);
+        await clickXpath('//button[@title="tryit"]');
+        await new Promise(resolve => setTimeout(resolve, 2000));
+        await clickXpath('//img[@title="Go"]');
+        await new Promise(resolve => setTimeout(resolve, 2000));
+        await clickXpath('//img[@title="Stop"]');
+        const logs = await getLogs();
+        await expect(logs).toEqual([]);
+    });
+
+    test('Load a project by ID (fullscreen)', async () => {
+        const prevSize = driver.manage()
+            .window()
+            .getSize();
+        await new Promise(resolve => setTimeout(resolve, 2000));
+        driver.manage()
+            .window()
+            .setSize(1920, 1080);
+        const projectId = '96708228';
+        await loadUri(`${uri}#${projectId}`);
+        await clickXpath('//button[@title="tryit"]');
+        await new Promise(resolve => setTimeout(resolve, 2000));
+        await clickXpath('//img[@title="Full Screen Control"]');
+        await clickXpath('//img[@title="Go"]');
+        await new Promise(resolve => setTimeout(resolve, 2000));
+        await clickXpath('//img[@title="Stop"]');
+        prevSize.then(value => {
+            driver.manage()
+                .window()
+                .setSize(value.width, value.height);
+        });
+        const logs = await getLogs();
+        await expect(logs).toEqual([]);
+    });
+});
diff --git a/test/integration/sounds.test.js b/test/integration/sounds.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..475d2271907b234f5a595c53eca43b74b7d5fcbd
--- /dev/null
+++ b/test/integration/sounds.test.js
@@ -0,0 +1,89 @@
+import path from 'path';
+import SeleniumHelper from '../helpers/selenium-helper';
+
+const {
+    clickText,
+    clickXpath,
+    findByXpath,
+    getDriver,
+    getLogs,
+    loadUri,
+    rightClickText,
+    scope
+} = new SeleniumHelper();
+
+const uri = path.resolve(__dirname, '../../build/index.html');
+
+let driver;
+
+describe('Working with sounds', () => {
+    beforeAll(() => {
+        driver = getDriver();
+    });
+
+    afterAll(async () => {
+        await driver.quit();
+    });
+
+    test('Adding a sound', async () => {
+        await loadUri(uri);
+        await clickXpath('//button[@title="tryit"]');
+        await clickText('Sounds');
+
+        // Delete the sound
+        await rightClickText('Meow', scope.soundsTab);
+        await clickText('delete', scope.soundsTab);
+        await driver.switchTo().alert()
+            .accept();
+
+        // Add it back
+        await clickText('Add Sound');
+        let el = await findByXpath("//input[@placeholder='what are you looking for?']");
+        await el.sendKeys('meow');
+        await clickText('Meow', scope.modal); // Should close the modal
+
+        // Add a new sound
+        await clickText('Add Sound');
+        el = await findByXpath("//input[@placeholder='what are you looking for?']");
+        await el.sendKeys('chom');
+        await clickText('Chomp'); // Should close the modal, then click the sounds in the selector
+        await findByXpath("//input[@value='Chomp']"); // Should show editor for new sound
+
+        await clickXpath('//button[@title="Play"]');
+
+        await clickText('Louder');
+        await clickText('Softer');
+        await clickText('Faster');
+        await clickText('Slower');
+        await clickText('Robot');
+        await clickText('Echo');
+        await clickText('Reverse');
+
+        const logs = await getLogs();
+        await expect(logs).toEqual([]);
+    });
+
+    // Regression test for gui issue #1320
+    test('Switching sprites with different numbers of sounds', async () => {
+        await loadUri(uri);
+        await clickXpath('//button[@title="tryit"]');
+
+        // Add a sound so this sprite has 2 sounds.
+        await clickText('Sounds');
+        await clickText('Add Sound');
+        await clickText('A Bass'); // Closes the modal
+
+        // Now add a sprite with only one sound.
+        await clickText('Add Sprite');
+        await clickText('Abby'); // Doing this used to crash the editor.
+
+        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for error
+
+        // Make sure the 'Oops' screen is not visible
+        const content = await driver.getPageSource();
+        expect(content.indexOf('Oops')).toEqual(-1);
+
+        const logs = await getLogs();
+        await expect(logs).toEqual([]);
+    });
+});
diff --git a/test/integration/sprites.test.js b/test/integration/sprites.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..5e02623ee3ec026d18a26de2f784d16e24d87ee4
--- /dev/null
+++ b/test/integration/sprites.test.js
@@ -0,0 +1,41 @@
+import path from 'path';
+import SeleniumHelper from '../helpers/selenium-helper';
+
+const {
+    clickText,
+    clickXpath,
+    findByText,
+    getDriver,
+    getLogs,
+    loadUri,
+    rightClickText,
+    scope
+} = new SeleniumHelper();
+
+const uri = path.resolve(__dirname, '../../build/index.html');
+
+let driver;
+
+describe('Working with sprites', () => {
+    beforeAll(() => {
+        driver = getDriver();
+    });
+
+    afterAll(async () => {
+        await driver.quit();
+    });
+
+    test('Deleting only sprite does not crash', async () => {
+        await loadUri(uri);
+        await clickXpath('//button[@title="tryit"]');
+        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
+        await rightClickText('Sprite1', scope.spriteTile);
+        await clickText('delete', scope.spriteTile);
+        await driver.switchTo().alert()
+            .accept();
+        // Confirm that the stage has been switched to
+        await findByText('Stage selected: no motion blocks');
+        const logs = await getLogs();
+        await expect(logs).toEqual([]);
+    });
+});
diff --git a/test/integration/test.js b/test/integration/test.js
deleted file mode 100644
index 7fa5cadb6e0161b16545f2c334f34d20a995322e..0000000000000000000000000000000000000000
--- a/test/integration/test.js
+++ /dev/null
@@ -1,299 +0,0 @@
-import path from 'path';
-import SeleniumHelper from '../helpers/selenium-helper';
-
-const {
-    clickText,
-    clickButton,
-    clickXpath,
-    findByText,
-    findByXpath,
-    getDriver,
-    getLogs,
-    loadUri,
-    rightClickText
-} = new SeleniumHelper();
-
-const uri = path.resolve(__dirname, '../../build/index.html');
-
-const errorWhitelist = [
-    'The play() request was interrupted by a call to pause()'
-];
-
-let driver;
-
-const blocksTabScope = "*[@id='react-tabs-1']";
-const soundsTabScope = "*[@id='react-tabs-5']";
-const reportedValueScope = '*[@class="blocklyDropDownContent"]';
-const modalScope = '*[@class="ReactModalPortal"]';
-
-describe('costumes, sounds and variables', () => {
-    beforeAll(() => {
-        driver = getDriver();
-    });
-
-    afterAll(async () => {
-        await driver.quit();
-    });
-
-    test('Blocks report when clicked in the toolbox', async () => {
-        await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
-        await clickText('Blocks');
-        await clickText('Operators', blocksTabScope);
-        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
-        await clickText('join', blocksTabScope); // Click "join <hello> <world>" block
-        await findByText('helloworld', reportedValueScope); // Tooltip with result
-        const logs = await getLogs(errorWhitelist);
-        await expect(logs).toEqual([]);
-    });
-
-    test('Switching sprites updates the block menus', async () => {
-        await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
-        await clickText('Sound', blocksTabScope);
-        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
-        // "Meow" sound block should be visible
-        await findByText('Meow', blocksTabScope);
-        await clickText('Backdrops'); // Switch to the backdrop
-        // Now "pop" sound block should be visible and motion blocks hidden
-        await findByText('pop', blocksTabScope);
-        await clickText('Motion', blocksTabScope);
-        await findByText('Stage selected: no motion blocks');
-
-        const logs = await getLogs(errorWhitelist);
-        await expect(logs).toEqual([]);
-    });
-
-    test('Adding a costume', async () => {
-        await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
-        await clickText('Costumes');
-        await clickText('Add Costume');
-        const el = await findByXpath("//input[@placeholder='what are you looking for?']");
-        await el.sendKeys('abb');
-        await clickText('Abby-a'); // Should close the modal, then click the costumes in the selector
-        await findByXpath("//input[@value='Abby-a']"); // Should show editor for new costume
-        const logs = await getLogs(errorWhitelist);
-        await expect(logs).toEqual([]);
-    });
-
-    test('Adding a backdrop', async () => {
-        await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
-        await clickText('Add Backdrop');
-        const el = await findByXpath("//input[@placeholder='what are you looking for?']");
-        await el.sendKeys('blue');
-        await clickText('Blue Sky'); // Should close the modal
-        const logs = await getLogs(errorWhitelist);
-        await expect(logs).toEqual([]);
-    });
-
-    test('Adding a sound', async () => {
-        await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
-        await clickText('Sounds');
-
-        // Delete the sound
-        await rightClickText('Meow', soundsTabScope);
-        await clickText('delete', soundsTabScope);
-        await driver.switchTo().alert()
-            .accept();
-
-        // Add it back
-        await clickText('Add Sound');
-        let el = await findByXpath("//input[@placeholder='what are you looking for?']");
-        await el.sendKeys('meow');
-        await clickText('Meow', modalScope); // Should close the modal
-
-        // Add a new sound
-        await clickText('Add Sound');
-        el = await findByXpath("//input[@placeholder='what are you looking for?']");
-        await el.sendKeys('chom');
-        await clickText('Chomp'); // Should close the modal, then click the sounds in the selector
-        await findByXpath("//input[@value='Chomp']"); // Should show editor for new sound
-
-        await clickXpath('//button[@title="Play"]');
-
-        await clickText('Louder');
-        await clickText('Softer');
-        await clickText('Faster');
-        await clickText('Slower');
-        await clickText('Robot');
-        await clickText('Echo');
-        await clickText('Reverse');
-
-        const logs = await getLogs(errorWhitelist);
-        await expect(logs).toEqual([]);
-    });
-
-    test('Load a project by ID', async () => {
-        const projectId = '96708228';
-        await loadUri(`${uri}#${projectId}`);
-        await new Promise(resolve => setTimeout(resolve, 2000));
-        await clickXpath('//img[@title="Go"]');
-        await new Promise(resolve => setTimeout(resolve, 2000));
-        await clickXpath('//img[@title="Stop"]');
-        const logs = await getLogs(errorWhitelist);
-        await expect(logs).toEqual([]);
-    });
-
-    test('Load a project by ID (fullscreen)', async () => {
-        const prevSize = driver.manage()
-            .window()
-            .getSize();
-        await new Promise(resolve => setTimeout(resolve, 2000));
-        driver.manage()
-            .window()
-            .setSize(1920, 1080);
-        const projectId = '96708228';
-        await loadUri(`${uri}#${projectId}`);
-        await clickXpath('//button[@title="tryit"]');
-        await new Promise(resolve => setTimeout(resolve, 2000));
-        await clickXpath('//img[@title="Full Screen Control"]');
-        await clickXpath('//img[@title="Go"]');
-        await new Promise(resolve => setTimeout(resolve, 2000));
-        await clickXpath('//img[@title="Stop"]');
-        prevSize.then(value => {
-            driver.manage()
-                .window()
-                .setSize(value.width, value.height);
-        });
-        const logs = await getLogs(errorWhitelist);
-        await expect(logs).toEqual([]);
-    });
-
-    test('Creating variables', async () => {
-        await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
-        await clickText('Blocks');
-        await clickText('Variables', blocksTabScope);
-        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
-
-        // Expect a default variable "my variable" to be visible
-        await clickText('my\u00A0variable', blocksTabScope);
-        await findByText('0', reportedValueScope);
-
-        await clickText('Make a Variable');
-        let el = await findByXpath("//input[@placeholder='']");
-        await el.sendKeys('score');
-        await clickButton('OK');
-        await clickText('Make a Variable');
-        el = await findByXpath("//input[@placeholder='']");
-        await el.sendKeys('second variable');
-        await clickButton('OK');
-
-        // Make sure reporting works on a new variable
-        await clickText('Variables', blocksTabScope);
-        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
-        await clickText('score', blocksTabScope);
-        await findByText('0', reportedValueScope); // Tooltip with result
-
-        const logs = await getLogs(errorWhitelist);
-        await expect(logs).toEqual([]);
-    });
-
-    test('Importing extensions', async () => {
-        await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
-        await clickText('Blocks');
-        await clickText('Extensions');
-        await clickText('Pen', modalScope); // Modal closes
-        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
-        await clickText('stamp', blocksTabScope); // Click the "stamp" block
-
-        // Make sure trying to load the extension again scrolls back down
-        await clickText('Motion', blocksTabScope); // To scroll the list back to the top
-        await clickText('Extensions');
-        await clickText('Pen', modalScope); // Modal closes
-        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
-        await clickText('stamp', blocksTabScope); // Would fail if didn't scroll back
-
-        // Make sure switching sprites doesn't clear extensions
-        await clickText('Backdrops'); // Switch to the backdrop
-        await findByText('Pen', blocksTabScope); // Pen extension should still be loaded
-
-        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 clickXpath('//button[@title="tryit"]');
-        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([]);
-    });
-
-    test('Custom procedures', async () => {
-        await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
-        await clickText('My Blocks');
-        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
-        await clickText('Make a Block');
-        // Click on the "add an input" buttons
-        await clickText('number or text', modalScope);
-        await clickText('boolean', modalScope);
-        await clickText('Add a label', modalScope);
-        await clickText('OK', modalScope);
-
-        // Make sure a "define" block has been added to the workspace
-        await findByText('define', blocksTabScope);
-
-        const logs = await getLogs(errorWhitelist);
-        await expect(logs).toEqual([]);
-    });
-
-    // Skipped temporarily while the language selector is marked as
-    // "Coming Soon"
-    test.skip('Localization', async () => {
-        await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
-        await clickText('Blocks');
-        await clickText('Extensions');
-        await clickText('Pen', modalScope); // Modal closes
-        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
-        await clickText('English');
-        await clickText('Deutsch');
-        await new Promise(resolve => setTimeout(resolve, 1000)); // wait for blocks refresh
-        await clickText('Pen'); // will need to be updated when 'Pen' is translated
-
-        // Make sure "Add Sprite" has changed to "Figur hinzufügen"
-        await findByText('Figur hinzufügen');
-        // Find the stamp block in German
-        await findByText('Abdruck');
-
-        const logs = await getLogs(errorWhitelist);
-        await expect(logs).toEqual([]);
-    });
-
-    // Regression test for gui issue #1320
-    test('Switching sprites with different numbers of sounds', async () => {
-        await loadUri(uri);
-        await clickXpath('//button[@title="tryit"]');
-
-        // Add a sound so this sprite has 2 sounds.
-        await clickText('Sounds');
-        await clickText('Add Sound');
-        await clickText('A Bass'); // Closes the modal
-
-        // Now add a sprite with only one sound.
-        await clickText('Add Sprite');
-        await clickText('Abby'); // Doing this used to crash the editor.
-
-        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for error
-
-        // Make sure the 'Oops' screen is not visible
-        const content = await driver.getPageSource();
-        expect(content.indexOf('Oops')).toEqual(-1);
-
-        const logs = await getLogs(errorWhitelist);
-        await expect(logs).toEqual([]);
-    });
-});