Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: chrome/browser/pdf/pdf_extension_test.cc

Issue 2100753003: Enable PDF accessibility when RenderFrame's accessibility mode changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix win assertion Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stddef.h> 5 #include <stddef.h>
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/base_paths.h" 9 #include "base/base_paths.h"
10 #include "base/files/file_enumerator.h" 10 #include "base/files/file_enumerator.h"
(...skipping 30 matching lines...) Expand all
41 #include "content/public/browser/notification_registrar.h" 41 #include "content/public/browser/notification_registrar.h"
42 #include "content/public/browser/plugin_service.h" 42 #include "content/public/browser/plugin_service.h"
43 #include "content/public/browser/render_process_host.h" 43 #include "content/public/browser/render_process_host.h"
44 #include "content/public/browser/render_view_host.h" 44 #include "content/public/browser/render_view_host.h"
45 #include "content/public/browser/render_widget_host.h" 45 #include "content/public/browser/render_widget_host.h"
46 #include "content/public/browser/web_contents.h" 46 #include "content/public/browser/web_contents.h"
47 #include "content/public/test/browser_test_utils.h" 47 #include "content/public/test/browser_test_utils.h"
48 #include "extensions/browser/extension_registry.h" 48 #include "extensions/browser/extension_registry.h"
49 #include "extensions/common/manifest_handlers/mime_types_handler.h" 49 #include "extensions/common/manifest_handlers/mime_types_handler.h"
50 #include "extensions/test/result_catcher.h" 50 #include "extensions/test/result_catcher.h"
51 #include "net/dns/mock_host_resolver.h"
51 #include "net/test/embedded_test_server/embedded_test_server.h" 52 #include "net/test/embedded_test_server/embedded_test_server.h"
52 #include "ui/base/resource/resource_bundle.h" 53 #include "ui/base/resource/resource_bundle.h"
53 #include "url/gurl.h" 54 #include "url/gurl.h"
54 55
55 #if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX) 56 #if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
56 #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h" 57 #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h"
57 #endif 58 #endif
58 59
59 const int kNumberLoadTestParts = 10; 60 const int kNumberLoadTestParts = 10;
60 61
62 // Using ASSERT_TRUE deliberately instead of ASSERT_EQ or ASSERT_STREQ
63 // in order to print a more readable message if the strings differ.
64 #define ASSERT_MULTILINE_STREQ(expected, actual) \
65 ASSERT_TRUE(expected == actual) \
66 << "Expected:\n" << expected \
67 << "\n\nActual:\n" << actual
68
61 bool GetGuestCallback(content::WebContents** guest_out, 69 bool GetGuestCallback(content::WebContents** guest_out,
62 content::WebContents* guest) { 70 content::WebContents* guest) {
63 EXPECT_FALSE(*guest_out); 71 EXPECT_FALSE(*guest_out);
64 *guest_out = guest; 72 *guest_out = guest;
65 // Return false so that we iterate through all the guests and verify there is 73 // Return false so that we iterate through all the guests and verify there is
66 // only one. 74 // only one.
67 return false; 75 return false;
68 } 76 }
69 77
70 class PDFExtensionTest : public ExtensionApiTest, 78 class PDFExtensionTest : public ExtensionApiTest,
71 public testing::WithParamInterface<int> { 79 public testing::WithParamInterface<int> {
72 public: 80 public:
73 ~PDFExtensionTest() override {} 81 ~PDFExtensionTest() override {}
74 82
83 void SetUpCommandLine(base::CommandLine* command_line) override {
84 content::IsolateAllSitesForTesting(command_line);
raymes 2016/07/12 01:36:23 Don't we have site isolation bots that will run al
dmazzoni 2016/07/13 23:17:53 My understanding is that when the test is agnostic
raymes 2016/07/14 03:15:54 Should we only enable it in PdfAccessibilityInOOPI
nasko 2016/07/14 18:21:44 Long term the goal is to eliminate the FYI bots th
85 }
86
75 void SetUpOnMainThread() override { 87 void SetUpOnMainThread() override {
76 ExtensionApiTest::SetUpOnMainThread(); 88 ExtensionApiTest::SetUpOnMainThread();
89 host_resolver()->AddRule("*", "127.0.0.1");
raymes 2016/07/12 01:36:23 How come this is needed?
dmazzoni 2016/07/13 23:17:53 This allows us to use a url of "/cross-site/1.com/
raymes 2016/07/14 03:15:54 Thanks. This might conflict with https://coderevie
nasko 2016/07/14 18:21:44 We have the * rule all over the place. What is a g
77 ASSERT_TRUE(embedded_test_server()->Start()); 90 ASSERT_TRUE(embedded_test_server()->Start());
91 content::SetupCrossSiteRedirector(embedded_test_server());
78 } 92 }
79 93
80 void TearDownOnMainThread() override { 94 void TearDownOnMainThread() override {
81 ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete()); 95 ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
82 ExtensionApiTest::TearDownOnMainThread(); 96 ExtensionApiTest::TearDownOnMainThread();
83 } 97 }
84 98
85 bool PdfIsExpectedToFailLoad(const std::string& pdf_file) { 99 bool PdfIsExpectedToFailLoad(const std::string& pdf_file) {
86 const char* const kFailingPdfs[] = { 100 const char* const kFailingPdfs[] = {
87 // TODO(thestig): Investigate why this file doesn't fail when served by 101 // TODO(thestig): Investigate why this file doesn't fail when served by
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 #endif 520 #endif
507 ASSERT_TRUE( 521 ASSERT_TRUE(
508 content::ExecuteScript(guest_contents, "viewer.viewport.zoomIn();")); 522 content::ExecuteScript(guest_contents, "viewer.viewport.zoomIn();"));
509 523
510 watcher.Wait(); 524 watcher.Wait();
511 #if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX) 525 #if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
512 EXPECT_EQ(nullptr, ZoomBubbleView::GetZoomBubble()); 526 EXPECT_EQ(nullptr, ZoomBubbleView::GetZoomBubble());
513 #endif 527 #endif
514 } 528 }
515 529
516 IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibility) { 530 static std::string DumpPdfAccessibilityTree(const ui::AXTreeUpdate& ax_tree) {
517 content::BrowserAccessibilityState::GetInstance()->EnableAccessibility();
518
519 GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf"));
520 content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
521 ASSERT_TRUE(guest_contents);
522
523 WaitForAccessibilityTreeToContainNodeWithName(guest_contents,
524 "1 First Section\r\n");
525 ui::AXTreeUpdate ax_tree = GetAccessibilityTreeSnapshot(guest_contents);
526
527 // Create a string representation of the tree starting with the embedded 531 // Create a string representation of the tree starting with the embedded
528 // object. 532 // object.
529 std::string ax_tree_dump; 533 std::string ax_tree_dump;
530 base::hash_map<int32_t, int> id_to_indentation; 534 base::hash_map<int32_t, int> id_to_indentation;
531 bool found_embedded_object = false; 535 bool found_embedded_object = false;
532 for (auto& node : ax_tree.nodes) { 536 for (auto& node : ax_tree.nodes) {
533 if (node.role == ui::AX_ROLE_EMBEDDED_OBJECT) 537 if (node.role == ui::AX_ROLE_EMBEDDED_OBJECT)
534 found_embedded_object = true; 538 found_embedded_object = true;
535 if (!found_embedded_object) 539 if (!found_embedded_object)
536 continue; 540 continue;
537 541
538 int indent = id_to_indentation[node.id]; 542 int indent = id_to_indentation[node.id];
539 ax_tree_dump += std::string(2 * indent, ' '); 543 ax_tree_dump += std::string(2 * indent, ' ');
540 ax_tree_dump += ui::ToString(node.role); 544 ax_tree_dump += ui::ToString(node.role);
541 545
542 std::string name = node.GetStringAttribute(ui::AX_ATTR_NAME); 546 std::string name = node.GetStringAttribute(ui::AX_ATTR_NAME);
543 base::ReplaceChars(name, "\r", "\\r", &name); 547 base::ReplaceChars(name, "\r", "\\r", &name);
544 base::ReplaceChars(name, "\n", "\\n", &name); 548 base::ReplaceChars(name, "\n", "\\n", &name);
545 if (!name.empty()) 549 if (!name.empty())
546 ax_tree_dump += " '" + name + "'"; 550 ax_tree_dump += " '" + name + "'";
547 ax_tree_dump += "\n"; 551 ax_tree_dump += "\n";
548 for (size_t j = 0; j < node.child_ids.size(); ++j) 552 for (size_t j = 0; j < node.child_ids.size(); ++j)
549 id_to_indentation[node.child_ids[j]] = indent + 1; 553 id_to_indentation[node.child_ids[j]] = indent + 1;
550 } 554 }
551 555
552 const char* expected_ax_tree = 556 return ax_tree_dump;
553 "embeddedObject\n" 557 }
554 " group\n"
555 " region 'Page 1'\n"
556 " paragraph\n"
557 " staticText '1 First Section\\r\\n'\n"
558 " inlineTextBox '1 '\n"
559 " inlineTextBox 'First Section\\r\\n'\n"
560 " paragraph\n"
561 " staticText 'This is the first section.\\r\\n1'\n"
562 " inlineTextBox 'This is the first section.\\r\\n'\n"
563 " inlineTextBox '1'\n"
564 " region 'Page 2'\n"
565 " paragraph\n"
566 " staticText '1.1 First Subsection\\r\\n'\n"
567 " inlineTextBox '1.1 '\n"
568 " inlineTextBox 'First Subsection\\r\\n'\n"
569 " paragraph\n"
570 " staticText 'This is the first subsection.\\r\\n2'\n"
571 " inlineTextBox 'This is the first subsection.\\r\\n'\n"
572 " inlineTextBox '2'\n"
573 " region 'Page 3'\n"
574 " paragraph\n"
575 " staticText '2 Second Section\\r\\n'\n"
576 " inlineTextBox '2 '\n"
577 " inlineTextBox 'Second Section\\r\\n'\n"
578 " paragraph\n"
579 " staticText '3'\n"
580 " inlineTextBox '3'\n";
581 558
582 // Using ASSERT_TRUE deliberately instead of ASSERT_EQ or ASSERT_STREQ 559 static const char* kExpectedPDFAXTree =
583 // in order to print a more readable message if the strings differ. 560 "embeddedObject\n"
584 ASSERT_TRUE(expected_ax_tree == ax_tree_dump) 561 " group\n"
585 << "Expected:\n" << expected_ax_tree 562 " region 'Page 1'\n"
586 << "\n\nActual:\n" << ax_tree_dump; 563 " paragraph\n"
564 " staticText '1 First Section\\r\\n'\n"
565 " inlineTextBox '1 '\n"
566 " inlineTextBox 'First Section\\r\\n'\n"
567 " paragraph\n"
568 " staticText 'This is the first section.\\r\\n1'\n"
569 " inlineTextBox 'This is the first section.\\r\\n'\n"
570 " inlineTextBox '1'\n"
571 " region 'Page 2'\n"
572 " paragraph\n"
573 " staticText '1.1 First Subsection\\r\\n'\n"
574 " inlineTextBox '1.1 '\n"
575 " inlineTextBox 'First Subsection\\r\\n'\n"
576 " paragraph\n"
577 " staticText 'This is the first subsection.\\r\\n2'\n"
578 " inlineTextBox 'This is the first subsection.\\r\\n'\n"
579 " inlineTextBox '2'\n"
580 " region 'Page 3'\n"
581 " paragraph\n"
582 " staticText '2 Second Section\\r\\n'\n"
583 " inlineTextBox '2 '\n"
584 " inlineTextBox 'Second Section\\r\\n'\n"
585 " paragraph\n"
586 " staticText '3'\n"
587 " inlineTextBox '3'\n";
588
589 IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibility) {
590 content::BrowserAccessibilityState::GetInstance()->EnableAccessibility();
591
592 GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf"));
593 content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
594 ASSERT_TRUE(guest_contents);
595
596 WaitForAccessibilityTreeToContainNodeWithName(guest_contents,
597 "1 First Section\r\n");
598 ui::AXTreeUpdate ax_tree = GetAccessibilityTreeSnapshot(guest_contents);
599 std::string ax_tree_dump = DumpPdfAccessibilityTree(ax_tree);
600 ASSERT_MULTILINE_STREQ(kExpectedPDFAXTree, ax_tree_dump);
587 } 601 }
602
603 IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityEnableLater) {
604 // In this test, load the PDF file first, with accessibility off.
605 GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf"));
606 content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
607 ASSERT_TRUE(guest_contents);
608
609 // Now enable accessibility globally, and assert that the
raymes 2016/07/12 01:36:23 nit: fill 80 chars
dmazzoni 2016/07/13 23:17:53 Done
610 // PDF accessibility tree loads.
611 EnableAccessibilityForWebContents(guest_contents);
612 WaitForAccessibilityTreeToContainNodeWithName(guest_contents,
613 "1 First Section\r\n");
614 ui::AXTreeUpdate ax_tree = GetAccessibilityTreeSnapshot(guest_contents);
615 std::string ax_tree_dump = DumpPdfAccessibilityTree(ax_tree);
616 ASSERT_MULTILINE_STREQ(kExpectedPDFAXTree, ax_tree_dump);
617 }
618
619 bool RetrieveGuestContents(
620 content::WebContents** out_guest_contents,
621 content::WebContents* in_guest_contents) {
622 *out_guest_contents = in_guest_contents;
623 return true;
624 }
625
626 IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityInIframe) {
627 content::BrowserAccessibilityState::GetInstance()->EnableAccessibility();
628 GURL test_iframe_url(embedded_test_server()->GetURL("/pdf/test-iframe.html"));
629 ui_test_utils::NavigateToURL(browser(), test_iframe_url);
630 content::WebContents* contents =
631 browser()->tab_strip_model()->GetActiveWebContents();
632 WaitForAccessibilityTreeToContainNodeWithName(contents,
633 "1 First Section\r\n");
634
635 content::WebContents* guest_contents = nullptr;
636 content::BrowserPluginGuestManager* guest_manager =
637 contents->GetBrowserContext()->GetGuestManager();
638 guest_manager->ForEachGuest(contents,
639 base::Bind(&RetrieveGuestContents,
640 &guest_contents));
641 ASSERT_TRUE(guest_contents);
642
643 ui::AXTreeUpdate ax_tree = GetAccessibilityTreeSnapshot(guest_contents);
raymes 2016/07/12 01:36:23 Hmm, why can't we get the accessibility tree from
dmazzoni 2016/07/13 23:17:53 It's easy to get a single frame's accessibility tr
raymes 2016/07/14 03:15:54 I still don't fully understand. Does WaitForAccess
dmazzoni 2016/07/14 21:04:40 WaitForAccessibilityTreeToContainNodeWithName is i
644 std::string ax_tree_dump = DumpPdfAccessibilityTree(ax_tree);
645 ASSERT_MULTILINE_STREQ(kExpectedPDFAXTree, ax_tree_dump);
646 }
647
648 IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityInOOPIF) {
649 content::BrowserAccessibilityState::GetInstance()->EnableAccessibility();
650 GURL test_iframe_url(embedded_test_server()->GetURL(
651 "/pdf/test-cross-site-iframe.html"));
652 ui_test_utils::NavigateToURL(browser(), test_iframe_url);
653 content::WebContents* contents =
654 browser()->tab_strip_model()->GetActiveWebContents();
655 WaitForAccessibilityTreeToContainNodeWithName(contents,
656 "1 First Section\r\n");
657
658 content::WebContents* guest_contents = nullptr;
659 content::BrowserPluginGuestManager* guest_manager =
660 contents->GetBrowserContext()->GetGuestManager();
661 guest_manager->ForEachGuest(contents,
662 base::Bind(&RetrieveGuestContents,
663 &guest_contents));
664 ASSERT_TRUE(guest_contents);
665
666 ui::AXTreeUpdate ax_tree = GetAccessibilityTreeSnapshot(guest_contents);
667 std::string ax_tree_dump = DumpPdfAccessibilityTree(ax_tree);
668 ASSERT_MULTILINE_STREQ(kExpectedPDFAXTree, ax_tree_dump);
669 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698