fix: Fix browser tests PART 1 (#9064)

* Move block into view before clicking

* fix right click test failures

* Fix drag three blocks test

dragAndDrop is relative to the start and the test window is very small.

* Fix a few more tests

- Switch to using clickBlock instead of getting the block and clicking it
- Update drag positions for some tests so they don't snap and change size

* Add a pause between right clicking a block and waiting for the menu

* Fix mutator test by finding the dragged out elseif block

* Make disable test less flakey
This commit is contained in:
RoboErikG
2025-05-19 14:25:55 -07:00
committed by GitHub
parent 8e11337531
commit 361b453f17
6 changed files with 63 additions and 44 deletions

View File

@@ -31,7 +31,7 @@ suite('Basic block tests', function (done) {
test('Drag three blocks into the workspace', async function () {
for (let i = 1; i <= 3; i++) {
await dragNthBlockFromFlyout(this.browser, 'Align', 0, 250, 50 * i);
await dragNthBlockFromFlyout(this.browser, 'Align', 0, 50, 50);
chai.assert.equal((await getAllBlocks(this.browser)).length, i);
}
});

View File

@@ -126,15 +126,15 @@ suite('Disabling', function () {
this.browser,
'Logic',
'controls_if',
10,
10,
15,
0,
);
const child = await dragBlockTypeFromFlyout(
this.browser,
'Logic',
'logic_boolean',
110,
110,
100,
0,
);
await connect(this.browser, child, 'OUTPUT', parent, 'IF0');
await this.browser.pause(PAUSE_TIME);
@@ -152,18 +152,20 @@ suite('Disabling', function () {
this.browser,
'Logic',
'controls_if',
10,
10,
15,
0,
);
const child = await dragBlockTypeFromFlyout(
this.browser,
'Logic',
'controls_if',
110,
110,
100,
0,
);
await this.browser.pause(PAUSE_TIME);
await connect(this.browser, child, 'PREVIOUS', parent, 'DO0');
await this.browser.pause(PAUSE_TIME);
await contextMenuSelect(this.browser, parent, 'Disable Block');
chai.assert.isTrue(await getIsDisabled(this.browser, child.id));
@@ -178,16 +180,17 @@ suite('Disabling', function () {
this.browser,
'Logic',
'controls_if',
10,
10,
15,
0,
);
const child = await dragBlockTypeFromFlyout(
this.browser,
'Logic',
'controls_if',
110,
110,
100,
0,
);
await connect(this.browser, child, 'PREVIOUS', parent, 'NEXT');
await contextMenuSelect(this.browser, parent, 'Disable Block');

View File

@@ -141,7 +141,7 @@ suite('Delete blocks', function (done) {
test('Delete block using backspace key', async function () {
const before = (await getAllBlocks(this.browser)).length;
// Get first print block, click to select it, and delete it using backspace key.
await clickBlock(this.browser, this.firstBlock, {button: 1});
await clickBlock(this.browser, this.firstBlock.id, {button: 1});
await this.browser.keys([Key.Backspace]);
const after = (await getAllBlocks(this.browser)).length;
chai.assert.equal(
@@ -154,7 +154,7 @@ suite('Delete blocks', function (done) {
test('Delete block using delete key', async function () {
const before = (await getAllBlocks(this.browser)).length;
// Get first print block, click to select it, and delete it using delete key.
await clickBlock(this.browser, this.firstBlock, {button: 1});
await clickBlock(this.browser, this.firstBlock.id, {button: 1});
await this.browser.keys([Key.Delete]);
const after = (await getAllBlocks(this.browser)).length;
chai.assert.equal(
@@ -176,10 +176,11 @@ suite('Delete blocks', function (done) {
);
});
test('Undo block deletion', async function () {
// TODO(#9029) enable this test once deleting a block doesn't lose focus
test.skip('Undo block deletion', async function () {
const before = (await getAllBlocks(this.browser)).length;
// Get first print block, click to select it, and delete it using backspace key.
await clickBlock(this.browser, this.firstBlock, {button: 1});
await clickBlock(this.browser, this.firstBlock.id, {button: 1});
await this.browser.keys([Key.Backspace]);
await this.browser.pause(PAUSE_TIME);
// Undo
@@ -187,8 +188,8 @@ suite('Delete blocks', function (done) {
await this.browser.pause(PAUSE_TIME);
const after = (await getAllBlocks(this.browser)).length;
chai.assert.equal(
before,
after,
before,
'Expected there to be the original number of blocks after undoing a delete',
);
});
@@ -196,7 +197,7 @@ suite('Delete blocks', function (done) {
test('Redo block deletion', async function () {
const before = (await getAllBlocks(this.browser)).length;
// Get first print block, click to select it, and delete it using backspace key.
await clickBlock(this.browser, this.firstBlock, {button: 1});
await clickBlock(this.browser, this.firstBlock.id, {button: 1});
await this.browser.keys([Key.Backspace]);
await this.browser.pause(PAUSE_TIME);
// Undo

View File

@@ -11,8 +11,8 @@
import * as chai from 'chai';
import {Key} from 'webdriverio';
import {
clickBlock,
getAllBlocks,
getBlockElementById,
PAUSE_TIME,
testFileLocations,
testSetup,
@@ -33,18 +33,15 @@ suite('This tests loading Large Configuration and Deletion', function (done) {
});
test('deleting block results in the correct number of blocks', async function () {
const fourthRepeatDo = await getBlockElementById(
this.browser,
'E8bF[-r:B~cabGLP#QYd',
);
await fourthRepeatDo.click({x: -100, y: -40});
await clickBlock(this.browser, 'E8bF[-r:B~cabGLP#QYd', {button: 1});
await this.browser.keys([Key.Delete]);
await this.browser.pause(PAUSE_TIME);
const allBlocks = await getAllBlocks(this.browser);
chai.assert.equal(allBlocks.length, 10);
});
test('undoing delete block results in the correct number of blocks', async function () {
// TODO(#8793) Re-enable test after deleting a block updates focus correctly.
test.skip('undoing delete block results in the correct number of blocks', async function () {
await this.browser.keys([Key.Ctrl, 'z']);
await this.browser.pause(PAUSE_TIME);
const allBlocks = await getAllBlocks(this.browser);

View File

@@ -34,16 +34,15 @@ async function testMutator(browser, delta) {
browser,
'Logic',
'controls_if',
delta * 50,
delta * 150,
50,
);
await openMutatorForBlock(browser, mutatorBlock);
await browser.pause(PAUSE_TIME);
await dragBlockFromMutatorFlyout(
browser,
mutatorBlock,
'controls_if_elseif',
delta * 50,
delta * 150,
50,
);
await browser.pause(PAUSE_TIME);
@@ -67,8 +66,8 @@ async function testMutator(browser, delta) {
'g:nth-child(2) > svg:nth-child(1) > g > g.blocklyBlockCanvas > ' +
'g.blocklyDraggable',
);
// For some reason this needs a lot more time.
await browser.pause(2000);
await browser.pause(PAUSE_TIME);
await connect(
browser,
await getBlockElementById(browser, elseIfQuarkId),

View File

@@ -165,28 +165,35 @@ export async function getBlockElementById(browser, id) {
* causes problems if it has holes (e.g. statement inputs). Instead, this tries
* to get the first text field on the block. It falls back on the block's SVG root.
* @param browser The active WebdriverIO Browser object.
* @param block The block to click, as an interactable element.
* @param blockId The id of the block to click, as an interactable element.
* @param clickOptions The options to pass to webdriverio's element.click function.
* @return A Promise that resolves when the actions are completed.
*/
export async function clickBlock(browser, block, clickOptions) {
export async function clickBlock(browser, blockId, clickOptions) {
const findableId = 'clickTargetElement';
// In the browser context, find the element that we want and give it a findable ID.
await browser.execute(
(blockId, newElemId) => {
const block = Blockly.getMainWorkspace().getBlockById(blockId);
for (const input of block.inputList) {
for (const field of input.fieldRow) {
if (field instanceof Blockly.FieldLabel) {
field.getSvgRoot().id = newElemId;
return;
// Ensure the block we want to click is within the viewport.
Blockly.getMainWorkspace().scrollBoundsIntoView(
block.getBoundingRectangleWithoutChildren(),
10,
);
if (!block.isCollapsed()) {
for (const input of block.inputList) {
for (const field of input.fieldRow) {
if (field instanceof Blockly.FieldLabel) {
field.getSvgRoot().id = newElemId;
return;
}
}
}
}
// No label field found. Fall back to the block's SVG root.
block.getSvgRoot().id = findableId;
block.getSvgRoot().id = newElemId;
},
block.id,
blockId,
findableId,
);
@@ -477,8 +484,8 @@ export async function dragBlockTypeFromFlyout(
}
/**
* Drags the specified block type from the mutator flyout of the given block and
* returns the root element of the block.
* Drags the specified block type from the mutator flyout of the given block
* and returns the root element of the block.
*
* @param browser The active WebdriverIO Browser object.
* @param mutatorBlock The block with the mutator attached that we want to drag
@@ -512,7 +519,18 @@ export async function dragBlockFromMutatorFlyout(
);
const flyoutBlock = await getBlockElementById(browser, id);
await flyoutBlock.dragAndDrop({x: x, y: y});
return await getSelectedBlockElement(browser);
const draggedBlockId = await browser.execute(
(mutatorBlockId, blockType) => {
return Blockly.getMainWorkspace()
.getBlockById(mutatorBlockId)
.mutator.getWorkspace()
.getBlocksByType(blockType)[0].id;
},
mutatorBlock.id,
type,
);
return await getBlockElementById(browser, draggedBlockId);
}
/**
@@ -526,8 +544,9 @@ export async function dragBlockFromMutatorFlyout(
* @return A Promise that resolves when the actions are completed.
*/
export async function contextMenuSelect(browser, block, itemText) {
await clickBlock(browser, block, {button: 2});
await clickBlock(browser, block.id, {button: 2});
await browser.pause(PAUSE_TIME);
const item = await browser.$(`div=${itemText}`);
await item.waitForExist();
await item.click();