Commit d7d2ccdf authored by Hajime Hoshi's avatar Hajime Hoshi Committed by Commit Bot

BackForwardCache: Add tests for CLS scores

Bug: 1014174
Change-Id: Ia75170ea791b5c8ffff100f58af1a7f65497b882
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2283037
Commit-Queue: Hajime Hoshi <hajimehoshi@chromium.org>
Reviewed-by: default avatarNicolás Peña Moreno <npm@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790789}
parent 889ab576
...@@ -188,12 +188,23 @@ IN_PROC_BROWSER_TEST_F(BackForwardCachePageLoadMetricsObserverBrowserTest, ...@@ -188,12 +188,23 @@ IN_PROC_BROWSER_TEST_F(BackForwardCachePageLoadMetricsObserverBrowserTest,
IN_PROC_BROWSER_TEST_F(BackForwardCachePageLoadMetricsObserverBrowserTest, IN_PROC_BROWSER_TEST_F(BackForwardCachePageLoadMetricsObserverBrowserTest,
CumulativeLayoutShiftAfterBackForwardCacheRestore) { CumulativeLayoutShiftAfterBackForwardCacheRestore) {
ASSERT_TRUE(embedded_test_server()->Start()); Start();
GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
const char path[] = "/layout-instability/simple-block-movement.html";
GURL url_a(embedded_test_server()->GetURL("a.com", path));
GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html")); GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
// Navigate to A. // Navigate to A.
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a)); {
auto waiter = CreatePageLoadMetricsTestWaiter();
waiter->AddPageExpectation(
page_load_metrics::PageLoadMetricsTestWaiter::TimingField::kFirstPaint);
waiter->AddPageExpectation(page_load_metrics::PageLoadMetricsTestWaiter::
TimingField::kLayoutShift);
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a));
waiter->Wait();
}
content::RenderFrameHost* rfh_a = top_frame_host(); content::RenderFrameHost* rfh_a = top_frame_host();
// Navigate to B. // Navigate to B.
...@@ -201,10 +212,35 @@ IN_PROC_BROWSER_TEST_F(BackForwardCachePageLoadMetricsObserverBrowserTest, ...@@ -201,10 +212,35 @@ IN_PROC_BROWSER_TEST_F(BackForwardCachePageLoadMetricsObserverBrowserTest,
EXPECT_TRUE(rfh_a->IsInBackForwardCache()); EXPECT_TRUE(rfh_a->IsInBackForwardCache());
// Go back to A. // Go back to A.
web_contents()->GetController().GoBack(); double next_score;
EXPECT_TRUE(WaitForLoadStop(web_contents())); {
EXPECT_EQ(rfh_a, top_frame_host()); auto waiter = CreatePageLoadMetricsTestWaiter();
EXPECT_FALSE(rfh_a->IsInBackForwardCache()); waiter->AddPageExpectation(
page_load_metrics::PageLoadMetricsTestWaiter::TimingField::
kFirstPaintAfterBackForwardCacheRestore);
waiter->AddPageExpectation(page_load_metrics::PageLoadMetricsTestWaiter::
TimingField::kLayoutShift);
web_contents()->GetController().GoBack();
EXPECT_TRUE(WaitForLoadStop(web_contents()));
EXPECT_EQ(rfh_a, top_frame_host());
EXPECT_FALSE(rfh_a->IsInBackForwardCache());
base::ListValue expectations =
EvalJs(web_contents(), "cls_run_tests").ExtractList();
next_score = EvalJs(web_contents(),
R"((async() => {
const shifter = document.querySelector('#shifter');
const currentTop =
parseInt(getComputedStyle(shifter).getPropertyValue('top'), 10);
const newTop = 320;
shifter.style.top = newTop + 'px';
const score = computeExpectedScore(
300 * (200 + newTop - currentTop), newTop - currentTop);
return score;
})())")
.ExtractDouble();
waiter->Wait();
}
// The RenderFrameHost for the page B was likely in the back-forward cache // The RenderFrameHost for the page B was likely in the back-forward cache
// just after the history navigation, but now this might be evicted due to // just after the history navigation, but now this might be evicted due to
...@@ -216,7 +252,13 @@ IN_PROC_BROWSER_TEST_F(BackForwardCachePageLoadMetricsObserverBrowserTest, ...@@ -216,7 +252,13 @@ IN_PROC_BROWSER_TEST_F(BackForwardCachePageLoadMetricsObserverBrowserTest,
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url_b)); EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url_b));
EXPECT_TRUE(rfh_a->IsInBackForwardCache()); EXPECT_TRUE(rfh_a->IsInBackForwardCache());
// As A enters to the back-forward cache once, CLS is recorded. auto samples = histogram_tester().GetAllSamples(
internal::
kHistogramCumulativeShiftScoreMainFrameAfterBackForwardCacheRestore);
EXPECT_EQ(1ul, samples.size());
EXPECT_EQ(base::Bucket(page_load_metrics::LayoutShiftUmaValue(next_score), 1),
samples[0]);
histogram_tester().ExpectTotalCount( histogram_tester().ExpectTotalCount(
internal:: internal::
kHistogramCumulativeShiftScoreMainFrameAfterBackForwardCacheRestore, kHistogramCumulativeShiftScoreMainFrameAfterBackForwardCacheRestore,
......
...@@ -105,7 +105,15 @@ void PageLoadMetricsTestWaiter::OnTimingUpdated( ...@@ -105,7 +105,15 @@ void PageLoadMetricsTestWaiter::OnTimingUpdated(
const page_load_metrics::mojom::FrameMetadata& metadata = const page_load_metrics::mojom::FrameMetadata& metadata =
subframe_rfh ? GetDelegateForCommittedLoad().GetSubframeMetadata() subframe_rfh ? GetDelegateForCommittedLoad().GetSubframeMetadata()
: GetDelegateForCommittedLoad().GetMainFrameMetadata(); : GetDelegateForCommittedLoad().GetMainFrameMetadata();
TimingFieldBitSet matched_bits = GetMatchedBits(timing, metadata); // There is no way to get the layout shift score only for a subframe so far.
// See the score only when the frame is the main frame.
const PageRenderData* render_data =
subframe_rfh ? nullptr
: &GetDelegateForCommittedLoad().GetMainFrameRenderData();
TimingFieldBitSet matched_bits =
GetMatchedBits(timing, metadata, render_data);
if (subframe_rfh) { if (subframe_rfh) {
subframe_expected_fields_.ClearMatching(matched_bits); subframe_expected_fields_.ClearMatching(matched_bits);
} else { } else {
...@@ -224,7 +232,8 @@ void PageLoadMetricsTestWaiter::FrameSizeChanged( ...@@ -224,7 +232,8 @@ void PageLoadMetricsTestWaiter::FrameSizeChanged(
PageLoadMetricsTestWaiter::TimingFieldBitSet PageLoadMetricsTestWaiter::TimingFieldBitSet
PageLoadMetricsTestWaiter::GetMatchedBits( PageLoadMetricsTestWaiter::GetMatchedBits(
const page_load_metrics::mojom::PageLoadTiming& timing, const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::mojom::FrameMetadata& metadata) { const page_load_metrics::mojom::FrameMetadata& metadata,
const PageRenderData* render_data) {
PageLoadMetricsTestWaiter::TimingFieldBitSet matched_bits; PageLoadMetricsTestWaiter::TimingFieldBitSet matched_bits;
if (timing.document_timing->load_event_start) if (timing.document_timing->load_event_start)
matched_bits.Set(TimingField::kLoadEvent); matched_bits.Set(TimingField::kLoadEvent);
...@@ -258,6 +267,13 @@ PageLoadMetricsTestWaiter::GetMatchedBits( ...@@ -258,6 +267,13 @@ PageLoadMetricsTestWaiter::GetMatchedBits(
} }
} }
if (render_data) {
double layout_shift_score = render_data->layout_shift_score;
if (last_main_frame_layout_shift_score_ < layout_shift_score)
matched_bits.Set(TimingField::kLayoutShift);
last_main_frame_layout_shift_score_ = layout_shift_score;
}
return matched_bits; return matched_bits;
} }
......
...@@ -33,6 +33,7 @@ class PageLoadMetricsTestWaiter ...@@ -33,6 +33,7 @@ class PageLoadMetricsTestWaiter
kFirstInputDelay = 1 << 8, kFirstInputDelay = 1 << 8,
kFirstPaintAfterBackForwardCacheRestore = 1 << 9, kFirstPaintAfterBackForwardCacheRestore = 1 << 9,
kFirstInputDelayAfterBackForwardCacheRestore = 1 << 10, kFirstInputDelayAfterBackForwardCacheRestore = 1 << 10,
kLayoutShift = 1 << 11,
}; };
using FrameTreeNodeId = using FrameTreeNodeId =
page_load_metrics::PageLoadMetricsObserver::FrameTreeNodeId; page_load_metrics::PageLoadMetricsObserver::FrameTreeNodeId;
...@@ -181,9 +182,10 @@ class PageLoadMetricsTestWaiter ...@@ -181,9 +182,10 @@ class PageLoadMetricsTestWaiter
bool operator()(const gfx::Size a, const gfx::Size b) const; bool operator()(const gfx::Size a, const gfx::Size b) const;
}; };
static TimingFieldBitSet GetMatchedBits( TimingFieldBitSet GetMatchedBits(
const page_load_metrics::mojom::PageLoadTiming& timing, const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::mojom::FrameMetadata& metadata); const page_load_metrics::mojom::FrameMetadata& metadata,
const PageRenderData* render_data);
// Updates observed page fields when a timing update is received by the // Updates observed page fields when a timing update is received by the
// MetricsWebContentsObserver. Stops waiting if expectations are satsfied // MetricsWebContentsObserver. Stops waiting if expectations are satsfied
...@@ -280,6 +282,8 @@ class PageLoadMetricsTestWaiter ...@@ -280,6 +282,8 @@ class PageLoadMetricsTestWaiter
bool attach_on_tracker_creation_ = false; bool attach_on_tracker_creation_ = false;
bool did_add_observer_ = false; bool did_add_observer_ = false;
double last_main_frame_layout_shift_score_ = 0;
base::WeakPtrFactory<PageLoadMetricsTestWaiter> weak_factory_{this}; base::WeakPtrFactory<PageLoadMetricsTestWaiter> weak_factory_{this};
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment