chromium/third_party/blink/renderer/core/timing/window_performance_test.cc

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

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "third_party/blink/renderer/core/timing/window_performance.h"

#include <cstdint>

#include "base/numerics/safe_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/test/trace_event_analyzer.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/viz/common/frame_timing_details.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/responsiveness_metrics/user_interaction_latency.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_keyboard_event_init.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_pointer_event_init.h"
#include "third_party/blink/renderer/core/dom/document_init.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/events/input_event.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/core/events/pointer_event.h"
#include "third_party/blink/renderer/core/execution_context/security_context_init.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/performance_monitor.h"
#include "third_party/blink/renderer/core/loader/document_load_timing.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/performance_entry_names.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/core/testing/mock_policy_container_host.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/performance_event_timing.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/testing/scoped_fake_ukm_recorder.h"
#include "third_party/blink/renderer/platform/testing/task_environment.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"

namespace blink {

RunPendingTasks;

namespace {

base::TimeTicks GetTimeOrigin() {}

base::TimeTicks GetTimeStamp(int64_t time) {}

}  // namespace

class WindowPerformanceTest : public testing::Test,
                              public ::testing::WithParamInterface<bool> {};

TEST_P(WindowPerformanceTest, SanitizedLongTaskName) {}

TEST_P(WindowPerformanceTest, SanitizedLongTaskName_CrossOrigin) {}

// https://crbug.com/706798: Checks that after navigation that have replaced the
// window object, calls to not garbage collected yet WindowPerformance belonging
// to the old window do not cause a crash.
TEST_P(WindowPerformanceTest, NavigateAway) {}

// Checks that WindowPerformance object and its fields (like PerformanceTiming)
// function correctly after transition to another document in the same window.
// This happens when a page opens a new window and it navigates to a same-origin
// document.
TEST(PerformanceLifetimeTest, SurviveContextSwitch) {}

// Make sure the output entries with the same timestamps follow the insertion
// order. (http://crbug.com/767560)
TEST_P(WindowPerformanceTest, EnsureEntryListOrder) {}

TEST_P(WindowPerformanceTest, EventTimingEntryBuffering) {}

TEST_P(WindowPerformanceTest, Expose100MsEvents) {}

TEST_P(WindowPerformanceTest, EventTimingDuration) {}

// Test the case where multiple events are registered and then their
// presentation promise is resolved.
TEST_P(WindowPerformanceTest, MultipleEventsThenPresent) {}

// Test the case where commit finish timestamps are recorded on all pending
// EventTimings.
TEST_P(WindowPerformanceTest,
       CommitFinishTimeRecordedOnAllPendingEventTimings) {}

// Test the case where a new commit finish timestamps does not affect previous
// EventTiming who has already seen a commit finish.
TEST_P(WindowPerformanceTest, NewCommitNotOverwritePreviousEventTimings) {}

// Test for existence of 'first-input' given different types of first events.
TEST_P(WindowPerformanceTest, FirstInput) {}

// Test that the 'first-input' is populated after some irrelevant events are
// ignored.
TEST_P(WindowPerformanceTest, FirstInputAfterIgnored) {}

// Test that pointerdown followed by pointerup works as a 'firstInput'.
TEST_P(WindowPerformanceTest, FirstPointerUp) {}

// When the pointerdown is optimized out, the mousedown works as a
// 'first-input'.
TEST_P(WindowPerformanceTest, PointerdownOptimizedOut) {}

// Test that pointerdown followed by mousedown, pointerup works as a
// 'first-input'.
TEST_P(WindowPerformanceTest, PointerdownOnDesktop) {}

TEST_P(WindowPerformanceTest, OneKeyboardInteraction) {}

TEST_P(WindowPerformanceTest, HoldingDownAKey) {}

TEST_P(WindowPerformanceTest, PressMultipleKeys) {}

// Test a real world scenario, where keydown got presented first but its
// callback got invoked later than keyup's due to multi processes & threading
// overhead.
TEST_P(WindowPerformanceTest, KeyupFinishLastButCallbackInvokedFirst) {}

TEST_P(WindowPerformanceTest, TapOrClick) {}

TEST_P(WindowPerformanceTest, PageVisibilityChanged) {}

TEST_P(WindowPerformanceTest, Drag) {}

TEST_P(WindowPerformanceTest, Scroll) {}

TEST_P(WindowPerformanceTest, TouchesWithoutClick) {}

#if BUILDFLAG(IS_MAC)
//  Test artificial pointerup and click on MacOS fall back to use processingEnd
//  as event duration ending time.
//  See crbug.com/1321819
TEST_P(WindowPerformanceTest, ArtificialPointerupOrClick) {
  // Arbitrary pointerId picked for testing
  PointerId pointer_id = 4;

  // Pointerdown
  base::TimeTicks pointerdown_timestamp = GetTimeOrigin();
  base::TimeTicks processing_start_pointerdown = GetTimeStamp(1);
  base::TimeTicks processing_end_pointerdown = GetTimeStamp(2);
  base::TimeTicks presentation_time_pointerdown = GetTimeStamp(3);
  RegisterPointerEvent(event_type_names::kPointerdown, pointerdown_timestamp,
                       processing_start_pointerdown, processing_end_pointerdown,
                       pointer_id);
  SimulatePaintAndResolvePresentationPromise(presentation_time_pointerdown);
  // Artificial Pointerup
  base::TimeTicks pointerup_timestamp = pointerdown_timestamp;
  base::TimeTicks processing_start_pointerup = GetTimeStamp(5);
  base::TimeTicks processing_end_pointerup = GetTimeStamp(6);
  base::TimeTicks presentation_time_pointerup = GetTimeStamp(10);
  RegisterPointerEvent(event_type_names::kPointerup, pointerup_timestamp,
                       processing_start_pointerup, processing_end_pointerup,
                       pointer_id);
  SimulatePaintAndResolvePresentationPromise(presentation_time_pointerup);
  // Artificial Click
  base::TimeTicks click_timestamp = pointerup_timestamp;
  base::TimeTicks processing_start_click = GetTimeStamp(11);
  base::TimeTicks processing_end_click = GetTimeStamp(12);
  base::TimeTicks presentation_time_click = GetTimeStamp(20);
  RegisterPointerEvent(event_type_names::kClick, click_timestamp,
                       processing_start_click, processing_end_click,
                       pointer_id);
  SimulatePaintAndResolvePresentationPromise(presentation_time_click);

  // Flush UKM logging mojo request.
  RunPendingTasks();

  // Check UKM recording.
  auto entries = GetUkmRecorder()->GetEntriesByName(
      ukm::builders::Responsiveness_UserInteraction::kEntryName);
  EXPECT_EQ(1u, entries.size());
  const ukm::mojom::UkmEntry* ukm_entry = entries[0];
  GetUkmRecorder()->ExpectEntryMetric(
      ukm_entry,
      ukm::builders::Responsiveness_UserInteraction::kMaxEventDurationName, 12);
  GetUkmRecorder()->ExpectEntryMetric(
      ukm_entry,
      ukm::builders::Responsiveness_UserInteraction::kTotalEventDurationName,
      12);
  GetUkmRecorder()->ExpectEntryMetric(
      ukm_entry,
      ukm::builders::Responsiveness_UserInteraction::kInteractionTypeName, 1);

  // Check UMA recording.
  GetHistogramTester().ExpectTotalCount(
      "Blink.Responsiveness.UserInteraction.MaxEventDuration.AllTypes", 1);
  GetHistogramTester().ExpectTotalCount(
      "Blink.Responsiveness.UserInteraction.MaxEventDuration.Keyboard", 0);
  GetHistogramTester().ExpectTotalCount(
      "Blink.Responsiveness.UserInteraction.MaxEventDuration.TapOrClick", 1);
  GetHistogramTester().ExpectTotalCount(
      "Blink.Responsiveness.UserInteraction.MaxEventDuration.Drag", 0);
}
#endif  // BUILDFLAG(IS_MAC)

// The trace_analyzer does not work on platforms on which the migration of
// tracing into Perfetto has not completed.
TEST_P(WindowPerformanceTest, PerformanceMarkTraceEvent) {}

TEST_P(WindowPerformanceTest, ElementTimingTraceEvent) {}

TEST_P(WindowPerformanceTest, EventTimingTraceEvents) {}

TEST_P(WindowPerformanceTest, SlowInteractionToNextPaintTraceEvents) {}

TEST_P(WindowPerformanceTest, InteractionID) {}

INSTANTIATE_TEST_SUITE_P();

class InteractionIdTest : public WindowPerformanceTest {};

// Tests English typing.
TEST_P(InteractionIdTest, InputOutsideComposition) {}

// Tests Japanese on Mac.
TEST_P(InteractionIdTest, CompositionSingleKeydown) {}

// Tests Chinese on Mac. Windows is similar, but has more keyups inside the
// composition.
TEST_P(InteractionIdTest, CompositionToFinalInput) {}

// Tests Chinese on Windows.
TEST_P(InteractionIdTest, CompositionToFinalInputMultipleKeyUps) {}

// Tests Android smart suggestions (similar to Android Chinese).
TEST_P(InteractionIdTest, SmartSuggestion) {}

TEST_P(InteractionIdTest, TapWithoutClick) {}

TEST_P(InteractionIdTest, PointerupClick) {}

TEST_P(InteractionIdTest, JustClick) {}

TEST_P(InteractionIdTest, PointerdownClick) {}

TEST_P(InteractionIdTest, MultiTouch) {}

TEST_P(InteractionIdTest, ClickIncorrectPointerId) {}

INSTANTIATE_TEST_SUITE_P();

}  // namespace blink