OLD | NEW |
| (Empty) |
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 | |
5 #include "base/command_line.h" | |
6 #include "base/file_path.h" | |
7 #include "base/file_util.h" | |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "base/path_service.h" | |
10 #include "base/string_split.h" | |
11 #include "base/string_util.h" | |
12 #include "base/test/test_timeouts.h" | |
13 #include "base/utf_string_conversions.h" | |
14 #include "base/values.h" | |
15 #include "chrome/common/chrome_paths.h" | |
16 #include "chrome/common/chrome_switches.h" | |
17 #include "chrome/test/automation/tab_proxy.h" | |
18 #include "chrome/test/ui/ui_test.h" | |
19 #include "content/common/json_value_serializer.h" | |
20 #include "googleurl/src/gurl.h" | |
21 #include "net/base/net_util.h" | |
22 | |
23 namespace { | |
24 | |
25 static const FilePath::CharType kBaseUrl[] = | |
26 FILE_PATH_LITERAL("http://localhost:8000/"); | |
27 | |
28 static const FilePath::CharType kTestDirectory[] = | |
29 FILE_PATH_LITERAL("dom_checker/"); | |
30 | |
31 static const FilePath::CharType kStartFile[] = | |
32 FILE_PATH_LITERAL("dom_checker.html"); | |
33 | |
34 const char kRunDomCheckerTest[] = "run-dom-checker-test"; | |
35 | |
36 class DomCheckerTest : public UITest { | |
37 public: | |
38 typedef std::list<std::string> ResultsList; | |
39 typedef std::set<std::string> ResultsSet; | |
40 | |
41 DomCheckerTest() { | |
42 dom_automation_enabled_ = true; | |
43 enable_file_cookies_ = false; | |
44 show_window_ = true; | |
45 launch_arguments_.AppendSwitch(switches::kDisablePopupBlocking); | |
46 } | |
47 | |
48 void RunTest(bool use_http, ResultsList* new_passes, | |
49 ResultsList* new_failures) { | |
50 int test_count = 0; | |
51 ResultsSet expected_failures, current_failures; | |
52 | |
53 std::string failures_file = use_http ? | |
54 #if defined(OS_MACOSX) | |
55 "expected_failures-http.txt" : "expected_failures_mac-file.txt"; | |
56 #elif defined(OS_LINUX) | |
57 "expected_failures-http.txt" : "expected_failures_linux-file.txt"; | |
58 #elif defined(OS_WIN) | |
59 "expected_failures-http.txt" : "expected_failures_win-file.txt"; | |
60 #else | |
61 "" : ""; | |
62 #endif | |
63 | |
64 ASSERT_TRUE(GetExpectedFailures(failures_file, &expected_failures)); | |
65 | |
66 RunDomChecker(use_http, &test_count, ¤t_failures); | |
67 printf("\nTests run: %d\n", test_count); | |
68 | |
69 // Compute the list of new passes and failures. | |
70 CompareSets(current_failures, expected_failures, new_passes); | |
71 CompareSets(expected_failures, current_failures, new_failures); | |
72 } | |
73 | |
74 void PrintResults(const ResultsList& new_passes, | |
75 const ResultsList& new_failures) { | |
76 PrintResults(new_failures, "new tests failing", true); | |
77 PrintResults(new_passes, "new tests passing", false); | |
78 } | |
79 | |
80 private: | |
81 void PrintResults(const ResultsList& results, const char* message, | |
82 bool add_failure) { | |
83 if (!results.empty()) { | |
84 if (add_failure) | |
85 ADD_FAILURE(); | |
86 | |
87 printf("%s:\n", message); | |
88 ResultsList::const_iterator it = results.begin(); | |
89 for (; it != results.end(); ++it) | |
90 printf(" %s\n", it->c_str()); | |
91 printf("\n"); | |
92 } | |
93 } | |
94 | |
95 // Find the elements of "b" that are not in "a". | |
96 void CompareSets(const ResultsSet& a, const ResultsSet& b, | |
97 ResultsList* only_in_b) { | |
98 ResultsSet::const_iterator it = b.begin(); | |
99 for (; it != b.end(); ++it) { | |
100 if (a.find(*it) == a.end()) | |
101 only_in_b->push_back(*it); | |
102 } | |
103 } | |
104 | |
105 // Return the path to the DOM checker directory on the local filesystem. | |
106 FilePath GetDomCheckerDir() { | |
107 FilePath test_dir; | |
108 PathService::Get(chrome::DIR_TEST_DATA, &test_dir); | |
109 return test_dir.AppendASCII("dom_checker"); | |
110 } | |
111 | |
112 bool ReadExpectedResults(const std::string& failures_file, | |
113 std::string* results) { | |
114 FilePath results_path = GetDomCheckerDir(); | |
115 results_path = results_path.AppendASCII(failures_file); | |
116 return file_util::ReadFileToString(results_path, results); | |
117 } | |
118 | |
119 void ParseExpectedFailures(const std::string& input, ResultsSet* output) { | |
120 if (input.empty()) | |
121 return; | |
122 | |
123 std::vector<std::string> tokens; | |
124 base::SplitString(input, '\n', &tokens); | |
125 | |
126 std::vector<std::string>::const_iterator it = tokens.begin(); | |
127 for (; it != tokens.end(); ++it) { | |
128 // Allow comments (lines that start with #). | |
129 if (it->length() > 0 && it->at(0) != '#') | |
130 output->insert(*it); | |
131 } | |
132 } | |
133 | |
134 bool GetExpectedFailures(const std::string& failures_file, | |
135 ResultsSet* expected_failures) { | |
136 std::string expected_failures_text; | |
137 bool have_expected_results = ReadExpectedResults(failures_file, | |
138 &expected_failures_text); | |
139 if (!have_expected_results) | |
140 return false; | |
141 ParseExpectedFailures(expected_failures_text, expected_failures); | |
142 return true; | |
143 } | |
144 | |
145 bool WaitUntilTestCompletes(TabProxy* tab) { | |
146 return WaitUntilJavaScriptCondition(tab, L"", | |
147 L"window.domAutomationController.send(automation.IsDone());", | |
148 TestTimeouts::huge_test_timeout_ms()); | |
149 } | |
150 | |
151 bool GetTestCount(TabProxy* tab, int* test_count) { | |
152 return tab->ExecuteAndExtractInt(L"", | |
153 L"window.domAutomationController.send(automation.GetTestCount());", | |
154 test_count); | |
155 } | |
156 | |
157 bool GetTestsFailed(TabProxy* tab, ResultsSet* tests_failed) { | |
158 std::wstring json_wide; | |
159 bool succeeded = tab->ExecuteAndExtractString(L"", | |
160 L"window.domAutomationController.send(" | |
161 L" JSON.stringify(automation.GetFailures()));", | |
162 &json_wide); | |
163 | |
164 // Note that we don't use ASSERT_TRUE here (and in some other places) as it | |
165 // doesn't work inside a function with a return type other than void. | |
166 EXPECT_TRUE(succeeded); | |
167 if (!succeeded) | |
168 return false; | |
169 | |
170 std::string json = WideToUTF8(json_wide); | |
171 JSONStringValueSerializer deserializer(json); | |
172 scoped_ptr<Value> value(deserializer.Deserialize(NULL, NULL)); | |
173 | |
174 EXPECT_TRUE(value.get()); | |
175 if (!value.get()) | |
176 return false; | |
177 | |
178 EXPECT_TRUE(value->IsType(Value::TYPE_LIST)); | |
179 if (!value->IsType(Value::TYPE_LIST)) | |
180 return false; | |
181 | |
182 ListValue* list_value = static_cast<ListValue*>(value.get()); | |
183 | |
184 // The parsed JSON object will be an array of strings, each of which is a | |
185 // test failure. Add those strings to the results set. | |
186 ListValue::const_iterator it = list_value->begin(); | |
187 for (; it != list_value->end(); ++it) { | |
188 EXPECT_TRUE((*it)->IsType(Value::TYPE_STRING)); | |
189 if ((*it)->IsType(Value::TYPE_STRING)) { | |
190 std::string test_name; | |
191 succeeded = (*it)->GetAsString(&test_name); | |
192 EXPECT_TRUE(succeeded); | |
193 if (succeeded) | |
194 tests_failed->insert(test_name); | |
195 } | |
196 } | |
197 | |
198 return true; | |
199 } | |
200 | |
201 void RunDomChecker(bool use_http, int* test_count, ResultsSet* tests_failed) { | |
202 GURL test_url; | |
203 FilePath::StringType start_file(kStartFile); | |
204 if (use_http) { | |
205 FilePath::StringType test_directory(kTestDirectory); | |
206 FilePath::StringType url_string(kBaseUrl); | |
207 url_string.append(test_directory); | |
208 url_string.append(start_file); | |
209 test_url = GURL(url_string); | |
210 } else { | |
211 FilePath test_path = GetDomCheckerDir(); | |
212 test_path = test_path.Append(start_file); | |
213 test_url = net::FilePathToFileURL(test_path); | |
214 } | |
215 | |
216 scoped_refptr<TabProxy> tab(GetActiveTab()); | |
217 ASSERT_TRUE(tab.get()); | |
218 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(test_url)); | |
219 | |
220 // Wait for the test to finish. | |
221 ASSERT_TRUE(WaitUntilTestCompletes(tab.get())); | |
222 | |
223 // Get the test results. | |
224 ASSERT_TRUE(GetTestCount(tab.get(), test_count)); | |
225 ASSERT_TRUE(GetTestsFailed(tab.get(), tests_failed)); | |
226 ASSERT_GT(*test_count, 0); | |
227 } | |
228 | |
229 DISALLOW_COPY_AND_ASSIGN(DomCheckerTest); | |
230 }; | |
231 | |
232 TEST_F(DomCheckerTest, File) { | |
233 if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDomCheckerTest)) | |
234 return; | |
235 | |
236 ResultsList new_passes, new_failures; | |
237 RunTest(false, &new_passes, &new_failures); | |
238 PrintResults(new_passes, new_failures); | |
239 } | |
240 | |
241 // This test was previously failing because it was looking for an | |
242 // expected results file that didn't exist. Fixing that bug revealed | |
243 // that the expected results weren't correct anyway. | |
244 // http://crbug.com/21321 | |
245 TEST_F(DomCheckerTest, FAILS_Http) { | |
246 if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDomCheckerTest)) | |
247 return; | |
248 | |
249 ResultsList new_passes, new_failures; | |
250 RunTest(true, &new_passes, &new_failures); | |
251 PrintResults(new_passes, new_failures); | |
252 } | |
253 | |
254 } // namespace | |
OLD | NEW |