testSelectionChangeOnMouseUp() {
    /** @suppress {checkTypes} suppression added to enable type checking */
    const fakeEvent = new BrowserEvent({type: 'mouseup', target: 'fakeTarget'});
    const editableField = new FieldConstructor('testField', document);
    const clock = new MockClock(true);
    const beforeSelectionChanges = recordFunction();
    events.listen(
        editableField, Field.EventType.BEFORESELECTIONCHANGE,
        beforeSelectionChanges);
    const selectionChanges = recordFunction();
    events.listen(
        editableField, Field.EventType.SELECTIONCHANGE, selectionChanges);

    const plugin = new TestPlugin();
    plugin.handleSelectionChange = recordFunction();
    editableField.registerPlugin(plugin);

    editableField.makeEditable();

    // Emulate a mouseup event, this should result in immediate
    // BEFORESELECTIONCHANGE and SELECTIONCHANGE, plus a second
    // SELECTIONCHANGE in IE after a short timeout.
    editableField.handleMouseUp_(fakeEvent);
    assertEquals(
        'Before selection change should fire immediately', 1,
        beforeSelectionChanges.getCallCount());
    assertEquals(
        'Selection change should fire immediately', 1,
        selectionChanges.getCallCount());
    assertEquals(
        'Plugin should have handled selection change immediately', 1,
        plugin.handleSelectionChange.getCallCount());
    assertEquals(
        'Plugin should have received original browser event to handle',
        fakeEvent,
        plugin.handleSelectionChange.getLastCall().getArguments()[0]);

    // Pretend another plugin fired a SELECTIONCHANGE in the meantime.
    editableField.dispatchSelectionChangeEvent();
    assertEquals(
        'Second selection change should fire immediately', 2,
        selectionChanges.getCallCount());
    assertEquals(
        'Plugin should have handled second selection change immediately', 2,
        plugin.handleSelectionChange.getCallCount());
    /**
     * @suppress {missingProperties} suppression added to enable type
     * checking
     */
    const args = plugin.handleSelectionChange.getLastCall().getArguments();
    assertTrue(
        'Plugin should not have received data from extra firing',
        args.length == 0 || !args[0] && (args.length == 1 || !args[1]));

    // Now check for the extra call in IE.
    clock.tick(1000);
    if (userAgent.IE) {
      assertEquals(
          'Additional selection change should fire within 1s', 3,
          selectionChanges.getCallCount());
      assertEquals(
          'Plugin should have handled selection change within 1s', 3,
          plugin.handleSelectionChange.getCallCount());
      assertEquals(
          'Plugin should have received target of original browser event',
          fakeEvent.target,
          plugin.handleSelectionChange.getLastCall().getArguments().pop());
    } else {
      assertEquals(
          'No additional selection change should fire', 2,
          selectionChanges.getCallCount());
      assertEquals(
          'Plugin should not have handled selection change again', 2,
          plugin.handleSelectionChange.getCallCount());
    }

    clock.dispose();
    editableField.dispose();
  }
@suppress {missingProperties} suppression added to enable type
     checking