blob: 37bd56b3b5d6fe10bb713846c6ff24a6958be900 [file] [log] [blame]
[email protected]fad73672012-06-15 23:26:061// Copyright (c) 2012 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/extensions/extension_browsertest.h"
6#include "chrome/browser/ui/browser.h"
[email protected]617ee962013-01-29 20:49:127#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]fad73672012-06-15 23:26:068#include "chrome/common/url_constants.h"
9#include "chrome/test/base/ui_test_utils.h"
10#include "content/public/browser/web_contents.h"
[email protected]7d478cb2012-07-24 17:19:4211#include "content/public/test/browser_test_utils.h"
[email protected]885c0e92012-11-13 20:27:4212#include "extensions/common/constants.h"
[email protected]e4452d32013-11-15 23:07:4113#include "extensions/common/extension.h"
[email protected]fad73672012-06-15 23:26:0614
15using content::WebContents;
16using extensions::Extension;
17
18namespace {
19
[email protected]06bc5d92013-01-02 22:44:1320const char kSubscribePage[] = "/subscribe.html";
21const char kFeedPageMultiRel[] = "files/feeds/feed_multi_rel.html";
22const char kValidFeedNoLinks[] = "files/feeds/feed_nolinks.xml";
23const char kValidFeed0[] = "files/feeds/feed_script.xml";
24const char kValidFeed1[] = "files/feeds/feed1.xml";
25const char kValidFeed2[] = "files/feeds/feed2.xml";
26const char kValidFeed3[] = "files/feeds/feed3.xml";
27const char kValidFeed4[] = "files/feeds/feed4.xml";
28const char kValidFeed5[] = "files/feeds/feed5.xml";
29const char kValidFeed6[] = "files/feeds/feed6.xml";
30const char kInvalidFeed1[] = "files/feeds/feed_invalid1.xml";
31const char kInvalidFeed2[] = "files/feeds/feed_invalid2.xml";
[email protected]fad73672012-06-15 23:26:0632// We need a triple encoded string to prove that we are not decoding twice in
33// subscribe.js because one layer is also stripped off when subscribe.js passes
34// it to the XMLHttpRequest object.
[email protected]06bc5d92013-01-02 22:44:1335const char kFeedTripleEncoded[] = "files/feeds/url%25255Fdecoding.html";
[email protected]fad73672012-06-15 23:26:0636
[email protected]06bc5d92013-01-02 22:44:1337static const char kScriptFeedTitle[] =
38 "window.domAutomationController.send("
39 " document.getElementById('title') ? "
40 " document.getElementById('title').textContent : "
41 " \"element 'title' not found\""
42 ");";
43static const char kScriptAnchor[] =
44 "window.domAutomationController.send("
45 " document.getElementById('anchor_0') ? "
46 " document.getElementById('anchor_0').textContent : "
47 " \"element 'anchor_0' not found\""
48 ");";
49static const char kScriptDesc[] =
50 "window.domAutomationController.send("
51 " document.getElementById('desc_0') ? "
52 " document.getElementById('desc_0').textContent : "
53 " \"element 'desc_0' not found\""
54 ");";
55static const char kScriptError[] =
56 "window.domAutomationController.send("
57 " document.getElementById('error') ? "
58 " document.getElementById('error').textContent : "
59 " \"No error\""
60 ");";
[email protected]fad73672012-06-15 23:26:0661
[email protected]ce7d0cbc2013-05-03 18:57:2262GURL GetFeedUrl(net::SpawnedTestServer* server, const std::string& feed_page,
[email protected]fad73672012-06-15 23:26:0663 bool direct_url, std::string extension_id) {
64 GURL feed_url = server->GetURL(feed_page);
65 if (direct_url) {
66 // We navigate directly to the subscribe page for feeds where the feed
67 // sniffing won't work, in other words, as is the case for malformed feeds.
[email protected]885c0e92012-11-13 20:27:4268 return GURL(std::string(extensions::kExtensionScheme) +
[email protected]fad73672012-06-15 23:26:0669 content::kStandardSchemeSeparator +
70 extension_id + std::string(kSubscribePage) + std::string("?") +
71 feed_url.spec() + std::string("&synchronous"));
72 } else {
73 // Navigate to the feed content (which will cause the extension to try to
74 // sniff the type and display the subscribe page in another tab.
75 return GURL(feed_url.spec());
76 }
77}
78
79bool ValidatePageElement(WebContents* tab,
[email protected]b6987e02013-01-04 18:30:4380 const std::string& frame_xpath,
[email protected]06bc5d92013-01-02 22:44:1381 const std::string& javascript,
[email protected]fad73672012-06-15 23:26:0682 const std::string& expected_value) {
83 std::string returned_value;
[email protected]fad73672012-06-15 23:26:0684
[email protected]b6987e02013-01-04 18:30:4385 if (!content::ExecuteScriptInFrameAndExtractString(tab, frame_xpath,
86 javascript,
87 &returned_value))
[email protected]fad73672012-06-15 23:26:0688 return false;
89
90 EXPECT_STREQ(expected_value.c_str(), returned_value.c_str());
91 return expected_value == returned_value;
92}
93
94// Navigates to a feed page and, if |sniff_xml_type| is set, wait for the
95// extension to kick in, detect the feed and redirect to a feed preview page.
96// |sniff_xml_type| is generally set to true if the feed is sniffable and false
97// for invalid feeds.
[email protected]ce7d0cbc2013-05-03 18:57:2298void NavigateToFeedAndValidate(net::SpawnedTestServer* server,
[email protected]fad73672012-06-15 23:26:0699 const std::string& url,
100 Browser* browser,
101 std::string extension_id,
102 bool sniff_xml_type,
103 const std::string& expected_feed_title,
104 const std::string& expected_item_title,
105 const std::string& expected_item_desc,
106 const std::string& expected_error) {
107 if (sniff_xml_type) {
108 // TODO(finnur): Implement this is a non-flaky way.
109 }
110
111 // Navigate to the subscribe page directly.
112 ui_test_utils::NavigateToURL(browser,
113 GetFeedUrl(server, url, true, extension_id));
114
[email protected]617ee962013-01-29 20:49:12115 WebContents* tab = browser->tab_strip_model()->GetActiveWebContents();
[email protected]007b3f82013-04-09 08:46:45116 ASSERT_TRUE(ValidatePageElement(
117 tab, std::string(), kScriptFeedTitle, expected_feed_title));
[email protected]fad73672012-06-15 23:26:06118 ASSERT_TRUE(ValidatePageElement(tab,
[email protected]06bc5d92013-01-02 22:44:13119 "//html/body/div/iframe[1]",
120 kScriptAnchor,
[email protected]fad73672012-06-15 23:26:06121 expected_item_title));
122 ASSERT_TRUE(ValidatePageElement(tab,
[email protected]06bc5d92013-01-02 22:44:13123 "//html/body/div/iframe[1]",
124 kScriptDesc,
[email protected]fad73672012-06-15 23:26:06125 expected_item_desc));
126 ASSERT_TRUE(ValidatePageElement(tab,
[email protected]06bc5d92013-01-02 22:44:13127 "//html/body/div/iframe[1]",
128 kScriptError,
[email protected]fad73672012-06-15 23:26:06129 expected_error));
130}
131
132} // namespace
133
134// Makes sure that the RSS detects RSS feed links, even when rel tag contains
135// more than just "alternate".
136IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSMultiRelLink) {
137 ASSERT_TRUE(test_server()->Start());
138
139 ASSERT_TRUE(LoadExtension(
140 test_data_dir_.AppendASCII("subscribe_page_action")));
141
142 ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0));
143
144 // Navigate to the feed page.
145 GURL feed_url = test_server()->GetURL(kFeedPageMultiRel);
146 ui_test_utils::NavigateToURL(browser(), feed_url);
147 // We should now have one page action ready to go in the LocationBar.
148 ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
149}
150
[email protected]b1258c82014-02-03 20:32:11151// This test is flaky on all platforms; see http://crbug.com/340354
152IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, DISABLED_RSSParseFeedValidFeed1) {
[email protected]fad73672012-06-15 23:26:06153 ASSERT_TRUE(test_server()->Start());
154
155 const Extension* extension = LoadExtension(
156 test_data_dir_.AppendASCII("subscribe_page_action"));
157 ASSERT_TRUE(extension);
158 std::string id = extension->id();
159
160 NavigateToFeedAndValidate(test_server(), kValidFeed1, browser(), id, true,
161 "Feed for MyFeedTitle",
162 "Title 1",
163 "Desc",
164 "No error");
165}
166
[email protected]efe5ba22014-01-07 13:23:27167IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed2) {
[email protected]fad73672012-06-15 23:26:06168 ASSERT_TRUE(test_server()->Start());
169
170 const Extension* extension = LoadExtension(
171 test_data_dir_.AppendASCII("subscribe_page_action"));
172 ASSERT_TRUE(extension);
173 std::string id = extension->id();
174
175 NavigateToFeedAndValidate(test_server(), kValidFeed2, browser(), id, true,
176 "Feed for MyFeed2",
177 "My item title1",
178 "This is a summary.",
179 "No error");
180}
181
[email protected]efe5ba22014-01-07 13:23:27182IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed3) {
[email protected]fad73672012-06-15 23:26:06183 ASSERT_TRUE(test_server()->Start());
184
185 const Extension* extension = LoadExtension(
186 test_data_dir_.AppendASCII("subscribe_page_action"));
187 ASSERT_TRUE(extension);
188 std::string id = extension->id();
189
190 NavigateToFeedAndValidate(test_server(), kValidFeed3, browser(), id, true,
191 "Feed for Google Code buglist rss feed",
192 "My dear title",
193 "My dear content",
194 "No error");
195}
196
[email protected]efe5ba22014-01-07 13:23:27197IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed4) {
[email protected]fad73672012-06-15 23:26:06198 ASSERT_TRUE(test_server()->Start());
199
200 const Extension* extension = LoadExtension(
201 test_data_dir_.AppendASCII("subscribe_page_action"));
202 ASSERT_TRUE(extension);
203 std::string id = extension->id();
204
205 NavigateToFeedAndValidate(test_server(), kValidFeed4, browser(), id, true,
206 "Feed for Title chars <script> %23 stop",
207 "Title chars %23 stop",
208 "My dear content %23 stop",
209 "No error");
210}
211
[email protected]efe5ba22014-01-07 13:23:27212IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed0) {
[email protected]fad73672012-06-15 23:26:06213 ASSERT_TRUE(test_server()->Start());
214
215 const Extension* extension = LoadExtension(
216 test_data_dir_.AppendASCII("subscribe_page_action"));
217 ASSERT_TRUE(extension);
218 std::string id = extension->id();
219
220 // Try a feed with a link with an onclick handler (before r27440 this would
221 // trigger a NOTREACHED).
222 NavigateToFeedAndValidate(test_server(), kValidFeed0, browser(), id, true,
223 "Feed for MyFeedTitle",
224 "Title 1",
225 "Desc VIDEO",
226 "No error");
227}
228
[email protected]efe5ba22014-01-07 13:23:27229IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed5) {
[email protected]fad73672012-06-15 23:26:06230 ASSERT_TRUE(test_server()->Start());
231
232 const Extension* extension = LoadExtension(
233 test_data_dir_.AppendASCII("subscribe_page_action"));
234 ASSERT_TRUE(extension);
235 std::string id = extension->id();
236
237 // Feed with valid but mostly empty xml.
238 NavigateToFeedAndValidate(test_server(), kValidFeed5, browser(), id, true,
239 "Feed for Unknown feed name",
240 "element 'anchor_0' not found",
241 "element 'desc_0' not found",
242 "This feed contains no entries.");
243}
244
[email protected]efe5ba22014-01-07 13:23:27245IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed6) {
[email protected]fad73672012-06-15 23:26:06246 ASSERT_TRUE(test_server()->Start());
247
248 const Extension* extension = LoadExtension(
249 test_data_dir_.AppendASCII("subscribe_page_action"));
250 ASSERT_TRUE(extension);
251 std::string id = extension->id();
252
253 // Feed that is technically invalid but still parseable.
254 NavigateToFeedAndValidate(test_server(), kValidFeed6, browser(), id, true,
255 "Feed for MyFeedTitle",
256 "Title 1",
257 "Desc",
258 "No error");
259}
260
[email protected]efe5ba22014-01-07 13:23:27261IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedInvalidFeed1) {
[email protected]fad73672012-06-15 23:26:06262 ASSERT_TRUE(test_server()->Start());
263
264 const Extension* extension = LoadExtension(
265 test_data_dir_.AppendASCII("subscribe_page_action"));
266 ASSERT_TRUE(extension);
267 std::string id = extension->id();
268
269 // Try an empty feed.
270 NavigateToFeedAndValidate(test_server(), kInvalidFeed1, browser(), id, false,
271 "Feed for Unknown feed name",
272 "element 'anchor_0' not found",
273 "element 'desc_0' not found",
274 "This feed contains no entries.");
275}
276
[email protected]efe5ba22014-01-07 13:23:27277IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedInvalidFeed2) {
[email protected]fad73672012-06-15 23:26:06278 ASSERT_TRUE(test_server()->Start());
279
280 const Extension* extension = LoadExtension(
281 test_data_dir_.AppendASCII("subscribe_page_action"));
282 ASSERT_TRUE(extension);
283 std::string id = extension->id();
284
285 // Try a garbage feed.
286 NavigateToFeedAndValidate(test_server(), kInvalidFeed2, browser(), id, false,
287 "Feed for Unknown feed name",
288 "element 'anchor_0' not found",
289 "element 'desc_0' not found",
290 "This feed contains no entries.");
291}
292
[email protected]efe5ba22014-01-07 13:23:27293IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedInvalidFeed3) {
[email protected]fad73672012-06-15 23:26:06294 ASSERT_TRUE(test_server()->Start());
295
296 const Extension* extension = LoadExtension(
297 test_data_dir_.AppendASCII("subscribe_page_action"));
298 ASSERT_TRUE(extension);
299 std::string id = extension->id();
300
301 // Try a feed that doesn't exist.
302 NavigateToFeedAndValidate(test_server(), "foo.xml", browser(), id, false,
303 "Feed for Unknown feed name",
304 "element 'anchor_0' not found",
305 "element 'desc_0' not found",
306 "This feed contains no entries.");
307}
308
[email protected]efe5ba22014-01-07 13:23:27309IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedInvalidFeed4) {
[email protected]fad73672012-06-15 23:26:06310 ASSERT_TRUE(test_server()->Start());
311
312 const Extension* extension = LoadExtension(
313 test_data_dir_.AppendASCII("subscribe_page_action"));
314 ASSERT_TRUE(extension);
315 std::string id = extension->id();
316
317 // subscribe.js shouldn't double-decode the URL passed in. Otherwise feed
318 // links such as http://search.twitter.com/search.atom?lang=en&q=%23chrome
319 // will result in no feed being downloaded because %23 gets decoded to # and
320 // therefore #chrome is not treated as part of the Twitter query. This test
321 // uses an underscore instead of a hash, but the principle is the same. If
322 // we start erroneously double decoding again, the path (and the feed) will
323 // become valid resulting in a failure for this test.
324 NavigateToFeedAndValidate(
325 test_server(), kFeedTripleEncoded, browser(), id, true,
326 "Feed for Unknown feed name",
327 "element 'anchor_0' not found",
328 "element 'desc_0' not found",
329 "This feed contains no entries.");
330}
331
[email protected]efe5ba22014-01-07 13:23:27332IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeedNoLinks) {
[email protected]fad73672012-06-15 23:26:06333 ASSERT_TRUE(test_server()->Start());
334
335 const Extension* extension = LoadExtension(
336 test_data_dir_.AppendASCII("subscribe_page_action"));
337 ASSERT_TRUE(extension);
338 std::string id = extension->id();
339
340 // Valid feed but containing no links.
341 NavigateToFeedAndValidate(
342 test_server(), kValidFeedNoLinks, browser(), id, true,
343 "Feed for MyFeedTitle",
344 "Title with no link",
345 "Desc",
346 "No error");
347}