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

#include "third_party/blink/renderer/core/html/lazy_load_frame_observer.h"

#include <algorithm>
#include <memory>
#include <tuple>

#include "base/optional.h"
#include "third_party/blink/public/platform/web_effective_connection_type.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/testing/sim/sim_compositor.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
#include "third_party/blink/renderer/platform/testing/histogram_tester.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace blink {

namespace {

constexpr std::pair<WebEffectiveConnectionType, const char*>
    kVisibleLoadTimeAboveTheFoldHistogramNames[] = {
        {WebEffectiveConnectionType::kTypeSlow2G,
         "Blink.VisibleLoadTime.LazyLoadEligibleFrames.AboveTheFold.Slow2G"},
        {WebEffectiveConnectionType::kType2G,
         "Blink.VisibleLoadTime.LazyLoadEligibleFrames.AboveTheFold.2G"},
        {WebEffectiveConnectionType::kType3G,
         "Blink.VisibleLoadTime.LazyLoadEligibleFrames.AboveTheFold.3G"},
        {WebEffectiveConnectionType::kType4G,
         "Blink.VisibleLoadTime.LazyLoadEligibleFrames.AboveTheFold.4G"},
};

constexpr std::pair<WebEffectiveConnectionType, const char*>
    kVisibleLoadTimeBelowTheFoldHistogramNames[] = {
        {WebEffectiveConnectionType::kTypeSlow2G,
         "Blink.VisibleLoadTime.LazyLoadEligibleFrames.BelowTheFold.Slow2G"},
        {WebEffectiveConnectionType::kType2G,
         "Blink.VisibleLoadTime.LazyLoadEligibleFrames.BelowTheFold.2G"},
        {WebEffectiveConnectionType::kType3G,
         "Blink.VisibleLoadTime.LazyLoadEligibleFrames.BelowTheFold.3G"},
        {WebEffectiveConnectionType::kType4G,
         "Blink.VisibleLoadTime.LazyLoadEligibleFrames.BelowTheFold.4G"},
};

constexpr std::pair<WebEffectiveConnectionType, const char*>
    kInitialDeferralActionHistogramNames[] = {
        {WebEffectiveConnectionType::kTypeUnknown,
         "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.Unknown"},
        {WebEffectiveConnectionType::kTypeOffline,
         "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.Offline"},
        {WebEffectiveConnectionType::kTypeSlow2G,
         "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.Slow2G"},
        {WebEffectiveConnectionType::kType2G,
         "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.2G"},
        {WebEffectiveConnectionType::kType3G,
         "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.3G"},
        {WebEffectiveConnectionType::kType4G,
         "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.4G"},
};

// Convenience enums to make it easy to access the appropriate value of the
// tuple parameters in the parameterized tests below, e.g. so that
// std::get<LazyFrameLoadingFeatureStatus>(GetParam()) can be used instead of
// std::get<0>(GetParam()) if they were just booleans.
enum class LazyFrameLoadingFeatureStatus { kDisabled, kEnabled };
enum class LazyFrameVisibleLoadTimeFeatureStatus { kDisabled, kEnabled };

class LazyLoadFramesParamsTest
    : public SimTest,
      public ::testing::WithParamInterface<
          std::tuple<LazyFrameLoadingFeatureStatus,
                     LazyFrameVisibleLoadTimeFeatureStatus,
                     WebEffectiveConnectionType>> {
 public:
  static constexpr int kViewportWidth = 800;
  static constexpr int kViewportHeight = 600;

  LazyLoadFramesParamsTest()
      : scoped_lazy_frame_loading_for_test_(
            std::get<LazyFrameLoadingFeatureStatus>(GetParam()) ==
            LazyFrameLoadingFeatureStatus::kEnabled),
        scoped_lazy_frame_visible_load_time_metrics_for_test_(
            std::get<LazyFrameVisibleLoadTimeFeatureStatus>(GetParam()) ==
            LazyFrameVisibleLoadTimeFeatureStatus::kEnabled),
        scoped_restrict_lazy_frame_loading_to_data_saver_for_test_(false) {}

  void SetUp() override {
    WebFrameClient().SetEffectiveConnectionTypeForTesting(
        std::get<WebEffectiveConnectionType>(GetParam()));

    SimTest::SetUp();
    WebView().MainFrameWidget()->Resize(
        WebSize(kViewportWidth, kViewportHeight));

    Settings& settings = WebView().GetPage()->GetSettings();

    // These should match the values that would be returned by
    // GetLoadingDistanceThreshold().
    settings.SetLazyFrameLoadingDistanceThresholdPxUnknown(200);
    settings.SetLazyFrameLoadingDistanceThresholdPxOffline(300);
    settings.SetLazyFrameLoadingDistanceThresholdPxSlow2G(400);
    settings.SetLazyFrameLoadingDistanceThresholdPx2G(500);
    settings.SetLazyFrameLoadingDistanceThresholdPx3G(600);
    settings.SetLazyFrameLoadingDistanceThresholdPx4G(700);
    settings.SetLazyLoadEnabled(
        RuntimeEnabledFeatures::LazyFrameLoadingEnabled());
  }

  int GetLoadingDistanceThreshold() const {
    static constexpr int kDistanceThresholdByEffectiveConnectionType[] = {
        200, 300, 400, 500, 600, 700};
    return kDistanceThresholdByEffectiveConnectionType[static_cast<int>(
        std::get<WebEffectiveConnectionType>(GetParam()))];
  }

  void ExpectVisibleLoadTimeHistogramSamplesIfApplicable(
      int expected_above_the_fold_count,
      int expected_below_the_fold_count) {
    if (!RuntimeEnabledFeatures::LazyFrameVisibleLoadTimeMetricsEnabled()) {
      // Expect zero samples if the visible load time metrics feature is
      // disabled.
      expected_above_the_fold_count = 0;
      expected_below_the_fold_count = 0;
    }

    for (const auto& pair : kVisibleLoadTimeAboveTheFoldHistogramNames) {
      histogram_tester()->ExpectTotalCount(
          pair.second,
          std::get<WebEffectiveConnectionType>(GetParam()) == pair.first
              ? expected_above_the_fold_count
              : 0);
    }
    for (const auto& pair : kVisibleLoadTimeBelowTheFoldHistogramNames) {
      histogram_tester()->ExpectTotalCount(
          pair.second,
          std::get<WebEffectiveConnectionType>(GetParam()) == pair.first
              ? expected_below_the_fold_count
              : 0);
    }
  }

  void ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction action,
      int expected_count) {
    for (const auto& pair : kInitialDeferralActionHistogramNames) {
      if (RuntimeEnabledFeatures::LazyFrameLoadingEnabled() &&
          std::get<WebEffectiveConnectionType>(GetParam()) == pair.first) {
        histogram_tester()->ExpectUniqueSample(
            pair.second, static_cast<int>(action), expected_count);
      } else {
        histogram_tester()->ExpectTotalCount(pair.second, 0);
      }
    }
  }

  void ExpectLoadStartedAfterDeferredSamplesIfApplicable(int expected_count) {
    if (RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
      histogram_tester()->ExpectUniqueSample(
          "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred",
          static_cast<int>(std::get<WebEffectiveConnectionType>(GetParam())),
          expected_count);
    } else {
      histogram_tester()->ExpectTotalCount(
          "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
    }
  }

  void ExpectVisibleAfterDeferredSamplesIfApplicable(int expected_count) {
    if (RuntimeEnabledFeatures::LazyFrameLoadingEnabled() &&
        RuntimeEnabledFeatures::LazyFrameVisibleLoadTimeMetricsEnabled()) {
      histogram_tester()->ExpectUniqueSample(
          "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred",
          static_cast<int>(std::get<WebEffectiveConnectionType>(GetParam())),
          expected_count);
    } else {
      histogram_tester()->ExpectTotalCount(
          "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
    }
  }

  HistogramTester* histogram_tester() { return &histogram_tester_; }

  // Convenience function to load a page with a cross origin frame far down the
  // page such that it's not near the viewport.
  std::unique_ptr<SimRequest> LoadPageWithCrossOriginFrameFarFromViewport() {
    SimRequest main_resource("https://example.com/", "text/html");
    std::unique_ptr<SimRequest> child_frame_resource;

    if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
      // This SimRequest needs to be created now if the frame won't actually be
      // lazily loaded. Otherwise, it'll be defined later to ensure that the
      // subframe resource isn't requested until the page is scrolled down.
      child_frame_resource.reset(
          new SimRequest("https://crossorigin.com/subframe.html", "text/html"));
    }

    LoadURL("https://example.com/");

    main_resource.Complete(String::Format(
        R"HTML(
          <body onload='console.log("main body onload");'>
          <div style='height: %dpx;'></div>
          <iframe src='https://crossorigin.com/subframe.html'
               style='width: 400px; height: 400px;'
               onload='console.log("child frame element onload");'></iframe>
          </body>)HTML",
        kViewportHeight + GetLoadingDistanceThreshold() + 100));

    Compositor().BeginFrame();
    test::RunPendingTasks();

    // If the child frame is being lazy loaded, then the body's load event
    // should have already fired.
    EXPECT_EQ(RuntimeEnabledFeatures::LazyFrameLoadingEnabled(),
              ConsoleMessages().Contains("main body onload"));
    EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload"));

    ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);

    ExpectInitialDeferralActionHistogramSamplesIfApplicable(
        LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
    histogram_tester()->ExpectTotalCount(
        "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
    histogram_tester()->ExpectTotalCount(
        "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);

    if (!child_frame_resource) {
      child_frame_resource.reset(
          new SimRequest("https://crossorigin.com/subframe.html", "text/html"));
    }

    return child_frame_resource;
  }

 private:
  ScopedLazyFrameLoadingForTest scoped_lazy_frame_loading_for_test_;
  ScopedLazyFrameVisibleLoadTimeMetricsForTest
      scoped_lazy_frame_visible_load_time_metrics_for_test_;
  ScopedRestrictLazyFrameLoadingToDataSaverForTest
      scoped_restrict_lazy_frame_loading_to_data_saver_for_test_;

  HistogramTester histogram_tester_;
};

TEST_P(LazyLoadFramesParamsTest, SameOriginFrame) {
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest child_frame_resource("https://example.com/subframe.html",
                                  "text/html");

  LoadURL("https://example.com/");

  main_resource.Complete(String::Format(
      R"HTML(
        <body onload='console.log("main body onload");'>
        <div style='height: %dpx;'></div>
        <iframe src='https://example.com/subframe.html'
             style='width: 200px; height: 200px;'
             onload='console.log("child frame element onload");'></iframe>
        </body>)HTML",
      kViewportHeight + GetLoadingDistanceThreshold() + 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  child_frame_resource.Complete("");

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));

  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);

  for (const auto& pair : kInitialDeferralActionHistogramNames)
    histogram_tester()->ExpectTotalCount(pair.second, 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
}

TEST_P(LazyLoadFramesParamsTest, AboveTheFoldFrame) {
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest child_frame_resource("https://crossorigin.com/subframe.html",
                                  "text/html");

  LoadURL("https://example.com/");

  main_resource.Complete(String::Format(
      R"HTML(
        <body onload='console.log("main body onload");'>
        <div style='height: %dpx;'></div>
        <iframe src='https://crossorigin.com/subframe.html'
             style='width: 200px; height: 200px;'
             onload='console.log("child frame element onload");'></iframe>
        </body>)HTML",
      kViewportHeight - 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  // The child frame is visible, but hasn't finished loading yet, so no visible
  // load time samples should have been recorded yet.
  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);

  child_frame_resource.Complete("");
  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));

  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(1, 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);

  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction::
          kLoadedNearOrInViewport,
      1);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
}

TEST_P(LazyLoadFramesParamsTest, BelowTheFoldButNearViewportFrame) {
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest child_frame_resource("https://crossorigin.com/subframe.html",
                                  "text/html");

  LoadURL("https://example.com/");

  main_resource.Complete(String::Format(
      R"HTML(
        <body onload='console.log("main body onload");'>
        <div style='height: %dpx;'></div>
        <iframe src='https://crossorigin.com/subframe.html'
             style='width: 200px; height: 200px;'
             onload='console.log("child frame element onload");'></iframe>
        </body>)HTML",
      kViewportHeight + 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  child_frame_resource.Complete("");

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));

  // The frame is below the fold, but hasn't been scrolled down to yet, so there
  // should be no samples in any of the below the fold visible load time
  // histograms yet.
  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);

  // Scroll down until the child frame is visible.
  GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 150),
                                                          kProgrammaticScroll);

  Compositor().BeginFrame();
  test::RunPendingTasks();

  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 1);

  // The frame finished loading before it became visible, so there should be no
  // samples in the VisibleBeforeLoaded histogram.
  histogram_tester()->ExpectTotalCount(
      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);

  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction::
          kLoadedNearOrInViewport,
      1);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
}

TEST_P(LazyLoadFramesParamsTest, HiddenAndTinyFrames) {
  SimRequest main_resource("https://example.com/", "text/html");

  SimRequest display_none_frame_resource(
      "https://crossorigin.com/display_none.html", "text/html");
  SimRequest visibility_hidden_frame_resource(
      "https://crossorigin.com/visibility_hidden.html", "text/html");
  SimRequest tiny_frame_resource("https://crossorigin.com/tiny.html",
                                 "text/html");
  SimRequest tiny_width_frame_resource(
      "https://crossorigin.com/tiny_width.html", "text/html");
  SimRequest tiny_height_frame_resource(
      "https://crossorigin.com/tiny_height.html", "text/html");
  SimRequest off_screen_left_frame_resource(
      "https://crossorigin.com/off_screen_left.html", "text/html");
  SimRequest off_screen_top_frame_resource(
      "https://crossorigin.com/off_screen_top.html", "text/html");

  LoadURL("https://example.com/");

  main_resource.Complete(String::Format(
      R"HTML(
        <head><style>
          /* Chrome by default sets borders for iframes, so explicitly specify
           * no borders, padding, or margins here so that the dimensions of the
           * tiny frames aren't artifically inflated past the dimensions that
           * the lazy loading logic considers "tiny". */
          iframe { border-style: none; padding: 0px; margin: 0px; }
        </style></head>

        <body onload='console.log("main body onload");'>
        <div style='height: %dpx'></div>
        <iframe src='https://crossorigin.com/display_none.html'
             style='display: none;'
             onload='console.log("display none element onload");'></iframe>
        <iframe src='https://crossorigin.com/visibility_hidden.html'
             style='visibility:hidden;width:100px;height:100px;'
             onload='console.log("visibility hidden element onload");'></iframe>
        <iframe src='https://crossorigin.com/tiny.html'
             style='width: 4px; height: 4px;'
             onload='console.log("tiny element onload");'></iframe>
        <iframe src='https://crossorigin.com/tiny_width.html'
             style='width: 0px; height: 50px;'
             onload='console.log("tiny width element onload");'></iframe>
        <iframe src='https://crossorigin.com/tiny_height.html'
             style='width: 50px; height: 0px;'
             onload='console.log("tiny height element onload");'></iframe>
        <iframe src='https://crossorigin.com/off_screen_left.html'
             style='position:relative;right:9000px;width:50px;height:50px;'
             onload='console.log("off screen left element onload");'></iframe>
        <iframe src='https://crossorigin.com/off_screen_top.html'
             style='position:relative;bottom:9000px;width:50px;height:50px;'
             onload='console.log("off screen top element onload");'></iframe>
        </body>
      )HTML",
      kViewportHeight + GetLoadingDistanceThreshold() + 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  display_none_frame_resource.Complete("");
  visibility_hidden_frame_resource.Complete("");
  tiny_frame_resource.Complete("");
  tiny_width_frame_resource.Complete("");
  tiny_height_frame_resource.Complete("");
  off_screen_left_frame_resource.Complete("");
  off_screen_top_frame_resource.Complete("");

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("display none element onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("visibility hidden element onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("tiny element onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("tiny width element onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("tiny height element onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("off screen left element onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("off screen top element onload"));

  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);

  // Scroll down to where the hidden frames are.
  GetDocument().View()->LayoutViewport()->SetScrollOffset(
      ScrollOffset(0, kViewportHeight + GetLoadingDistanceThreshold()),
      kProgrammaticScroll);

  // All of the frames on the page are hidden or tiny, so no visible load time
  // samples should have been recorded for them.
  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);

  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction::kLoadedHidden, 7);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
}

TEST_P(LazyLoadFramesParamsTest, LoadCrossOriginFrameFarFromViewport) {
  std::unique_ptr<SimRequest> child_frame_resource =
      LoadPageWithCrossOriginFrameFarFromViewport();

  if (RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
    // If LazyFrameLoading is enabled, then scroll down near the child frame to
    // cause the child frame to start loading.
    GetDocument().View()->LayoutViewport()->SetScrollOffset(
        ScrollOffset(0, 150), kProgrammaticScroll);

    Compositor().BeginFrame();
    test::RunPendingTasks();
  }

  EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload"));
  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);

  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
  ExpectLoadStartedAfterDeferredSamplesIfApplicable(1);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);

  child_frame_resource->Complete("");

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);

  // Scroll down so that the child frame is visible.
  GetDocument().View()->LayoutViewport()->SetScrollOffset(
      ScrollOffset(0, GetLoadingDistanceThreshold() + 150),
      kProgrammaticScroll);

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 1);

  histogram_tester()->ExpectTotalCount(
      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);

  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
  ExpectLoadStartedAfterDeferredSamplesIfApplicable(1);
  ExpectVisibleAfterDeferredSamplesIfApplicable(1);
}

TEST_P(LazyLoadFramesParamsTest,
       CrossOriginFrameFarFromViewportBecomesVisibleBeforeFinishedLoading) {
  std::unique_ptr<SimRequest> child_frame_resource =
      LoadPageWithCrossOriginFrameFarFromViewport();

  // Scroll down so that the child frame is visible.
  GetDocument().View()->LayoutViewport()->SetScrollOffset(
      ScrollOffset(0, GetLoadingDistanceThreshold() + 150),
      kProgrammaticScroll);

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload"));
  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);

  if (RuntimeEnabledFeatures::LazyFrameVisibleLoadTimeMetricsEnabled()) {
    // Even though the child frame hasn't loaded yet, a sample should still have
    // been recorded for VisibleBeforeLoaded.
    histogram_tester()->ExpectUniqueSample(
        "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold",
        static_cast<int>(std::get<WebEffectiveConnectionType>(GetParam())), 1);
  } else {
    histogram_tester()->ExpectTotalCount(
        "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);
  }

  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
  ExpectLoadStartedAfterDeferredSamplesIfApplicable(1);
  ExpectVisibleAfterDeferredSamplesIfApplicable(1);

  child_frame_resource->Complete("");

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 1);

  // The samples recorded for VisibleBeforeLoaded should be unchanged.
  histogram_tester()->ExpectTotalCount(
      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold",
      RuntimeEnabledFeatures::LazyFrameVisibleLoadTimeMetricsEnabled() ? 1 : 0);

  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
  ExpectLoadStartedAfterDeferredSamplesIfApplicable(1);
  ExpectVisibleAfterDeferredSamplesIfApplicable(1);
}

TEST_P(LazyLoadFramesParamsTest, NestedFrameInCrossOriginFrameFarFromViewport) {
  std::unique_ptr<SimRequest> child_frame_resource =
      LoadPageWithCrossOriginFrameFarFromViewport();

  if (RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
    // If LazyFrameLoading is enabled, then scroll down near the child frame to
    // cause the child frame to start loading.
    GetDocument().View()->LayoutViewport()->SetScrollOffset(
        ScrollOffset(0, 150), kProgrammaticScroll);

    Compositor().BeginFrame();
    test::RunPendingTasks();
  }

  // There's another nested cross origin iframe inside the first child frame,
  // even further down such that it's not near the viewport. It should start
  // loading immediately, even if LazyFrameLoading is enabled, since it's nested
  // inside a frame that was previously deferred.
  SimRequest nested_frame_resource("https://test.com/", "text/html");
  child_frame_resource->Complete(String::Format(
      "<div style='height: %dpx;'></div>"
      "<iframe src='https://test.com/' style='width: 200px; height: 200px;'>"
      "</iframe>",
      kViewportHeight + GetLoadingDistanceThreshold() + 100));

  nested_frame_resource.Complete("");

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));

  // The child frame isn't visible, so no visible load time samples should have
  // been recorded.
  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);

  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
  ExpectLoadStartedAfterDeferredSamplesIfApplicable(1);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
}

TEST_P(LazyLoadFramesParamsTest, AboutBlankChildFrameNavigation) {
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest child_frame_resource("https://crossorigin.com/subframe.html",
                                  "text/html");

  LoadURL("https://example.com/");

  main_resource.Complete(String::Format(
      R"HTML(
        <body onload='BodyOnload()'>
        <script>
          function BodyOnload() {
            console.log('main body onload');
            document.getElementsByTagName('iframe')[0].src =
                'https://crossorigin.com/subframe.html';
          }
        </script>

        <div style='height: %dpx;'></div>
        <iframe
             style='width: 200px; height: 200px;'
             onload='console.log("child frame element onload");'></iframe>
        </body>)HTML",
      kViewportHeight + GetLoadingDistanceThreshold() + 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_EQ(1, static_cast<int>(std::count(ConsoleMessages().begin(),
                                           ConsoleMessages().end(),
                                           "child frame element onload")));

  child_frame_resource.Complete("");

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_EQ(2, static_cast<int>(std::count(ConsoleMessages().begin(),
                                           ConsoleMessages().end(),
                                           "child frame element onload")));

  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);

  for (const auto& pair : kInitialDeferralActionHistogramNames)
    histogram_tester()->ExpectTotalCount(pair.second, 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
}

TEST_P(LazyLoadFramesParamsTest, JavascriptStringFrameUrl) {
  SimRequest main_resource("https://example.com/", "text/html");
  LoadURL("https://example.com/");

  main_resource.Complete(String::Format(
      R"HTML(
        <body onload='console.log("main body onload");'>
        <div style='height: %dpx;'></div>
        <iframe src='javascript:"Hello World!";'
             style='width: 200px; height: 200px;'
             onload='console.log("child frame element onload");'></iframe>
        </body>)HTML",
      kViewportHeight + GetLoadingDistanceThreshold() + 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));

  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);

  for (const auto& pair : kInitialDeferralActionHistogramNames)
    histogram_tester()->ExpectTotalCount(pair.second, 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
}

TEST_P(LazyLoadFramesParamsTest,
       CrossOriginFrameFarFromViewportWithLazyLoadAttrOff) {
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest child_frame_resource("https://crossorigin.com/subframe.html",
                                  "text/html");

  LoadURL("https://example.com/");

  main_resource.Complete(String::Format(
      R"HTML(
        <body onload='console.log("main body onload");'>
        <div style='height: %dpx;'></div>
        <iframe src='https://crossorigin.com/subframe.html'
             style='width: 200px; height: 200px;' lazyload='off'
             onload='console.log("child frame element onload");'></iframe>
        </body>)HTML",
      kViewportHeight + GetLoadingDistanceThreshold() + 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  child_frame_resource.Complete("");

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));

  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);

  for (const auto& pair : kInitialDeferralActionHistogramNames)
    histogram_tester()->ExpectTotalCount(pair.second, 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
}

TEST_P(LazyLoadFramesParamsTest,
       LoadSameOriginFrameFarFromViewportWithLazyLoadAttributeOn) {
  SimRequest main_resource("https://example.com/", "text/html");
  base::Optional<SimRequest> child_frame_resource;

  if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
    // This SimRequest needs to be created now if the frame won't actually be
    // lazily loaded. Otherwise, it'll be defined later to ensure that the
    // subframe resource isn't requested until the page is scrolled down.
    child_frame_resource.emplace("https://example.com/subframe.html",
                                 "text/html");
  }

  LoadURL("https://example.com/");

  main_resource.Complete(String::Format(
      R"HTML(
          <body onload='console.log("main body onload");'>
          <div style='height: %dpx;'></div>
          <iframe src='https://example.com/subframe.html'
               style='width: 400px; height: 400px;' lazyload='on'
               onload='console.log("child frame element onload");'></iframe>
          </body>)HTML",
      kViewportHeight + GetLoadingDistanceThreshold() + 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  // If the child frame is being lazy loaded, then the body's load event
  // should have already fired.
  EXPECT_EQ(RuntimeEnabledFeatures::LazyFrameLoadingEnabled(),
            ConsoleMessages().Contains("main body onload"));
  EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload"));

  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);

  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);

  if (!child_frame_resource) {
    child_frame_resource.emplace("https://example.com/subframe.html",
                                 "text/html");
  }

  if (RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
    // If LazyFrameLoading is enabled, then scroll down near the child frame to
    // cause the child frame to start loading.
    GetDocument().View()->LayoutViewport()->SetScrollOffset(
        ScrollOffset(0, 150), kProgrammaticScroll);

    Compositor().BeginFrame();
    test::RunPendingTasks();
  }

  EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload"));
  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);

  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
  ExpectLoadStartedAfterDeferredSamplesIfApplicable(1);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);

  child_frame_resource->Complete("");

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);

  // Scroll down so that the child frame is visible.
  GetDocument().View()->LayoutViewport()->SetScrollOffset(
      ScrollOffset(0, GetLoadingDistanceThreshold() + 150),
      kProgrammaticScroll);

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 1);

  histogram_tester()->ExpectTotalCount(
      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);

  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
  ExpectLoadStartedAfterDeferredSamplesIfApplicable(1);
  ExpectVisibleAfterDeferredSamplesIfApplicable(1);
}

TEST_P(LazyLoadFramesParamsTest,
       LoadCrossOriginFrameFarFromViewportThenSetLazyLoadAttributeOff) {
  SimRequest main_resource("https://example.com/", "text/html");
  base::Optional<SimRequest> child_frame_resource;

  if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
    // This SimRequest needs to be created now if the frame won't actually be
    // lazily loaded. Otherwise, it'll be defined later to ensure that the
    // subframe resource isn't requested until the page is scrolled down.
    child_frame_resource.emplace("https://crossorigin.com/subframe.html",
                                 "text/html");
  }

  LoadURL("https://example.com/");

  main_resource.Complete(String::Format(
      R"HTML(
        <body onload='console.log("main body onload");'>
        <div style='height: %dpx;'></div>
        <iframe id='child_frame' src='https://crossorigin.com/subframe.html'
             style='width: 400px; height: 400px;'
             onload='console.log("child frame element onload");'></iframe>
        </body>)HTML",
      kViewportHeight + GetLoadingDistanceThreshold() + 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  // If the child frame is being lazy loaded, then the body's load event
  // should have already fired.
  EXPECT_EQ(RuntimeEnabledFeatures::LazyFrameLoadingEnabled(),
            ConsoleMessages().Contains("main body onload"));
  EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload"));

  if (!child_frame_resource) {
    child_frame_resource.emplace("https://crossorigin.com/subframe.html",
                                 "text/html");
  }

  Element* child_frame_element = GetDocument().getElementById("child_frame");
  ASSERT_TRUE(child_frame_element);
  child_frame_element->setAttribute(html_names::kLazyloadAttr, "off");

  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
  ExpectLoadStartedAfterDeferredSamplesIfApplicable(1);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);

  child_frame_resource->Complete("");

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));

  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);

  histogram_tester()->ExpectTotalCount(
      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);

  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
      LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
  ExpectLoadStartedAfterDeferredSamplesIfApplicable(1);
  histogram_tester()->ExpectTotalCount(
      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
}

TEST_P(LazyLoadFramesParamsTest,
       NestedFrameWithLazyLoadAttributeOnInFrameWithNoLazyLoadAttribute) {
  std::unique_ptr<SimRequest> child_frame_resource =
      LoadPageWithCrossOriginFrameFarFromViewport();

  if (RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
    // If LazyFrameLoading is enabled, then scroll down near the child frame to
    // cause the child frame to start loading.
    GetDocument().View()->LayoutViewport()->SetScrollOffset(
        ScrollOffset(0, 150), kProgrammaticScroll);

    Compositor().BeginFrame();
    test::RunPendingTasks();
  }

  // There's another nested cross origin iframe inside the first child frame,
  // even further down such that it's not near the viewport. If LazyLoad is
  // enabled, it should be deferred even though it's nested inside a frame that
  // was previously deferred, because it has the attribute lazyload=on.
  base::Optional<SimRequest> nested_frame_resource;
  if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled())
    nested_frame_resource.emplace("https://test.com/", "text/html");

  child_frame_resource->Complete(
      String::Format("<div style='height: %dpx;'></div>"
                     "<iframe src='https://test.com/' lazyload='on'"
                     "     style='width: 200px; height: 200px;'>"
                     "</iframe>",
                     kViewportHeight + GetLoadingDistanceThreshold() + 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
    nested_frame_resource->Complete("");

    Compositor().BeginFrame();
    test::RunPendingTasks();
  }

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
}

TEST_P(LazyLoadFramesParamsTest,
       NestedFrameWithLazyLoadAttributeOnInFrameWithLazyLoadAttributeOff) {
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest child_frame_resource("https://crossorigin.com/subframe.html",
                                  "text/html");

  LoadURL("https://example.com/");

  main_resource.Complete(String::Format(
      R"HTML(
        <body onload='console.log("main body onload");'>
        <div style='height: %dpx;'></div>
        <iframe src='https://crossorigin.com/subframe.html'
             style='width: 200px; height: 200px;' lazyload='off'
             onload='console.log("child frame element onload");'></iframe>
        </body>)HTML",
      kViewportHeight + GetLoadingDistanceThreshold() + 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  // There's another nested cross origin iframe inside the first child frame,
  // even further down such that it's not near the viewport. If LazyLoad is
  // enabled, it should be deferred because it has the attribute lazyload=on,
  // even though it's nested inside a frame that has the attribute lazyload=off.
  base::Optional<SimRequest> nested_frame_resource;
  if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled())
    nested_frame_resource.emplace("https://test.com/", "text/html");

  child_frame_resource.Complete(
      String::Format("<div style='height: %dpx;'></div>"
                     "<iframe src='https://test.com/' lazyload='on'"
                     "     style='width: 200px; height: 200px;'>"
                     "</iframe>",
                     kViewportHeight + GetLoadingDistanceThreshold() + 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
    nested_frame_resource->Complete("");

    Compositor().BeginFrame();
    test::RunPendingTasks();
  }

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
}

TEST_P(LazyLoadFramesParamsTest,
       NestedFrameWithLazyLoadAttributeOffInFrameWithLazyLoadAttributeOff) {
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest child_frame_resource("https://crossorigin.com/subframe.html",
                                  "text/html");

  LoadURL("https://example.com/");

  main_resource.Complete(String::Format(
      R"HTML(
        <body onload='console.log("main body onload");'>
        <div style='height: %dpx;'></div>
        <iframe src='https://crossorigin.com/subframe.html'
             style='width: 200px; height: 200px;' lazyload='off'
             onload='console.log("child frame element onload");'></iframe>
        </body>)HTML",
      kViewportHeight + GetLoadingDistanceThreshold() + 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  // There's another nested cross origin iframe inside the first child frame,
  // even further down such that it's not near the viewport. Since it has the
  // attribute lazyload=off, it shouldn't be deferred. Note that this also
  // matches the default behavior that would happen if the lazyload attribute
  // was omitted on the nested iframe entirely.
  SimRequest nested_frame_resource("https://test.com/", "text/html");

  child_frame_resource.Complete(
      String::Format("<div style='height: %dpx;'></div>"
                     "<iframe src='https://test.com/' lazyload='off'"
                     "     style='width: 200px; height: 200px;'>"
                     "</iframe>",
                     kViewportHeight + GetLoadingDistanceThreshold() + 100));

  Compositor().BeginFrame();
  test::RunPendingTasks();

  nested_frame_resource.Complete("");

  Compositor().BeginFrame();
  test::RunPendingTasks();

  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
  EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
}

INSTANTIATE_TEST_CASE_P(
    LazyFrameLoading,
    LazyLoadFramesParamsTest,
    ::testing::Combine(
        ::testing::Values(LazyFrameLoadingFeatureStatus::kDisabled,
                          LazyFrameLoadingFeatureStatus::kEnabled),
        ::testing::Values(LazyFrameVisibleLoadTimeFeatureStatus::kDisabled,
                          LazyFrameVisibleLoadTimeFeatureStatus::kEnabled),
        ::testing::Values(WebEffectiveConnectionType::kTypeUnknown,
                          WebEffectiveConnectionType::kTypeOffline,
                          WebEffectiveConnectionType::kTypeSlow2G,
                          WebEffectiveConnectionType::kType2G,
                          WebEffectiveConnectionType::kType3G,
                          WebEffectiveConnectionType::kType4G)));

class LazyLoadFramesTest : public SimTest {
 public:
  static constexpr int kViewportWidth = 800;
  static constexpr int kViewportHeight = 600;
  static constexpr int kLoadingDistanceThresholdPx = 1000;

  void SetUp() override {
    WebFrameClient().SetEffectiveConnectionTypeForTesting(
        WebEffectiveConnectionType::kTypeUnknown);

    SimTest::SetUp();
    WebView().MainFrameWidget()->Resize(
        WebSize(kViewportWidth, kViewportHeight));

    Settings& settings = WebView().GetPage()->GetSettings();
    settings.SetLazyFrameLoadingDistanceThresholdPxUnknown(
        kLoadingDistanceThresholdPx);
    settings.SetLazyLoadEnabled(true);
  }

  void TearDown() override {
    GetNetworkStateNotifier().SetSaveDataEnabled(false);
    SimTest::TearDown();
  }

  void TestCrossOriginFrameIsImmediatelyLoaded(const char* iframe_attributes) {
    SimRequest main_resource("https://example.com/", "text/html");
    SimRequest child_frame_resource("https://crossorigin.com/subframe.html",
                                    "text/html");
    LoadURL("https://example.com/");

    main_resource.Complete(String::Format(
        R"HTML(
          <body onload='console.log("main body onload");'>
          <div style='height: %dpx;'></div>
          <iframe src='https://crossorigin.com/subframe.html'
               style='width: 200px; height: 200px;' %s
               onload='console.log("child frame element onload");'></iframe>
          </body>)HTML",
        kViewportHeight + kLoadingDistanceThresholdPx + 100,
        iframe_attributes));

    Compositor().BeginFrame();
    test::RunPendingTasks();

    child_frame_resource.Complete("");
    Compositor().BeginFrame();
    test::RunPendingTasks();

    EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
    EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
  }

  void TestCrossOriginFrameIsLazilyLoaded(const char* iframe_attributes) {
    SimRequest main_resource("https://example.com/", "text/html");
    LoadURL("https://example.com/");

    main_resource.Complete(String::Format(
        R"HTML(
          <body onload='console.log("main body onload");'>
          <div style='height: %dpx;'></div>
          <iframe src='https://crossorigin.com/subframe.html'
               style='width: 200px; height: 200px;' %s
               onload='console.log("child frame element onload");'></iframe>
          </body>)HTML",
        kViewportHeight + kLoadingDistanceThresholdPx + 100,
        iframe_attributes));

    Compositor().BeginFrame();
    test::RunPendingTasks();

    // The body's load event should have already fired.
    EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
    EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload"));

    SimRequest child_frame_resource("https://crossorigin.com/subframe.html",
                                    "text/html");

    // Scroll down near the child frame to cause the child frame to start
    // loading.
    GetDocument().View()->LayoutViewport()->SetScrollOffset(
        ScrollOffset(0, 150), kProgrammaticScroll);

    Compositor().BeginFrame();
    test::RunPendingTasks();

    EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload"));

    child_frame_resource.Complete("");

    Compositor().BeginFrame();
    test::RunPendingTasks();

    EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
  }
};

TEST_F(LazyLoadFramesTest, LazyLoadWhenNotRestricted) {
  ScopedLazyFrameLoadingForTest scoped_lazy_frame_loading_for_test(true);
  ScopedRestrictLazyFrameLoadingToDataSaverForTest
      scoped_restrict_lazy_frame_loading_to_data_saver_for_test_(false);

  TestCrossOriginFrameIsLazilyLoaded("");
}

TEST_F(LazyLoadFramesTest,
       LazyLoadWhenDataSaverDisabledAndNotRestrictedAttrOff) {
  ScopedLazyFrameLoadingForTest scoped_lazy_frame_loading_for_test(true);
  ScopedRestrictLazyFrameLoadingToDataSaverForTest
      scoped_restrict_lazy_frame_loading_to_data_saver_for_test_(false);

  TestCrossOriginFrameIsImmediatelyLoaded("lazyload='off'");
}

TEST_F(LazyLoadFramesTest, LazyLoadWhenDataSaverDisabledAndRestricted) {
  ScopedLazyFrameLoadingForTest scoped_lazy_frame_loading_for_test(true);
  ScopedRestrictLazyFrameLoadingToDataSaverForTest
      scoped_restrict_lazy_frame_loading_to_data_saver_for_test_(true);

  GetNetworkStateNotifier().SetSaveDataEnabled(false);
  WebView().GetPage()->GetSettings().SetDataSaverHoldbackWebApi(false);
  TestCrossOriginFrameIsImmediatelyLoaded("");
}

TEST_F(LazyLoadFramesTest, LazyLoadWhenDataSaverEnabledHoldbackAndRestricted) {
  ScopedLazyFrameLoadingForTest scoped_lazy_frame_loading_for_test(true);
  ScopedRestrictLazyFrameLoadingToDataSaverForTest
      scoped_restrict_lazy_frame_loading_to_data_saver_for_test_(true);

  GetNetworkStateNotifier().SetSaveDataEnabled(true);
  WebView().GetPage()->GetSettings().SetDataSaverHoldbackWebApi(true);
  TestCrossOriginFrameIsImmediatelyLoaded("");
}

TEST_F(LazyLoadFramesTest, LazyLoadWhenDataSaverEnabledAndRestricted) {
  ScopedLazyFrameLoadingForTest scoped_lazy_frame_loading_for_test(true);
  ScopedRestrictLazyFrameLoadingToDataSaverForTest
      scoped_restrict_lazy_frame_loading_to_data_saver_for_test_(true);

  GetNetworkStateNotifier().SetSaveDataEnabled(true);
  WebView().GetPage()->GetSettings().SetDataSaverHoldbackWebApi(false);
  TestCrossOriginFrameIsLazilyLoaded("");
}

TEST_F(LazyLoadFramesTest, LazyLoadWhenDataSaverDisabledAndRestrictedAttrOn) {
  ScopedLazyFrameLoadingForTest scoped_lazy_frame_loading_for_test(true);
  ScopedRestrictLazyFrameLoadingToDataSaverForTest
      scoped_restrict_lazy_frame_loading_to_data_saver_for_test_(true);

  GetNetworkStateNotifier().SetSaveDataEnabled(false);
  WebView().GetPage()->GetSettings().SetDataSaverHoldbackWebApi(false);
  TestCrossOriginFrameIsImmediatelyLoaded("lazyload='on'");
}

}  // namespace

}  // namespace blink
