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