Repository: flutter
Issue: [go_router] Fail to restore widget states after "restart and restore" when using go_router
Labels: package,has reproducible steps,P2,p: go_router,found in release: 3.3,found in release: 3.7,team-go_router,triaged-go_router

## Steps to Reproduce

Given two similar `MaterialApp`, one using `go_router` and one who doesn't, the one using `go_router` is unable to restore the screen state when the app is restarted.

The best way to see this problem is by running the included code sample.

Their implementation is very similar:

```dart
  MaterialApp.router(
      restorationScopeId: 'app',
      routerConfig: GoRouter(
        restorationScopeId: 'router',
        routes: [
          GoRoute(
            path: '/',
            builder: (context, state) => const ScrollScreen(),
          ),
        ],
      ),
    );
```

and:

```dart
  MaterialApp(
      restorationScopeId: 'app',
      home: ScrollScreen(),
    );
```

The one using `GoRouter` is unable to restore the state of the `ScrollScreen` when the app is restarted.

You can see this behavior with the attached widget tests in the "code" section.

I've looked for similar reported issues, but I couldn't find one that explains this exact problem:

- The example in https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/others/state_restoration.dart shows how to do state restoration for `GoRouter`, which *does not* restore the state of the Pages, only the state of the `GoRouter` (e.g. the location)
- https://github.com/flutter/flutter/issues/99124 is similar, but it refers to the restoration of pages while the app is still in use, e.g. navigating from Page1 to Page2 and keeping the state of Page1. This is a similar problem, however is not the same use-case, so I don't think this is a duplicated of that issue.
- This is a problem that I am facing while trying to migrate the sample app "veggieseasons" to use `go_router`, at first I have thought this was a problem with `ShellRoute` but I have reduced the problem to a minimal example that doesn't use `ShellRoute`. Link to the WIP PR: https://github.com/flutter/samples/pull/1544

**Expected results:** 

Both cases should work the same way. The screen state should be restored after restart just like when using a `MaterialApp` without `GoRouter`

**Actual results:** 

In this case, the state of the screen when using `GoRouter` is not restored, and this can be seen by using the included widget tests.

<details>
<summary>Code sample</summary>

Add `go_router` to your project, then paste the following three classes into your main.dart.

Also, copy the two widget tests into your widget_test.dart to run them.

First class is the `AppGoRoute`, which is a simple `MaterialApp` that uses `GoRouter`.

```dart
class AppGoRoute extends StatelessWidget {
  const AppGoRoute({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      restorationScopeId: 'app',
      title: 'Flutter Demo',
      routerConfig: GoRouter(
        restorationScopeId: 'router',
        routes: [
          GoRoute(
            path: '/',
            builder: (context, state) => const ScrollScreen(),
          ),
        ],
      ),
    );
  }
}
```

The second class is `AppSimple`, which is a simple `MaterialApp` that doesn't use `GoRouter`.

```dart
class AppSimple extends StatelessWidget {
  const AppSimple({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      restorationScopeId: 'app',
      title: 'Flutter Demo',
      home: ScrollScreen(),
    );
  }
}
```

`ScrollScreen` is a simple `Scaffold` with a `ListView` of a 1000 items.

```dart
class ScrollScreen extends StatelessWidget {
  const ScrollScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      restorationId: 'scroll-screen',
      body: ListView.builder(
        restorationId: 'list',
        itemCount: 1000,
        itemBuilder: (context, index) => ListTile(
          title: Text('Item $index'),
        ),
      ),
    );
  }
}
```

Test 1: Fails: This test fails, as when the screen state is restored, the scroll position is lost and is back at the item 0.

This test uses the `AppGoRoute`, which uses `GoRouter` internally to handle navigation.

```dart
  testWidgets('restoration test go_router', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(
      const RootRestorationScope(
        restorationId: 'root',
        child: AppGoRoute(),
      ),
    );

    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 500'), findsNothing);

    await tester.scrollUntilVisible(
      find.text('Item 100'),
      10,
      maxScrolls: 10000,
    );

    expect(find.text('Item 0'), findsNothing);
    expect(find.text('Item 100'), findsOneWidget);

    await tester.restartAndRestore();

    // scroll position restored
    expect(find.text('Item 0'), findsNothing); // <-- fails here
    expect(find.text('Item 100'), findsOneWidget);
  });
```

Test 2: Passes. 

This test uses `AppSimple`, same test content, and the test passes.

```dart
  testWidgets('restoration test without go_router', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(
      const RootRestorationScope(
        restorationId: 'root',
        child: AppSimple(),
      ),
    );

    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 500'), findsNothing);

    await tester.scrollUntilVisible(
      find.text('Item 100'),
      10,
      maxScrolls: 10000,
    );

    expect(find.text('Item 0'), findsNothing);
    expect(find.text('Item 100'), findsOneWidget);

    await tester.restartAndRestore();

    // scroll position restored
    expect(find.text('Item 0'), findsNothing);
    expect(find.text('Item 100'), findsOneWidget);
  });
```

</details>

<details>
  <summary>Logs</summary>

These are the test results:

```
/home/miquel/dev/tools/flutter/bin/flutter --no-color test --machine --start-paused test/widget_test.dart
Testing started at 16:17 ...

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: no matching nodes in the widget tree
  Actual: _TextFinder:<exactly one widget with text "Item 0" (ignoring offstage widgets): Text("Item
0", dependencies: [DefaultSelectionStyle, DefaultTextStyle, MediaQuery])>
   Which: means one was found but none were expected

When the exception was thrown, this was the stack:
#4      main.<anonymous closure> (file:///home/miquel/tmp/go_route_push_shell/test/widget_test.dart:38:5)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

This was caught by the test expectation on the following line:
  file:///home/miquel/tmp/go_route_push_shell/test/widget_test.dart line 38
The test description was:
  restoration test go_router
════════════════════════════════════════════════════════════════════════════════════════════════════

Test failed. See exception logs above.
The test description was: restoration test go_router
```

```
flutter analyze
Analyzing go_route_push_shell...                                        
No issues found! (ran in 1.0s)

```

```
flutter doctor -v
[✓] Flutter (Channel stable, 3.3.10, on Ubuntu 22.04.1 LTS 5.15.0-56-generic, locale en_US.UTF-8)
    • Flutter version 3.3.10 on channel stable at /home/miquel/dev/tools/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 135454af32 (12 days ago), 2022-12-15 07:36:55 -0800
    • Engine revision 3316dd8728
    • Dart version 2.18.6
    • DevTools version 2.15.0

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.1)
    • Android SDK at /home/miquel/Android/Sdk
    • Platform android-33, build-tools 33.0.1
    • Java binary at:
      /home/miquel/.local/share/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335/jre/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
    • All Android licenses accepted.

[✓] Chrome - develop for the web
    • Chrome at google-chrome

[✓] Linux toolchain - develop for Linux desktop
    • Homebrew clang version 15.0.5
    • cmake version 3.22.1
    • ninja version 1.10.1
    • pkg-config version 0.29.2

[✓] Android Studio (version 2021.3)
    • Android Studio at /home/miquel/.local/share/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[✓] IntelliJ IDEA Community Edition (version 2022.3)
    • IntelliJ at /home/miquel/.local/share/JetBrains/Toolbox/apps/IDEA-C/ch-0/223.8214.52
    • Flutter plugin version 71.2.6
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart

[✓] VS Code (version 1.66.2)
    • VS Code at /usr/share/code
    • Flutter extension version 3.40.0

[✓] VS Code
    • VS Code at /snap/code/current
    • Flutter extension version 3.40.0

[✓] Connected device (2 available)
    • Linux (desktop) • linux  • linux-x64      • Ubuntu 22.04.1 LTS 5.15.0-56-generic
    • Chrome (web)    • chrome • web-javascript • Google Chrome 108.0.5359.124

[✓] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!

```

</details>