Track the OS for browser platforms (#2449)

We currently do not allow making configuration using tools like
`OnPlatform` that is specific to an OS and browser combination. So if
there is a situation where tests don't work on firefox on windows, but
work everywhere else, we cannot express an intent to skip just the
failing tests.

In a usage like `OnPlatform({'windows && firefox'})` the selector will
never be true because `firefox` and `windows` are mutually exclusive.
It does allow cases like `'windows || firefox'` which matches windows VM
tests and firefox everywhere.

Changing this means a change to how existing selectors are evaluated. CI
may be impacted if a package is configuring a skip for an OS expecting
only the VM tests to be skipped on that OS with the browser tests still
running.

Use the new capability to skip a test that is failing on windows firefox
browser.
diff --git a/integration_tests/wasm/test/hello_world_test.dart b/integration_tests/wasm/test/hello_world_test.dart
index 0cd7997..a4fab2d 100644
--- a/integration_tests/wasm/test/hello_world_test.dart
+++ b/integration_tests/wasm/test/hello_world_test.dart
@@ -4,7 +4,7 @@
 
 @TestOn('wasm')
 // TODO: https://github.com/dart-lang/test/issues/2288
-@OnPlatform({'firefox': Skip()})
+@OnPlatform({'windows && firefox': Skip()})
 // This retry is a regression test for https://github.com/dart-lang/test/issues/2006
 @Retry(2)
 library;
diff --git a/pkgs/test/CHANGELOG.md b/pkgs/test/CHANGELOG.md
index 1c60dcd..66d75f8 100644
--- a/pkgs/test/CHANGELOG.md
+++ b/pkgs/test/CHANGELOG.md
@@ -1,5 +1,16 @@
 ## 1.31.2-wip
 
+* **Impacts Configuration** Support using the OS platform selector to configure
+  browser tests.
+  Previously tests loaded for the browser would have an operating system of
+  "none", now they will have an operating system matching the system the browser
+  is running on. This allows more specific configuration, such as skipping a
+  particular browser test on a particular platform. This may impact existing
+  configuration which relied on the configuration for browser tests being
+  independent from any OS specific configuration. For instance a wide skip of
+  all tests with OS `'windows'` would previously still run browser tests on
+  windows, but will now skip all tests including browser tests.
+
 ## 1.31.1
 
 * Ignore an error locating the SDK directory on platforms where the
diff --git a/pkgs/test_api/CHANGELOG.md b/pkgs/test_api/CHANGELOG.md
index ab2859b..3f36614 100644
--- a/pkgs/test_api/CHANGELOG.md
+++ b/pkgs/test_api/CHANGELOG.md
@@ -1,6 +1,7 @@
 ## 0.7.13-wip
 
 * Expose several more backend APIs for use in `flutter_test`.
+* Allow using browser platforms with a specified OS.
 
 ## 0.7.12
 
diff --git a/pkgs/test_api/lib/src/backend/suite_platform.dart b/pkgs/test_api/lib/src/backend/suite_platform.dart
index 241c432..82f17a1 100644
--- a/pkgs/test_api/lib/src/backend/suite_platform.dart
+++ b/pkgs/test_api/lib/src/backend/suite_platform.dart
@@ -38,9 +38,6 @@
     this.os = OperatingSystem.none,
     this.inGoogle = false,
   }) : compiler = compiler ?? runtime.defaultCompiler {
-    if (runtime.isBrowser && os != OperatingSystem.none) {
-      throw ArgumentError('No OS should be passed for runtime "$runtime".');
-    }
     if (!runtime.supportedCompilers.contains(this.compiler)) {
       throw ArgumentError(
         'The platform $runtime does not support the compiler ${this.compiler}',
diff --git a/pkgs/test_core/CHANGELOG.md b/pkgs/test_core/CHANGELOG.md
index fe47567..b0e5659 100644
--- a/pkgs/test_core/CHANGELOG.md
+++ b/pkgs/test_core/CHANGELOG.md
@@ -1,5 +1,7 @@
 ## 0.6.19-wip
 
+* Support using the OS platform selector to configure browser tests.
+
 ## 0.6.18
 
 * Ignore an error locating the SDK directory on platforms where the
diff --git a/pkgs/test_core/lib/src/util/io.dart b/pkgs/test_core/lib/src/util/io.dart
index 1951a91..02c56cd 100644
--- a/pkgs/test_core/lib/src/util/io.dart
+++ b/pkgs/test_core/lib/src/util/io.dart
@@ -60,7 +60,7 @@
     SuitePlatform(
       runtime,
       compiler: compiler,
-      os: runtime.isBrowser ? OperatingSystem.none : currentOS,
+      os: currentOS,
       inGoogle: inGoogle,
     );