// Copyright 2014 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:core' hide print;
import 'dart:io' hide exit;

import 'package:path/path.dart' as path;
import 'package:shelf/shelf.dart';

import 'browser.dart';
import 'run_command.dart';
import 'test/common.dart';
import 'utils.dart';

final String _bat = Platform.isWindows ? '.bat' : '';
final String _flutterRoot = path.dirname(path.dirname(path.dirname(path.fromUri(Platform.script))));
final String _flutter = path.join(_flutterRoot, 'bin', 'flutter$_bat');
final String _testAppDirectory = path.join(_flutterRoot, 'dev', 'integration_tests', 'web');
final String _testAppWebDirectory = path.join(_testAppDirectory, 'web');
final String _appBuildDirectory = path.join(_testAppDirectory, 'build', 'web');
final String _target = path.join('lib', 'service_worker_test.dart');
final String _targetWithCachedResources = path.join('lib', 'service_worker_test_cached_resources.dart');
final String _targetWithBlockedServiceWorkers = path.join('lib', 'service_worker_test_blocked_service_workers.dart');
final String _targetPath = path.join(_testAppDirectory, _target);

enum ServiceWorkerTestType {
  // Mocks how FF disables service workers.
  blockedServiceWorkers,
  // Drops the main.dart.js directly on the page.
  withoutFlutterJs,
  // Uses the standard, promise-based, flutterJS initialization.
  withFlutterJs,
  // Uses the shorthand engineInitializer.autoStart();
  withFlutterJsShort,
  // Uses onEntrypointLoaded callback instead of returned promise.
  withFlutterJsEntrypointLoadedEvent,
  // Same as withFlutterJsEntrypointLoadedEvent, but with TrustedTypes enabled.
  withFlutterJsTrustedTypesOn,
  // Entrypoint generated by `flutter create`.
  generatedEntrypoint,
}

// Run a web service worker test as a standalone Dart program.
Future<void> main() async {
  // When updating this list, also update `dev/bots/test.dart`. This `main()`
  // function is only here for convenience. Adding tests here will not add them
  // to LUCI.
  await runWebServiceWorkerTest(headless: false, testType: ServiceWorkerTestType.withoutFlutterJs);
  await runWebServiceWorkerTest(headless: false, testType: ServiceWorkerTestType.withFlutterJs);
  await runWebServiceWorkerTest(headless: false, testType: ServiceWorkerTestType.withFlutterJsShort);
  await runWebServiceWorkerTest(headless: false, testType: ServiceWorkerTestType.withFlutterJsEntrypointLoadedEvent);
  await runWebServiceWorkerTest(headless: false, testType: ServiceWorkerTestType.withFlutterJsTrustedTypesOn);
  await runWebServiceWorkerTestWithCachingResources(headless: false, testType: ServiceWorkerTestType.withoutFlutterJs);
  await runWebServiceWorkerTestWithCachingResources(headless: false, testType: ServiceWorkerTestType.withFlutterJs);
  await runWebServiceWorkerTestWithCachingResources(headless: false, testType: ServiceWorkerTestType.withFlutterJsShort);
  await runWebServiceWorkerTestWithCachingResources(headless: false, testType: ServiceWorkerTestType.withFlutterJsEntrypointLoadedEvent);
  await runWebServiceWorkerTestWithCachingResources(headless: false, testType: ServiceWorkerTestType.withFlutterJsTrustedTypesOn);
  await runWebServiceWorkerTestWithGeneratedEntrypoint(headless: false);
  await runWebServiceWorkerTestWithBlockedServiceWorkers(headless: false);

  if (hasError) {
    reportErrorsAndExit('${bold}One or more tests failed.$reset');
  }
  reportSuccessAndExit('${bold}Tests successful.$reset');
}

// Regression test for https://github.com/flutter/flutter/issues/109093.
//
// Tests the entrypoint that's generated by `flutter create`.
Future<void> runWebServiceWorkerTestWithGeneratedEntrypoint({
  required bool headless,
}) async {
  await _generateEntrypoint();
  await runWebServiceWorkerTestWithCachingResources(headless: headless, testType: ServiceWorkerTestType.generatedEntrypoint);
}

Future<void> _generateEntrypoint() async {
  final Directory tempDirectory = Directory.systemTemp.createTempSync('flutter_web_generated_entrypoint.');
  await runCommand(
    _flutter,
    <String>[ 'create', 'generated_entrypoint_test' ],
    workingDirectory: tempDirectory.path,
  );
  final File generatedEntrypoint = File(path.join(tempDirectory.path, 'generated_entrypoint_test', 'web', 'index.html'));
  final String generatedEntrypointCode = generatedEntrypoint.readAsStringSync();
  final File testEntrypoint = File(path.join(
    _testAppWebDirectory,
    _testTypeToIndexFile(ServiceWorkerTestType.generatedEntrypoint),
  ));
  testEntrypoint.writeAsStringSync(generatedEntrypointCode);
  tempDirectory.deleteSync(recursive: true);
}

Future<void> _setAppVersion(int version) async {
  final File targetFile = File(_targetPath);
  await targetFile.writeAsString(
    (await targetFile.readAsString()).replaceFirst(
      RegExp(r'CLOSE\?version=\d+'),
      'CLOSE?version=$version',
    )
  );
}

String _testTypeToIndexFile(ServiceWorkerTestType type) {
  late String indexFile;
  switch (type) {
    case ServiceWorkerTestType.blockedServiceWorkers:
      indexFile = 'index_with_blocked_service_workers.html';
      break;
    case ServiceWorkerTestType.withFlutterJs:
      indexFile = 'index_with_flutterjs.html';
      break;
    case ServiceWorkerTestType.withoutFlutterJs:
      indexFile = 'index_without_flutterjs.html';
      break;
    case ServiceWorkerTestType.withFlutterJsShort:
      indexFile = 'index_with_flutterjs_short.html';
      break;
    case ServiceWorkerTestType.withFlutterJsEntrypointLoadedEvent:
      indexFile = 'index_with_flutterjs_entrypoint_loaded.html';
      break;
    case ServiceWorkerTestType.withFlutterJsTrustedTypesOn:
      indexFile = 'index_with_flutterjs_el_tt_on.html';
      break;
    case ServiceWorkerTestType.generatedEntrypoint:
      indexFile = 'generated_entrypoint.html';
      break;
  }
  return indexFile;
}

Future<void> _rebuildApp({ required int version, required ServiceWorkerTestType testType, required String target }) async {
  await _setAppVersion(version);
  await runCommand(
    _flutter,
    <String>[ 'clean' ],
    workingDirectory: _testAppDirectory,
  );
  await runCommand(
    'cp',
    <String>[
      _testTypeToIndexFile(testType),
      'index.html',
    ],
    workingDirectory: _testAppWebDirectory,
  );
  await runCommand(
    _flutter,
    <String>['build', 'web', '--profile', '-t', target],
    workingDirectory: _testAppDirectory,
    environment: <String, String>{
      'FLUTTER_WEB': 'true',
    },
  );
}

void _expectRequestCounts(
    Map<String, int> expectedCounts,
    Map<String, int> requestedPathCounts,
) {
  expect(requestedPathCounts, expectedCounts);
  requestedPathCounts.clear();
}

Future<void> _waitForAppToLoad(
    Map<String, int> waitForCounts,
    Map<String, int> requestedPathCounts,
    AppServer? server
) async {
  print('Waiting for app to load $waitForCounts');
  await Future.any(<Future<Object?>>[
    () async {
      while (!waitForCounts.entries.every((MapEntry<String, int> entry) => (requestedPathCounts[entry.key] ?? 0) >= entry.value)) {
        await Future<void>.delayed(const Duration(milliseconds: 100));
      }
    }(),
    server!.onChromeError.then((String error) {
      throw Exception('Chrome error: $error');
    }),
  ]);
}

/// A drop-in replacement for `package:test` expect that can run outside the
/// test zone.
void expect(Object? actual, Object? expected) {
  final Matcher matcher = wrapMatcher(expected);
  // matchState needs to be of type <Object?, Object?>, see https://github.com/flutter/flutter/issues/99522
  final Map<Object?, Object?> matchState = <Object?, Object?>{};
  if (matcher.matches(actual, matchState)) {
    return;
  }
  final StringDescription mismatchDescription = StringDescription();
  matcher.describeMismatch(actual, mismatchDescription, matchState, true);
  throw TestFailure(mismatchDescription.toString());
}

Future<void> runWebServiceWorkerTest({
  required bool headless,
  required ServiceWorkerTestType testType,
}) async {
  final Map<String, int> requestedPathCounts = <String, int>{};
  void expectRequestCounts(Map<String, int> expectedCounts) =>
      _expectRequestCounts(expectedCounts, requestedPathCounts);

  AppServer? server;
  Future<void> waitForAppToLoad(Map<String, int> waitForCounts) async =>
      _waitForAppToLoad(waitForCounts, requestedPathCounts, server);

  String? reportedVersion;

  Future<void> startAppServer({
    required String cacheControl,
  }) async {
    final int serverPort = await findAvailablePortAndPossiblyCauseFlakyTests();
    final int browserDebugPort = await findAvailablePortAndPossiblyCauseFlakyTests();
    server = await AppServer.start(
      headless: headless,
      cacheControl: cacheControl,
      // TODO(yjbanov): use a better port disambiguation strategy than trying
      //                to guess what ports other tests use.
      appUrl: 'http://localhost:$serverPort/index.html',
      serverPort: serverPort,
      browserDebugPort: browserDebugPort,
      appDirectory: _appBuildDirectory,
      additionalRequestHandlers: <Handler>[
        (Request request) {
          final String requestedPath = request.url.path;
          requestedPathCounts.putIfAbsent(requestedPath, () => 0);
          requestedPathCounts[requestedPath] = requestedPathCounts[requestedPath]! + 1;
          if (requestedPath == 'CLOSE') {
            reportedVersion = request.url.queryParameters['version'];
            return Response.ok('OK');
          }
          return Response.notFound('');
        },
      ],
    );
  }

  // Preserve old index.html as index_og.html so we can restore it later for other tests
  await runCommand(
    'mv',
    <String>[
      'index.html',
      'index_og.html',
    ],
    workingDirectory: _testAppWebDirectory,
  );

  final bool shouldExpectFlutterJs = testType != ServiceWorkerTestType.withoutFlutterJs;

  print('BEGIN runWebServiceWorkerTest(headless: $headless, testType: $testType)');

  try {
    /////
    // Attempt to load a different version of the service worker!
    /////
    await _rebuildApp(version: 1, testType: testType, target: _target);

    print('Call update() on the current web worker');
    await startAppServer(cacheControl: 'max-age=0');
    await waitForAppToLoad(<String, int> {
      if (shouldExpectFlutterJs)
        'flutter.js': 1,
      'CLOSE': 1,
    });
    expect(reportedVersion, '1');
    reportedVersion = null;

    await server!.chrome.reloadPage(ignoreCache: true);
    await waitForAppToLoad(<String, int> {
      if (shouldExpectFlutterJs)
        'flutter.js': 2,
      'CLOSE': 2,
    });
    expect(reportedVersion, '1');
    reportedVersion = null;

    await _rebuildApp(version: 2, testType: testType, target: _target);

    await server!.chrome.reloadPage(ignoreCache: true);
    await waitForAppToLoad(<String, int>{
      if (shouldExpectFlutterJs)
        'flutter.js': 3,
      'CLOSE': 3,
    });
    expect(reportedVersion, '2');

    reportedVersion = null;
    requestedPathCounts.clear();
    await server!.stop();

    //////////////////////////////////////////////////////
    // Caching server
    //////////////////////////////////////////////////////
    await _rebuildApp(version: 1, testType: testType, target: _target);

    print('With cache: test first page load');
    await startAppServer(cacheControl: 'max-age=3600');
    await waitForAppToLoad(<String, int>{
      'CLOSE': 1,
      'flutter_service_worker.js': 1,
    });

    expectRequestCounts(<String, int>{
      // Even though the server is caching index.html is downloaded twice,
      // once by the initial page load, and once by the service worker.
      // Other resources are loaded once only by the service worker.
      'index.html': 2,
      if (shouldExpectFlutterJs)
        'flutter.js': 1,
      'main.dart.js': 1,
      'flutter_service_worker.js': 1,
      'assets/FontManifest.json': 1,
      'assets/AssetManifest.json': 1,
      'assets/fonts/MaterialIcons-Regular.otf': 1,
      'CLOSE': 1,
      // In headless mode Chrome does not load 'manifest.json' and 'favicon.ico'.
      if (!headless)
        ...<String, int>{
          'manifest.json': 1,
          'favicon.ico': 1,
        },
    });
    expect(reportedVersion, '1');
    reportedVersion = null;

    print('With cache: test page reload');
    await server!.chrome.reloadPage();
    await waitForAppToLoad(<String, int>{
      'CLOSE': 1,
      'flutter_service_worker.js': 1,
    });

    expectRequestCounts(<String, int>{
      'flutter_service_worker.js': 1,
      'CLOSE': 1,
    });
    expect(reportedVersion, '1');
    reportedVersion = null;

    print('With cache: test page reload after rebuild');
    await _rebuildApp(version: 2, testType: testType, target: _target);

    // Since we're caching, we need to ignore cache when reloading the page.
    await server!.chrome.reloadPage(ignoreCache: true);
    await waitForAppToLoad(<String, int>{
      'CLOSE': 1,
      'flutter_service_worker.js': 2,
    });
    expectRequestCounts(<String, int>{
      'index.html': 2,
      if (shouldExpectFlutterJs)
        'flutter.js': 1,
      'flutter_service_worker.js': 2,
      'main.dart.js': 1,
      'assets/AssetManifest.json': 1,
      'assets/FontManifest.json': 1,
      'CLOSE': 1,
      if (!headless)
        'favicon.ico': 1,
    });

    expect(reportedVersion, '2');
    reportedVersion = null;
    await server!.stop();


    //////////////////////////////////////////////////////
    // Non-caching server
    //////////////////////////////////////////////////////
    print('No cache: test first page load');
    await _rebuildApp(version: 3, testType: testType, target: _target);
    await startAppServer(cacheControl: 'max-age=0');
    await waitForAppToLoad(<String, int>{
      'CLOSE': 1,
      'flutter_service_worker.js': 1,
    });

    expectRequestCounts(<String, int>{
      'index.html': 2,
      if (shouldExpectFlutterJs)
        'flutter.js': 1,
      'main.dart.js': 1,
      'assets/FontManifest.json': 1,
      'flutter_service_worker.js': 1,
      'assets/AssetManifest.json': 1,
      'assets/fonts/MaterialIcons-Regular.otf': 1,
      'CLOSE': 1,
      // In headless mode Chrome does not load 'manifest.json' and 'favicon.ico'.
      if (!headless)
        ...<String, int>{
          'manifest.json': 1,
          'favicon.ico': 1,
        },
    });

    expect(reportedVersion, '3');
    reportedVersion = null;

    print('No cache: test page reload');
    await server!.chrome.reloadPage();
    await waitForAppToLoad(<String, int>{
      'CLOSE': 1,
      if (shouldExpectFlutterJs)
        'flutter.js': 1,
      'flutter_service_worker.js': 1,
    });

    expectRequestCounts(<String, int>{
      if (shouldExpectFlutterJs)
        'flutter.js': 1,
      'flutter_service_worker.js': 1,
      'CLOSE': 1,
      if (!headless)
        'manifest.json': 1,
    });
    expect(reportedVersion, '3');
    reportedVersion = null;

    print('No cache: test page reload after rebuild');
    await _rebuildApp(version: 4, testType: testType, target: _target);

    // TODO(yjbanov): when running Chrome with DevTools protocol, for some
    // reason a hard refresh is still required. This works without a hard
    // refresh when running Chrome manually as normal. At the time of writing
    // this test I wasn't able to figure out what's wrong with the way we run
    // Chrome from tests.
    await server!.chrome.reloadPage(ignoreCache: true);
    await waitForAppToLoad(<String, int>{
      'CLOSE': 1,
      'flutter_service_worker.js': 1,
    });
    expectRequestCounts(<String, int>{
      'index.html': 2,
      if (shouldExpectFlutterJs)
        'flutter.js': 1,
      'flutter_service_worker.js': 2,
      'main.dart.js': 1,
      'assets/AssetManifest.json': 1,
      'assets/FontManifest.json': 1,
      'CLOSE': 1,
      if (!headless)
        ...<String, int>{
          'manifest.json': 1,
          'favicon.ico': 1,
        },
    });

    expect(reportedVersion, '4');
    reportedVersion = null;
  } finally {
    await runCommand(
      'mv',
      <String>[
        'index_og.html',
        'index.html',
      ],
      workingDirectory: _testAppWebDirectory,
    );
    await _setAppVersion(1);
    await server?.stop();
  }

  print('END runWebServiceWorkerTest(headless: $headless, testType: $testType)');
}

Future<void> runWebServiceWorkerTestWithCachingResources({
  required bool headless,
  required ServiceWorkerTestType testType
}) async {
  final Map<String, int> requestedPathCounts = <String, int>{};
  void expectRequestCounts(Map<String, int> expectedCounts) =>
      _expectRequestCounts(expectedCounts, requestedPathCounts);

  AppServer? server;
  Future<void> waitForAppToLoad(Map<String, int> waitForCounts) async =>
      _waitForAppToLoad(waitForCounts, requestedPathCounts, server);

  Future<void> startAppServer({
    required String cacheControl,
  }) async {
    final int serverPort = await findAvailablePortAndPossiblyCauseFlakyTests();
    final int browserDebugPort = await findAvailablePortAndPossiblyCauseFlakyTests();
    server = await AppServer.start(
      headless: headless,
      cacheControl: cacheControl,
      // TODO(yjbanov): use a better port disambiguation strategy than trying
      //                to guess what ports other tests use.
      appUrl: 'http://localhost:$serverPort/index.html',
      serverPort: serverPort,
      browserDebugPort: browserDebugPort,
      appDirectory: _appBuildDirectory,
      additionalRequestHandlers: <Handler>[
            (Request request) {
          final String requestedPath = request.url.path;
          requestedPathCounts.putIfAbsent(requestedPath, () => 0);
          requestedPathCounts[requestedPath] = requestedPathCounts[requestedPath]! + 1;
          if (requestedPath == 'assets/fonts/MaterialIcons-Regular.otf') {
            return Response.internalServerError();
          }
          return Response.notFound('');
        },
      ],
    );
  }

  // Preserve old index.html as index_og.html so we can restore it later for other tests
  await runCommand(
    'mv',
    <String>[
      'index.html',
      'index_og.html',
    ],
    workingDirectory: _testAppWebDirectory,
  );

  final bool shouldExpectFlutterJs = testType != ServiceWorkerTestType.withoutFlutterJs;

  print('BEGIN runWebServiceWorkerTestWithCachingResources(headless: $headless, testType: $testType)');

  try {
    //////////////////////////////////////////////////////
    // Caching server
    //////////////////////////////////////////////////////
    await _rebuildApp(version: 1, testType: testType, target: _targetWithCachedResources);

    print('With cache: test first page load');
    await startAppServer(cacheControl: 'max-age=3600');
    await waitForAppToLoad(<String, int>{
      'assets/fonts/MaterialIcons-Regular.otf': 1,
      'flutter_service_worker.js': 1,
    });

    expectRequestCounts(<String, int>{
      // Even though the server is caching index.html is downloaded twice,
      // once by the initial page load, and once by the service worker.
      // Other resources are loaded once only by the service worker.
      'index.html': 2,
      if (shouldExpectFlutterJs)
        'flutter.js': 1,
      'main.dart.js': 1,
      'flutter_service_worker.js': 1,
      'assets/FontManifest.json': 1,
      'assets/AssetManifest.json': 1,
      'assets/fonts/MaterialIcons-Regular.otf': 1,
      // In headless mode Chrome does not load 'manifest.json' and 'favicon.ico'.
      if (!headless)
        ...<String, int>{
          'manifest.json': 1,
          'favicon.ico': 1,
        },
    });

    print('With cache: test first page reload');
    await server!.chrome.reloadPage();
    await waitForAppToLoad(<String, int>{
      'assets/fonts/MaterialIcons-Regular.otf': 1,
      'flutter_service_worker.js': 1,
    });
    expectRequestCounts(<String, int>{
      'assets/fonts/MaterialIcons-Regular.otf': 1,
      'flutter_service_worker.js': 1,
    });

    print('With cache: test second page reload');
    await server!.chrome.reloadPage();
    await waitForAppToLoad(<String, int>{
      'assets/fonts/MaterialIcons-Regular.otf': 1,
      'flutter_service_worker.js': 1,
    });
    expectRequestCounts(<String, int>{
      'assets/fonts/MaterialIcons-Regular.otf': 1,
      'flutter_service_worker.js': 1,
    });

    print('With cache: test third page reload');
    await server!.chrome.reloadPage();
    await waitForAppToLoad(<String, int>{
      'assets/fonts/MaterialIcons-Regular.otf': 1,
      'flutter_service_worker.js': 1,
    });
    expectRequestCounts(<String, int>{
      'assets/fonts/MaterialIcons-Regular.otf': 1,
      'flutter_service_worker.js': 1,
    });

    print('With cache: test page reload after rebuild');
    await _rebuildApp(version: 1, testType: testType, target: _targetWithCachedResources);

    // Since we're caching, we need to ignore cache when reloading the page.
    await server!.chrome.reloadPage(ignoreCache: true);
    await waitForAppToLoad(<String, int>{
      'assets/fonts/MaterialIcons-Regular.otf': 1,
      'flutter_service_worker.js': 1,
    });
    expectRequestCounts(<String, int>{
      'index.html': 2,
      if (shouldExpectFlutterJs)
        'flutter.js': 1,
      'main.dart.js': 1,
      'flutter_service_worker.js': 2,
      'assets/FontManifest.json': 1,
      'assets/AssetManifest.json': 1,
      'assets/fonts/MaterialIcons-Regular.otf': 1,
      // In headless mode Chrome does not load 'manifest.json' and 'favicon.ico'.
      if (!headless)
        ...<String, int>{
          'favicon.ico': 1,
        },
    });
  } finally {
    await runCommand(
      'mv',
      <String>[
        'index_og.html',
        'index.html',
      ],
      workingDirectory: _testAppWebDirectory,
    );
    await server?.stop();
  }

  print('END runWebServiceWorkerTestWithCachingResources(headless: $headless, testType: $testType)');
}

Future<void> runWebServiceWorkerTestWithBlockedServiceWorkers({
  required bool headless
}) async {
  final Map<String, int> requestedPathCounts = <String, int>{};
  void expectRequestCounts(Map<String, int> expectedCounts) =>
      _expectRequestCounts(expectedCounts, requestedPathCounts);

  AppServer? server;
  Future<void> waitForAppToLoad(Map<String, int> waitForCounts) async =>
      _waitForAppToLoad(waitForCounts, requestedPathCounts, server);

  Future<void> startAppServer({
    required String cacheControl,
  }) async {
    final int serverPort = await findAvailablePortAndPossiblyCauseFlakyTests();
    final int browserDebugPort = await findAvailablePortAndPossiblyCauseFlakyTests();
    server = await AppServer.start(
      headless: headless,
      cacheControl: cacheControl,
      // TODO(yjbanov): use a better port disambiguation strategy than trying
      //                to guess what ports other tests use.
      appUrl: 'http://localhost:$serverPort/index.html',
      serverPort: serverPort,
      browserDebugPort: browserDebugPort,
      appDirectory: _appBuildDirectory,
      additionalRequestHandlers: <Handler>[
        (Request request) {
          final String requestedPath = request.url.path;
          requestedPathCounts.putIfAbsent(requestedPath, () => 0);
          requestedPathCounts[requestedPath] = requestedPathCounts[requestedPath]! + 1;
          if (requestedPath == 'CLOSE') {
            return Response.ok('OK');
          }
          return Response.notFound('');
        },
      ],
    );
  }

  // Preserve old index.html as index_og.html so we can restore it later for other tests
  await runCommand(
    'mv',
    <String>[
      'index.html',
      'index_og.html',
    ],
    workingDirectory: _testAppWebDirectory,
  );

  print('BEGIN runWebServiceWorkerTestWithBlockedServiceWorkers(headless: $headless)');
  try {
    await _rebuildApp(version: 1, testType: ServiceWorkerTestType.blockedServiceWorkers, target: _targetWithBlockedServiceWorkers);

    print('Ensure app starts (when service workers are blocked)');
    await startAppServer(cacheControl: 'max-age=3600');
    await waitForAppToLoad(<String, int>{
      'CLOSE': 1,
    });
    expectRequestCounts(<String, int>{
      'index.html': 1,
      'flutter.js': 1,
      'main.dart.js': 1,
      'assets/FontManifest.json': 1,
      'assets/fonts/MaterialIcons-Regular.otf': 1,
      'CLOSE': 1,
      // In headless mode Chrome does not load 'manifest.json' and 'favicon.ico'.
      if (!headless)
        ...<String, int>{
          'manifest.json': 1,
          'favicon.ico': 1,
        },
    });
  } finally {
    await runCommand(
      'mv',
      <String>[
        'index_og.html',
        'index.html',
      ],
      workingDirectory: _testAppWebDirectory,
    );
    await server?.stop();
  }
  print('END runWebServiceWorkerTestWithBlockedServiceWorkers(headless: $headless)');
}
