mirror of
https://github.com/google/blockly.git
synced 2026-01-07 00:50:27 +01:00
Support dispatching pointer events in click tests (#4154)
* Add helpers for simulating mouse click. * Update field and workspace click tests.
This commit is contained in:
@@ -15,9 +15,11 @@
|
||||
"captureWarnings": true,
|
||||
"createRenderedBlock": true,
|
||||
"createTestBlock": true,
|
||||
"defineBasicBlockWithField": true,
|
||||
"defineRowBlock": true,
|
||||
"defineStackBlock": true,
|
||||
"defineStatementBlock": true,
|
||||
"dispatchPointerEvent": true,
|
||||
"createFireChangeListenerSpy": true,
|
||||
"createGenUidStubWithReturns": true,
|
||||
"getCategoryJSON": true,
|
||||
@@ -25,8 +27,9 @@
|
||||
"getXmlArray": true,
|
||||
"sharedTestSetup": true,
|
||||
"sharedTestTeardown": true,
|
||||
"simulateClick": true,
|
||||
"testAWorkspace": true,
|
||||
"testHelpers" : true,
|
||||
"testHelpers": true,
|
||||
"workspaceTeardown": true
|
||||
},
|
||||
"rules": {
|
||||
|
||||
@@ -11,77 +11,88 @@
|
||||
'use strict';
|
||||
|
||||
suite('Gesture', function() {
|
||||
function testGestureIsFieldClick(block, isFieldClick){
|
||||
var field = block.getField('NAME');
|
||||
var eventTarget = field.getClickTarget_();
|
||||
chai.assert.exists(eventTarget,
|
||||
'Precondition: missing click target for field');
|
||||
|
||||
dispatchPointerEvent(eventTarget, 'pointerdown');
|
||||
|
||||
var fieldWorkspace = field.sourceBlock_.workspace;
|
||||
// Gestures triggered on flyouts are stored on targetWorkspace.
|
||||
var gestureWorkspace = fieldWorkspace.targetWorkspace || fieldWorkspace;
|
||||
var gesture = gestureWorkspace.currentGesture_;
|
||||
chai.assert.exists(gesture, 'Gesture exists after pointerdown.');
|
||||
var isFieldClickSpy = sinon.spy(gesture, 'isFieldClick_');
|
||||
|
||||
dispatchPointerEvent(eventTarget, 'pointerup');
|
||||
dispatchPointerEvent(eventTarget, 'click');
|
||||
|
||||
sinon.assert.called(isFieldClickSpy);
|
||||
chai.assert.isTrue(isFieldClickSpy.alwaysReturned(isFieldClick));
|
||||
}
|
||||
|
||||
function getTopFlyoutBlock(flyout) {
|
||||
return flyout.workspace_.topBlocks_[0];
|
||||
}
|
||||
|
||||
setup(function() {
|
||||
sharedTestSetup.call(this);
|
||||
this.workspace = new Blockly.Workspace();
|
||||
this.e = {};
|
||||
defineBasicBlockWithField();
|
||||
var toolbox = document.getElementById('gesture-test-toolbox');
|
||||
this.workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
sharedTestTeardown.call(this);
|
||||
delete Blockly.Block['test_field_block'];
|
||||
});
|
||||
|
||||
test('Constructor', function() {
|
||||
var gesture = new Blockly.Gesture(this.e, this.workspace);
|
||||
chai.assert.equal(gesture.mostRecentEvent_, this.e);
|
||||
var e = { id: 'dummy_test_event'};
|
||||
var gesture = new Blockly.Gesture(e, this.workspace);
|
||||
chai.assert.equal(gesture.mostRecentEvent_, e);
|
||||
chai.assert.equal(gesture.creatorWorkspace_, this.workspace);
|
||||
});
|
||||
|
||||
test('Field click - Click in workspace', function() {
|
||||
var block = new Blockly.Block(this.workspace);
|
||||
var field = new Blockly.Field();
|
||||
field.setSourceBlock(block);
|
||||
field.showEditor_ = function() {};
|
||||
var gesture = new Blockly.Gesture(this.e, this.workspace);
|
||||
gesture.setStartField(field);
|
||||
var block = this.workspace.newBlock('test_field_block');
|
||||
block.initSvg();
|
||||
block.render();
|
||||
|
||||
var isFieldClick = gesture.isFieldClick_();
|
||||
chai.assert.isTrue(isFieldClick);
|
||||
testGestureIsFieldClick(block, true);
|
||||
});
|
||||
|
||||
function gestureIsFieldClick_InFlyoutHelper(flyout, expectedResult){
|
||||
// Assign workspace flyout
|
||||
this.workspace.flyout_ = flyout;
|
||||
// Create a Field inside of a Block
|
||||
var block = new Blockly.Block(this.workspace);
|
||||
var field = new Blockly.Field();
|
||||
field.setSourceBlock(block);
|
||||
field.showEditor_ = function() {};
|
||||
// Create gesture from the flyout
|
||||
var gesture = new Blockly.Gesture(this.e, this.workspace.flyout_);
|
||||
// Populate gesture with click start information
|
||||
gesture.setStartField(field);
|
||||
gesture.setStartFlyout_(this.workspace.flyout_);
|
||||
|
||||
var isFieldClick = gesture.isFieldClick_();
|
||||
chai.assert.equal(isFieldClick, expectedResult);
|
||||
}
|
||||
|
||||
test('Field click - Auto close flyout', function() {
|
||||
var flyout = new Blockly.VerticalFlyout(new Blockly.Options({}));
|
||||
flyout.autoClose = false;
|
||||
gestureIsFieldClick_InFlyoutHelper.call(this, flyout, true);
|
||||
var flyout = this.workspace.flyout_;
|
||||
chai.assert.exists(this.workspace.flyout_,
|
||||
'Precondition: missing flyout');
|
||||
flyout.autoClose = true;
|
||||
|
||||
var block = getTopFlyoutBlock(flyout);
|
||||
testGestureIsFieldClick(block, false);
|
||||
});
|
||||
|
||||
test('Field click - Always open flyout', function() {
|
||||
var flyout = new Blockly.VerticalFlyout(new Blockly.Options({}));
|
||||
var flyout = this.workspace.flyout_;
|
||||
chai.assert.exists(this.workspace.flyout_,
|
||||
'Precondition: missing flyout');
|
||||
flyout.autoClose = false;
|
||||
gestureIsFieldClick_InFlyoutHelper.call(this, flyout, true);
|
||||
|
||||
var block = getTopFlyoutBlock(flyout);
|
||||
testGestureIsFieldClick(block, true);
|
||||
});
|
||||
|
||||
test('Workspace click in accessibility mode - moves the cursor', function() {
|
||||
var event = {
|
||||
shiftKey : true,
|
||||
clientX : 10,
|
||||
clientY : 10,
|
||||
test('Shift click in accessibility mode - moves the cursor', function() {
|
||||
this.workspace.keyboardAccessibilityMode = true;
|
||||
|
||||
};
|
||||
var ws = Blockly.inject('blocklyDiv', {});
|
||||
ws.keyboardAccessibilityMode = true;
|
||||
var gesture = new Blockly.Gesture(event, ws);
|
||||
gesture.doWorkspaceClick_(event);
|
||||
var cursor = ws.getCursor();
|
||||
chai.assert.equal(cursor.getCurNode().getType(), Blockly.ASTNode.types.WORKSPACE);
|
||||
var eventTarget = this.workspace.svgGroup_;
|
||||
simulateClick(eventTarget, {shiftKey: true});
|
||||
|
||||
var cursor = this.workspace.getCursor();
|
||||
var cursorNode = cursor.getCurNode();
|
||||
chai.assert.exists(cursorNode);
|
||||
chai.assert.equal(cursorNode.getType(), Blockly.ASTNode.types.WORKSPACE);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -150,6 +150,10 @@
|
||||
<block type="row_block"></block>
|
||||
</xml>
|
||||
|
||||
<xml xmlns="https://developers.google.com/blockly/xml" id="gesture-test-toolbox" style="display: none">
|
||||
<block type="test_field_block"></block>
|
||||
</xml>
|
||||
|
||||
<script>
|
||||
mocha.run(function(failures) {
|
||||
var failureDiv = document.getElementById('failureCount');
|
||||
|
||||
@@ -283,6 +283,19 @@ function defineStatementBlock() {
|
||||
"helpUrl": ""
|
||||
}]);
|
||||
}
|
||||
function defineBasicBlockWithField() {
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
"type": "test_field_block",
|
||||
"message0": "%1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "field_input",
|
||||
"name": "NAME"
|
||||
}
|
||||
],
|
||||
"output": null
|
||||
}]);
|
||||
}
|
||||
|
||||
function createTestBlock() {
|
||||
return {
|
||||
@@ -300,3 +313,39 @@ function createRenderedBlock(workspaceSvg, type) {
|
||||
block.render();
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers pointer event on target.
|
||||
* @param {!EventTarget} target The object receiving the event.
|
||||
* @param {string} type The type of mouse event (eg: mousedown, mouseup,
|
||||
* click).
|
||||
* @param {Object<string, string>=} properties Properties to pass into event
|
||||
* constructor.
|
||||
*/
|
||||
function dispatchPointerEvent(target, type, properties) {
|
||||
const eventInitDict = {
|
||||
cancelable: true,
|
||||
bubbles: true,
|
||||
isPrimary: true,
|
||||
pressure: 0.5,
|
||||
clientX: 10,
|
||||
clientY: 10,
|
||||
};
|
||||
if (properties) {
|
||||
Object.assign(eventInitDict, properties);
|
||||
}
|
||||
const event = new PointerEvent(type, eventInitDict);
|
||||
target.dispatchEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates mouse click by triggering relevant mouse events.
|
||||
* @param {!EventTarget} target The object receiving the event.
|
||||
* @param {Object<string, string>=} properties Properties to pass into event
|
||||
* constructor.
|
||||
*/
|
||||
function simulateClick(target, properties) {
|
||||
dispatchPointerEvent(target, 'pointerdown', properties);
|
||||
dispatchPointerEvent(target, 'pointerup', properties);
|
||||
dispatchPointerEvent(target, 'click', properties);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user