diff --git a/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPagesWidget.js b/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPagesWidget.js
index d7b1fecc068..f2a99d332a5 100644
--- a/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPagesWidget.js
+++ b/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPagesWidget.js
@@ -24,25 +24,221 @@ import PropTypes from 'prop-types';
/**
* WordPress dependencies
*/
+import { __ } from '@wordpress/i18n';
import { compose } from '@wordpress/compose';
/**
* Internal dependencies
*/
+import Data from 'googlesitekit-data';
+import { MODULES_ANALYTICS_4 } from '../../datastore/constants';
+import { KEY_METRICS_WIDGETS } from '../../../../components/KeyMetrics/key-metrics-widgets';
import { KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES } from '../../../../googlesitekit/datastore/user/constants';
-import { MetricTileTable } from '../../../../components/KeyMetrics';
+import Link from '../../../../components/Link';
import { ZeroDataMessage } from '../../../analytics/components/common';
+import { getDateString, getPreviousDate, numFmt } from '../../../../util';
+import {
+ MetricTileTable,
+ MetricTileTablePlainText,
+} from '../../../../components/KeyMetrics';
import whenActive from '../../../../util/when-active';
-import withCustomDimensions from '../../utils/withCustomDimensions';
import ConnectGA4CTATileWidget from './ConnectGA4CTATileWidget';
+import useViewOnly from '../../../../hooks/useViewOnly';
+import withCustomDimensions from '../../utils/withCustomDimensions';
+const { useSelect, useInViewSelect } = Data;
+
+/**
+ * Computes the dates for the last three days relative to today.
+ *
+ * Utilizing the current date, the function calculates the dates
+ * for the previous day, two days ago, and three days ago.
+ *
+ * @since n.e.x.t
+ *
+ * @return {Object} An object containing the dates for yesterday,
+ * two days ago, and three days ago.
+ */
+export const getDates = () => {
+ const today = new Date();
+ const todayDateString = getDateString( today );
+
+ const yesterday = getPreviousDate( todayDateString, 1 );
+ const twoDaysAgo = getPreviousDate( todayDateString, 2 );
+ const threeDaysAgo = getPreviousDate( todayDateString, 3 );
+
+ return {
+ yesterday,
+ twoDaysAgo,
+ threeDaysAgo,
+ };
+};
+
+/**
+ * Returns the date range (eg. the `startDate` and `endDate`) for this widget's
+ * reporting options.
+ *
+ * @since n.e.x.t
+ *
+ * @return {Object} An object containing the `startDate` and `endDate` for a
+ * report.
+ */
+export const getDateRange = () => {
+ const { yesterday, threeDaysAgo } = getDates();
+
+ return {
+ startDate: threeDaysAgo,
+ endDate: yesterday,
+ };
+};
+
+/**
+ * Generates the report options required for fetching data in
+ * `topRecentTrendingPagesWidget`.
+ *
+ * The function utilizes the dates from the last three days to
+ * prepare the filter and structure required for the report.
+ *
+ * This is defined as a function outside the component so that both
+ * the component and the higher-order-component (`withCustomDimensions`)
+ * can use it.
+ *
+ * @since n.e.x.t
+ *
+ * @return {Object} The report options containing dimensions, filters,
+ * metrics, and other parameters.
+ */
+export const getReportOptions = () => {
+ const { yesterday, twoDaysAgo, threeDaysAgo } = getDates();
+
+ const dates = getDateRange();
+
+ const reportOptions = {
+ ...dates,
+ dimensions: [ 'pagePath' ],
+ dimensionFilters: {
+ 'customEvent:googlesitekit_post_date': {
+ filterType: 'inListFilter',
+ value: [
+ yesterday.replace( /-/g, '' ),
+ twoDaysAgo.replace( /-/g, '' ),
+ threeDaysAgo.replace( /-/g, '' ),
+ ],
+ },
+ },
+ metrics: [ { name: 'screenPageViews' } ],
+ orderby: [
+ {
+ metric: {
+ metricName: 'screenPageViews',
+ },
+ desc: true,
+ },
+ ],
+ limit: 3,
+ };
+
+ return reportOptions;
+};
function TopRecentTrendingPagesWidget( { Widget } ) {
+ const viewOnlyDashboard = useViewOnly();
+
+ const dates = getDateRange();
+
+ const reportOptions = getReportOptions();
+
+ const report = useInViewSelect( ( select ) =>
+ select( MODULES_ANALYTICS_4 ).getReport( reportOptions )
+ );
+
+ const error = useSelect( ( select ) =>
+ select( MODULES_ANALYTICS_4 ).getErrorForSelector( 'getReport', [
+ reportOptions,
+ ] )
+ );
+
+ const titles = useInViewSelect( ( select ) =>
+ ! error && report
+ ? select( MODULES_ANALYTICS_4 ).getPageTitles(
+ report,
+ reportOptions
+ )
+ : undefined
+ );
+
+ const loading = useSelect(
+ ( select ) =>
+ ! select( MODULES_ANALYTICS_4 ).hasFinishedResolution(
+ 'getReport',
+ [ reportOptions ]
+ ) || titles === undefined
+ );
+
+ const { rows = [] } = report || {};
+
+ const columns = [
+ {
+ field: 'dimensionValues.0.value',
+ Component: ( { fieldValue } ) => {
+ const url = fieldValue;
+ const title = titles[ url ];
+ // Utilizing `useSelect` inside the component rather than
+ // returning its direct value to the `columns` array.
+ // This pattern ensures that the component re-renders correctly based on changes in state,
+ // preventing potential issues with stale or out-of-sync data.
+ // Note: This pattern is replicated in a few other spots within our codebase.
+ const serviceURL = useSelect( ( select ) => {
+ return ! viewOnlyDashboard
+ ? select( MODULES_ANALYTICS_4 ).getServiceReportURL(
+ 'all-pages-and-screens',
+ {
+ filters: {
+ unifiedPagePathScreen: url,
+ },
+ dates,
+ }
+ )
+ : null;
+ } );
+
+ if ( viewOnlyDashboard ) {
+ return ;
+ }
+
+ return (
+
+ { title }
+
+ );
+ },
+ },
+ {
+ field: 'metricValues.0.value',
+ Component: ( { fieldValue } ) => (
+ { numFmt( fieldValue ) }
+ ),
+ },
+ ];
+
return (
);
}
@@ -56,5 +252,10 @@ export default compose(
moduleName: 'analytics-4',
FallbackComponent: ConnectGA4CTATileWidget,
} ),
- withCustomDimensions()
+ withCustomDimensions( {
+ dimensions:
+ KEY_METRICS_WIDGETS[ KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES ]
+ .requiredCustomDimensions?.[ 0 ],
+ reportOptions: getReportOptions(),
+ } )
)( TopRecentTrendingPagesWidget );
diff --git a/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPages.stories.js b/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPagesWidget.stories.js
similarity index 54%
rename from assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPages.stories.js
rename to assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPagesWidget.stories.js
index 55255ba2648..e7bb5a13bc1 100644
--- a/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPages.stories.js
+++ b/assets/js/modules/analytics-4/components/widgets/TopRecentTrendingPagesWidget.stories.js
@@ -26,13 +26,40 @@ import { KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES } from '../../../../googlesiteki
import { provideModules } from '../../../../../../tests/js/utils';
import { withWidgetComponentProps } from '../../../../googlesitekit/widgets/util';
import WithRegistrySetup from '../../../../../../tests/js/WithRegistrySetup';
-import TopRecentTrendingPagesWidget from './TopRecentTrendingPagesWidget';
+import TopRecentTrendingPagesWidget, {
+ getDateRange,
+ getReportOptions,
+} from './TopRecentTrendingPagesWidget';
import { provideCustomDimensionError } from '../../utils/custom-dimensions';
+import {
+ STRATEGY_ZIP,
+ getAnalytics4MockResponse,
+ provideAnalytics4MockReport,
+} from '../../utils/data-mock';
+import { replaceValuesInAnalytics4ReportWithZeroData } from '../../../../../../.storybook/utils/zeroReports';
const WidgetWithComponentProps = withWidgetComponentProps(
KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES
)( TopRecentTrendingPagesWidget );
+const reportOptions = getReportOptions();
+
+const dateRange = getDateRange();
+
+const pageTitlesReportOptions = {
+ ...dateRange,
+ dimensionFilters: {
+ pagePath: new Array( 3 )
+ .fill( '' )
+ .map( ( _, i ) => `/test-post-${ i + 1 }/` )
+ .sort(),
+ },
+ dimensions: [ 'pagePath', 'pageTitle' ],
+ metrics: [ { name: 'screenPageViews' } ],
+ orderby: [ { metric: { metricName: 'screenPageViews' }, desc: true } ],
+ limit: 15,
+};
+
const Template = ( { setupRegistry, ...args } ) => (
@@ -50,11 +77,120 @@ Ready.args = {
.requiredCustomDimensions?.[ 0 ],
],
} );
+
+ const pageTitlesReport = getAnalytics4MockResponse(
+ pageTitlesReportOptions,
+ // Use the zip combination strategy to ensure a one-to-one mapping of page paths to page titles.
+ // Otherwise, by using the default cartesian product of dimension values, the resulting output will have non-matching
+ // page paths to page titles.
+ { dimensionCombinationStrategy: STRATEGY_ZIP }
+ );
+
+ registry
+ .dispatch( MODULES_ANALYTICS_4 )
+ .receiveGetReport( pageTitlesReport, {
+ options: pageTitlesReportOptions,
+ } );
+
+ provideAnalytics4MockReport( registry, reportOptions );
},
};
Ready.parameters = {
features: [ 'newsKeyMetrics' ],
};
+Ready.scenario = {
+ label: 'KeyMetrics/TopRecentTrendingPagesWidget/Ready',
+};
+
+export const Loading = Template.bind( {} );
+Loading.storyName = 'Loading';
+Loading.args = {
+ setupRegistry: ( { dispatch } ) => {
+ dispatch( MODULES_ANALYTICS_4 ).setSettings( {
+ propertyID: '12345',
+ availableCustomDimensions: [
+ KEY_METRICS_WIDGETS[ KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES ]
+ .requiredCustomDimensions?.[ 0 ],
+ ],
+ } );
+
+ dispatch( MODULES_ANALYTICS_4 ).startResolution( 'getReport', [
+ reportOptions,
+ ] );
+ },
+};
+Loading.parameters = {
+ features: [ 'newsKeyMetrics' ],
+};
+Loading.scenario = {
+ label: 'KeyMetrics/TopRecentTrendingPagesWidget/Loading',
+};
+
+export const ZeroData = Template.bind( {} );
+ZeroData.storyName = 'Zero Data';
+ZeroData.args = {
+ setupRegistry: ( { dispatch } ) => {
+ const report = getAnalytics4MockResponse( reportOptions );
+ const zeroReport =
+ replaceValuesInAnalytics4ReportWithZeroData( report );
+
+ dispatch( MODULES_ANALYTICS_4 ).receiveGetReport( zeroReport, {
+ options: reportOptions,
+ } );
+ dispatch( MODULES_ANALYTICS_4 ).setSettings( {
+ propertyID: '12345',
+ availableCustomDimensions: [
+ KEY_METRICS_WIDGETS[ KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES ]
+ .requiredCustomDimensions?.[ 0 ],
+ ],
+ } );
+ },
+};
+ZeroData.scenario = {
+ label: 'KeyMetrics/TopRecentTrendingPagesWidget/ZeroData',
+};
+
+export const Error = Template.bind( {} );
+Error.storyName = 'Error';
+Error.args = {
+ setupRegistry: ( { dispatch } ) => {
+ const errorObject = {
+ code: 400,
+ message: 'Test error message. ',
+ data: {
+ status: 400,
+ reason: 'badRequest',
+ },
+ selectorData: {
+ storeName: 'modules/analytics-4',
+ name: 'getReport',
+ args: [ reportOptions ],
+ },
+ };
+
+ dispatch( MODULES_ANALYTICS_4 ).receiveError(
+ errorObject,
+ 'getReport',
+ [ reportOptions ]
+ );
+
+ dispatch( MODULES_ANALYTICS_4 ).finishResolution( 'getReport', [
+ reportOptions,
+ ] );
+
+ dispatch( MODULES_ANALYTICS_4 ).setSettings( {
+ propertyID: '12345',
+ availableCustomDimensions: [
+ KEY_METRICS_WIDGETS[ KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES ]
+ .requiredCustomDimensions?.[ 0 ],
+ ],
+ } );
+ },
+};
+Error.scenario = {
+ label: 'KeyMetrics/TopRecentTrendingPagesWidget/Error',
+ delay: 250,
+};
export const ErrorMissingCustomDimensions = Template.bind( {} );
ErrorMissingCustomDimensions.storyName = 'Error - Missing custom dimensions';
diff --git a/assets/js/modules/index.test.js b/assets/js/modules/index.test.js
index 04ba3fc41e3..df64990351a 100644
--- a/assets/js/modules/index.test.js
+++ b/assets/js/modules/index.test.js
@@ -49,11 +49,17 @@ function getComponentNames( componentPath ) {
describe( 'all modules', () => {
describe.each( directories( '.' ) )( '%s', ( moduleSlug ) => {
const components = directories( `${ moduleSlug }/components` );
- if ( ! components.length ) {
+
+ // Filter out the custom-dimensions-report-options directory
+ const filteredComponents = components.filter(
+ ( component ) => component !== 'custom-dimensions-report-options'
+ );
+
+ if ( ! filteredComponents.length ) {
return;
}
- it.each( components )(
+ it.each( filteredComponents )(
'components/%s has an index module with all components exported',
( componentDir ) => {
const componentDirPath = path.join(
@@ -62,6 +68,7 @@ describe( 'all modules', () => {
'components',
componentDir
);
+
const {
// eslint-disable-next-line no-unused-vars
default: _,
@@ -71,7 +78,12 @@ describe( 'all modules', () => {
const componentNames =
getComponentNames( componentDirPath ).sort();
- expect( indexExportNames ).toEqual( componentNames );
+ const filteredComponentNames = componentNames.filter(
+ ( component ) =>
+ component !== 'custom-dimensions-report-options'
+ );
+
+ expect( indexExportNames ).toEqual( filteredComponentNames );
}
);
} );
diff --git a/includes/Modules/Analytics_4/Report/Request.php b/includes/Modules/Analytics_4/Report/Request.php
index 5aa973584c3..a225bc1f8e4 100644
--- a/includes/Modules/Analytics_4/Report/Request.php
+++ b/includes/Modules/Analytics_4/Report/Request.php
@@ -282,6 +282,7 @@ protected function validate_shared_dimensions( $dimensions ) {
'pageTitle',
'sessionDefaultChannelGroup',
'sessionDefaultChannelGrouping',
+ 'customEvent:googlesitekit_post_date',
'customEvent:googlesitekit_post_categories',
)
);
@@ -381,6 +382,11 @@ protected function parse_dimension_filter( $dimension_name, $dimension_value ) {
$filter_class = String_Filter::class;
} elseif ( 'inListFilter' === $filter_type ) {
$filter_class = In_List_Filter::class;
+ // Ensure that the 'inListFilter' is provided a flat array of values.
+ // Extract the actual values from the 'value' key if present.
+ if ( isset( $dimension_value['value'] ) ) {
+ $dimension_value = $dimension_value['value'];
+ }
} else {
return null;
}
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Error_0_document_0_small.png
new file mode 100644
index 00000000000..5cf342137fc
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Error_0_document_0_small.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Error_0_document_1_medium.png
new file mode 100644
index 00000000000..958f8fb90df
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Error_0_document_1_medium.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Error_0_document_2_large.png
new file mode 100644
index 00000000000..f04c9cf4b08
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Error_0_document_2_large.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Loading_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Loading_0_document_0_small.png
new file mode 100644
index 00000000000..aa3e175672b
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Loading_0_document_0_small.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Loading_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Loading_0_document_1_medium.png
new file mode 100644
index 00000000000..684640975ca
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Loading_0_document_1_medium.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Loading_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Loading_0_document_2_large.png
new file mode 100644
index 00000000000..1fa93a07c45
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Loading_0_document_2_large.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Ready_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Ready_0_document_0_small.png
new file mode 100644
index 00000000000..732cb2270b2
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Ready_0_document_0_small.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Ready_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Ready_0_document_1_medium.png
new file mode 100644
index 00000000000..5f8bb6741d0
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Ready_0_document_1_medium.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Ready_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Ready_0_document_2_large.png
new file mode 100644
index 00000000000..4b3a086d1a5
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_Ready_0_document_2_large.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_ZeroData_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_ZeroData_0_document_0_small.png
new file mode 100644
index 00000000000..8edc9ebc078
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_ZeroData_0_document_0_small.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_ZeroData_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_ZeroData_0_document_1_medium.png
new file mode 100644
index 00000000000..982640f5e5e
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_ZeroData_0_document_1_medium.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_ZeroData_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_ZeroData_0_document_2_large.png
new file mode 100644
index 00000000000..eaf351bd661
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPagesWidget_ZeroData_0_document_2_large.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Error_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Error_0_document_0_small.png
new file mode 100644
index 00000000000..5cf342137fc
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Error_0_document_0_small.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Error_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Error_0_document_1_medium.png
new file mode 100644
index 00000000000..958f8fb90df
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Error_0_document_1_medium.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Error_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Error_0_document_2_large.png
new file mode 100644
index 00000000000..f04c9cf4b08
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Error_0_document_2_large.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Loading_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Loading_0_document_0_small.png
new file mode 100644
index 00000000000..aa3e175672b
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Loading_0_document_0_small.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Loading_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Loading_0_document_1_medium.png
new file mode 100644
index 00000000000..684640975ca
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Loading_0_document_1_medium.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Loading_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Loading_0_document_2_large.png
new file mode 100644
index 00000000000..1fa93a07c45
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Loading_0_document_2_large.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Ready_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Ready_0_document_0_small.png
new file mode 100644
index 00000000000..732cb2270b2
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Ready_0_document_0_small.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Ready_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Ready_0_document_1_medium.png
new file mode 100644
index 00000000000..5f8bb6741d0
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Ready_0_document_1_medium.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Ready_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Ready_0_document_2_large.png
new file mode 100644
index 00000000000..4b3a086d1a5
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_Ready_0_document_2_large.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_ZeroData_0_document_0_small.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_ZeroData_0_document_0_small.png
new file mode 100644
index 00000000000..8edc9ebc078
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_ZeroData_0_document_0_small.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_ZeroData_0_document_1_medium.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_ZeroData_0_document_1_medium.png
new file mode 100644
index 00000000000..982640f5e5e
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_ZeroData_0_document_1_medium.png differ
diff --git a/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_ZeroData_0_document_2_large.png b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_ZeroData_0_document_2_large.png
new file mode 100644
index 00000000000..eaf351bd661
Binary files /dev/null and b/tests/backstop/reference/google-site-kit_KeyMetrics_TopRecentTrendingPages_ZeroData_0_document_2_large.png differ