Add mojo conformance validation test to ts/js bindings
Design doc: go/conformancets This change adds the mojo conformance validation test to the js/ts bindings. The test cases are read and parsed by the C++ side. A new mojo service is introduced to plumb the test cases to the typescript. On the typescript side, a new receiver/remote pair is created for each test case, then the buffer is manually injected into the receiver's message router. This allows us to bypass the underlying C-runtime and directly pass the message to the js message handler. This does require adding a new test method in mojojs' interface support library. Unfortunately, error reporting/handling is very inconsistent in the js bindings. A combination of console.error, console.assert, exception throwing, and onError callbacks are used to report errors. Therefore we need to override all those functions to determine whether or not a mojo error has been reported for a given buffer. Bug: 376760886 Change-Id: I5f21d933c0325cf937009df604ddf27d4cb89bdb Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5817681 Commit-Queue: Fred Shih <ffred@chromium.org> Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com> Reviewed-by: Rebekah Potter <rbpotter@chromium.org> Reviewed-by: Yuzhu Shen <yzshen@chromium.org> Reviewed-by: Charlie Reis <creis@chromium.org> Cr-Commit-Position: refs/heads/main@{#1379210}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
77fffdfcf4
commit
040bcbd09c
content
browser
test
mojo/public
ui/webui/resources/mojo
@ -2,11 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifdef UNSAFE_BUFFERS_BUILD
|
||||
// TODO(crbug.com/342213636): Remove this and spanify to fix the errors.
|
||||
#pragma allow_unsafe_buffers
|
||||
#endif
|
||||
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
|
||||
@ -166,7 +161,7 @@ class TestWebUIController : public WebUIController {
|
||||
{BindingsPolicyValue::kMojoWebUi}))
|
||||
: WebUIController(web_ui) {
|
||||
const base::span<const webui::ResourcePath> kMojoWebUiResources =
|
||||
base::make_span(kWebUiMojoTestResources, kWebUiMojoTestResourcesSize);
|
||||
base::make_span(kWebUiMojoTestResources);
|
||||
|
||||
web_ui->SetBindings(bindings);
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
|
225
content/browser/webui/web_ui_mojo_conformance_browsertest.cc
Normal file
225
content/browser/webui/web_ui_mojo_conformance_browsertest.cc
Normal file
@ -0,0 +1,225 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
|
||||
#include "base/base_paths.h"
|
||||
#include "base/containers/span.h"
|
||||
#include "base/files/file_enumerator.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/location.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/task/sequenced_task_runner.h"
|
||||
#include "base/test/bind.h"
|
||||
#include "content/browser/webui/url_data_source_impl.h"
|
||||
#include "content/browser/webui/web_ui_impl.h"
|
||||
#include "content/public/browser/web_ui_controller.h"
|
||||
#include "content/public/browser/web_ui_controller_interface_binder.h"
|
||||
#include "content/public/browser/web_ui_data_source.h"
|
||||
#include "content/public/common/bindings_policy.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "content/public/test/browser_test.h"
|
||||
#include "content/public/test/browser_test_utils.h"
|
||||
#include "content/public/test/content_browser_test.h"
|
||||
#include "content/public/test/content_browser_test_content_browser_client.h"
|
||||
#include "content/public/test/content_browser_test_utils.h"
|
||||
#include "content/public/test/scoped_web_ui_controller_factory_registration.h"
|
||||
#include "content/public/test/test_utils.h"
|
||||
#include "content/public/test/web_ui_browsertest_util.h"
|
||||
#include "content/shell/browser/shell.h"
|
||||
#include "content/test/grit/web_ui_mojo_test_resources.h"
|
||||
#include "content/test/grit/web_ui_mojo_test_resources_map.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "mojo/public/cpp/bindings/tests/validation_test_input_parser.h"
|
||||
#include "mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom.h"
|
||||
#include "ui/base/webui/resource_path.h"
|
||||
|
||||
namespace content {
|
||||
namespace {
|
||||
|
||||
std::vector<base::FilePath> EnumerateFilesInDirectory(
|
||||
const base::FilePath& dir,
|
||||
const base::FilePath::StringType& pattern) {
|
||||
std::vector<base::FilePath> test_files;
|
||||
|
||||
base::FileEnumerator e(dir, false, base::FileEnumerator::FILES, pattern);
|
||||
e.ForEach([&test_files](const base::FilePath& file_path) -> void {
|
||||
test_files.push_back(file_path);
|
||||
});
|
||||
|
||||
return test_files;
|
||||
}
|
||||
|
||||
// Reads the content of a file to a string. Crashes if reading failed.
|
||||
std::string ReadFile(const base::FilePath& file_path) {
|
||||
std::string content;
|
||||
CHECK(base::ReadFileToString(file_path, &content));
|
||||
return std::string(
|
||||
base::TrimWhitespaceASCII(content, base::TrimPositions::TRIM_TRAILING));
|
||||
}
|
||||
|
||||
std::vector<mojo::test::TestCasePtr> ParseTestCases() {
|
||||
base::FilePath base_dir;
|
||||
base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &base_dir);
|
||||
const auto test_dir_relative_path = base::FilePath::FromASCII(
|
||||
"mojo/public/interfaces/bindings/tests/data/"
|
||||
"validation/");
|
||||
base::FilePath test_cases_dir = base_dir.Append(test_dir_relative_path);
|
||||
std::vector<base::FilePath> test_cases = EnumerateFilesInDirectory(
|
||||
test_cases_dir, FILE_PATH_LITERAL("conformance_*.data"));
|
||||
|
||||
std::vector<mojo::test::TestCasePtr> parsed_test_cases;
|
||||
for (const base::FilePath& test_file : test_cases) {
|
||||
std::string test_data_raw = ReadFile(test_file);
|
||||
|
||||
std::vector<uint8_t> bytes;
|
||||
size_t num_handles;
|
||||
std::string error_msg;
|
||||
CHECK(mojo::test::ParseValidationTestInput(test_data_raw, &bytes,
|
||||
&num_handles, &error_msg));
|
||||
|
||||
std::string expectation = ReadFile(
|
||||
test_file.RemoveFinalExtension().AddExtensionASCII("expected"));
|
||||
|
||||
parsed_test_cases.push_back(mojo::test::TestCase::New(
|
||||
test_file.BaseName().RemoveFinalExtension().MaybeAsASCII(), bytes,
|
||||
expectation));
|
||||
}
|
||||
CHECK(parsed_test_cases.size() > 0)
|
||||
<< "No test cases were found, there might be an issue with pathing, "
|
||||
"looked at: "
|
||||
<< test_cases_dir;
|
||||
|
||||
return parsed_test_cases;
|
||||
}
|
||||
|
||||
// WebUIController that sets up mojo bindings.
|
||||
class ConformanceTestWebUIController : public WebUIController,
|
||||
public mojo::test::PageHandlerFactory {
|
||||
public:
|
||||
explicit ConformanceTestWebUIController(WebUI* web_ui)
|
||||
: WebUIController(web_ui) {
|
||||
const base::span<const webui::ResourcePath> kMojoWebUiResources =
|
||||
base::make_span(kWebUiMojoTestResources);
|
||||
|
||||
web_ui->SetBindings(
|
||||
{BindingsPolicyValue::kMojoWebUi, BindingsPolicyValue::kWebUi});
|
||||
WebUIDataSource* data_source = WebUIDataSource::CreateAndAdd(
|
||||
web_ui->GetWebContents()->GetBrowserContext(),
|
||||
"mojo-web-ui-conformance");
|
||||
data_source->OverrideContentSecurityPolicy(
|
||||
network::mojom::CSPDirectiveName::ScriptSrc,
|
||||
"script-src chrome://resources 'self';");
|
||||
data_source->AddResourcePaths(kMojoWebUiResources);
|
||||
data_source->AddResourcePath("", IDR_WEB_UI_TS_TEST_CONFORMANCE_HTML);
|
||||
}
|
||||
|
||||
ConformanceTestWebUIController(const ConformanceTestWebUIController&) =
|
||||
delete;
|
||||
ConformanceTestWebUIController& operator=(
|
||||
const ConformanceTestWebUIController&) = delete;
|
||||
|
||||
void BindInterface(
|
||||
mojo::PendingReceiver<mojo::test::PageHandlerFactory> receiver) {
|
||||
page_factory_receiver_.reset();
|
||||
page_factory_receiver_.Bind(std::move(receiver));
|
||||
}
|
||||
|
||||
private:
|
||||
void GetTestCases(GetTestCasesCallback cb) override {
|
||||
base::ThreadPool::PostTask(
|
||||
FROM_HERE, {base::MayBlock()},
|
||||
base::BindOnce(
|
||||
[](GetTestCasesCallback cb,
|
||||
const scoped_refptr<base::SequencedTaskRunner>& runner) {
|
||||
auto test_cases = ParseTestCases();
|
||||
runner->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(std::move(cb), std::move(test_cases)));
|
||||
},
|
||||
std::move(cb), base::SequencedTaskRunner::GetCurrentDefault()));
|
||||
}
|
||||
|
||||
mojo::Receiver<mojo::test::PageHandlerFactory> page_factory_receiver_{this};
|
||||
|
||||
WEB_UI_CONTROLLER_TYPE_DECL();
|
||||
};
|
||||
|
||||
WEB_UI_CONTROLLER_TYPE_IMPL(ConformanceTestWebUIController)
|
||||
|
||||
class ConformanceTestWebUIControllerFactory : public WebUIControllerFactory {
|
||||
public:
|
||||
ConformanceTestWebUIControllerFactory() = default;
|
||||
ConformanceTestWebUIControllerFactory(const TestWebUIControllerFactory&) =
|
||||
delete;
|
||||
ConformanceTestWebUIControllerFactory& operator=(
|
||||
const TestWebUIControllerFactory&) = delete;
|
||||
|
||||
std::unique_ptr<WebUIController> CreateWebUIControllerForURL(
|
||||
WebUI* web_ui,
|
||||
const GURL& url) override {
|
||||
return std::make_unique<ConformanceTestWebUIController>(web_ui);
|
||||
}
|
||||
|
||||
WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
|
||||
const GURL& url) override {
|
||||
if (!url.SchemeIs(kChromeUIScheme)) {
|
||||
return WebUI::kNoWebUI;
|
||||
}
|
||||
return reinterpret_cast<WebUI::TypeID>(1);
|
||||
}
|
||||
|
||||
bool UseWebUIForURL(BrowserContext* browser_context,
|
||||
const GURL& url) override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class ConformanceTestWebUIClient
|
||||
: public ContentBrowserTestContentBrowserClient {
|
||||
public:
|
||||
ConformanceTestWebUIClient() = default;
|
||||
ConformanceTestWebUIClient(const ConformanceTestWebUIClient&) = delete;
|
||||
ConformanceTestWebUIClient& operator=(const ConformanceTestWebUIClient&) =
|
||||
delete;
|
||||
|
||||
void RegisterBrowserInterfaceBindersForFrame(
|
||||
RenderFrameHost* render_frame_host,
|
||||
mojo::BinderMapWithContext<content::RenderFrameHost*>* map) override {
|
||||
RegisterWebUIControllerInterfaceBinder<mojo::test::PageHandlerFactory,
|
||||
ConformanceTestWebUIController>(map);
|
||||
}
|
||||
};
|
||||
|
||||
class WebUIMojoConformanceTest : public ContentBrowserTest {
|
||||
public:
|
||||
WebUIMojoConformanceTest() = default;
|
||||
WebUIMojoConformanceTest(const WebUIMojoConformanceTest&) = delete;
|
||||
WebUIMojoConformanceTest& operator=(const WebUIMojoConformanceTest&) = delete;
|
||||
|
||||
protected:
|
||||
void SetUpOnMainThread() override {
|
||||
client_ = std::make_unique<ConformanceTestWebUIClient>();
|
||||
}
|
||||
void TearDownOnMainThread() override {}
|
||||
|
||||
ConformanceTestWebUIControllerFactory factory_;
|
||||
ScopedWebUIControllerFactoryRegistration factory_registration_{&factory_};
|
||||
std::unique_ptr<ConformanceTestWebUIClient> client_;
|
||||
};
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(WebUIMojoConformanceTest, ConformanceTest) {
|
||||
EXPECT_TRUE(NavigateToURL(shell(), GURL("data:,foo")));
|
||||
|
||||
GURL kTestUrl(GetWebUIURL("mojo-web-ui-conformance/"));
|
||||
const std::string kTestScript = "runTest();";
|
||||
EXPECT_TRUE(NavigateToURL(shell(), kTestUrl));
|
||||
EXPECT_EQ(true, EvalJs(shell()->web_contents(), kTestScript));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace content
|
@ -1232,6 +1232,7 @@ preprocess_if_expr("preprocess_mojo_webui_test") {
|
||||
in_folder = "./data"
|
||||
out_folder = "$target_gen_dir/data"
|
||||
in_files = [
|
||||
"web_ui_mojo_conformance_test.ts",
|
||||
"web_ui_mojo_ts_test.ts",
|
||||
"web_ui_mojo_ts_test_converters.ts",
|
||||
"web_ui_mojo_ts_test_mapped_types.ts",
|
||||
@ -1240,10 +1241,21 @@ preprocess_if_expr("preprocess_mojo_webui_test") {
|
||||
]
|
||||
}
|
||||
|
||||
preprocess_if_expr("preprocess_mojo_webui_test_deps") {
|
||||
in_folder = "$root_gen_dir/mojo/public/interfaces/bindings/tests"
|
||||
out_folder = "$target_gen_dir/data"
|
||||
in_files = [ "validation_test_interfaces.mojom-webui.ts" ]
|
||||
deps = [
|
||||
"//mojo/public/interfaces/bindings/tests:test_interfaces_ts__generator",
|
||||
]
|
||||
}
|
||||
|
||||
webui_ts_library("web_ui_mojo_test_build_ts") {
|
||||
root_dir = "$target_gen_dir/data"
|
||||
out_dir = "$target_gen_dir/data/tsc"
|
||||
in_files = [
|
||||
"validation_test_interfaces.mojom-webui.ts",
|
||||
"web_ui_mojo_conformance_test.ts",
|
||||
"web_ui_mojo_ts_test.ts",
|
||||
"web_ui_mojo_ts_test_converters.ts",
|
||||
"web_ui_mojo_ts_test_mapped_types.ts",
|
||||
@ -1259,6 +1271,7 @@ webui_ts_library("web_ui_mojo_test_build_ts") {
|
||||
deps = [ "//ui/webui/resources/mojo:build_ts" ]
|
||||
extra_deps = [
|
||||
":preprocess_mojo_webui_test",
|
||||
":preprocess_mojo_webui_test_deps",
|
||||
":web_ui_managed_interface_tests_bindings_ts__generator",
|
||||
":web_ui_ts_test_mojo_bindings_ts__generator",
|
||||
":web_ui_ts_test_other_mojo_bindings_ts__generator",
|
||||
@ -1735,6 +1748,7 @@ test("content_browsertests") {
|
||||
"../browser/webui/web_ui_browsertest.cc",
|
||||
"../browser/webui/web_ui_managed_interface_browsertest.cc",
|
||||
"../browser/webui/web_ui_mojo_browsertest.cc",
|
||||
"../browser/webui/web_ui_mojo_conformance_browsertest.cc",
|
||||
"../browser/webui/web_ui_navigation_browsertest.cc",
|
||||
"../browser/webui/web_ui_security_browsertest.cc",
|
||||
"../browser/worker_host/worker_browsertest.cc",
|
||||
@ -1866,8 +1880,11 @@ test("content_browsertests") {
|
||||
"//media:test_support",
|
||||
"//media/webrtc",
|
||||
"//mojo/core/embedder",
|
||||
"//mojo/core/test:test_support",
|
||||
"//mojo/public/cpp/bindings",
|
||||
"//mojo/public/cpp/bindings/tests:mojo_public_bindings_test_utils",
|
||||
"//mojo/public/cpp/test_support:test_utils",
|
||||
"//mojo/public/interfaces/bindings/tests:test_interfaces",
|
||||
"//net:quic_test_tools",
|
||||
"//net:simple_quic_tools",
|
||||
"//net:test_support",
|
||||
@ -1950,6 +1967,7 @@ test("content_browsertests") {
|
||||
data = [
|
||||
"data/",
|
||||
"//media/test/data/",
|
||||
"//mojo/public/interfaces/bindings/tests/data/validation/",
|
||||
"$root_gen_dir/third_party/perfetto/protos/perfetto/config/chrome/scenario_config.descriptor",
|
||||
]
|
||||
|
||||
@ -1962,6 +1980,7 @@ test("content_browsertests") {
|
||||
":gpu_process_bundle",
|
||||
":network_process_bundle",
|
||||
"//media/test:media_bundle_data",
|
||||
"//mojo/public/interfaces/bindings/tests:validation_unittest_bundle_data",
|
||||
"//testing/buildbot/filters:content_browsertests_filter_bundle_data",
|
||||
]
|
||||
} else {
|
||||
|
@ -8112,6 +8112,8 @@ data/web_ui_dedicated_worker.js
|
||||
data/web_ui_managed_interface_test.html
|
||||
data/web_ui_managed_interface_test.test-mojom
|
||||
data/web_ui_managed_interface_test.ts
|
||||
data/web_ui_mojo_conformance_test.html
|
||||
data/web_ui_mojo_conformance_test.ts
|
||||
data/web_ui_mojo_native.html
|
||||
data/web_ui_mojo_native.js
|
||||
data/web_ui_mojo_test.html
|
||||
|
5
content/test/data/web_ui_mojo_conformance_test.html
Normal file
5
content/test/data/web_ui_mojo_conformance_test.html
Normal file
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
<script src="web_ui_mojo_conformance_test.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
126
content/test/data/web_ui_mojo_conformance_test.ts
Normal file
126
content/test/data/web_ui_mojo_conformance_test.ts
Normal file
@ -0,0 +1,126 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {mojo} from '//resources/mojo/mojo/public/js/bindings.js';
|
||||
|
||||
import {ConformanceTestInterfaceCallbackRouter, PageHandlerFactory} from './validation_test_interfaces.mojom-webui.js';
|
||||
|
||||
// TODO(ffred): These test cases do not match their associated expectation.
|
||||
// Each case should be investigated and removed from this set.
|
||||
const knownFailures = new Set([
|
||||
'conformance_mthd0_incomplete_struct',
|
||||
'conformance_mthd1_misaligned_struct',
|
||||
'conformance_mthd13_good_2',
|
||||
'conformance_mthd14_uknown_non_extensible_enum_value',
|
||||
'conformance_mthd15_uknown_non_extensible_enum_array_value',
|
||||
'conformance_mthd16_uknown_non_extensible_enum_map_key',
|
||||
'conformance_mthd16_uknown_non_extensible_enum_map_value',
|
||||
'conformance_mthd17_good',
|
||||
'conformance_mthd19_exceed_recursion_limit',
|
||||
'conformance_mthd2_multiple_pointers_to_same_struct',
|
||||
'conformance_mthd2_overlapped_objects',
|
||||
'conformance_mthd2_wrong_layout_order',
|
||||
'conformance_mthd22_empty_nonextensible_enum_accepts_no_values',
|
||||
'conformance_mthd23_array_of_optionals_less_than_necessary_bytes',
|
||||
'conformance_mthd24_map_of_optionals_less_than_necessary_bytes',
|
||||
'conformance_mthd3_array_num_bytes_huge',
|
||||
'conformance_mthd3_array_num_bytes_less_than_array_header',
|
||||
'conformance_mthd3_array_num_bytes_less_than_necessary_size',
|
||||
'conformance_mthd3_misaligned_array',
|
||||
'conformance_mthd4_multiple_pointers_to_same_array',
|
||||
'conformance_mthd4_overlapped_objects',
|
||||
'conformance_mthd4_wrong_layout_order',
|
||||
'conformance_mthd5_good',
|
||||
'conformance_mthd7_unmatched_array_elements',
|
||||
'conformance_mthd7_unmatched_array_elements_nested',
|
||||
'conformance_mthd9_good',
|
||||
]);
|
||||
|
||||
class Fixture {
|
||||
private endpoint: mojo.internal.interfaceSupport.Endpoint;
|
||||
|
||||
constructor() {
|
||||
// We only need one end of the pipe
|
||||
const pipes = Mojo.createMessagePipe();
|
||||
const receiver = new ConformanceTestInterfaceCallbackRouter();
|
||||
this.endpoint =
|
||||
mojo.internal.interfaceSupport.getEndpointForReceiver(pipes.handle0);
|
||||
// Binding is necessary to set up message routing.
|
||||
receiver.$.bindHandle(this.endpoint);
|
||||
}
|
||||
|
||||
// Return true if the test case passed. False otherwise.
|
||||
runTestCase(buffer: ArrayBuffer): boolean {
|
||||
const errors: Array<string> = [];
|
||||
|
||||
const oldConsoleError = console.error;
|
||||
console.error = (errMsg: string) => errors.push(errMsg);
|
||||
|
||||
// Some mojo validations are done through console.assert and console.error.
|
||||
// We need to capture errors on those channels to check whether or not
|
||||
// incorrect buffers are correctly identified.
|
||||
const oldConsoleAssert = console.assert;
|
||||
console.assert = (condition: boolean, errMsg: string) => {
|
||||
if (!condition) {
|
||||
errors.push(errMsg);
|
||||
}
|
||||
};
|
||||
|
||||
// Other places use exception throwing to signal errors.
|
||||
try {
|
||||
mojo.internal.interfaceSupport.acceptBufferForTesting(
|
||||
this.endpoint, buffer);
|
||||
} catch (e) {
|
||||
errors.push('' + e);
|
||||
}
|
||||
|
||||
console.error = oldConsoleError;
|
||||
console.assert = oldConsoleAssert;
|
||||
|
||||
return errors.length === 0;
|
||||
}
|
||||
}
|
||||
|
||||
async function runTest(): Promise<boolean> {
|
||||
const remote = PageHandlerFactory.getRemote();
|
||||
|
||||
const testCases =
|
||||
(await remote.getTestCases())
|
||||
.testCases.sort((a, b) => a.testName.localeCompare(b.testName));
|
||||
|
||||
|
||||
const failures = [];
|
||||
const expectedFailures = [];
|
||||
for (const testCase of testCases) {
|
||||
const shouldSucceed = testCase.expectation === 'PASS';
|
||||
|
||||
const succeeded =
|
||||
(new Fixture()).runTestCase(new Uint8Array(testCase.data).buffer);
|
||||
|
||||
if (succeeded !== shouldSucceed) {
|
||||
if (knownFailures.has(testCase.testName)) {
|
||||
expectedFailures.push(testCase.testName);
|
||||
} else {
|
||||
failures.push(testCase.testName);
|
||||
}
|
||||
} else {
|
||||
if (knownFailures.has(testCase.testName)) {
|
||||
throw new Error(
|
||||
testCase.testName +
|
||||
' is now passing, please remove from known failures');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (expectedFailures.length > 0) {
|
||||
console.log('tests continuing to fail: \n' + expectedFailures.join('\n'));
|
||||
}
|
||||
|
||||
if (failures.length > 0) {
|
||||
throw new Error('failed the following tests: \n' + failures.join('\n'));
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
// Exporting on |window| since this method is directly referenced by C++.
|
||||
Object.assign(window, {runTest});
|
@ -37,6 +37,9 @@ This file specifies resources for content_browsertests.
|
||||
<include name="IDR_WEB_UI_TS_TEST_OTHER_MAPPED_TYPES_JS" file="${root_gen_dir}/content/test/data/tsc/web_ui_mojo_ts_test_other_mapped_types.js" use_base_dir="false" type="BINDATA" resource_path="web_ui_mojo_ts_test_other_mapped_types.js" />
|
||||
<include name="IDR_WEB_UI_TS_TEST_CONVERTERS_JS" file="${root_gen_dir}/content/test/data/tsc/web_ui_mojo_ts_test_converters.js" use_base_dir="false" type="BINDATA" resource_path="web_ui_mojo_ts_test_converters.js" />
|
||||
<include name="IDR_WEB_UI_TS_TEST_TYPES_MOJOM_JS" file="${root_gen_dir}/content/test/data/tsc/web_ui_ts_test_types.test-mojom-webui.js" use_base_dir="false" type="BINDATA" resource_path="web_ui_ts_test_types.test-mojom-webui.js" />
|
||||
<include name="IDR_WEB_UI_TS_TEST_CONFORMANCE_HTML" file="data/web_ui_mojo_conformance_test.html" type="BINDATA" />
|
||||
<include name="IDR_WEB_UI_TS_TEST_CONFORMANCE_JS" file="${root_gen_dir}/content/test/data/tsc/web_ui_mojo_conformance_test.js" use_base_dir="false" type="BINDATA" resource_path="web_ui_mojo_conformance_test.js" />
|
||||
<include name="IDR_WEB_UI_TS_TEST_VALIDATION_MOJO_JS" file="${root_gen_dir}/content/test/data/tsc/validation_test_interfaces.mojom-webui.js" use_base_dir="false" type="BINDATA" resource_path="validation_test_interfaces.mojom-webui.js" />
|
||||
</includes>
|
||||
</release>
|
||||
</grit>
|
||||
|
@ -60,6 +60,9 @@ mojom("test_interfaces") {
|
||||
testonly = true
|
||||
generate_java = true
|
||||
generate_rust = true
|
||||
webui_module_path = "/"
|
||||
generate_legacy_js_bindings = true
|
||||
|
||||
sources = [
|
||||
"math_calculator.mojom",
|
||||
"no_module.mojom",
|
||||
@ -283,6 +286,8 @@ mojom("test_mojom_import") {
|
||||
testonly = true
|
||||
generate_java = true
|
||||
generate_rust = true
|
||||
webui_module_path = "/"
|
||||
generate_legacy_js_bindings = true
|
||||
sources = [ "sample_import.mojom" ]
|
||||
}
|
||||
|
||||
@ -304,6 +309,8 @@ mojom("test_mojom_import2") {
|
||||
testonly = true
|
||||
generate_java = true
|
||||
generate_rust = true
|
||||
webui_module_path = "/"
|
||||
generate_legacy_js_bindings = true
|
||||
sources = [ "sample_import2.mojom" ]
|
||||
public_deps = [
|
||||
":test_mojom_import",
|
||||
|
@ -68,6 +68,21 @@ union UnionA {
|
||||
bool b;
|
||||
};
|
||||
|
||||
// Used by WebUI ts test.
|
||||
struct TestCase {
|
||||
string test_name;
|
||||
// Bytes of a mojo message.
|
||||
array<uint8> data;
|
||||
// PASS for success. Every other string is the expected failure.
|
||||
string? expectation;
|
||||
};
|
||||
|
||||
// Used by WebUI ts test.
|
||||
interface PageHandlerFactory {
|
||||
// Gets the conformance test cases.
|
||||
GetTestCases() => (array<TestCase> test_cases);
|
||||
};
|
||||
|
||||
// This interface is used for testing bounds-checking in the mojom
|
||||
// binding code. If you add a method please update the files
|
||||
// ./data/validation/boundscheck_*. If you add a response please update
|
||||
|
@ -336,10 +336,21 @@ mojo.internal.interfaceSupport.Endpoint = class {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!mojo.internal.interfaceSupport.Endpoint} endpoint
|
||||
* @param {!ArrayBuffer} buffer
|
||||
* @export
|
||||
*/
|
||||
mojo.internal.interfaceSupport.acceptBufferForTesting = function(
|
||||
endpoint, buffer) {
|
||||
endpoint.router_.onMessageReceived_(buffer, []);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new Endpoint wrapping a given pipe handle.
|
||||
*
|
||||
* @param {!MojoHandle|!mojo.internal.interfaceSupport.Endpoint} pipeOrEndpoint
|
||||
* @param {!MojoHandle|!mojo.internal.interfaceSupport.Endpoint}
|
||||
* pipeOrEndpoint
|
||||
* @param {boolean=} setNamespaceBit
|
||||
* @return {!mojo.internal.interfaceSupport.Endpoint}
|
||||
*/
|
||||
|
2
ui/webui/resources/mojo/bindings.d.ts
vendored
2
ui/webui/resources/mojo/bindings.d.ts
vendored
@ -135,6 +135,8 @@ export namespace mojo {
|
||||
interface Endpoint {}
|
||||
|
||||
function getEndpointForReceiver(handle: MojoHandle|Endpoint): Endpoint;
|
||||
function acceptBufferForTesting(endpoint: Endpoint, buffer: ArrayBuffer):
|
||||
void;
|
||||
|
||||
function bind(handle: Endpoint, name: string, scope: string): void;
|
||||
|
||||
|
Reference in New Issue
Block a user