Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 212 additions & 0 deletions test/webdriverio/test/delete_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import * as chai from 'chai';
import {
blockIsPresent,
currentFocusIsMainWorkspace,
setCurrentCursorNodeById,
getCurrentFocusNodeId,
getFocusedBlockType,
moveToToolboxCategory,
testSetup,
testFileLocations,
PAUSE_TIME,
tabNavigateToWorkspace,
} from './test_setup.js';
import {Key} from 'webdriverio';

suite.only('Deleting Blocks', function () {
// Setting timeout to unlimited as these tests take a longer time to run than most mocha test
this.timeout(0);

setup(async function () {
this.browser = await testSetup(testFileLocations.NAVIGATION_TEST_BLOCKS);
await this.browser.pause(PAUSE_TIME);
});

test('Deleting block selects previous connection', async function () {
await tabNavigateToWorkspace(this.browser);
await this.browser.pause(PAUSE_TIME);
await setCurrentCursorNodeById(this.browser, 'controls_if_2');
await this.browser.pause(PAUSE_TIME);

chai
.expect(await blockIsPresent(this.browser, 'controls_if_2'))
.equal(true);

await this.browser.keys(Key.Backspace);
await this.browser.pause(PAUSE_TIME);

chai
.expect(await blockIsPresent(this.browser, 'controls_if_2'))
.equal(false);

chai
.expect(await getCurrentFocusNodeId(this.browser))
.to.include('controls_if_1_connection_');
});

test('Cutting block selects previous connection', async function () {
await tabNavigateToWorkspace(this.browser);
await this.browser.pause(PAUSE_TIME);
await setCurrentCursorNodeById(this.browser, 'controls_if_2');
await this.browser.pause(PAUSE_TIME);

chai
.expect(await blockIsPresent(this.browser, 'controls_if_2'))
.equal(true);

await this.browser.keys([Key.Ctrl, 'x']);
await this.browser.pause(PAUSE_TIME);

chai
.expect(await blockIsPresent(this.browser, 'controls_if_2'))
.equal(false);

chai
.expect(await getCurrentFocusNodeId(this.browser))
.to.include('controls_if_1_connection_');
});

test('Deleting block also deletes children and inputs', async function () {
await tabNavigateToWorkspace(this.browser);
await this.browser.pause(PAUSE_TIME);
await setCurrentCursorNodeById(this.browser, 'controls_if_2');
await this.browser.pause(PAUSE_TIME);

chai
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
.equal(true);
chai.expect(await blockIsPresent(this.browser, 'text_print_1')).equal(true);

await this.browser.keys(Key.Backspace);
await this.browser.pause(PAUSE_TIME);

chai
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
.equal(false);
chai
.expect(await blockIsPresent(this.browser, 'text_print_1'))
.equal(false);
});

test('Cutting block also removes children and inputs', async function () {
await tabNavigateToWorkspace(this.browser);
await this.browser.pause(PAUSE_TIME);
await setCurrentCursorNodeById(this.browser, 'controls_if_2');
await this.browser.pause(PAUSE_TIME);

chai
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
.equal(true);
chai.expect(await blockIsPresent(this.browser, 'text_print_1')).equal(true);

await this.browser.keys([Key.Ctrl, 'x']);
await this.browser.pause(PAUSE_TIME);

chai
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
.equal(false);
chai
.expect(await blockIsPresent(this.browser, 'text_print_1'))
.equal(false);
});

test('Deleting inline input selects parent connection', async function () {
await tabNavigateToWorkspace(this.browser);
await this.browser.pause(PAUSE_TIME);
await setCurrentCursorNodeById(this.browser, 'logic_boolean_1');
await this.browser.pause(PAUSE_TIME);

chai
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
.equal(true);

await this.browser.keys(Key.Backspace);
await this.browser.pause(PAUSE_TIME);

chai
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
.equal(false);

chai
.expect(await getCurrentFocusNodeId(this.browser))
.to.include('controls_if_2_connection_');
});

test('Cutting inline input selects parent connection', async function () {
await tabNavigateToWorkspace(this.browser);
await this.browser.pause(PAUSE_TIME);
await setCurrentCursorNodeById(this.browser, 'logic_boolean_1');
await this.browser.pause(PAUSE_TIME);

chai
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
.equal(true);

await this.browser.keys([Key.Ctrl, 'x']);
await this.browser.pause(PAUSE_TIME);

chai
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
.equal(false);

chai
.expect(await getCurrentFocusNodeId(this.browser))
.to.include('controls_if_2_connection_');
});

test('Deleting stranded block selects workspace', async function () {
await tabNavigateToWorkspace(this.browser);
await this.browser.pause(PAUSE_TIME);

// The test workspace doesn't already contain a stranded block, so add one.
await moveToToolboxCategory(this.browser, 'Math');
await this.browser.pause(PAUSE_TIME);
// Move to flyout.
await this.browser.keys(Key.ArrowRight);
await this.browser.pause(PAUSE_TIME);
// Select number block.
await this.browser.keys(Key.Enter);
await this.browser.pause(PAUSE_TIME);
// Confirm move.
await this.browser.keys(Key.Enter);
await this.browser.pause(PAUSE_TIME);

chai.assert.equal('math_number', await getFocusedBlockType(this.browser));

await this.browser.keys(Key.Backspace);
await this.browser.pause(PAUSE_TIME);

chai.expect(await currentFocusIsMainWorkspace(this.browser)).equal(true);
});

test('Cutting stranded block selects workspace', async function () {
await tabNavigateToWorkspace(this.browser);
await this.browser.pause(PAUSE_TIME);

// The test workspace doesn't already contain a stranded block, so add one.
await moveToToolboxCategory(this.browser, 'Math');
await this.browser.pause(PAUSE_TIME);
// Move to flyout.
await this.browser.keys(Key.ArrowRight);
await this.browser.pause(PAUSE_TIME);
// Select number block.
await this.browser.keys(Key.Enter);
await this.browser.pause(PAUSE_TIME);
// Confirm move.
await this.browser.keys(Key.Enter);
await this.browser.pause(PAUSE_TIME);

chai.assert.equal('math_number', await getFocusedBlockType(this.browser));

await this.browser.keys([Key.Ctrl, 'x']);
await this.browser.pause(PAUSE_TIME);

chai.expect(await currentFocusIsMainWorkspace(this.browser)).equal(true);
});
});
17 changes: 1 addition & 16 deletions test/webdriverio/test/insert_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
*/

import * as chai from 'chai';
import {Browser, Key} from 'webdriverio';

Check warning on line 8 in test/webdriverio/test/insert_test.ts

View workflow job for this annotation

GitHub Actions / Eslint check

'Browser' is defined but never used
import {
getFocusedBlockType,
moveToToolboxCategory,
PAUSE_TIME,
setCurrentCursorNodeById,
tabNavigateToWorkspace,
Expand Down Expand Up @@ -44,19 +45,3 @@
);
});
});

async function moveToToolboxCategory(browser: Browser, category: string) {
await browser.keys('t');
const categoryIndex = await browser.execute((category) => {
const all = Array.from(
document.querySelectorAll('.blocklyToolboxCategoryLabel'),
).map((node) => node.textContent);
return all.indexOf(category);
}, category);
if (categoryIndex < 0) {
throw new Error(`No category found: ${category}`);
}
if (categoryIndex > 0) {
await browser.keys(Key.ArrowDown.repeat(categoryIndex));
}
}
58 changes: 57 additions & 1 deletion test/webdriverio/test/test_setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,62 @@
await workspaceElement.click();
}

/**

Check warning on line 174 in test/webdriverio/test/test_setup.ts

View workflow job for this annotation

GitHub Actions / Eslint check

Missing JSDoc @param "category" declaration
* Focuses the toolbox category with the given name.
*
* @param browser The active WebdriverIO Browser object.
* @param blockId The id of the block.

Check warning on line 178 in test/webdriverio/test/test_setup.ts

View workflow job for this annotation

GitHub Actions / Eslint check

Expected @param names to be "browser, category". Got "browser, blockId"
*/
export async function moveToToolboxCategory(
browser: WebdriverIO.Browser,
category: string,
) {
await browser.keys('t');
const categoryIndex = await browser.execute((category) => {
const all = Array.from(
document.querySelectorAll('.blocklyToolboxCategoryLabel'),
).map((node) => node.textContent);
return all.indexOf(category);
}, category);
if (categoryIndex < 0) {
throw new Error(`No category found: ${category}`);
}
if (categoryIndex > 0) {
await browser.keys(webdriverio.Key.ArrowDown.repeat(categoryIndex));
}
}

/**
* Returns whether the workspace contains a block with the given id.
*
* @param browser The active WebdriverIO Browser object.
* @param blockId The id of the block.
*/
export async function blockIsPresent(
browser: WebdriverIO.Browser,
blockId: string,
): Promise<boolean> {
return await browser.execute((blockId) => {
const workspaceSvg = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg;
const block = workspaceSvg.getBlockById(blockId);
return block !== null;
}, blockId);
}

/**
* Returns whether the main workspace is the current focus.
*
* @param browser The active WebdriverIO Browser object.
*/
export async function currentFocusIsMainWorkspace(
browser: WebdriverIO.Browser,
): Promise<boolean> {
return await browser.execute(() => {
const workspaceSvg = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg;
return Blockly.getFocusManager().getFocusedNode() === workspaceSvg;
});
}

/**
* Select a block with the given id as the current cursor node.
*
Expand All @@ -191,7 +247,7 @@
}

/**
* Select a block with the given id as the current cursor node.
* Select a block's field with the given block id and field name.
*
* @param browser The active WebdriverIO Browser object.
* @param blockId The id of the block to select.
Expand Down
Loading