send_text_focus_semantics.dart 3.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
// Copyright 2020 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:typed_data';
import 'dart:ui';

import 'package:vector_math/vector_math_64.dart';

import 'channel_util.dart';
import 'scenario.dart';

/// A scenario that sends back messages when touches are received.
class SendTextFocusScemantics extends Scenario {
  /// Constructor for `SendTextFocusScemantics`.
  SendTextFocusScemantics(Window window) : super(window);

  @override
  void onBeginFrame(Duration duration) {
    // Doesn't matter what we draw. Just paint white.
    final SceneBuilder builder = SceneBuilder();
    final PictureRecorder recorder = PictureRecorder();
    final Canvas canvas = Canvas(recorder);

    canvas.drawRect(
      Rect.fromLTWH(0, 0, window.physicalSize.width, window.physicalSize.height),
      Paint()..color = const Color.fromARGB(255, 255, 255, 255),
    );
    final Picture picture = recorder.endRecording();

    builder.addPicture(
      Offset.zero,
      picture,
    );
    final Scene scene = builder.build();
    window.render(scene);
    scene.dispose();

    // On the first frame, also pretend that it drew a text field. Send the
    // corresponding semantics tree comprised of 1 node for the text field.
    window.updateSemantics((SemanticsUpdateBuilder()
      ..updateNode(
        id: 0,
        // SemanticsFlag.isTextField.
        flags: 16,
        // SemanticsAction.tap.
        actions: 1,
        rect: const Rect.fromLTRB(0.0, 0.0, 414.0, 48.0),
        label: 'flutter textfield',
        textDirection: TextDirection.ltr,
        textSelectionBase: -1,
        textSelectionExtent: -1,
        platformViewId: -1,
        maxValueLength: -1,
        currentValueLength: 0,
        scrollChildren: 0,
        scrollIndex: 0,
        transform: Matrix4.identity().storage,
        elevation: 0.0,
        thickness: 0.0,
        childrenInTraversalOrder: Int32List(0),
        childrenInHitTestOrder: Int32List(0),
        additionalActions: Int32List(0),
      )).build()
    );
  }

  // We don't really care about the touch itself. It's just a way for the
  // XCUITest to communicate timing to the mock framework.
  @override
  void onPointerDataPacket(PointerDataPacket packet) {
    // This mimics the framework which shows the FlutterTextInputView before
    // updating the TextInputSemanticsObject.
    sendJsonMethodCall(
      window: window,
      channel: 'flutter/textinput',
      method: 'TextInput.setClient',
      arguments: <dynamic>[
        1,
        // The arguments are text field configurations. It doesn't really matter
        // since we're just testing text field accessibility here.
        <String, dynamic>{ 'obscureText': false },
      ]
    );

    sendJsonMethodCall(
      window: window,
      channel: 'flutter/textinput',
      method: 'TextInput.show',
    );

    window.updateSemantics((SemanticsUpdateBuilder()
      ..updateNode(
        id: 0,
        // SemanticsFlag.isTextField and SemanticsFlag.isFocused.
        flags: 48,
        actions: 18433,
        rect: const Rect.fromLTRB(0.0, 0.0, 414.0, 48.0),
        label: 'focused flutter textfield',
        textDirection: TextDirection.ltr,
        textSelectionBase: 0,
        textSelectionExtent: 0,
        platformViewId: -1,
        maxValueLength: -1,
        currentValueLength: 0,
        scrollChildren: 0,
        scrollIndex: 0,
        transform: Matrix4.identity().storage,
        elevation: 0.0,
        thickness: 0.0,
        childrenInTraversalOrder: Int32List(0),
        childrenInHitTestOrder: Int32List(0),
        additionalActions: Int32List(0),
      )).build()
    );
  }
}