#include <memory>
#include <optional>
#include "ash/constants/ash_features.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/ash_test_util.h"
#include "ash/test/pixel/ash_pixel_differ.h"
#include "ash/test/pixel/ash_pixel_test_helper.h"
#include "ash/wm/overview/overview_item_base.h"
#include "ash/wm/overview/overview_test_util.h"
#include "ash/wm/overview/overview_utils.h"
#include "ash/wm/overview/scoped_overview_transform_window.h"
#include "ash/wm/snap_group/snap_group_controller.h"
#include "ash/wm/snap_group/snap_group_test_util.h"
#include "ash/wm/splitview/split_view_constants.h"
#include "ash/wm/splitview/split_view_divider.h"
#include "ash/wm/splitview/split_view_test_util.h"
#include "ash/wm/window_cycle/window_cycle_controller.h"
#include "ash/wm/window_cycle/window_cycle_list.h"
#include "ash/wm/window_cycle/window_cycle_view.h"
#include "chromeos/constants/chromeos_features.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/aura/window_tree_host.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/geometry/point.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/window_util.h"
namespace ash {
class SnapGroupPixelTest : public AshTestBase {
public:
SnapGroupPixelTest() = default;
SnapGroupPixelTest(const SnapGroupPixelTest&) = delete;
SnapGroupPixelTest& operator=(const SnapGroupPixelTest&) = delete;
~SnapGroupPixelTest() override = default;
private:
std::optional<pixel_test::InitParams> CreatePixelTestInitParams()
const override {
return pixel_test::InitParams();
}
};
class SnapGroupWindowCyclePixelTest
: public SnapGroupPixelTest,
public testing::WithParamInterface</*enable_system_blur=*/bool> {
public:
SnapGroupWindowCyclePixelTest() = default;
SnapGroupWindowCyclePixelTest(const SnapGroupPixelTest&) = delete;
SnapGroupWindowCyclePixelTest& operator=(const SnapGroupPixelTest&) = delete;
~SnapGroupWindowCyclePixelTest() override = default;
private:
std::optional<pixel_test::InitParams> CreatePixelTestInitParams()
const override {
pixel_test::InitParams init_params;
init_params.system_blur_enabled = GetParam();
return init_params;
}
};
INSTANTIATE_TEST_SUITE_P(
,
SnapGroupWindowCyclePixelTest,
testing::Bool());
TEST_F(SnapGroupPixelTest, SnapGroupDividerBasic) {
std::unique_ptr<aura::Window> w1(CreateAppWindow());
DecorateWindow(w1.get(), u"w1", SK_ColorGREEN);
auto* w1_widget = views::Widget::GetWidgetForNativeView(w1.get());
std::unique_ptr<aura::Window> w2(CreateAppWindow());
DecorateWindow(w2.get(), u"w2", SK_ColorBLUE);
auto* w2_widget = views::Widget::GetWidgetForNativeView(w2.get());
auto* event_generator = GetEventGenerator();
SnapTwoTestWindows(w1.get(), w2.get(), true, event_generator);
auto* divider_widget = GetTopmostSnapGroupDivider()->divider_widget();
ASSERT_TRUE(divider_widget);
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
"snap_group_divider_default_state",
0, divider_widget, w1_widget, w2_widget));
event_generator->MoveMouseTo(
GetTopmostSnapGroupDividerBoundsInScreen().CenterPoint() +
gfx::Vector2d(0, 10));
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
"snap_group_divider_hover_state",
0, divider_widget, w1_widget, w2_widget));
}
TEST_F(SnapGroupPixelTest, PartialSplit) {
std::unique_ptr<aura::Window> w1(CreateAppWindow());
DecorateWindow(w1.get(), u"w1", SK_ColorGREEN);
auto* w1_widget = views::Widget::GetWidgetForNativeView(w1.get());
std::unique_ptr<aura::Window> w2(CreateAppWindow());
DecorateWindow(w2.get(), u"w2", SK_ColorBLUE);
auto* w2_widget = views::Widget::GetWidgetForNativeView(w2.get());
SnapOneTestWindow(w1.get(),
chromeos::WindowStateType::kPrimarySnapped,
chromeos::kTwoThirdSnapRatio);
VerifySplitViewOverviewSession(w1.get());
ClickOverviewItem(GetEventGenerator(), w2.get());
auto* snap_group_controller = SnapGroupController::Get();
EXPECT_TRUE(snap_group_controller->AreWindowsInSnapGroup(w1.get(), w2.get()));
auto* divider_widget = GetTopmostSnapGroupDivider()->divider_widget();
ASSERT_TRUE(divider_widget);
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
"snap_group_partial_split",
0, divider_widget, w1_widget, w2_widget));
}
TEST_F(SnapGroupPixelTest, OverviewGroupItem) {
ScopedOverviewTransformWindow::SetImmediateCloseForTests(true);
std::unique_ptr<aura::Window> w1(CreateAppWindow());
DecorateWindow(w1.get(), u"w1", SK_ColorGREEN);
std::unique_ptr<aura::Window> w2(CreateAppWindow());
DecorateWindow(w2.get(), u"w2", SK_ColorBLUE);
SnapTwoTestWindows(w1.get(), w2.get(), true,
GetEventGenerator());
ToggleOverview();
ASSERT_TRUE(IsInOverviewSession());
OverviewItemBase* overview_group_item = GetOverviewItemForWindow(w1.get());
ASSERT_TRUE(overview_group_item);
auto* group_item_widget = overview_group_item->item_widget();
ASSERT_TRUE(group_item_widget);
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
"overviewgroupitem",
4, group_item_widget));
w2.reset();
OverviewItemBase* item_after_destruction = GetOverviewItemForWindow(w1.get());
ASSERT_TRUE(item_after_destruction);
auto* remaining_item_widget = item_after_destruction->item_widget();
ASSERT_TRUE(item_after_destruction);
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
"remaining_item_widget",
4, remaining_item_widget));
}
TEST_P(SnapGroupWindowCyclePixelTest, WindowCycleView) {
WindowCycleList::SetDisableInitialDelayForTesting(true);
std::unique_ptr<aura::Window> w1(CreateAppWindow());
DecorateWindow(w1.get(), u"w1", SK_ColorGREEN);
std::unique_ptr<aura::Window> w2(CreateAppWindow());
DecorateWindow(w2.get(), u"w2", SK_ColorBLUE);
SnapTwoTestWindows(w1.get(), w2.get(), true,
GetEventGenerator());
wm::ActivateWindow(w1.get());
auto* event_generator = GetEventGenerator();
event_generator->PressAndReleaseKey(ui::VKEY_TAB, ui::EF_ALT_DOWN);
WindowCycleController* window_cycle_controller =
Shell::Get()->window_cycle_controller();
EXPECT_TRUE(window_cycle_controller->IsCycling());
const WindowCycleView* window_cycle_view =
window_cycle_controller->window_cycle_list()->cycle_view();
ASSERT_TRUE(window_cycle_view);
views::Widget* window_cycle_widget =
const_cast<views::Widget*>(window_cycle_view->GetWidget());
ASSERT_TRUE(window_cycle_widget);
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
GenerateScreenshotName("window_cycle_with_snap_group_secondary_focused"),
pixel_test_helper()->IsSystemBlurEnabled() ? 6 : 0,
window_cycle_widget));
event_generator->PressAndReleaseKey(ui::VKEY_TAB, ui::EF_ALT_DOWN);
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
GenerateScreenshotName("window_cycle_with_snap_group_primary_focused"),
pixel_test_helper()->IsSystemBlurEnabled() ? 6 : 0,
window_cycle_widget));
w2.reset();
EXPECT_TRUE(window_cycle_controller->IsCycling());
const WindowCycleView* updated_window_cycle_view =
window_cycle_controller->window_cycle_list()->cycle_view();
ASSERT_TRUE(updated_window_cycle_view);
views::Widget* updated_window_cycle_widget =
const_cast<views::Widget*>(window_cycle_view->GetWidget());
ASSERT_TRUE(updated_window_cycle_widget);
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
GenerateScreenshotName("window_cycle_with_snap_group_window_destruction"),
pixel_test_helper()->IsSystemBlurEnabled() ? 6 : 0,
updated_window_cycle_widget));
}
TEST_F(SnapGroupPixelTest, SnapGroupDividerBasicInPortrait) {
UpdateDisplay("900x1200");
std::unique_ptr<aura::Window> w1(CreateAppWindow());
DecorateWindow(w1.get(), u"w1", SK_ColorGREEN);
auto* w1_widget = views::Widget::GetWidgetForNativeView(w1.get());
std::unique_ptr<aura::Window> w2(CreateAppWindow());
DecorateWindow(w2.get(), u"w2", SK_ColorBLUE);
auto* w2_widget = views::Widget::GetWidgetForNativeView(w2.get());
auto* event_generator = GetEventGenerator();
SnapTwoTestWindows(w1.get(), w2.get(), false, event_generator);
auto* divider_widget = GetTopmostSnapGroupDivider()->divider_widget();
ASSERT_TRUE(divider_widget);
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
"snap_group_divider_default_state_in_portrait",
0, divider_widget, w1_widget, w2_widget));
event_generator->MoveMouseTo(
GetTopmostSnapGroupDividerBoundsInScreen().CenterPoint() +
gfx::Vector2d(10, 0));
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
"snap_group_divider_hover_state_in_portrait",
0, divider_widget, w1_widget, w2_widget));
}
TEST_F(SnapGroupPixelTest, OverviewGroupItemInPortrait) {
UpdateDisplay("900x1200");
ScopedOverviewTransformWindow::SetImmediateCloseForTests(true);
std::unique_ptr<aura::Window> w1(CreateAppWindow());
DecorateWindow(w1.get(), u"w1", SK_ColorGREEN);
std::unique_ptr<aura::Window> w2(CreateAppWindow());
DecorateWindow(w2.get(), u"w2", SK_ColorBLUE);
SnapTwoTestWindows(w1.get(), w2.get(), false,
GetEventGenerator());
ToggleOverview();
ASSERT_TRUE(IsInOverviewSession());
OverviewItemBase* overview_group_item = GetOverviewItemForWindow(w1.get());
ASSERT_TRUE(overview_group_item);
auto* group_item_widget = overview_group_item->item_widget();
ASSERT_TRUE(group_item_widget);
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
"overviewgroupitem_in_portrait",
5, group_item_widget));
}
TEST_P(SnapGroupWindowCyclePixelTest, WindowCycleViewInPortrait) {
UpdateDisplay("900x1200");
WindowCycleList::SetDisableInitialDelayForTesting(true);
std::unique_ptr<aura::Window> w1(CreateAppWindow());
DecorateWindow(w1.get(), u"w1", SK_ColorGREEN);
std::unique_ptr<aura::Window> w2(CreateAppWindow());
DecorateWindow(w2.get(), u"w2", SK_ColorBLUE);
SnapTwoTestWindows(w1.get(), w2.get(), false,
GetEventGenerator());
wm::ActivateWindow(w1.get());
auto* event_generator = GetEventGenerator();
event_generator->PressAndReleaseKey(ui::VKEY_TAB, ui::EF_ALT_DOWN);
WindowCycleController* window_cycle_controller =
Shell::Get()->window_cycle_controller();
EXPECT_TRUE(window_cycle_controller->IsCycling());
const WindowCycleView* window_cycle_view =
window_cycle_controller->window_cycle_list()->cycle_view();
ASSERT_TRUE(window_cycle_view);
views::Widget* window_cycle_widget =
const_cast<views::Widget*>(window_cycle_view->GetWidget());
ASSERT_TRUE(window_cycle_widget);
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
GenerateScreenshotName(
"window_cycle_with_snap_group_secondary_focused_in_portrait"),
pixel_test_helper()->IsSystemBlurEnabled() ? 6 : 0,
window_cycle_widget));
event_generator->PressAndReleaseKey(ui::VKEY_TAB, ui::EF_ALT_DOWN);
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
GenerateScreenshotName(
"window_cycle_with_snap_group_primary_focused_in_portrait"),
pixel_test_helper()->IsSystemBlurEnabled() ? 6 : 0,
window_cycle_widget));
}
}