1# XR Browser Tests
2
3[TOC]
4
5## Introduction
6
7This documentation concerns `xr_browser_test.h`, `xr_browser_test.cc`, and files
8that use them or their subclasses.
9
10These files port the framework used by XR instrumentation tests (located in
11[`//chrome/android/javatests/src/org/chromium/chrome/browser/vr/`][vr android dir]
12and documented in
13`//chrome/android/javatests/src/org/chromium/chrome/browser/vr/*.md`) for
14use in browser tests in order to test XR features on desktop platforms.
15
16[vr android dir]: https://chromium.googlesource.com/chromium/src/+/master/chrome/android/javatests/src/org/chromium/chrome/browser/vr
17
18This is pretty much a direct port, with the same JavaScript/HTML files being
19used for both and the Java/C++ code being functionally equivalent to each other,
20so the instrumentation test's documentation on writing tests using the framework
21is applicable here, too. As such, this documentation only covers any notable
22differences between the two implementations.
23
24## Restrictions
25
26Both the instrumentation tests and browser tests have hardware/software
27restrictions - in the case of browser tests, XR is only supported on Windows 8
28and later (or Windows 7 with a non-standard patch applied) with a GPU that
29supports DirectX 11.1, although several tests exist that don't actually use XR
30functionality, and thus don't have these requirements.
31
32Runtime restrictions in browser tests are handled via the macros in
33`conditional_skipping.h`. To add a runtime requirement to a test class, simply
34append it to the `runtime_requirements_` vector that each class has. The
35test setup will automatically skip tests that don't meet all requirements.
36
37One-off skipping within a test can also be done by using the XR_CONDITIONAL_SKIP
38macro directly in a test.
39
40The bots can be made to ignore these runtime requirement checks if we expect
41the requirements to always be met (and thus we want the tests to fail if they
42aren't) via the `--ignore-runtime-requirements` argument. This takes a
43comma-separated list of requirements to ignore, or the wildcard (\*) to ignore
44all requirements. For example, `--ignore-runtime-requirements=DirectX_11.1`
45would cause a test that requires a DirectX 11.1 device to be run even if a
46suitable device is not found.
47
48New requirements can be added by adding to the `XrTestRequirement` enum in
49`conditional_skipping.h` and adding its associated checking logic in
50`conditional_skipping.cc`.
51
52## Command Line Switches
53
54Instrumentation tests are able to add and remove command line switches on a
55per-test-case basis using `@CommandLine` annotations, but equivalent
56functionality does not exist in browser tests.
57
58Instead, if different command line flags are needed, a new class will need to
59be created that extends the correct type of `*BrowserTestBase` and overrides the
60flags that are set in its `SetUp` function.
61
62## Compiling And Running
63
64The tests are compiled in the `xr_browser_tests` target. This is a combination
65of the `xr_browser_tests_binary` target, which is the actual test, and the
66`xr_browser_tests_runner` target, which is a wrapper script that ensures special
67setup is completed before running the tests.
68
69Once compiled, the tests can be run using the following command line:
70
71`run_xr_browser_tests.py --enable-gpu --test-launcher-jobs=1
72--enable-pixel-output-in-tests`
73
74Additional options such as test filtering can be found by running
75`xr_browser_tests.exe --help` and `xr_browser_tests.exe --gtest_help`.
76
77Because the "test" is actually a Python wrapper script, you may need to prepend
78`python` to the front of the command on Windows if Python file association is
79not set up on your machine.
80
81## Adding New Files
82
83If you are adding a new test or infrastructure file to the target, you'll need
84to consider whether it's useful with the `enable_vr` gn arg set to false or not.
85If it is, then it should be included in `//chrome/test:xr_browser_tests_common`,
86otherwise it should be included in
87`//chrome/browser/vr:xr_browser_tests_vr_required`.
88
89If including in `//chrome/test:xr_browser_tests_common`, you may need to hide
90some VR-specific functionality in the file behind `#if BUILDFLAG(ENABLE_VR)`.
91
92## Running A Test Multiple Times With Different Runtimes
93
94The macros provided by
95[`//chrome/browser/vr/test/multi_class_browser_test.h`][multi class macros]
96provide a shorthand method for running a test multiple times with different
97classes/runtimes. This is effectively the same as declaring some implementation
98function that takes a reference to some base class shared by all the subclasses
99you want to run the test with, then having each test call that implementation.
100
101These macros help cut down on boilerplate code, but if you need either:
102
1031. Class-specific setup before running the implementation
1042. Different test logic in the implementation depending on the provided class
105
106You should consider using the standard IN_PROC_BROWSER_TEST_F macros instead.
107Small snippets of runtime-specific code are acceptable, but if it affects
108readability significantly, the tests should probably remain separate.
109
110Most tests simply use the standard `WebXrVrOpenXrBrowserTest` and
111`WebXrVrWmrBrowserTest` classes. In this case, you can instead use the
112`WEBXR_VR_ALL_RUNTIMES_BROWSER_TEST_F` macro, which only needs to take the test
113name, further cutting down on boilerplate code.
114
115You can also use `WEBXR_VR_ALL_RUNTIMES_PLUS_INCOGNITO_BROWSER_TEST_F` if you
116want the same functionality as `WEBXR_VR_ALL_RUNTIMES_BROWSER_TEST_F`, but
117also want the test run in Incognito mode in addition to regular Chrome.
118
119[multi class macros]: https://chromium.googlesource.com/chromium/src/+/master/chrome/browser/vr/test/multi_class_browser_test.h
120
121## Test Class Names
122
123The test classes that are used to provide feature and runtime-specific setup and
124functions are named in the following order:
125
1261. Feature
1272. Runtime
1283. "BrowserTest"
1294. Optional Descriptor/special flags
130
131For example, `WebXrVrOpenXrBrowserTest` is meant for testing the WebXR for VR
132feature using the OpenXR runtime with standard flags enabled, i.e. the flags
133required for using WebXR and the OpenXR runtime with other runtimes disabled.
134`WebXrVrRuntimelessBrowserTestSensorless` on the other hand would be for
135testing WebVR for VR without any runtimes and with the orientation sensor
136device explicitly disabled.
137
138In general, classes ending in "Base" should not be used directly.
139
140## Controller and Head Input
141
142The XR browser tests provide a way to plumb controller and headset data (e.g.
143currently touched/pressed buttons and poses) from the test through the runtime
144being tested. Details about what goes on under the hood can be found in
145[`//chrome/browser/vr/test/xr_browser_test_details.md`][xr details], but below
146is a quick guide on how to use them.
147
148[xr details]: https://chromium.googlesource.com/chromium/src/+/master/chrome/browser/vr/test/xr_browser_test_details.md
149
150In order to let a test provide data to a runtime, it must create an instance of
151[`MockXRDeviceHookBase`][xr hook base] or some subclass of it. This should be
152created at the beginning of the test before any attempts to enter VR are made,
153as there are currently assumptions that prevent switching to or from the mock
154runtimes once they have been attempted to be started.
155
156[xr hook base]: https://chromium.googlesource.com/chromium/src/+/master/chrome/browser/vr/test/mock_xr_device_hook_base.h
157
158Once created, the runtime being used will call the various functions inherited
159from [`VRTestHook`][vr test hook] whenever it would normally acquire or submit
160data from or to an actual device. For example, `WaitGetControllerData()` will be
161called every time the runtime would normally check the state of a real
162controller, and `OnFrameSubmitted()` will be called each time the runtime
163submits a finished frame to the headset.
164
165[vr test hook]: https://chromium.googlesource.com/chromium/src/+/master/device/vr/test/test_hook.h
166
167For real examples on how to use the input capabilities, look at the tests in
168[`//chrome/browser/vr/webxr_vr_input_browser_test.cc`][input test].
169
170[input test]: https://chromium.googlesource.com/chromium/src/+/master/chrome/browser/vr/webxr_vr_input_browser_test.cc
171