1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
|
// 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.
#ifndef CHROME_BROWSER_VR_TEST_XR_BROWSER_TEST_H_
#define CHROME_BROWSER_VR_TEST_XR_BROWSER_TEST_H_
#include <unordered_set>
#include "base/environment.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/vr/test/conditional_skipping.h"
#include "chrome/test/base/platform_browser_test.h"
#include "device/vr/public/cpp/features.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "url/gurl.h"
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#endif
namespace content {
class WebContents;
}
namespace vr {
// Base browser test class for running XR-related tests.
// This is essentially a C++ port of the way Android does similar tests in
// //chrome/android/javatests/src/.../browser/vr/XrTestFramework.java
// This must be subclassed for different XR features to handle the differences
// between APIs and different usecases of the same API.
class XrBrowserTestBase : public PlatformBrowserTest {
public:
static constexpr base::TimeDelta kPollCheckIntervalShort =
base::Milliseconds(50);
static constexpr base::TimeDelta kPollCheckIntervalLong =
base::Milliseconds(100);
static constexpr base::TimeDelta kPollTimeoutShort = base::Milliseconds(1000);
static constexpr base::TimeDelta kPollTimeoutMedium =
base::Milliseconds(5000);
static constexpr base::TimeDelta kPollTimeoutLong = base::Milliseconds(10000);
static constexpr char kOpenXrConfigPathEnvVar[] = "XR_RUNTIME_JSON";
static constexpr char kOpenXrConfigPathVal[] =
"./mock_vr_clients/bin/openxr/openxr.json";
static constexpr char kTestFileDir[] =
"chrome/test/data/xr/e2e_test_files/html/";
static constexpr char kSwitchIgnoreRuntimeRequirements[] =
"ignore-runtime-requirements";
static const std::vector<std::string> kRequiredTestSwitches;
static const std::vector<std::pair<std::string, std::string>>
kRequiredTestSwitchesWithValues;
enum class TestStatus {
STATUS_RUNNING = 0,
STATUS_PASSED = 1,
STATUS_FAILED = 2
};
enum class RuntimeType {
RUNTIME_NONE = 0,
RUNTIME_OPENXR = 3
};
XrBrowserTestBase();
XrBrowserTestBase(const XrBrowserTestBase&) = delete;
XrBrowserTestBase& operator=(const XrBrowserTestBase&) = delete;
~XrBrowserTestBase() override;
void SetUp() override;
void TearDown() override;
virtual RuntimeType GetRuntimeType() const;
// Convenience function for accessing the WebContents belonging to the current
// tab open in the browser.
content::WebContents* GetCurrentWebContents();
// Loads the given GURL and blocks until the JavaScript on the page has
// signalled that pre-test initialization is complete.
void LoadFileAndAwaitInitialization(const std::string& url);
// Convenience function for ensuring the given JavaScript runs successfully
// without having to always surround in ASSERT_TRUE.
void RunJavaScriptOrFail(const std::string& js_expression,
content::WebContents* web_contents);
// Convenience function for ensuring EvalJs runs successfully.
bool RunJavaScriptAndExtractBoolOrFail(const std::string& js_expression,
content::WebContents* web_contents);
// Convenience function for ensuring EvalJs runs successfully.
std::string RunJavaScriptAndExtractStringOrFail(
const std::string& js_expression,
content::WebContents* web_contents);
// Blocks until the given JavaScript expression evaluates to true or the
// timeout is reached. Returns true if the expression evaluated to true or
// false on timeout.
bool PollJavaScriptBoolean(const std::string& bool_expression,
const base::TimeDelta& timeout,
content::WebContents* web_contents);
// Polls the provided JavaScript boolean expression, failing the test if it
// does not evaluate to true within the provided timeout.
void PollJavaScriptBooleanOrFail(const std::string& bool_expression,
const base::TimeDelta& timeout,
content::WebContents* web_contents);
// Blocks until the given callback returns true or the timeout is reached.
// Fills the given bool with true if the condition successfully resolved or
// false on timeout.
void BlockOnCondition(base::RepeatingCallback<bool()> condition,
bool* result,
base::RunLoop* wait_loop,
const base::Time& start_time,
const base::TimeDelta& timeout = kPollTimeoutLong,
const base::TimeDelta& period = kPollCheckIntervalLong);
// Blocks until the JavaScript in the given WebContents signals that it is
// finished.
void WaitOnJavaScriptStep(content::WebContents* web_contents);
// Executes the given step/JavaScript expression and blocks until JavaScript
// signals that it is finished.
void ExecuteStepAndWait(const std::string& step_function,
content::WebContents* web_contents);
// Retrieves the current status of the JavaScript test and returns an enum
// corresponding to it.
TestStatus CheckTestStatus(content::WebContents* web_contents);
// Asserts that the JavaScript test code completed successfully.
void EndTest(content::WebContents* web_contents);
// Asserts that the JavaScript test harness did not detect any failures.
// Similar to EndTest, but does not fail if the test is still detected as
// running. This is useful because not all tests make use of the test harness'
// test/assert features, but may still want to ensure that no unexpected
// JavaScript errors were encountered.
void AssertNoJavaScriptErrors(content::WebContents* web_contents);
void SetIncognito();
void OpenNewTab(const std::string& url);
void OpenNewTab(const std::string& url, bool incognito);
// Convenience function for running RunJavaScriptOrFail with the return value
// of GetCurrentWebContents.
void RunJavaScriptOrFail(const std::string& js_expression);
// Convenience function for running RunJavaScriptAndExtractBoolOrFail with the
// return value of GetCurrentWebContents.
bool RunJavaScriptAndExtractBoolOrFail(const std::string& js_expression);
// Convenience function for running RunJavaScriptAndExtractStringOrFail with
// the return value of GetCurrentWebContents.
std::string RunJavaScriptAndExtractStringOrFail(
const std::string& js_expression);
// Convenience function for running PollJavaScriptBoolean with the return
// value of GetCurrentWebContents.
bool PollJavaScriptBoolean(const std::string& bool_expression,
const base::TimeDelta& timeout);
// Convenience function for running PollJavaScriptBooleanOrFail with the
// return value of GetCurrentWebContents.
void PollJavaScriptBooleanOrFail(
const std::string& bool_expression,
const base::TimeDelta& timeout = kPollTimeoutShort);
// Convenience function for running WaitOnJavaScriptStep with the return value
// of GetCurrentWebContents.
void WaitOnJavaScriptStep();
// Convenience function for running ExecuteStepAndWait with the return value
// of GetCurrentWebContents.
void ExecuteStepAndWait(const std::string& step_function);
// Convenience function for running EndTest with the return value of
// GetCurrentWebContents.
void EndTest();
// Convenience function for running AssertNoJavaScriptErrors with the return
// value of GetCurrentWebContents.
void AssertNoJavaScriptErrors();
// Returns the set of runtime requirements to ignore, i.e. if a requirement
// is in the vector, tests should not be skipped even if they don't meet the
// requirement.
std::unordered_set<std::string> GetIgnoredRuntimeRequirements() {
return ignored_requirements_;
}
protected:
// Called at the start of |LoadFileAndAwaitInitialization| to allow base
// classes to manage any logic that they may want to manage.
virtual void OnBeforeLoadFile() {}
std::unique_ptr<base::Environment> env_;
std::vector<base::test::FeatureRef> enable_features_;
std::vector<base::test::FeatureRef> disable_features_;
std::vector<XrTestRequirement> runtime_requirements_;
std::unordered_set<std::string> ignored_requirements_;
std::optional<std::string> forced_runtime_;
#if BUILDFLAG(IS_WIN)
HWND hwnd_;
#endif
private:
void LogJavaScriptFailure();
// Returns a GURL to the XR test HTML file of the given name served through
// the local server.
GURL GetUrlForFile(const std::string& test_name);
// Returns a pointer to the embedded test server capable of serving test
// HTML files, initializing and starting the server if necessary.
net::EmbeddedTestServer* GetEmbeddedServer();
std::unique_ptr<net::EmbeddedTestServer> server_;
base::test::ScopedFeatureList scoped_feature_list_;
bool test_skipped_at_startup_ = false;
bool javascript_failed_ = false;
bool incognito_ = false;
};
} // namespace vr
#endif // CHROME_BROWSER_VR_TEST_XR_BROWSER_TEST_H_
|