test_view.cc 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright (c) 2011 The Chromium 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. #include "ppapi/tests/test_view.h"
  5. #include <stddef.h>
  6. #include <sstream>
  7. #include "ppapi/c/pp_time.h"
  8. #include "ppapi/c/private/ppb_testing_private.h"
  9. #include "ppapi/cpp/completion_callback.h"
  10. #include "ppapi/tests/testing_instance.h"
  11. REGISTER_TEST_CASE(View);
  12. TestView::TestView(TestingInstance* instance)
  13. : TestCase(instance),
  14. post_quit_on_view_changed_(false) {
  15. }
  16. void TestView::DidChangeView(const pp::View& view) {
  17. last_view_ = view;
  18. page_visibility_log_.push_back(view.IsPageVisible());
  19. if (post_quit_on_view_changed_) {
  20. post_quit_on_view_changed_ = false;
  21. testing_interface_->QuitMessageLoop(instance_->pp_instance());
  22. }
  23. }
  24. bool TestView::Init() {
  25. return CheckTestingInterface();
  26. }
  27. void TestView::RunTests(const std::string& filter) {
  28. RUN_TEST(CreatedVisible, filter);
  29. RUN_TEST(CreatedInvisible, filter);
  30. RUN_TEST(PageHideShow, filter);
  31. RUN_TEST(SizeChange, filter);
  32. RUN_TEST(ClipChange, filter);
  33. RUN_TEST(ScrollOffsetChange, filter);
  34. }
  35. bool TestView::WaitUntilViewChanged() {
  36. size_t old_page_visibility_change_count = page_visibility_log_.size();
  37. // Run a nested run loop. It will exit either on ViewChanged or if the
  38. // timeout happens.
  39. post_quit_on_view_changed_ = true;
  40. testing_interface_->RunMessageLoop(instance_->pp_instance());
  41. post_quit_on_view_changed_ = false;
  42. // We know we got a view changed event if something was appended to the log.
  43. return page_visibility_log_.size() > old_page_visibility_change_count;
  44. }
  45. void TestView::QuitMessageLoop(int32_t result) {
  46. testing_interface_->QuitMessageLoop(instance_->pp_instance());
  47. }
  48. std::string TestView::TestCreatedVisible() {
  49. ASSERT_FALSE(page_visibility_log_.empty());
  50. ASSERT_TRUE(page_visibility_log_[0]);
  51. PASS();
  52. }
  53. std::string TestView::TestCreatedInvisible() {
  54. ASSERT_FALSE(page_visibility_log_.empty());
  55. if (page_visibility_log_[0]) {
  56. // Add more error message since this test has some extra requirements.
  57. instance_->AppendError("Initial page is set to visible. NOTE: "
  58. "This test must be run in a background tab. "
  59. "Either run in the UI test which does this, or you can middle-click "
  60. "on the test link to run manually.");
  61. }
  62. ASSERT_FALSE(page_visibility_log_[0]);
  63. PASS();
  64. }
  65. std::string TestView::TestPageHideShow() {
  66. // Initial state should be visible.
  67. ASSERT_FALSE(page_visibility_log_.empty());
  68. ASSERT_TRUE(page_visibility_log_[0]);
  69. // Now that we're alive, tell the test knows it can change our visibility.
  70. instance_->ReportProgress("TestPageHideShow:Created");
  71. // Wait until we get a hide event, being careful to handle spurious
  72. // notifications of ViewChanged.
  73. while (WaitUntilViewChanged() && page_visibility_log_.back()) {
  74. }
  75. if (page_visibility_log_.back()) {
  76. // Didn't get a view changed event that changed visibility (though there
  77. // may have been some that didn't change visibility).
  78. // Add more error message since this test has some extra requirements.
  79. return "Didn't receive a hide event in timeout. NOTE: "
  80. "This test requires tab visibility to change and won't pass if you "
  81. "just run it in a browser. Normally the UI test should handle "
  82. "this. You can also run manually by waiting 2 secs, creating a new "
  83. "tab, waiting 2 more secs, and closing the new tab.";
  84. }
  85. // Tell the test so it can show us again.
  86. instance_->ReportProgress("TestPageHideShow:Hidden");
  87. // Wait until we get a show event.
  88. while (WaitUntilViewChanged() && !page_visibility_log_.back()) {
  89. }
  90. ASSERT_TRUE(page_visibility_log_.back());
  91. PASS();
  92. }
  93. std::string TestView::TestSizeChange() {
  94. pp::Rect original_rect = last_view_.GetRect();
  95. pp::Rect desired_rect = original_rect;
  96. desired_rect.set_width(original_rect.width() + 10);
  97. desired_rect.set_height(original_rect.height() + 12);
  98. std::ostringstream script_stream;
  99. script_stream << "var plugin = document.getElementById('plugin');";
  100. script_stream << "plugin.setAttribute('width', "
  101. << desired_rect.width() << ");";
  102. script_stream << "plugin.setAttribute('height', "
  103. << desired_rect.height() << ");";
  104. instance_->EvalScript(script_stream.str());
  105. while (WaitUntilViewChanged() && last_view_.GetRect() != desired_rect) {
  106. }
  107. ASSERT_TRUE(last_view_.GetRect() == desired_rect);
  108. PASS();
  109. }
  110. std::string TestView::TestClipChange() {
  111. pp::Rect original_rect = last_view_.GetRect();
  112. // Original clip should be the full frame.
  113. pp::Rect original_clip = last_view_.GetClipRect();
  114. ASSERT_TRUE(original_clip.x() == 1);
  115. ASSERT_TRUE(original_clip.y() == 1);
  116. ASSERT_TRUE(original_clip.width() == original_rect.width());
  117. ASSERT_TRUE(original_clip.height() == original_rect.height());
  118. int clip_amount = original_rect.height() / 2;
  119. // It might be nice to set the position to be absolute and set the location,
  120. // but this will cause WebKit to actually tear down the plugin and recreate
  121. // it. So instead we add a big div to cause the document to be scrollable,
  122. // and scroll it down.
  123. std::ostringstream script_stream;
  124. script_stream
  125. << "var big = document.createElement('div');"
  126. << "big.setAttribute('style', 'position:absolute; left:100px; "
  127. "top:0px; width:1px; height:5000px;');"
  128. << "document.body.appendChild(big);"
  129. << "window.scrollBy(0, " << original_rect.y() + clip_amount << ");";
  130. instance_->EvalScript(script_stream.str());
  131. pp::Rect desired_clip = original_clip;
  132. desired_clip.set_y(clip_amount + original_clip.y());
  133. desired_clip.set_height(
  134. desired_clip.height() - desired_clip.y() + original_clip.y());
  135. while (WaitUntilViewChanged() && last_view_.GetClipRect() != desired_clip) {
  136. }
  137. ASSERT_TRUE(last_view_.GetClipRect() == desired_clip);
  138. PASS();
  139. }
  140. std::string TestView::TestScrollOffsetChange() {
  141. instance_->EvalScript("document.body.style.width = '5000px';"
  142. "document.body.style.height = '5000px';");
  143. instance_->EvalScript("window.scrollTo(5, 1);");
  144. while (WaitUntilViewChanged() &&
  145. last_view_.GetScrollOffset() != pp::Point(5, 1)) {
  146. }
  147. ASSERT_EQ(pp::Point(5, 1), last_view_.GetScrollOffset());
  148. instance_->EvalScript("window.scrollTo(0, 0);");
  149. while (WaitUntilViewChanged() &&
  150. last_view_.GetScrollOffset() != pp::Point(0, 0)) {
  151. }
  152. ASSERT_EQ(pp::Point(0, 0), last_view_.GetScrollOffset());
  153. PASS();
  154. }