Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit c60924e

Browse files
committed
Support fixture tests for Windows embedder
This adds support for running end-to-end tests that use a live engine to run Dart test fixtures. This enables testing the public Windows C API in //flutter/shell/platform/windows/public/flutter_windows.h This only adds support for a single test entrypoint (main). A followup patch will add support for this. See: flutter/flutter#93537 Issue: flutter/flutter#87299
1 parent d2489cd commit c60924e

10 files changed

+344
-1
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2449,6 +2449,12 @@ FILE: ../../../flutter/shell/platform/windows/task_runner.h
24492449
FILE: ../../../flutter/shell/platform/windows/task_runner_unittests.cc
24502450
FILE: ../../../flutter/shell/platform/windows/task_runner_window.cc
24512451
FILE: ../../../flutter/shell/platform/windows/task_runner_window.h
2452+
FILE: ../../../flutter/shell/platform/windows/testing/windows_test.cc
2453+
FILE: ../../../flutter/shell/platform/windows/testing/windows_test.h
2454+
FILE: ../../../flutter/shell/platform/windows/testing/windows_test_config_builder.cc
2455+
FILE: ../../../flutter/shell/platform/windows/testing/windows_test_config_builder.h
2456+
FILE: ../../../flutter/shell/platform/windows/testing/windows_test_context.cc
2457+
FILE: ../../../flutter/shell/platform/windows/testing/windows_test_context.h
24522458
FILE: ../../../flutter/shell/platform/windows/text_input_manager.cc
24532459
FILE: ../../../flutter/shell/platform/windows/text_input_manager.h
24542460
FILE: ../../../flutter/shell/platform/windows/text_input_plugin.cc

shell/platform/windows/BUILD.gn

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ shared_library("flutter_windows") {
158158
}
159159

160160
test_fixtures("flutter_windows_fixtures") {
161+
dart_main = "fixtures/main.dart"
161162
fixtures = []
162163
}
163164

@@ -198,6 +199,12 @@ executable("flutter_windows_unittests") {
198199
"testing/test_keyboard.cc",
199200
"testing/test_keyboard.h",
200201
"testing/test_keyboard_unittests.cc",
202+
"testing/windows_test.cc",
203+
"testing/windows_test.h",
204+
"testing/windows_test_config_builder.cc",
205+
"testing/windows_test_config_builder.h",
206+
"testing/windows_test_context.cc",
207+
"testing/windows_test_context.h",
201208
"testing/wm_builders.cc",
202209
"testing/wm_builders.h",
203210
"text_input_plugin_unittest.cc",
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
void main() {
6+
print('Hello windows engine test!');
7+
}

shell/platform/windows/flutter_windows_unittests.cc

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@
55
#include "flutter/shell/platform/windows/public/flutter_windows.h"
66

77
#include <cstring>
8+
#include <thread>
89

10+
#include "flutter/shell/platform/windows/testing/windows_test.h"
11+
#include "flutter/shell/platform/windows/testing/windows_test_config_builder.h"
12+
#include "flutter/shell/platform/windows/testing/windows_test_context.h"
913
#include "gtest/gtest.h"
1014

1115
namespace flutter {
1216
namespace testing {
1317

14-
TEST(FlutterWindowsTest, GetTextureRegistrar) {
18+
TEST(WindowsNoFixtureTest, GetTextureRegistrar) {
1519
FlutterDesktopEngineProperties properties;
1620
memset(&properties, 0, sizeof(FlutterDesktopEngineProperties));
1721
properties.assets_path = L"";
@@ -23,5 +27,19 @@ TEST(FlutterWindowsTest, GetTextureRegistrar) {
2327
FlutterDesktopEngineDestroy(engine);
2428
}
2529

30+
TEST_F(WindowsTest, LaunchMain) {
31+
auto& context = GetContext();
32+
WindowsConfigBuilder builder(context);
33+
ViewControllerPtr controller{builder.LaunchEngine()};
34+
ASSERT_NE(controller, nullptr);
35+
36+
// Run for 1 second, then shut down.
37+
//
38+
// TODO(cbracken): Support registring a native function we can use to
39+
// determine that execution has made it to a specific point in the Dart
40+
// code. https://github.com/flutter/flutter/issues/109242
41+
std::this_thread::sleep_for(std::chrono::seconds(1));
42+
}
43+
2644
} // namespace testing
2745
} // namespace flutter
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "flutter/shell/platform/windows/testing/windows_test.h"
6+
7+
#include <string>
8+
9+
#include "flutter/shell/platform/windows/testing/windows_test_context.h"
10+
#include "flutter/testing/testing.h"
11+
12+
namespace flutter {
13+
namespace testing {
14+
15+
WindowsTest::WindowsTest() : context_(GetFixturesDirectory()) {}
16+
17+
std::string WindowsTest::GetFixturesDirectory() const {
18+
return GetFixturesPath();
19+
}
20+
21+
WindowsTestContext& WindowsTest::GetContext() {
22+
return context_;
23+
}
24+
25+
} // namespace testing
26+
} // namespace flutter
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_WINDOWS_TEST_H_
6+
#define FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_WINDOWS_TEST_H_
7+
8+
#include <string>
9+
10+
#include "flutter/fml/macros.h"
11+
#include "flutter/shell/platform/windows/testing/windows_test_context.h"
12+
#include "flutter/testing/thread_test.h"
13+
14+
namespace flutter {
15+
namespace testing {
16+
17+
/// A GoogleTest test fixture for Windows tests.
18+
///
19+
/// Supports looking up the test fixture data defined in the GN `test_fixtures`
20+
/// associated with the unit test executable target. This typically includes
21+
/// the kernel bytecode `kernel_blob.bin` compiled from the Dart file specified
22+
/// in the test fixture's `dart_main` property, as well as any other data files
23+
/// used in tests, such as image files used in a screenshot golden test.
24+
///
25+
/// This test class can be used in GoogleTest tests using the standard
26+
/// `TEST_F(WindowsTest, TestName)` macro.
27+
class WindowsTest : public ThreadTest {
28+
public:
29+
WindowsTest();
30+
31+
// Returns the path to test fixture data such as kernel bytecode or images
32+
// used by the C++ side of the test.
33+
std::string GetFixturesDirectory() const;
34+
35+
// Returns the test context associated with this fixture.
36+
WindowsTestContext& GetContext();
37+
38+
private:
39+
WindowsTestContext context_;
40+
41+
FML_DISALLOW_COPY_AND_ASSIGN(WindowsTest);
42+
};
43+
44+
} // namespace testing
45+
} // namespace flutter
46+
47+
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_WINDOWS_TEST_H_
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "flutter/shell/platform/windows/testing/windows_test_config_builder.h"
6+
7+
#include <combaseapi.h>
8+
9+
#include <string>
10+
#include <string_view>
11+
#include <vector>
12+
13+
#include "flutter/fml/logging.h"
14+
#include "flutter/shell/platform/windows/public/flutter_windows.h"
15+
#include "flutter/shell/platform/windows/testing/windows_test_context.h"
16+
17+
namespace flutter {
18+
namespace testing {
19+
20+
WindowsConfigBuilder::WindowsConfigBuilder(WindowsTestContext& context)
21+
: context_(context) {}
22+
23+
WindowsConfigBuilder::~WindowsConfigBuilder() = default;
24+
25+
void WindowsConfigBuilder::AddDartEntrypointArgument(std::string_view arg) {
26+
if (arg.empty()) {
27+
return;
28+
}
29+
30+
dart_entrypoint_arguments_.emplace_back(std::move(arg));
31+
}
32+
33+
FlutterDesktopEngineProperties WindowsConfigBuilder::GetEngineProperties()
34+
const {
35+
FlutterDesktopEngineProperties engine_properties = {};
36+
engine_properties.assets_path = context_.GetAssetsPath().c_str();
37+
engine_properties.icu_data_path = context_.GetIcuDataPath().c_str();
38+
39+
// Set Dart entrypoint argc, argv.
40+
std::vector<const char*> dart_args;
41+
dart_args.reserve(dart_entrypoint_arguments_.size());
42+
for (const auto& arg : dart_entrypoint_arguments_) {
43+
dart_args.push_back(arg.c_str());
44+
}
45+
if (!dart_args.empty()) {
46+
engine_properties.dart_entrypoint_argv = dart_args.data();
47+
engine_properties.dart_entrypoint_argc = dart_args.size();
48+
} else {
49+
// Clear this out in case this is not the first engine launch from the
50+
// embedder config builder.
51+
engine_properties.dart_entrypoint_argv = nullptr;
52+
engine_properties.dart_entrypoint_argc = 0;
53+
}
54+
55+
return engine_properties;
56+
}
57+
58+
ViewControllerPtr WindowsConfigBuilder::LaunchEngine() const {
59+
InitializeCOM();
60+
61+
EnginePtr engine = InitializeEngine();
62+
if (!engine) {
63+
return {};
64+
}
65+
66+
int width = 600;
67+
int height = 400;
68+
ViewControllerPtr controller(
69+
FlutterDesktopViewControllerCreate(width, height, engine.release()));
70+
if (!controller) {
71+
return {};
72+
}
73+
74+
return controller;
75+
}
76+
77+
void WindowsConfigBuilder::InitializeCOM() const {
78+
FML_CHECK(SUCCEEDED(::CoInitializeEx(nullptr, COINIT_MULTITHREADED)));
79+
}
80+
81+
EnginePtr WindowsConfigBuilder::InitializeEngine() const {
82+
FlutterDesktopEngineProperties engine_properties = GetEngineProperties();
83+
return EnginePtr(FlutterDesktopEngineCreate(&engine_properties));
84+
}
85+
86+
} // namespace testing
87+
} // namespace flutter
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_WINDOWS_TEST_CONFIG_BUILDER_H_
6+
#define FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_WINDOWS_TEST_CONFIG_BUILDER_H_
7+
8+
#include <string>
9+
#include <string_view>
10+
#include <vector>
11+
12+
#include "flutter/fml/macros.h"
13+
#include "flutter/fml/unique_object.h"
14+
#include "flutter/shell/platform/windows/public/flutter_windows.h"
15+
#include "flutter/shell/platform/windows/testing/windows_test_context.h"
16+
17+
namespace flutter {
18+
namespace testing {
19+
20+
// Deleter for FlutterDesktopEngineRef objects.
21+
struct EngineDeleter {
22+
typedef FlutterDesktopEngineRef pointer;
23+
void operator()(FlutterDesktopEngineRef engine) {
24+
FML_CHECK(FlutterDesktopEngineDestroy(engine));
25+
}
26+
};
27+
28+
// Unique pointer wrapper for FlutterDesktopEngineRef.
29+
using EnginePtr = std::unique_ptr<FlutterDesktopEngine, EngineDeleter>;
30+
31+
// Deleter for FlutterViewControllerRef objects.
32+
struct ViewControllerDeleter {
33+
typedef FlutterDesktopViewControllerRef pointer;
34+
void operator()(FlutterDesktopViewControllerRef engine) {
35+
FlutterDesktopViewControllerDestroy(engine);
36+
}
37+
};
38+
39+
// Unique pointer wrapper for FlutterDesktopViewControllerRef.
40+
using ViewControllerPtr =
41+
std::unique_ptr<FlutterDesktopViewControllerState, ViewControllerDeleter>;
42+
43+
// Test configuration builder for WindowsTests.
44+
//
45+
// Utility class for configuring engine and view controller launch arguments,
46+
// and launching the engine to run a test fixture.
47+
class WindowsConfigBuilder {
48+
public:
49+
explicit WindowsConfigBuilder(WindowsTestContext& context);
50+
~WindowsConfigBuilder();
51+
52+
// Returns the desktop engine properties configured for this test.
53+
FlutterDesktopEngineProperties GetEngineProperties() const;
54+
55+
// Adds an argument to the Dart entrypoint arguments List<String>.
56+
void AddDartEntrypointArgument(std::string_view arg);
57+
58+
// Returns a configured and initialized view controller running the default
59+
// Dart entrypoint.
60+
ViewControllerPtr LaunchEngine() const;
61+
62+
private:
63+
// Initialize COM, so that it is available for use in the library and/or
64+
// plugins.
65+
void InitializeCOM() const;
66+
67+
// Returns a configured and initialized engine.
68+
EnginePtr InitializeEngine() const;
69+
70+
WindowsTestContext& context_;
71+
std::vector<std::string> dart_entrypoint_arguments_;
72+
73+
FML_DISALLOW_COPY_AND_ASSIGN(WindowsConfigBuilder);
74+
};
75+
76+
} // namespace testing
77+
} // namespace flutter
78+
79+
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_WINDOWS_TEST_CONFIG_BUILDER_H_
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "flutter/shell/platform/windows/testing/windows_test_context.h"
6+
7+
#include "flutter/fml/platform/win/wstring_conversion.h"
8+
9+
namespace flutter {
10+
namespace testing {
11+
12+
WindowsTestContext::WindowsTestContext(std::string_view assets_path)
13+
: assets_path_(fml::Utf8ToWideString(assets_path)) {}
14+
15+
WindowsTestContext::~WindowsTestContext() = default;
16+
17+
const std::wstring& WindowsTestContext::GetAssetsPath() const {
18+
return assets_path_;
19+
}
20+
21+
const std::wstring& WindowsTestContext::GetIcuDataPath() const {
22+
return icu_data_path_;
23+
}
24+
25+
} // namespace testing
26+
} // namespace flutter
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_WINDOWS_TEST_CONTEXT_H_
6+
#define FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_WINDOWS_TEST_CONTEXT_H_
7+
8+
#include <string>
9+
#include <string_view>
10+
11+
#include "flutter/fml/macros.h"
12+
13+
namespace flutter {
14+
namespace testing {
15+
16+
// Context associated with the current Windows test fixture.
17+
//
18+
// Context data includes global Flutter and Dart runtime context such as the
19+
// path of Flutter's asset directory, ICU path, and resolvers for any
20+
// registered native functions.
21+
class WindowsTestContext {
22+
public:
23+
explicit WindowsTestContext(std::string_view assets_path = "");
24+
virtual ~WindowsTestContext();
25+
26+
const std::wstring& GetAssetsPath() const;
27+
28+
const std::wstring& GetIcuDataPath() const;
29+
30+
private:
31+
std::wstring assets_path_;
32+
std::wstring icu_data_path_ = L"icudtl.dat";
33+
34+
FML_DISALLOW_COPY_AND_ASSIGN(WindowsTestContext);
35+
};
36+
37+
} // namespace testing
38+
} // namespace flutter
39+
40+
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_WINDOWS_TEST_CONTEXT_H_

0 commit comments

Comments
 (0)