[web] rename dialog to route to match the framework (#54228)

Rename "dialog" to "route" to match the framework. The ARIA role "dialog" is an implementation detail, and it might change if a better implementation comes along. The semantic node itself implements the framework's "route" concept.
diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter
index df663d1..bbd92f1 100644
--- a/ci/licenses_golden/licenses_flutter
+++ b/ci/licenses_golden/licenses_flutter
@@ -43014,7 +43014,6 @@
 ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics.dart + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics/accessibility.dart + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics/checkable.dart + ../../../flutter/LICENSE
-ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics/dialog.dart + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics/focusable.dart + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics/heading.dart + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics/image.dart + ../../../flutter/LICENSE
@@ -43023,6 +43022,7 @@
 ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics/link.dart + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics/live_region.dart + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics/platform_view.dart + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics/route.dart + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics/scrollable.dart + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics/semantics.dart + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/semantics/semantics_helper.dart + ../../../flutter/LICENSE
@@ -45903,7 +45903,6 @@
 FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics.dart
 FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics/accessibility.dart
 FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics/checkable.dart
-FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics/dialog.dart
 FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics/focusable.dart
 FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics/heading.dart
 FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics/image.dart
@@ -45912,6 +45911,7 @@
 FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics/link.dart
 FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics/live_region.dart
 FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics/platform_view.dart
+FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics/route.dart
 FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics/scrollable.dart
 FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics/semantics.dart
 FILE: ../../../flutter/lib/web_ui/lib/src/engine/semantics/semantics_helper.dart
diff --git a/lib/web_ui/lib/src/engine.dart b/lib/web_ui/lib/src/engine.dart
index b02fd59..cdf615a 100644
--- a/lib/web_ui/lib/src/engine.dart
+++ b/lib/web_ui/lib/src/engine.dart
@@ -145,7 +145,6 @@
 export 'engine/scene_view.dart';
 export 'engine/semantics/accessibility.dart';
 export 'engine/semantics/checkable.dart';
-export 'engine/semantics/dialog.dart';
 export 'engine/semantics/focusable.dart';
 export 'engine/semantics/heading.dart';
 export 'engine/semantics/image.dart';
@@ -154,6 +153,7 @@
 export 'engine/semantics/link.dart';
 export 'engine/semantics/live_region.dart';
 export 'engine/semantics/platform_view.dart';
+export 'engine/semantics/route.dart';
 export 'engine/semantics/scrollable.dart';
 export 'engine/semantics/semantics.dart';
 export 'engine/semantics/semantics_helper.dart';
diff --git a/lib/web_ui/lib/src/engine/semantics/dialog.dart b/lib/web_ui/lib/src/engine/semantics/dialog.dart
deleted file mode 100644
index 8489667..0000000
--- a/lib/web_ui/lib/src/engine/semantics/dialog.dart
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2013 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 '../dom.dart';
-import '../semantics.dart';
-import '../util.dart';
-
-/// Provides accessibility for routes, including dialogs and pop-up menus.
-class SemanticDialog extends SemanticRole {
-  SemanticDialog(SemanticsObject semanticsObject) : super.blank(SemanticRoleKind.dialog, semanticsObject) {
-    // The following behaviors can coexist with dialog. Generic `RouteName`
-    // and `LabelAndValue` are not used by this role because when the dialog
-    // names its own route an `aria-label` is used instead of `aria-describedby`.
-    addFocusManagement();
-    addLiveRegion();
-
-    // When a route/dialog shows up it is expected that the screen reader will
-    // focus on something inside it. There could be two possibilities:
-    //
-    // 1. The framework explicitly marked a node inside the dialog as focused
-    //    via the `isFocusable` and `isFocused` flags. In this case, the node
-    //    will request focus directly and there's nothing to do on top of that.
-    // 2. No node inside the route takes focus explicitly. In this case, the
-    //    expectation is to look through all nodes in traversal order and focus
-    //    on the first one.
-    semanticsObject.owner.addOneTimePostUpdateCallback(() {
-      if (semanticsObject.owner.hasNodeRequestingFocus) {
-        // Case 1: a node requested explicit focus. Nothing extra to do.
-        return;
-      }
-
-      // Case 2: nothing requested explicit focus. Focus on the first descendant.
-      _setDefaultFocus();
-    });
-  }
-
-  void _setDefaultFocus() {
-    semanticsObject.visitDepthFirstInTraversalOrder((SemanticsObject node) {
-      final SemanticRole? role = node.semanticRole;
-      if (role == null) {
-        return true;
-      }
-
-      // If the node does not take focus (e.g. focusing on it does not make
-      // sense at all). Despair not. Keep looking.
-      final bool didTakeFocus = role.focusAsRouteDefault();
-      return !didTakeFocus;
-    });
-  }
-
-  @override
-  void update() {
-    super.update();
-
-    // If semantic object corresponding to the dialog also provides the label
-    // for itself it is applied as `aria-label`. See also [describeBy].
-    if (semanticsObject.namesRoute) {
-      final String? label = semanticsObject.label;
-      assert(() {
-        if (label == null || label.trim().isEmpty) {
-          printWarning(
-            'Semantic node ${semanticsObject.id} had both scopesRoute and '
-            'namesRoute set, indicating a self-labelled dialog, but it is '
-            'missing the label. A dialog should be labelled either by setting '
-            'namesRoute on itself and providing a label, or by containing a '
-            'child node with namesRoute that can describe it with its content.'
-          );
-        }
-        return true;
-      }());
-      setAttribute('aria-label', label ?? '');
-      setAriaRole('dialog');
-    }
-  }
-
-  /// Sets the description of this dialog based on a [RouteName] descendant
-  /// node, unless the dialog provides its own label.
-  void describeBy(RouteName routeName) {
-    if (semanticsObject.namesRoute) {
-      // The dialog provides its own label, which takes precedence.
-      return;
-    }
-
-    setAriaRole('dialog');
-    setAttribute(
-      'aria-describedby',
-      routeName.semanticsObject.element.id,
-    );
-  }
-
-  @override
-  bool focusAsRouteDefault() {
-    // Dialogs are the ones that look inside themselves to find elements to
-    // focus on. It doesn't make sense to focus on the dialog itself.
-    return false;
-  }
-}
-
-/// Supplies a description for the nearest ancestor [SemanticDialog].
-///
-/// This role is assigned to nodes that have `namesRoute` set but not
-/// `scopesRoute`. When both flags are set the node only gets the [SemanticDialog] role.
-///
-/// If the ancestor dialog is missing, this role has no effect. It is up to the
-/// framework, widget, and app authors to make sure a route name is scoped under
-/// a route.
-class RouteName extends SemanticBehavior {
-  RouteName(super.semanticsObject, super.owner);
-
-  SemanticDialog? _dialog;
-
-  @override
-  void update() {
-    // NOTE(yjbanov): this does not handle the case when the node structure
-    // changes such that this RouteName is no longer attached to the same
-    // dialog. While this is technically expressible using the semantics API,
-    // after discussing this case with customers I decided that this case is not
-    // interesting enough to support. A tree restructure like this is likely to
-    // confuse screen readers, and it would add complexity to the engine's
-    // semantics code. Since reparenting can be done with no update to either
-    // the Dialog or RouteName we'd have to scan intermediate nodes for
-    // structural changes.
-    if (!semanticsObject.namesRoute) {
-      return;
-    }
-
-    if (semanticsObject.isLabelDirty) {
-      final SemanticDialog? dialog = _dialog;
-      if (dialog != null) {
-        // Already attached to a dialog, just update the description.
-        dialog.describeBy(this);
-      } else {
-        // Setting the label for the first time. Wait for the DOM tree to be
-        // established, then find the nearest dialog and update its label.
-        semanticsObject.owner.addOneTimePostUpdateCallback(() {
-          if (!isDisposed) {
-            _lookUpNearestAncestorDialog();
-            _dialog?.describeBy(this);
-          }
-        });
-      }
-    }
-  }
-
-  void _lookUpNearestAncestorDialog() {
-    SemanticsObject? parent = semanticsObject.parent;
-    while (parent != null && parent.semanticRole?.kind != SemanticRoleKind.dialog) {
-      parent = parent.parent;
-    }
-    if (parent != null && parent.semanticRole?.kind == SemanticRoleKind.dialog) {
-      _dialog = parent.semanticRole! as SemanticDialog;
-    }
-  }
-}
diff --git a/lib/web_ui/lib/src/engine/semantics/focusable.dart b/lib/web_ui/lib/src/engine/semantics/focusable.dart
index b3289e3..54bc0d4 100644
--- a/lib/web_ui/lib/src/engine/semantics/focusable.dart
+++ b/lib/web_ui/lib/src/engine/semantics/focusable.dart
@@ -254,14 +254,14 @@
       // as it is subject to non-local effects. Let's say the framework decides
       // that a semantics node is currently not focused. That would lead to
       // changeFocus(false) to be called. However, what if this node is inside
-      // a dialog, and nothing else in the dialog is focused. The Flutter
+      // a route, and nothing else in the route is focused? The Flutter
       // framework expects that the screen reader will focus on the first (in
-      // traversal order) focusable element inside the dialog and send a
+      // traversal order) focusable element inside the route and send a
       // SemanticsAction.focus action. Screen readers on the web do not do
       // that, and so the web engine has to implement this behavior directly. So
-      // the dialog will look for a focusable element and request focus on it,
+      // the route will look for a focusable element and request focus on it,
       // but now there may be a race between this method unsetting the focus and
-      // the dialog requesting focus on the same element.
+      // the route requesting focus on the same element.
       return;
     }
 
diff --git a/lib/web_ui/lib/src/engine/semantics/route.dart b/lib/web_ui/lib/src/engine/semantics/route.dart
new file mode 100644
index 0000000..89052e6
--- /dev/null
+++ b/lib/web_ui/lib/src/engine/semantics/route.dart
@@ -0,0 +1,174 @@
+// Copyright 2013 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 '../dom.dart';
+import '../semantics.dart';
+import '../util.dart';
+
+/// Denotes that all descendant nodes are inside a route.
+///
+/// Routes can include dialogs, pop-up menus, sub-screens, and more.
+///
+/// See also:
+///
+///   * [RouteName], which provides a description for this route in the absense
+///     of an explicit route label set on the route itself.
+class SemanticRoute extends SemanticRole {
+  SemanticRoute(SemanticsObject semanticsObject) : super.blank(SemanticRoleKind.route, semanticsObject) {
+    // The following behaviors can coexist with the route. Generic `RouteName`
+    // and `LabelAndValue` are not used by this role because when the route
+    // names its own route an `aria-label` is used instead of
+    // `aria-describedby`.
+    addFocusManagement();
+    addLiveRegion();
+
+    // When a route is pushed it is expected that the screen reader will focus
+    // on something inside it. There could be two possibilities:
+    //
+    // 1. The framework explicitly marked a node inside the route as focused
+    //    via the `isFocusable` and `isFocused` flags. In this case, the node
+    //    will request focus directly and there's nothing to do on top of that.
+    // 2. No node inside the route takes focus explicitly. In this case, the
+    //    expectation is to look through all nodes in traversal order and focus
+    //    on the first one.
+    semanticsObject.owner.addOneTimePostUpdateCallback(() {
+      if (semanticsObject.owner.hasNodeRequestingFocus) {
+        // Case 1: a node requested explicit focus. Nothing extra to do.
+        return;
+      }
+
+      // Case 2: nothing requested explicit focus. Focus on the first descendant.
+      _setDefaultFocus();
+    });
+  }
+
+  void _setDefaultFocus() {
+    semanticsObject.visitDepthFirstInTraversalOrder((SemanticsObject node) {
+      final SemanticRole? role = node.semanticRole;
+      if (role == null) {
+        return true;
+      }
+
+      // If the node does not take focus (e.g. focusing on it does not make
+      // sense at all). Despair not. Keep looking.
+      final bool didTakeFocus = role.focusAsRouteDefault();
+      return !didTakeFocus;
+    });
+  }
+
+  @override
+  void update() {
+    super.update();
+
+    // If semantic object corresponding to the route also provides the label for
+    // itself it is applied as `aria-label`. See also [describeBy].
+    if (semanticsObject.namesRoute) {
+      final String? label = semanticsObject.label;
+      assert(() {
+        if (label == null || label.trim().isEmpty) {
+          printWarning(
+            'Semantic node ${semanticsObject.id} had both scopesRoute and '
+            'namesRoute set, indicating a self-labelled route, but it is '
+            'missing the label. A route should be labelled either by setting '
+            'namesRoute on itself and providing a label, or by containing a '
+            'child node with namesRoute that can describe it with its content.'
+          );
+        }
+        return true;
+      }());
+
+      setAttribute('aria-label', label ?? '');
+      _assignRole();
+    }
+  }
+
+  /// Sets the description of this route based on a [RouteName] descendant
+  /// node, unless the route provides its own label.
+  void describeBy(RouteName routeName) {
+    if (semanticsObject.namesRoute) {
+      // The route provides its own label, which takes precedence.
+      return;
+    }
+
+    _assignRole();
+    setAttribute(
+      'aria-describedby',
+      routeName.semanticsObject.element.id,
+    );
+  }
+
+  void _assignRole() {
+    // Lacking any more specific information, ARIA role "dialog" is the
+    // closest thing to Flutter's route. This can be revisited if better
+    // options become available, especially if the framework volunteers more
+    // specific information about the route. Other attributes in the vicinity
+    // of routes include: "alertdialog", `aria-modal`, "menu", "tooltip".
+    setAriaRole('dialog');
+  }
+
+  @override
+  bool focusAsRouteDefault() {
+    // Routes are the ones that look inside themselves to find elements to
+    // focus on. It doesn't make sense to focus on the route itself.
+    return false;
+  }
+}
+
+/// Supplies a description for the nearest ancestor [SemanticRoute].
+///
+/// This role is assigned to nodes that have `namesRoute` set but not
+/// `scopesRoute`. When both flags are set the node only gets the
+/// [SemanticRoute] role.
+///
+/// If the ancestor route is missing, this role has no effect. It is up to the
+/// framework, widget, and app authors to make sure a route name is scoped
+/// under a route.
+class RouteName extends SemanticBehavior {
+  RouteName(super.semanticsObject, super.owner);
+
+  SemanticRoute? _route;
+
+  @override
+  void update() {
+    // NOTE(yjbanov): this does not handle the case when the node structure
+    // changes such that this RouteName is no longer attached to the same route.
+    // While this is technically expressible using the semantics API, after
+    // discussing this case with customers I decided that this case is not
+    // interesting enough to support. A tree restructure like this is likely to
+    // confuse screen readers, and it would add complexity to the engine's
+    // semantics code. Since reparenting can be done with no update to either
+    // the SemanticRoute or RouteName we'd have to scan intermediate nodes
+    // for structural changes.
+    if (!semanticsObject.namesRoute) {
+      return;
+    }
+
+    if (semanticsObject.isLabelDirty) {
+      final SemanticRoute? route = _route;
+      if (route != null) {
+        // Already attached to a route, just update the description.
+        route.describeBy(this);
+      } else {
+        // Setting the label for the first time. Wait for the DOM tree to be
+        // established, then find the nearest route and update its label.
+        semanticsObject.owner.addOneTimePostUpdateCallback(() {
+          if (!isDisposed) {
+            _lookUpNearestAncestorRoute();
+            _route?.describeBy(this);
+          }
+        });
+      }
+    }
+  }
+
+  void _lookUpNearestAncestorRoute() {
+    SemanticsObject? parent = semanticsObject.parent;
+    while (parent != null && parent.semanticRole?.kind != SemanticRoleKind.route) {
+      parent = parent.parent;
+    }
+    if (parent != null && parent.semanticRole?.kind == SemanticRoleKind.route) {
+      _route = parent.semanticRole! as SemanticRoute;
+    }
+  }
+}
diff --git a/lib/web_ui/lib/src/engine/semantics/semantics.dart b/lib/web_ui/lib/src/engine/semantics/semantics.dart
index a35651b..9b7135c 100644
--- a/lib/web_ui/lib/src/engine/semantics/semantics.dart
+++ b/lib/web_ui/lib/src/engine/semantics/semantics.dart
@@ -20,7 +20,6 @@
 import '../window.dart';
 import 'accessibility.dart';
 import 'checkable.dart';
-import 'dialog.dart';
 import 'focusable.dart';
 import 'heading.dart';
 import 'image.dart';
@@ -29,6 +28,7 @@
 import 'link.dart';
 import 'live_region.dart';
 import 'platform_view.dart';
+import 'route.dart';
 import 'scrollable.dart';
 import 'semantics_helper.dart';
 import 'tappable.dart';
@@ -379,19 +379,19 @@
   /// There are 3 possible situations:
   ///
   /// * The node also has the `namesRoute` bit set. This means that the node's
-  ///   `label` describes the dialog, which can be expressed by adding the
+  ///   `label` describes the route, which can be expressed by adding the
   ///   `aria-label` attribute.
   /// * A descendant node has the `namesRoute` bit set. This means that the
-  ///   child's content describes the dialog. The child may simply be labelled,
-  ///   or it may be a subtree of nodes that describe the dialog together. The
+  ///   child's content describes the route. The child may simply be labelled,
+  ///   or it may be a subtree of nodes that describe the route together. The
   ///   nearest HTML equivalent is `aria-describedby`. The child acquires the
   ///   [routeName] role, which manages the relevant ARIA attributes.
   /// * There is no `namesRoute` bit anywhere in the sub-tree rooted at the
-  ///   current node. In this case it's likely not a dialog at all, and the node
+  ///   current node. In this case it's likely not a route at all, and the node
   ///   should not get a label or the "dialog" role. It's just a group of
   ///   children. For example, a modal barrier has `scopesRoute` set but marking
-  ///   it as a dialog would be wrong.
-  dialog,
+  ///   it as a route would be wrong.
+  route,
 
   /// The node's role is to host a platform view.
   platformView,
@@ -1653,7 +1653,7 @@
     } else if (isScrollContainer) {
       return SemanticRoleKind.scrollable;
     } else if (scopesRoute) {
-      return SemanticRoleKind.dialog;
+      return SemanticRoleKind.route;
     } else if (isLink) {
       return SemanticRoleKind.link;
     } else {
@@ -1668,7 +1668,7 @@
       SemanticRoleKind.incrementable => SemanticIncrementable(this),
       SemanticRoleKind.button => SemanticButton(this),
       SemanticRoleKind.checkable => SemanticCheckable(this),
-      SemanticRoleKind.dialog => SemanticDialog(this),
+      SemanticRoleKind.route => SemanticRoute(this),
       SemanticRoleKind.image => SemanticImage(this),
       SemanticRoleKind.platformView => SemanticPlatformView(this),
       SemanticRoleKind.link => SemanticLink(this),
diff --git a/lib/web_ui/test/engine/semantics/semantics_test.dart b/lib/web_ui/test/engine/semantics/semantics_test.dart
index 5c5e25f..e55fc2c 100644
--- a/lib/web_ui/test/engine/semantics/semantics_test.dart
+++ b/lib/web_ui/test/engine/semantics/semantics_test.dart
@@ -102,8 +102,8 @@
   group('group', () {
     _testGroup();
   });
-  group('dialog', () {
-    _testDialog();
+  group('route', () {
+    _testRoute();
   });
   group('focusable', () {
     _testFocusable();
@@ -2970,7 +2970,7 @@
   });
 }
 
-void _testDialog() {
+void _testRoute() {
   test('renders named and labeled routes', () {
     semantics()
       ..debugOverrideTimestampFunction(() => _testTime)
@@ -2979,7 +2979,7 @@
     final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
     updateNode(
       builder,
-      label: 'this is a dialog label',
+      label: 'this is a route label',
       flags: 0 | ui.SemanticsFlag.scopesRoute.index | ui.SemanticsFlag.namesRoute.index,
       transform: Matrix4.identity().toFloat64(),
       rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
@@ -2995,12 +2995,12 @@
 
     owner().updateSemantics(builder.build());
     expectSemanticsTree(owner(), '''
-      <sem role="dialog" aria-label="this is a dialog label"><sem-c><sem></sem></sem-c></sem>
+      <sem role="dialog" aria-label="this is a route label"><sem-c><sem></sem></sem-c></sem>
     ''');
 
     expect(
       owner().debugSemanticsTree![0]!.semanticRole?.kind,
-      SemanticRoleKind.dialog,
+      SemanticRoleKind.route,
     );
 
     semantics().semanticsEnabled = false;
@@ -3034,7 +3034,7 @@
     expect(
       warnings,
       <String>[
-        'Semantic node 0 had both scopesRoute and namesRoute set, indicating a self-labelled dialog, but it is missing the label. A dialog should be labelled either by setting namesRoute on itself and providing a label, or by containing a child node with namesRoute that can describe it with its content.',
+        'Semantic node 0 had both scopesRoute and namesRoute set, indicating a self-labelled route, but it is missing the label. A route should be labelled either by setting namesRoute on itself and providing a label, or by containing a child node with namesRoute that can describe it with its content.',
       ],
     );
 
@@ -3045,13 +3045,13 @@
 
     expect(
       owner().debugSemanticsTree![0]!.semanticRole?.kind,
-      SemanticRoleKind.dialog,
+      SemanticRoleKind.route,
     );
 
     semantics().semanticsEnabled = false;
   });
 
-  test('dialog can be described by a descendant', () {
+  test('route can be described by a descendant', () {
     semantics()
       ..debugOverrideTimestampFunction(() => _testTime)
       ..semanticsEnabled = true;
@@ -3090,11 +3090,11 @@
       ''');
     }
 
-    pumpSemantics(label: 'Dialog label');
+    pumpSemantics(label: 'Route label');
 
     expect(
       owner().debugSemanticsTree![0]!.semanticRole?.kind,
-      SemanticRoleKind.dialog,
+      SemanticRoleKind.route,
     );
     expect(
       owner().debugSemanticsTree![2]!.semanticRole?.kind,
@@ -3105,12 +3105,12 @@
       contains(RouteName),
     );
 
-    pumpSemantics(label: 'Updated dialog label');
+    pumpSemantics(label: 'Updated route label');
 
     semantics().semanticsEnabled = false;
   });
 
-  test('scopesRoute alone sets the dialog role with no label', () {
+  test('scopesRoute alone sets the SemanticRoute role with no label', () {
     final List<String> warnings = <String>[];
     printWarning = warnings.add;
 
@@ -3132,7 +3132,7 @@
 
     expect(
       owner().debugSemanticsTree![0]!.semanticRole?.kind,
-      SemanticRoleKind.dialog,
+      SemanticRoleKind.route,
     );
     expect(
       owner().debugSemanticsTree![0]!.semanticRole?.behaviors,
@@ -3190,7 +3190,7 @@
     semantics().semanticsEnabled = false;
   });
 
-  // Test the simple scenario of a dialog coming up and containing focusable
+  // Test the simple scenario of a route coming up and containing focusable
   // descendants that are not initially focused. The expectation is that the
   // first descendant will be auto-focused.
   test('focuses on the first unfocused Focusable', () async {
@@ -3248,9 +3248,9 @@
     semantics().semanticsEnabled = false;
   });
 
-  // Test the scenario of a dialog coming up and containing focusable
+  // Test the scenario of a route coming up and containing focusable
   // descendants with one of them explicitly requesting focus. The expectation
-  // is that the dialog will not attempt to auto-focus on anything and let the
+  // is that the route will not attempt to auto-focus on anything and let the
   // respective descendant take focus.
   test('does nothing if a descendant asks for focus explicitly', () async {
     semantics()
@@ -3306,7 +3306,7 @@
     semantics().semanticsEnabled = false;
   });
 
-  // Test the scenario of a dialog coming up and containing non-focusable
+  // Test the scenario of a route coming up and containing non-focusable
   // descendants that can have a11y focus. The expectation is that the first
   // descendant will be auto-focused, even if it's not input-focusable.
   test('focuses on the first non-focusable descedant', () async {
@@ -3378,8 +3378,8 @@
   });
 
   // This mostly makes sure the engine doesn't crash if given a completely empty
-  // dialog trying to find something to focus on.
-  test('does nothing if nothing is focusable inside the dialog', () async {
+  // route trying to find something to focus on.
+  test('does nothing if nothing is focusable inside the route', () async {
     semantics()
       ..debugOverrideTimestampFunction(() => _testTime)
       ..semanticsEnabled = true;