1// Copyright 2013 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 5#include "chrome/browser/media/webrtc_browsertest_common.h" 6 7#include "base/files/file_util.h" 8#include "base/path_service.h" 9#include "base/strings/stringprintf.h" 10#include "base/test/test_timeouts.h" 11#include "base/time/time.h" 12#include "chrome/browser/profiles/profile.h" 13#include "chrome/browser/ui/browser_tabstrip.h" 14#include "chrome/common/chrome_paths.h" 15#include "content/public/test/browser_test_utils.h" 16 17namespace test { 18 19// Relative to the chrome/test/data directory. 20const base::FilePath::CharType kReferenceFilesDirName[] = 21 FILE_PATH_LITERAL("webrtc/resources"); 22const base::FilePath::CharType kReferenceFileName360p[] = 23 FILE_PATH_LITERAL("reference_video_640x360_30fps"); 24const base::FilePath::CharType kReferenceFileName720p[] = 25 FILE_PATH_LITERAL("reference_video_1280x720_30fps"); 26const base::FilePath::CharType kYuvFileExtension[] = FILE_PATH_LITERAL("yuv"); 27const base::FilePath::CharType kY4mFileExtension[] = FILE_PATH_LITERAL("y4m"); 28 29// This message describes how to modify your .gclient to get the reference 30// video files downloaded for you. 31static const char kAdviseOnGclientSolution[] = 32 "You need to add this solution to your .gclient to run this test:\n" 33 "{\n" 34 " \"name\" : \"webrtc.DEPS\",\n" 35 " \"url\" : \"svn://svn.chromium.org/chrome/trunk/deps/" 36 "third_party/webrtc/webrtc.DEPS\",\n" 37 "}"; 38 39const int kDefaultPollIntervalMsec = 250; 40 41base::FilePath GetReferenceFilesDir() { 42 base::FilePath test_data_dir; 43 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); 44 45 return test_data_dir.Append(kReferenceFilesDirName); 46} 47 48bool HasReferenceFilesInCheckout() { 49 if (!base::PathExists(GetReferenceFilesDir())) { 50 LOG(ERROR) 51 << "Cannot find the working directory for the reference video " 52 << "files, expected at " << GetReferenceFilesDir().value() << ". " << 53 kAdviseOnGclientSolution; 54 return false; 55 } 56 return HasYuvAndY4mFile(test::kReferenceFileName360p) && 57 HasYuvAndY4mFile(test::kReferenceFileName720p); 58} 59 60bool HasYuvAndY4mFile(const base::FilePath::CharType* reference_file) { 61 base::FilePath webrtc_reference_video_yuv = GetReferenceFilesDir() 62 .Append(reference_file).AddExtension(kYuvFileExtension); 63 if (!base::PathExists(webrtc_reference_video_yuv)) { 64 LOG(ERROR) 65 << "Missing YUV reference video to be used for quality" 66 << " comparison, expected at " << webrtc_reference_video_yuv.value() 67 << ". " << kAdviseOnGclientSolution; 68 return false; 69 } 70 71 base::FilePath webrtc_reference_video_y4m = GetReferenceFilesDir() 72 .Append(reference_file).AddExtension(kY4mFileExtension); 73 if (!base::PathExists(webrtc_reference_video_y4m)) { 74 LOG(ERROR) 75 << "Missing Y4M reference video to be used for quality" 76 << " comparison, expected at "<< webrtc_reference_video_y4m.value() 77 << ". " << kAdviseOnGclientSolution; 78 return false; 79 } 80 return true; 81} 82 83bool SleepInJavascript(content::WebContents* tab_contents, int timeout_msec) { 84 const std::string javascript = base::StringPrintf( 85 "setTimeout(function() {" 86 " window.domAutomationController.send('sleep-ok');" 87 "}, %d)", timeout_msec); 88 89 std::string result; 90 bool ok = content::ExecuteScriptAndExtractString( 91 tab_contents, javascript, &result); 92 return ok && result == "sleep-ok"; 93} 94 95bool PollingWaitUntil(const std::string& javascript, 96 const std::string& evaluates_to, 97 content::WebContents* tab_contents) { 98 return PollingWaitUntil(javascript, evaluates_to, tab_contents, 99 kDefaultPollIntervalMsec); 100} 101 102bool PollingWaitUntil(const std::string& javascript, 103 const std::string& evaluates_to, 104 content::WebContents* tab_contents, 105 int poll_interval_msec) { 106 base::Time start_time = base::Time::Now(); 107 base::TimeDelta timeout = TestTimeouts::action_max_timeout(); 108 std::string result; 109 110 while (base::Time::Now() - start_time < timeout) { 111 std::string result; 112 if (!content::ExecuteScriptAndExtractString(tab_contents, javascript, 113 &result)) { 114 LOG(ERROR) << "Failed to execute javascript " << javascript; 115 return false; 116 } 117 118 if (evaluates_to == result) 119 return true; 120 121 // Sleep a bit here to keep this loop from spinlocking too badly. 122 if (!SleepInJavascript(tab_contents, poll_interval_msec)) { 123 // TODO(phoglund): Figure out why this fails every now and then. 124 // It's not a huge deal if it does though. 125 LOG(ERROR) << "Failed to sleep."; 126 } 127 } 128 LOG(ERROR) 129 << "Timed out while waiting for " << javascript 130 << " to evaluate to " << evaluates_to << "; last result was '" << result 131 << "'"; 132 return false; 133} 134 135} // namespace test 136