| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/vr/test/mock_xr_device_hook_base.h" |
| #include "chrome/browser/vr/test/multi_class_browser_test.h" |
| #include "chrome/browser/vr/test/webxr_vr_browser_test.h" |
| #include "device/vr/buildflags/buildflags.h" |
| |
| // Browser test equivalent of |
| // chrome/android/javatests/src/.../browser/vr/WebXrVrTransitionTest.java. |
| // End-to-end tests for transitioning between immersive and non-immersive |
| // sessions. |
| |
| namespace vr { |
| |
| // Tests that WebXR is not exposed if the flag is not on and the page does |
| // not have an origin trial token. |
| void TestApiDisabledWithoutFlagSetImpl(WebXrVrBrowserTestBase* t, |
| std::string filename) { |
| t->LoadFileAndAwaitInitialization(filename); |
| t->WaitOnJavaScriptStep(); |
| t->EndTest(); |
| } |
| |
| #if BUILDFLAG(ENABLE_OPENXR) |
| IN_PROC_MULTI_CLASS_BROWSER_TEST_F1(WebXrVrOpenXrBrowserTestWebXrDisabled, |
| WebXrVrBrowserTestBase, |
| TestWebXrDisabledWithoutFlagSet) { |
| TestApiDisabledWithoutFlagSetImpl(t, "test_webxr_disabled_without_flag_set"); |
| } |
| #endif // BUILDFLAG(ENABLE_OPENXR) |
| |
| // Tests that window.requestAnimationFrame continues to fire when we have a |
| // non-immersive WebXR session. |
| WEBXR_VR_ALL_RUNTIMES_BROWSER_TEST_F( |
| TestWindowRafFiresDuringNonImmersiveSession) { |
| t->LoadFileAndAwaitInitialization( |
| "test_window_raf_fires_during_non_immersive_session"); |
| t->WaitOnJavaScriptStep(); |
| t->EndTest(); |
| } |
| |
| // Tests that a successful requestPresent or requestSession call enters |
| // an immersive session. |
| void TestPresentationEntryImpl(WebXrVrBrowserTestBase* t, |
| std::string filename) { |
| t->LoadFileAndAwaitInitialization(filename); |
| t->EnterSessionWithUserGestureOrFail(); |
| t->AssertNoJavaScriptErrors(); |
| } |
| |
| WEBXR_VR_ALL_RUNTIMES_PLUS_INCOGNITO_BROWSER_TEST_F( |
| TestRequestSessionEntersVr) { |
| TestPresentationEntryImpl(t, "generic_webxr_page"); |
| } |
| |
| // Tests that window.requestAnimationFrame continues to fire while in |
| // WebXR presentation since the tab is still visible. |
| void TestWindowRafFiresWhilePresentingImpl(WebXrVrBrowserTestBase* t, |
| std::string filename) { |
| t->LoadFileAndAwaitInitialization(filename); |
| t->ExecuteStepAndWait("stepVerifyBeforePresent()"); |
| t->EnterSessionWithUserGestureOrFail(); |
| t->ExecuteStepAndWait("stepVerifyDuringPresent()"); |
| t->EndSessionOrFail(); |
| t->ExecuteStepAndWait("stepVerifyAfterPresent()"); |
| t->EndTest(); |
| } |
| |
| WEBXR_VR_ALL_RUNTIMES_BROWSER_TEST_F(TestWindowRafFiresWhilePresenting) { |
| TestWindowRafFiresWhilePresentingImpl( |
| t, "webxr_test_window_raf_fires_while_presenting"); |
| } |
| |
| // Tests that non-immersive sessions stop receiving rAFs during an immersive |
| // session, but resume once the immersive session ends. |
| WEBXR_VR_ALL_RUNTIMES_BROWSER_TEST_F(TestNonImmersiveStopsDuringImmersive) { |
| t->LoadFileAndAwaitInitialization( |
| "test_non_immersive_stops_during_immersive"); |
| t->ExecuteStepAndWait("stepBeforeImmersive()"); |
| t->EnterSessionWithUserGestureOrFail(); |
| t->ExecuteStepAndWait("stepDuringImmersive()"); |
| t->EndSessionOrFail(); |
| t->ExecuteStepAndWait("stepAfterImmersive()"); |
| t->EndTest(); |
| } |
| |
| #if BUILDFLAG(ENABLE_OPENXR) |
| // Tests that WebXR session ends when certain events are received. |
| void TestWebXRSessionEndWhenEventTriggered( |
| WebXrVrBrowserTestBase* t, |
| device_test::mojom::EventType event_type) { |
| MockXRDeviceHookBase transition_mock; |
| t->LoadFileAndAwaitInitialization("test_webxr_presentation_ended"); |
| t->EnterSessionWithUserGestureOrFail(); |
| |
| // Wait for JavaScript to submit at least one frame. |
| ASSERT_TRUE( |
| t->PollJavaScriptBoolean("hasPresentedFrame", t->kPollTimeoutMedium)) |
| << "No frame submitted"; |
| device_test::mojom::EventData data = {}; |
| data.type = event_type; |
| transition_mock.PopulateEvent(data); |
| // Tell JavaScript that it is done with the test. |
| t->WaitOnJavaScriptStep(); |
| t->EndTest(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(WebXrVrOpenXrBrowserTest, TestSessionEnded) { |
| TestWebXRSessionEndWhenEventTriggered( |
| this, device_test::mojom::EventType::kSessionLost); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(WebXrVrOpenXrBrowserTest, TestInsanceLost) { |
| TestWebXRSessionEndWhenEventTriggered( |
| this, device_test::mojom::EventType::kInstanceLost); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(WebXrVrOpenXrBrowserTest, TestSessionExited) { |
| // Set the device up to reject the session request. This should translate to |
| // immediately translating the device to the "Exited" state. |
| MockXRDeviceHookBase transition_mock; |
| transition_mock.SetCanCreateSession(false); |
| |
| this->LoadFileAndAwaitInitialization("generic_webxr_page"); |
| |
| // Not using "EnterSessionWithUserGestureOrFail" because we actually expect |
| // the session to reject. So instead we check that an error got set. |
| this->EnterSessionWithUserGesture(); |
| this->PollJavaScriptBooleanOrFail( |
| "sessionInfos[sessionTypes.IMMERSIVE].error != null", kPollTimeoutLong); |
| |
| // Tell JavaScript that it is done with the test. |
| this->RunJavaScriptOrFail("done()"); |
| this->EndTest(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(WebXrVrOpenXrBrowserTest, TestVisibilityChanged) { |
| MockXRDeviceHookBase transition_mock; |
| this->LoadFileAndAwaitInitialization("webxr_test_visibility_changed"); |
| this->EnterSessionWithUserGestureOrFail(); |
| |
| // Wait for JavaScript to submit at least one frame. |
| ASSERT_TRUE(this->PollJavaScriptBoolean("hasPresentedFrame", |
| this->kPollTimeoutMedium)) |
| << "No frame submitted"; |
| |
| this->PollJavaScriptBooleanOrFail("isVisibilityEqualTo('visible')", |
| this->kPollTimeoutMedium); |
| |
| device_test::mojom::EventData event_data = {}; |
| event_data.type = device_test::mojom::EventType::kVisibilityVisibleBlurred; |
| transition_mock.PopulateEvent(event_data); |
| |
| // TODO(crbug.com/40646813): visible-blurred is forced to hidden in WebXR |
| this->PollJavaScriptBooleanOrFail("isVisibilityEqualTo('hidden')", |
| this->kPollTimeoutMedium); |
| this->RunJavaScriptOrFail("done()"); |
| this->EndTest(); |
| } |
| #endif // BUILDFLAG(ENABLE_OPENXR) |
| |
| } // namespace vr |