Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(431)

Unified Diff: ui/views/widget/widget_interactive_uitest.cc

Issue 1776763002: Convert the flaky SysCommand widget tests into interactive ui tests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | ui/views/widget/widget_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/widget/widget_interactive_uitest.cc
diff --git a/ui/views/widget/widget_interactive_uitest.cc b/ui/views/widget/widget_interactive_uitest.cc
index d077c3d4b3b5a160afbcd99e34614c0846517346..47d215345ff5715e021792753ede894f4821012c 100644
--- a/ui/views/widget/widget_interactive_uitest.cc
+++ b/ui/views/widget/widget_interactive_uitest.cc
@@ -805,6 +805,189 @@ TEST_F(WidgetTestInteractive, FullscreenBoundsReducedOnActivationLoss) {
widget1.CloseNow();
widget2.CloseNow();
}
+
+// Provides functionality to subclass a window and keep track of messages
+// received.
+class SubclassWindowHelper {
+ public:
+ explicit SubclassWindowHelper(HWND window)
+ : window_(window),
+ message_to_destroy_on_(0) {
+ EXPECT_EQ(instance_, nullptr);
+ instance_ = this;
+ EXPECT_TRUE(Subclass());
+ }
+
+ ~SubclassWindowHelper() {
+ Unsubclass();
+ instance_ = nullptr;
+ }
+
+ // Returns true if the |message| passed in was received.
+ bool received_message(unsigned int message) {
+ return (messages_.find(message) != messages_.end());
+ }
+
+ void Clear() {
+ messages_.clear();
+ }
+
+ void set_message_to_destroy_on(unsigned int message) {
+ message_to_destroy_on_ = message;
+ }
+
+ private:
+ bool Subclass() {
+ old_proc_ = reinterpret_cast<WNDPROC>(
+ ::SetWindowLongPtr(window_,
+ GWLP_WNDPROC,
+ reinterpret_cast<LONG_PTR>(WndProc)));
+ return old_proc_ != nullptr;
+ }
+
+ void Unsubclass() {
+ ::SetWindowLongPtr(window_,
+ GWLP_WNDPROC,
+ reinterpret_cast<LONG_PTR>(old_proc_));
+ }
+
+ static LRESULT CALLBACK WndProc(HWND window,
+ unsigned int message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ EXPECT_NE(instance_, nullptr);
+ EXPECT_EQ(window, instance_->window_);
+
+ // Keep track of messags received for this window.
+ instance_->messages_.insert(message);
+
+ LRESULT ret = ::CallWindowProc(instance_->old_proc_, window, message,
+ w_param, l_param);
+ if (message == instance_->message_to_destroy_on_) {
+ instance_->Unsubclass();
+ ::DestroyWindow(window);
+ }
+ return ret;
+ }
+
+ WNDPROC old_proc_;
+ HWND window_;
+ static SubclassWindowHelper* instance_;
+ std::set<unsigned int> messages_;
+ unsigned int message_to_destroy_on_;
+
+ DISALLOW_COPY_AND_ASSIGN(SubclassWindowHelper);
+};
+
+SubclassWindowHelper* SubclassWindowHelper::instance_ = nullptr;
+
+// This test validates whether the WM_SYSCOMMAND message for SC_MOVE is
+// received when we post a WM_NCLBUTTONDOWN message for the caption in the
+// following scenarios:-
+// 1. Posting a WM_NCMOUSEMOVE message for a different location.
+// 2. Posting a WM_NCMOUSEMOVE message with a different hittest code.
+// 3. Posting a WM_MOUSEMOVE message.
+TEST_F(WidgetTestInteractive,
+ SysCommandMoveOnNCLButtonDownOnCaptionAndMoveTest) {
+ Widget widget;
+ Widget::InitParams params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW);
+ params.native_widget = new DesktopNativeWidgetAura(&widget);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget.Init(params);
+ widget.SetBounds(gfx::Rect(0, 0, 200, 200));
+ widget.Show();
+ ::SetCursorPos(500, 500);
+
+ HWND window = widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget();
+
+ SubclassWindowHelper subclass_helper(window);
+
+ // Posting just a WM_NCLBUTTONDOWN message should not result in a
+ // WM_SYSCOMMAND
+ ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
+ RunPendingMessages();
+ EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
+ EXPECT_FALSE(subclass_helper.received_message(WM_SYSCOMMAND));
+
+ subclass_helper.Clear();
+ // Posting a WM_NCLBUTTONDOWN message followed by a WM_NCMOUSEMOVE at the
+ // same location should not result in a WM_SYSCOMMAND message.
+ ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
+ ::PostMessage(window, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(100, 100));
+ RunPendingMessages();
+
+ EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
+ EXPECT_TRUE(subclass_helper.received_message(WM_NCMOUSEMOVE));
+ EXPECT_FALSE(subclass_helper.received_message(WM_SYSCOMMAND));
+
+ subclass_helper.Clear();
+ // Posting a WM_NCLBUTTONDOWN message followed by a WM_NCMOUSEMOVE at a
+ // different location should result in a WM_SYSCOMMAND message.
+ ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
+ ::PostMessage(window, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(110, 110));
+ RunPendingMessages();
+
+ EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
+ EXPECT_TRUE(subclass_helper.received_message(WM_NCMOUSEMOVE));
+ EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));
+
+ subclass_helper.Clear();
+ // Posting a WM_NCLBUTTONDOWN message followed by a WM_NCMOUSEMOVE at a
+ // different location with a different hittest code should result in a
+ // WM_SYSCOMMAND message.
+ ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
+ ::PostMessage(window, WM_NCMOUSEMOVE, HTTOP, MAKELPARAM(110, 102));
+ RunPendingMessages();
+
+ EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
+ EXPECT_TRUE(subclass_helper.received_message(WM_NCMOUSEMOVE));
+ EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));
+
+ subclass_helper.Clear();
+ // Posting a WM_NCLBUTTONDOWN message followed by a WM_MOUSEMOVE should
+ // result in a WM_SYSCOMMAND message.
+ ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
+ ::PostMessage(window, WM_MOUSEMOVE, HTCLIENT, MAKELPARAM(110, 110));
+ RunPendingMessages();
+
+ EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
+ EXPECT_TRUE(subclass_helper.received_message(WM_MOUSEMOVE));
+ EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));
+
+ widget.CloseNow();
+}
+
+// This test validates that destroying the window in the context of the
+// WM_SYSCOMMAND message with SC_MOVE does not crash.
+TEST_F(WidgetTestInteractive, DestroyInSysCommandNCLButtonDownOnCaption) {
+ Widget widget;
+ Widget::InitParams params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW);
+ params.native_widget = new DesktopNativeWidgetAura(&widget);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget.Init(params);
+ widget.SetBounds(gfx::Rect(0, 0, 200, 200));
+ widget.Show();
+ ::SetCursorPos(500, 500);
+
+ HWND window = widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget();
+
+ SubclassWindowHelper subclass_helper(window);
+
+ // Destroying the window in the context of the WM_SYSCOMMAND message
+ // should not crash.
+ subclass_helper.set_message_to_destroy_on(WM_SYSCOMMAND);
+
+ ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
+ ::PostMessage(window, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(110, 110));
+ RunPendingMessages();
+
+ EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
+ EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));
+
+ widget.CloseNow();
+}
#endif // defined(OS_WIN)
#if !defined(OS_CHROMEOS)
« no previous file with comments | « no previous file | ui/views/widget/widget_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698