chore: clean up mutator tests (#7434)

* chore: work on cleaning up mutator tests

* chore: remove need for dragBlockSelector

* chore: add helpers to clean up tests

* chore: add issue link in TODO

* chore: format and add docs for new helpers

* Revert "chore: remove need for dragBlockSelector"

This reverts commit dfec88a6aa.

* chore: fixup connect helper
This commit is contained in:
Beka Westberg
2023-08-28 15:01:10 -07:00
committed by GitHub
parent 650e620e2b
commit 8193cffe77
3 changed files with 100 additions and 76 deletions

View File

@@ -4,94 +4,85 @@
* 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,
connect,
switchRTL,
dragBlockTypeFromFlyout,
getSelectedBlockId,
screenDirection,
PAUSE_TIME,
getBlockElementById,
dragBlockFromMutatorFlyout,
openMutatorForBlock,
} = require('./test_setup');
suite('This tests mutating a Blockly block', function (done) {
// Setting timeout to unlimited as the webdriver takes a longer time to run than most mocha test
suite('Mutating a block', function (done) {
this.timeout(0);
// Setup Selenium for all of the tests
suiteSetup(async function () {
this.browser = await testSetup(testFileLocations.PLAYGROUND);
});
test('This test mutating a block creates more inputs', async function () {
await testingMutator(this.browser, screenDirection.LTR);
test('Mutating a block creates more inputs', async function () {
await testMutator(this.browser, screenDirection.LTR);
});
});
async function testingMutator(browser, delta) {
// Drag out print from flyout.
const controlIfFlyout = await dragBlockTypeFromFlyout(
async function testMutator(browser, delta) {
const mutatorBlock = await dragBlockTypeFromFlyout(
browser,
'Logic',
'controls_if',
delta * 50,
50,
);
// Click on the mutator and drag out else if block
const mutatorWheel = await browser.$(
'#blocklyDiv > div > svg.blocklySvg > g > g.blocklyBlockCanvas > g.blocklyDraggable.blocklySelected > g.blocklyIconGroup',
);
await mutatorWheel.click();
await openMutatorForBlock(browser, mutatorBlock);
await browser.pause(PAUSE_TIME);
const elseIfFlyout = await browser.$(
'#blocklyDiv > div > svg.blocklySvg > g > g.blocklyBubbleCanvas > g > g:nth-child(2) > svg:nth-child(1) > g > g.blocklyFlyout > g > g.blocklyBlockCanvas > g:nth-child(3)',
await dragBlockFromMutatorFlyout(
browser,
mutatorBlock,
'controls_if_elseif',
delta * 50,
50,
);
await elseIfFlyout.dragAndDrop({x: delta * 50, y: 42});
await browser.pause(PAUSE_TIME);
await browser.pause(PAUSE_TIME);
// Get the ids for the blocks in the mutator
const blockIds = await browser.execute(() => {
const mutatorBlock = Blockly.getMainWorkspace().getAllBlocks()[0];
// Adding the first element in the array is the original block id, the second is the first mutator block, and the third is the second mutator block
const blockIds = [
mutatorBlock.id,
mutatorBlock.mutator.getWorkspace().getAllBlocks()[0].id,
mutatorBlock.mutator.getWorkspace().getAllBlocks()[1].id,
];
return blockIds;
});
const {mutatorBlockId, ifQuarkId, elseIfQuarkId} = await browser.execute(
() => {
const mutatorBlock = Blockly.getMainWorkspace().getAllBlocks()[0];
const quarkBlocks = mutatorBlock.mutator.getWorkspace().getAllBlocks();
return {
mutatorBlockId: mutatorBlock.id,
ifQuarkId: quarkBlocks[0].id,
elseIfQuarkId: quarkBlocks[1].id,
};
},
);
// The flyout block and the workspace block have the same id, so to get around that I pass in the selector to the connect function
// The flyout block and the workspace block have the same id, so to get
// around that I pass in the selector to the connect function.
const dragBlockSelector = await browser.$(
'#blocklyDiv > div > svg.blocklySvg > g > g.blocklyBubbleCanvas > g > g:nth-child(2) > svg:nth-child(1) > g > g.blocklyBlockCanvas > g.blocklyDraggable',
'#blocklyDiv > div > svg.blocklySvg > g > g.blocklyBubbleCanvas > g > ' +
'g:nth-child(2) > svg:nth-child(1) > g > g.blocklyBlockCanvas > ' +
'g.blocklyDraggable',
);
// For some reason this needs a lot more time
// For some reason this needs a lot more time.
await browser.pause(2000);
// Connect the mutator blocks
await connect(
browser,
blockIds[2],
await getBlockElementById(browser, elseIfQuarkId),
'PREVIOUS',
blockIds[1],
await getBlockElementById(browser, ifQuarkId),
'NEXT',
blockIds[0],
mutatorBlockId,
dragBlockSelector,
);
await browser.pause(PAUSE_TIME);
// Get the ids for block after mutating
const afterInputs = await browser.execute(() => {
const afterInputs =
Blockly.getMainWorkspace().getAllBlocks()[0].inputList.length;
return afterInputs;
const finalInputCount = await browser.execute(() => {
return Blockly.getMainWorkspace().getAllBlocks()[0].inputList.length;
});
chai.assert.equal(afterInputs, 4);
chai.assert.equal(finalInputCount, 4);
}

View File

@@ -295,7 +295,8 @@ async function getLocationOfBlockConnection(
* @param draggedConnection The active connection on the block being dragged.
* @param targetBlock The block to drag to.
* @param targetConnection The connection to connect to on the target block.
* @param mutatorBlockId The block that holds the mutator icon or null if the target block is on the main workspace
* @param mutatorBlockId The block that holds the mutator icon or null if the
* target block is on the main workspace
* @param dragBlockSelector The selector of the block to drag
* @return A Promise that resolves when the actions are completed.
*/
@@ -308,34 +309,18 @@ async function connect(
mutatorBlockId,
dragBlockSelector,
) {
let draggedLocation;
let targetLocation;
if (mutatorBlockId) {
draggedLocation = await getLocationOfBlockConnection(
browser,
draggedBlock,
draggedConnection,
mutatorBlockId,
);
targetLocation = await getLocationOfBlockConnection(
browser,
targetBlock,
targetConnection,
mutatorBlockId,
);
} else {
draggedLocation = await getLocationOfBlockConnection(
browser,
draggedBlock.id,
draggedConnection,
);
targetLocation = await getLocationOfBlockConnection(
browser,
targetBlock.id,
targetConnection,
);
}
const draggedLocation = await getLocationOfBlockConnection(
browser,
draggedBlock.id,
draggedConnection,
mutatorBlockId,
);
const targetLocation = await getLocationOfBlockConnection(
browser,
targetBlock.id,
targetConnection,
mutatorBlockId,
);
const delta = {
x: targetLocation.x - draggedLocation.x,
@@ -405,6 +390,39 @@ async function dragBlockTypeFromFlyout(browser, categoryName, type, x, y) {
return await getSelectedBlockElement(browser);
}
/**
* 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
* a block from.
* @param type The type of the block to search for.
* @param x The x-distance to drag, as a delta from the block's
* initial location on screen.
* @param y The y-distance to drag, as a delta from the block's
* initial location on screen.
* @return A Promise that resolves to the root element of the newly
* created block.
*/
async function dragBlockFromMutatorFlyout(browser, mutatorBlock, type, x, y) {
const id = await browser.execute(
(mutatorBlockId, blockType) => {
return Blockly.getMainWorkspace()
.getBlockById(mutatorBlockId)
.mutator.getWorkspace()
.getFlyout()
.getWorkspace()
.getBlocksByType(blockType)[0].id;
},
mutatorBlock.id,
type,
);
const flyoutBlock = await getBlockElementById(browser, id);
await flyoutBlock.dragAndDrop({x: x, y: y});
return await getSelectedBlockElement(browser);
}
/**
* Right-click on the specified block, then click on the specified
* context menu item.
@@ -435,6 +453,18 @@ async function contextMenuSelect(browser, block, itemText) {
await browser.pause(PAUSE_TIME);
}
/**
* Opens the mutator bubble for the given block.
*
* @param browser The active WebdriverIO Browser object.
* @param block The block to click, as an interactable element.
* @return A Promise that resolves when the actions are complete.
*/
async function openMutatorForBlock(browser, block) {
const icon = await browser.$(`[data-id="${block.id}"] > g.blocklyIconGroup`);
await icon.click();
}
/**
* Get all blocks on the main workspace. Because the blocks have circular
* references that can't be JSON-encoded they can't be returned directly, so
@@ -490,9 +520,11 @@ module.exports = {
getBlockTypeFromCategory,
dragNthBlockFromFlyout,
dragBlockTypeFromFlyout,
dragBlockFromMutatorFlyout,
connect,
switchRTL,
contextMenuSelect,
openMutatorForBlock,
screenDirection,
getBlockTypeFromWorkspace,
getAllBlocks,