diff --git a/tests/browser/test/extensive_test.js b/tests/browser/test/extensive_test.js new file mode 100644 index 000000000..edfd5d3b9 --- /dev/null +++ b/tests/browser/test/extensive_test.js @@ -0,0 +1,203 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview Node.js script to run Automated tests in Chrome, via webdriver. + */ + +const chai = require('chai'); +const { + testSetup, + testFileLocations, + getBlockElementById, +} = require('./test_setup'); +const {Key} = require('webdriverio'); + +let browser; +suite('This tests loading Large Configuration and Deletion', function (done) { + // Setting timeout to unlimited as the webdriver takes a longer time to run than most mocha test + this.timeout(0); + + // Setup Selenium for all of the tests + suiteSetup(async function () { + browser = await testSetup(testFileLocations.playground); + }); + + test('This test loading from JSON results in the correct number of blocks', async function () { + const blockNum = await testingJSONLoad(); + chai.assert.equal(blockNum, 13); + }); + + test('This test deleting block results in the correct number of blocks', async function () { + const fourthRepeatDo = await getBlockElementById( + browser, + 'E8bF[-r:B~cabGLP#QYd' + ); + await fourthRepeatDo.click({x: -100, y: -40}); + await browser.keys([Key.Delete]); + await browser.pause(100); + const blockNum = await browser.execute(() => { + return Blockly.getMainWorkspace().getAllBlocks(false).length; + }); + chai.assert.equal(blockNum, 10); + }); + + test('This test undoing delete block results in the correct number of blocks', async function () { + await browser.keys([Key.Ctrl, 'z']); + await browser.pause(100); + const blockNum = await browser.execute(() => { + return Blockly.getMainWorkspace().getAllBlocks(false).length; + }); + chai.assert.equal(blockNum, 13); + }); + + // Teardown entire suite after test are done running + suiteTeardown(async function () { + await browser.deleteSession(); + }); +}); + +async function testingJSONLoad() { + return await browser.execute(() => { + const myWorkspace = Blockly.getMainWorkspace(); + const state = { + 'blocks': { + 'languageVersion': 0, + 'blocks': [ + { + 'type': 'controls_if', + 'id': 'O]NpXoWXyz9okeD.PxV0', + 'x': 112, + 'y': 38, + 'extraState': { + 'elseIfCount': 1, + 'hasElse': true, + }, + 'inputs': { + 'DO0': { + 'block': { + 'type': 'controls_repeat_ext', + 'id': ',8#9eTr9hCrD3nR|uW1L', + 'inputs': { + 'TIMES': { + 'shadow': { + 'type': 'math_number', + 'id': '(6!seVzJ[5W=!M_s@s=I', + 'fields': { + 'NUM': 4, + }, + }, + }, + }, + }, + }, + 'DO1': { + 'block': { + 'type': 'controls_repeat_ext', + 'id': ']X9#sM4FJiVrRP;y0m6H', + 'inputs': { + 'TIMES': { + 'shadow': { + 'type': 'math_number', + 'id': '%k#p|;f+Y*#.8DX].a6Y', + 'fields': { + 'NUM': -10, + }, + }, + }, + }, + }, + }, + 'ELSE': { + 'block': { + 'type': 'controls_repeat_ext', + 'id': '`ZOj01@KGMQ?+MMcLKZ:', + 'inputs': { + 'TIMES': { + 'shadow': { + 'type': 'math_number', + 'id': 'IIK8IHzVCoUpTfx[j=^9', + 'fields': { + 'NUM': 10, + }, + }, + 'block': { + 'type': 'logic_ternary', + 'id': '!$UboN.F)peh:!o]D48-', + 'inputs': { + 'IF': { + 'block': { + 'type': 'logic_boolean', + 'id': '|?-zstzEVy,Ec%%dJZM{', + 'fields': { + 'BOOL': 'FALSE', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + 'next': { + 'block': { + 'type': 'controls_repeat_ext', + 'id': 'E8bF[-r:B~cabGLP#QYd', + 'inputs': { + 'TIMES': { + 'shadow': { + 'type': 'math_number', + 'id': 'vOb`Us7f.bIuXRGd(K.e', + 'fields': { + 'NUM': 10, + }, + }, + 'block': { + 'type': 'logic_ternary', + 'id': 'AyS?@78RwAtQ$?aU[-$L', + 'inputs': { + 'IF': { + 'block': { + 'type': 'logic_boolean', + 'id': 'K@$Ewnj*Y6JcKR`mycf8', + 'fields': { + 'BOOL': 'FALSE', + }, + }, + }, + }, + }, + }, + }, + 'next': { + 'block': { + 'type': 'controls_repeat_ext', + 'id': 'XFO4v:Cf@2~rgH9CQZ]/', + 'inputs': { + 'TIMES': { + 'shadow': { + 'type': 'math_number', + 'id': 'jf)XYgvoi!c.3V[u@h+-', + 'fields': { + 'NUM': 10, + }, + }, + }, + }, + }, + }, + }, + }, + }, + ], + }, + }; + Blockly.serialization.workspaces.load(state, myWorkspace); + return myWorkspace.getAllBlocks(false).length; + }); +} diff --git a/tests/browser/test/test_setup.js b/tests/browser/test/test_setup.js index 74cc42dfd..588b2c52d 100644 --- a/tests/browser/test/test_setup.js +++ b/tests/browser/test/test_setup.js @@ -180,6 +180,26 @@ async function getBlockTypeFromCategory(browser, categoryName, blockType) { return getBlockElementById(browser, id); } +/** + * @param browser The active WebdriverIO Browser object. + * @param blockType The type of the block to search for in the workspace. + * @param position The the position of the block type on the workspace. + * @return A Promise that resolves to the root element of the block with the + * given position and type on the workspace. + */ +async function getBlockTypeFromWorkspace(browser, blockType, position) { + const id = await browser.execute( + (blockType, position) => { + return Blockly.getMainWorkspace().getBlocksByType(blockType, true)[ + position + ].id; + }, + blockType, + position + ); + return getBlockElementById(browser, id); +} + /** * @param browser The active WebdriverIO Browser object. * @param id The ID of the block the connection is on. @@ -338,4 +358,5 @@ module.exports = { contextMenuSelect, dragBlockTypeFromFlyout, screenDirection, + getBlockTypeFromWorkspace, };