chromium/content/browser/accessibility/snapshot_ax_tree_browsertest.cc

// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/fenced_frame/fenced_frame.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/common/content_features.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/ax_node.h"
#include "ui/accessibility/ax_tree.h"

namespace content {

namespace {

class AXTreeSnapshotWaiter {};

void DumpRolesAndNamesAsText(const ui::AXNode* node,
                             int indent,
                             std::string* dst) {}

}  // namespace

class SnapshotAXTreeBrowserTest : public ContentBrowserTest {};

IN_PROC_BROWSER_TEST_F(SnapshotAXTreeBrowserTest,
                       SnapshotAccessibilityTreeFromWebContents) {}

class SnapshotAXTreeFencedFrameBrowserTest : public SnapshotAXTreeBrowserTest {};

IN_PROC_BROWSER_TEST_F(SnapshotAXTreeFencedFrameBrowserTest,
                       SnapshotAccessibilityTreeFromMultipleFrames) {}

IN_PROC_BROWSER_TEST_F(
    SnapshotAXTreeFencedFrameBrowserTest,
    SnapshotAccessibilityTreeFromMultipleFramesLimitedToNonFencedFrames) {}

IN_PROC_BROWSER_TEST_F(SnapshotAXTreeBrowserTest,
                       SnapshotAccessibilityTreeFromMultipleFrames) {}

IN_PROC_BROWSER_TEST_F(SnapshotAXTreeFencedFrameBrowserTest,
                       SnapshotAccessibilityTreeFromSameOriginOnly) {}

// This tests to make sure that RequestAXTreeSnapshot() correctly traverses
// inner contents, as used in features like <webview>.
IN_PROC_BROWSER_TEST_F(SnapshotAXTreeBrowserTest,
                       SnapshotAccessibilityTreeWithInnerContents) {}

// This tests to make sure that snapshotting with different modes gives
// different results. This is not intended to ensure that specific modes give
// specific attributes, but merely to ensure that the mode parameter makes a
// difference.
IN_PROC_BROWSER_TEST_F(SnapshotAXTreeBrowserTest,
                       SnapshotAccessibilityTreeModes) {}

IN_PROC_BROWSER_TEST_F(SnapshotAXTreeBrowserTest, SnapshotPDFMode) {}

IN_PROC_BROWSER_TEST_F(SnapshotAXTreeBrowserTest, MaxNodes) {}

IN_PROC_BROWSER_TEST_F(SnapshotAXTreeBrowserTest, Timeout) {}

IN_PROC_BROWSER_TEST_F(SnapshotAXTreeBrowserTest, Metadata) {}

// For Android, test the field trial param to change the number of max nodes.
#if BUILDFLAG(IS_ANDROID)
class SnapshotAXTreeMaxNodesParamBrowserTest : public ContentBrowserTest {
 public:
  SnapshotAXTreeMaxNodesParamBrowserTest() {
    scoped_feature_list_.InitAndEnableFeatureWithParameters(
        features::kAccessibilitySnapshotStressTests,
        {{"AccessibilitySnapshotStressTestsMaxNodes", "500"}});
  }
  ~SnapshotAXTreeMaxNodesParamBrowserTest() override = default;

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

IN_PROC_BROWSER_TEST_F(SnapshotAXTreeMaxNodesParamBrowserTest, MaxNodes) {
  GURL url(R"HTML(data:text/html,<body>
                  <style> p { margin: 50px; } </style>
                  <script>
                    let outerDiv = document.createElement('div');
                    for (let i = 0; i < 200; i++) {
                      let div = document.createElement('div');
                      for (let j = 0; j < 20; j++) {
                        let p = document.createElement('p');
                        p.innerHTML = j;
                        div.appendChild(p);
                      }
                      outerDiv.appendChild(div);
                    }
                    document.body.appendChild(outerDiv);
                  </script>
                  </body>)HTML");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());

  AXTreeSnapshotWaiter waiter;
  web_contents->RequestAXTreeSnapshot(
      base::BindOnce(&AXTreeSnapshotWaiter::ReceiveSnapshot,
                     base::Unretained(&waiter)),
      ui::kAXModeComplete,
      /* max_nodes= */ 10,
      /* timeout= */ {}, WebContents::AXTreeSnapshotPolicy::kAll);
  waiter.Wait();

  // If the feature flag and param was honored, we should see more than 100
  // nodes (which was the value set on the method call), but less than all the
  // possible nodes.
  EXPECT_GT(waiter.snapshot().nodes.size(), 100U);
  EXPECT_LT(waiter.snapshot().nodes.size(), 800U);
}

#endif
}  // namespace content