Skip to content

Commit 8115d40

Browse files
committed
chore: Add tests for focus after deletion.
1 parent a0bf76f commit 8115d40

File tree

3 files changed

+277
-17
lines changed

3 files changed

+277
-17
lines changed
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
/**
2+
* @license
3+
* Copyright 2025 Google LLC
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
import * as chai from 'chai';
8+
import {
9+
blockIsPresent,
10+
currentFocusIsMainWorkspace,
11+
setCurrentCursorNodeById,
12+
getCurrentFocusNodeId,
13+
getFocusedBlockType,
14+
moveToToolboxCategory,
15+
testSetup,
16+
testFileLocations,
17+
PAUSE_TIME,
18+
tabNavigateToWorkspace,
19+
} from './test_setup.js';
20+
import {Key} from 'webdriverio';
21+
22+
suite.only('Deleting Blocks', function () {
23+
// Setting timeout to unlimited as these tests take a longer time to run than most mocha test
24+
this.timeout(0);
25+
26+
setup(async function () {
27+
this.browser = await testSetup(testFileLocations.NAVIGATION_TEST_BLOCKS);
28+
await this.browser.pause(PAUSE_TIME);
29+
});
30+
31+
test('Deleting block selects previous connection', async function () {
32+
await tabNavigateToWorkspace(this.browser);
33+
await this.browser.pause(PAUSE_TIME);
34+
await setCurrentCursorNodeById(this.browser, 'controls_if_2');
35+
await this.browser.pause(PAUSE_TIME);
36+
37+
chai
38+
.expect(await blockIsPresent(this.browser, 'controls_if_2'))
39+
.equal(true);
40+
41+
await this.browser.keys(Key.Backspace);
42+
await this.browser.pause(PAUSE_TIME);
43+
44+
chai
45+
.expect(await blockIsPresent(this.browser, 'controls_if_2'))
46+
.equal(false);
47+
48+
chai
49+
.expect(await getCurrentFocusNodeId(this.browser))
50+
.to.include('controls_if_1_connection_');
51+
});
52+
53+
test('Cutting block selects previous connection', async function () {
54+
await tabNavigateToWorkspace(this.browser);
55+
await this.browser.pause(PAUSE_TIME);
56+
await setCurrentCursorNodeById(this.browser, 'controls_if_2');
57+
await this.browser.pause(PAUSE_TIME);
58+
59+
chai
60+
.expect(await blockIsPresent(this.browser, 'controls_if_2'))
61+
.equal(true);
62+
63+
await this.browser.keys([Key.Ctrl, 'x']);
64+
await this.browser.pause(PAUSE_TIME);
65+
66+
chai
67+
.expect(await blockIsPresent(this.browser, 'controls_if_2'))
68+
.equal(false);
69+
70+
chai
71+
.expect(await getCurrentFocusNodeId(this.browser))
72+
.to.include('controls_if_1_connection_');
73+
});
74+
75+
test('Deleting block also deletes children and inputs', async function () {
76+
await tabNavigateToWorkspace(this.browser);
77+
await this.browser.pause(PAUSE_TIME);
78+
await setCurrentCursorNodeById(this.browser, 'controls_if_2');
79+
await this.browser.pause(PAUSE_TIME);
80+
81+
chai
82+
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
83+
.equal(true);
84+
chai.expect(await blockIsPresent(this.browser, 'text_print_1')).equal(true);
85+
86+
await this.browser.keys(Key.Backspace);
87+
await this.browser.pause(PAUSE_TIME);
88+
89+
chai
90+
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
91+
.equal(false);
92+
chai
93+
.expect(await blockIsPresent(this.browser, 'text_print_1'))
94+
.equal(false);
95+
});
96+
97+
test('Cutting block also removes children and inputs', async function () {
98+
await tabNavigateToWorkspace(this.browser);
99+
await this.browser.pause(PAUSE_TIME);
100+
await setCurrentCursorNodeById(this.browser, 'controls_if_2');
101+
await this.browser.pause(PAUSE_TIME);
102+
103+
chai
104+
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
105+
.equal(true);
106+
chai.expect(await blockIsPresent(this.browser, 'text_print_1')).equal(true);
107+
108+
await this.browser.keys([Key.Ctrl, 'x']);
109+
await this.browser.pause(PAUSE_TIME);
110+
111+
chai
112+
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
113+
.equal(false);
114+
chai
115+
.expect(await blockIsPresent(this.browser, 'text_print_1'))
116+
.equal(false);
117+
});
118+
119+
test('Deleting inline input selects parent connection', async function () {
120+
await tabNavigateToWorkspace(this.browser);
121+
await this.browser.pause(PAUSE_TIME);
122+
await setCurrentCursorNodeById(this.browser, 'logic_boolean_1');
123+
await this.browser.pause(PAUSE_TIME);
124+
125+
chai
126+
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
127+
.equal(true);
128+
129+
await this.browser.keys(Key.Backspace);
130+
await this.browser.pause(PAUSE_TIME);
131+
132+
chai
133+
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
134+
.equal(false);
135+
136+
chai
137+
.expect(await getCurrentFocusNodeId(this.browser))
138+
.to.include('controls_if_2_connection_');
139+
});
140+
141+
test('Cutting inline input selects parent connection', async function () {
142+
await tabNavigateToWorkspace(this.browser);
143+
await this.browser.pause(PAUSE_TIME);
144+
await setCurrentCursorNodeById(this.browser, 'logic_boolean_1');
145+
await this.browser.pause(PAUSE_TIME);
146+
147+
chai
148+
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
149+
.equal(true);
150+
151+
await this.browser.keys([Key.Ctrl, 'x']);
152+
await this.browser.pause(PAUSE_TIME);
153+
154+
chai
155+
.expect(await blockIsPresent(this.browser, 'logic_boolean_1'))
156+
.equal(false);
157+
158+
chai
159+
.expect(await getCurrentFocusNodeId(this.browser))
160+
.to.include('controls_if_2_connection_');
161+
});
162+
163+
test('Deleting stranded block selects workspace', async function () {
164+
await tabNavigateToWorkspace(this.browser);
165+
await this.browser.pause(PAUSE_TIME);
166+
167+
await moveToToolboxCategory(this.browser, 'Math');
168+
await this.browser.pause(PAUSE_TIME);
169+
// Move to flyout.
170+
await this.browser.keys(Key.ArrowRight);
171+
await this.browser.pause(PAUSE_TIME);
172+
// Select number block.
173+
await this.browser.keys(Key.Enter);
174+
await this.browser.pause(PAUSE_TIME);
175+
// Confirm move.
176+
await this.browser.keys(Key.Enter);
177+
await this.browser.pause(PAUSE_TIME);
178+
179+
chai.assert.equal(
180+
'math_number',
181+
await getFocusedBlockType(this.browser),
182+
);
183+
184+
await this.browser.keys(Key.Backspace);
185+
await this.browser.pause(PAUSE_TIME);
186+
187+
chai
188+
.expect(await currentFocusIsMainWorkspace(this.browser))
189+
.equal(true);
190+
});
191+
192+
test('Cutting stranded block selects workspace', async function () {
193+
await tabNavigateToWorkspace(this.browser);
194+
await this.browser.pause(PAUSE_TIME);
195+
196+
await moveToToolboxCategory(this.browser, 'Math');
197+
await this.browser.pause(PAUSE_TIME);
198+
// Move to flyout.
199+
await this.browser.keys(Key.ArrowRight);
200+
await this.browser.pause(PAUSE_TIME);
201+
// Select number block.
202+
await this.browser.keys(Key.Enter);
203+
await this.browser.pause(PAUSE_TIME);
204+
// Confirm move.
205+
await this.browser.keys(Key.Enter);
206+
await this.browser.pause(PAUSE_TIME);
207+
208+
chai.assert.equal(
209+
'math_number',
210+
await getFocusedBlockType(this.browser),
211+
);
212+
213+
await this.browser.keys([Key.Ctrl, 'x']);
214+
await this.browser.pause(PAUSE_TIME);
215+
216+
chai
217+
.expect(await currentFocusIsMainWorkspace(this.browser))
218+
.equal(true);
219+
});
220+
});
221+
222+

test/webdriverio/test/insert_test.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import * as chai from 'chai';
88
import {Browser, Key} from 'webdriverio';
99
import {
1010
getFocusedBlockType,
11+
moveToToolboxCategory,
1112
PAUSE_TIME,
1213
setCurrentCursorNodeById,
1314
tabNavigateToWorkspace,
@@ -44,19 +45,3 @@ suite('Insert test', function () {
4445
);
4546
});
4647
});
47-
48-
async function moveToToolboxCategory(browser: Browser, category: string) {
49-
await browser.keys('t');
50-
const categoryIndex = await browser.execute((category) => {
51-
const all = Array.from(
52-
document.querySelectorAll('.blocklyToolboxCategoryLabel'),
53-
).map((node) => node.textContent);
54-
return all.indexOf(category);
55-
}, category);
56-
if (categoryIndex < 0) {
57-
throw new Error(`No category found: ${category}`);
58-
}
59-
if (categoryIndex > 0) {
60-
await browser.keys(Key.ArrowDown.repeat(categoryIndex));
61-
}
62-
}

test/webdriverio/test/test_setup.ts

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,59 @@ export async function focusWorkspace(browser: WebdriverIO.Browser) {
171171
await workspaceElement.click();
172172
}
173173

174+
/**
175+
* Focuses the toolbox category with the given name.
176+
*
177+
* @param browser The active WebdriverIO Browser object.
178+
* @param blockId The id of the block.
179+
*/
180+
export async function moveToToolboxCategory(browser: WebdriverIO.Browser, category: string) {
181+
await browser.keys('t');
182+
const categoryIndex = await browser.execute((category) => {
183+
const all = Array.from(
184+
document.querySelectorAll('.blocklyToolboxCategoryLabel'),
185+
).map((node) => node.textContent);
186+
return all.indexOf(category);
187+
}, category);
188+
if (categoryIndex < 0) {
189+
throw new Error(`No category found: ${category}`);
190+
}
191+
if (categoryIndex > 0) {
192+
await browser.keys(webdriverio.Key.ArrowDown.repeat(categoryIndex));
193+
}
194+
}
195+
196+
/**
197+
* Returns whether the workspace contains a block with the given id.
198+
*
199+
* @param browser The active WebdriverIO Browser object.
200+
* @param blockId The id of the block.
201+
*/
202+
export async function blockIsPresent(
203+
browser: WebdriverIO.Browser,
204+
blockId: string,
205+
): Promise<boolean> {
206+
return await browser.execute((blockId) => {
207+
const workspaceSvg = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg;
208+
const block = workspaceSvg.getBlockById(blockId);
209+
return block !== null;
210+
}, blockId);
211+
}
212+
213+
/**
214+
* Returns whether the main workspace is the current focus.
215+
*
216+
* @param browser The active WebdriverIO Browser object.
217+
*/
218+
export async function currentFocusIsMainWorkspace(
219+
browser: WebdriverIO.Browser,
220+
): Promise<boolean> {
221+
return await browser.execute(() => {
222+
const workspaceSvg = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg;
223+
return Blockly.getFocusManager().getFocusedNode() === workspaceSvg;
224+
});
225+
}
226+
174227
/**
175228
* Select a block with the given id as the current cursor node.
176229
*
@@ -191,7 +244,7 @@ export async function setCurrentCursorNodeById(
191244
}
192245

193246
/**
194-
* Select a block with the given id as the current cursor node.
247+
* Select a block's field with the given block id and field name.
195248
*
196249
* @param browser The active WebdriverIO Browser object.
197250
* @param blockId The id of the block to select.

0 commit comments

Comments
 (0)