1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "base/files/file_util.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/path_service.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/threading/thread_restrictions.h"
12 #include "build/build_config.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_commands.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/chrome_paths.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chrome/test/base/ui_test_utils.h"
21 #include "components/prefs/pref_service.h"
22 #include "content/public/browser/download_manager.h"
23 #include "content/public/browser/navigation_controller.h"
24 #include "content/public/browser/web_contents.h"
25 #include "content/public/test/browser_test.h"
26 #include "content/public/test/download_test_observer.h"
27 #include "content/public/test/test_navigation_observer.h"
28 #include "net/test/embedded_test_server/embedded_test_server.h"
32 struct EncodingTestData {
33 const char* file_name;
34 const char* encoding_name;
37 const EncodingTestData kEncodingTestDatas[] = {
38 { "Big5.html", "Big5" },
39 { "EUC-JP.html", "EUC-JP" },
40 { "gb18030.html", "gb18030" },
41 { "iso-8859-1.html", "windows-1252" },
42 { "ISO-8859-2.html", "ISO-8859-2" },
43 { "ISO-8859-4.html", "ISO-8859-4" },
44 { "ISO-8859-5.html", "ISO-8859-5" },
45 { "ISO-8859-6.html", "ISO-8859-6" },
46 { "ISO-8859-7.html", "ISO-8859-7" },
47 { "ISO-8859-8.html", "ISO-8859-8" },
48 { "ISO-8859-13.html", "ISO-8859-13" },
49 { "ISO-8859-15.html", "ISO-8859-15" },
50 { "KOI8-R.html", "KOI8-R" },
51 { "KOI8-U.html", "KOI8-U" },
52 { "macintosh.html", "macintosh" },
53 { "Shift-JIS.html", "Shift_JIS" },
54 { "US-ASCII.html", "windows-1252" }, // http://crbug.com/15801
55 { "UTF-8.html", "UTF-8" },
56 { "UTF-16LE.html", "UTF-16LE" },
57 { "windows-874.html", "windows-874" },
58 { "EUC-KR.html", "EUC-KR" },
59 { "windows-1250.html", "windows-1250" },
60 { "windows-1251.html", "windows-1251" },
61 { "windows-1252.html", "windows-1252" },
62 { "windows-1253.html", "windows-1253" },
63 { "windows-1254.html", "windows-1254" },
64 { "windows-1255.html", "windows-1255" },
65 { "windows-1256.html", "windows-1256" },
66 { "windows-1257.html", "windows-1257" },
67 { "windows-1258.html", "windows-1258" }
72 static const base::FilePath::CharType* kTestDir =
73 FILE_PATH_LITERAL("encoding_tests");
75 class BrowserEncodingTest
76 : public InProcessBrowserTest,
77 public testing::WithParamInterface<EncodingTestData> {
79 BrowserEncodingTest() {}
81 // Saves the current page and verifies that the output matches the expected
83 void SaveAndCompare(const char* filename_to_write,
84 const base::FilePath& expected,
86 // Dump the page, the content of dump page should be identical to the
87 // expected result file.
88 base::FilePath full_file_name = save_dir_.AppendASCII(filename_to_write);
89 // We save the page as way of complete HTML file, which requires a directory
90 // name to save sub resources in it. Although this test file does not have
91 // sub resources, but the directory name is still required.
92 scoped_refptr<content::MessageLoopRunner> loop_runner(
93 new content::MessageLoopRunner);
94 content::SavePackageFinishedObserver observer(
95 browser()->profile()->GetDownloadManager(), loop_runner->QuitClosure());
96 browser()->tab_strip_model()->GetActiveWebContents()->SavePage(
97 full_file_name, temp_sub_resource_dir_,
98 content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML);
101 base::FilePath expected_file_name = ui_test_utils::GetTestFilePath(
102 base::FilePath(kTestDir), expected);
104 std::string actual_contents;
105 std::string expected_contents;
108 base::ScopedAllowBlockingForTesting allow_blocking;
109 ASSERT_TRUE(base::ReadFileToString(full_file_name, &actual_contents));
111 base::ReadFileToString(expected_file_name, &expected_contents));
114 // Add "Mark of the Web" path with source URL.
115 expected_contents = base::StringPrintfNonConstexpr(
116 expected_contents.c_str(), url.spec().length(), url.spec().c_str());
118 EXPECT_EQ(expected_contents, actual_contents);
121 void SetUpOnMainThread() override {
122 base::FilePath test_data_dir;
123 ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
124 embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
125 ASSERT_TRUE(embedded_test_server()->Start());
127 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
128 save_dir_ = temp_dir_.GetPath();
129 temp_sub_resource_dir_ = save_dir_.AppendASCII("sub_resource_files");
132 base::ScopedTempDir temp_dir_;
133 base::FilePath save_dir_;
134 base::FilePath temp_sub_resource_dir_;
137 // TODO(jnd): 1. Some encodings are missing here. It'll be added later. See
138 // http://crbug.com/13306.
139 // 2. Add more files with multiple encoding name variants for each canonical
140 // encoding name). Webkit layout tests cover some, but testing in the UI test is
142 IN_PROC_BROWSER_TEST_P(BrowserEncodingTest, TestEncodingAliasMapping) {
143 const char* const kAliasTestDir = "alias_mapping";
145 base::FilePath test_dir_path = base::FilePath(kTestDir).AppendASCII(
147 base::FilePath test_file_path(test_dir_path);
148 test_file_path = test_file_path.AppendASCII(
149 GetParam().file_name);
152 embedded_test_server()->GetURL("/" + test_file_path.MaybeAsASCII());
153 ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
154 EXPECT_EQ(GetParam().encoding_name,
155 browser()->tab_strip_model()->GetActiveWebContents()->
159 INSTANTIATE_TEST_SUITE_P(EncodingAliases,
161 testing::ValuesIn(kEncodingTestDatas));
163 // The following encodings are excluded from the auto-detection test because
164 // it's a known issue that the current encoding detector does not detect them:
175 IN_PROC_BROWSER_TEST_F(BrowserEncodingTest, TestEncodingAutoDetect) {
176 struct EncodingAutoDetectTestData {
177 const char* test_file_name; // File name of test data.
178 const char* expected_result; // File name of expected results.
179 const char* expected_encoding; // expected encoding.
181 const EncodingAutoDetectTestData kTestDatas[] = {
182 { "Big5_with_no_encoding_specified.html",
183 "expected_Big5_saved_from_no_encoding_specified.html",
185 { "GBK_with_no_encoding_specified.html",
186 "expected_GBK_saved_from_no_encoding_specified.html",
188 { "iso-8859-1_with_no_encoding_specified.html",
189 "expected_iso-8859-1_saved_from_no_encoding_specified.html",
191 { "ISO-8859-5_with_no_encoding_specified.html",
192 "expected_ISO-8859-5_saved_from_no_encoding_specified.html",
194 { "ISO-8859-6_with_no_encoding_specified.html",
195 "expected_ISO-8859-6_saved_from_no_encoding_specified.html",
197 { "ISO-8859-7_with_no_encoding_specified.html",
198 "expected_ISO-8859-7_saved_from_no_encoding_specified.html",
200 { "ISO-8859-8-I_with_no_encoding_specified.html",
201 "expected_ISO-8859-8-I_saved_from_no_encoding_specified.html",
203 { "KOI8-R_with_no_encoding_specified.html",
204 "expected_KOI8-R_saved_from_no_encoding_specified.html",
206 { "Shift-JIS_with_no_encoding_specified.html",
207 "expected_Shift-JIS_saved_from_no_encoding_specified.html",
209 { "EUC-KR_with_no_encoding_specified.html",
210 "expected_EUC-KR_saved_from_no_encoding_specified.html",
212 { "windows-1251_with_no_encoding_specified.html",
213 "expected_windows-1251_saved_from_no_encoding_specified.html",
215 { "windows-1254_with_no_encoding_specified.html",
216 "expected_windows-1254_saved_from_no_encoding_specified.html",
218 { "windows-1255_with_no_encoding_specified.html",
219 "expected_windows-1255_saved_from_no_encoding_specified.html",
221 { "windows-1256_with_no_encoding_specified.html",
222 "expected_windows-1256_saved_from_no_encoding_specified.html",
225 const char* const kAutoDetectDir = "auto_detect";
226 // Directory of the files of expected results.
227 const char* const kExpectedResultDir = "expected_results";
229 base::FilePath test_dir_path =
230 base::FilePath(kTestDir).AppendASCII(kAutoDetectDir);
232 // Set the default charset to one of encodings not supported by the current
233 // auto-detector (Please refer to the above comments) to make sure we
234 // incorrectly decode the page. Now we use ISO-8859-4.
235 browser()->profile()->GetPrefs()->SetString(prefs::kDefaultCharset,
238 content::WebContents* web_contents =
239 browser()->tab_strip_model()->GetActiveWebContents();
240 for (size_t i = 0; i < std::size(kTestDatas); ++i) {
242 base::FilePath test_file_path(test_dir_path);
243 test_file_path = test_file_path.AppendASCII(kTestDatas[i].test_file_name);
245 embedded_test_server()->GetURL("/" + test_file_path.MaybeAsASCII());
246 ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
248 // Get the encoding of page. It should return the real encoding now.
249 EXPECT_EQ(kTestDatas[i].expected_encoding, web_contents->GetEncoding());
251 // Dump the page, the content of dump page should be equal with our expect
253 base::FilePath expected_result_file_name =
254 base::FilePath().AppendASCII(kAutoDetectDir).
255 AppendASCII(kExpectedResultDir).
256 AppendASCII(kTestDatas[i].expected_result);
257 SaveAndCompare(kTestDatas[i].test_file_name, expected_result_file_name,