Skip to content

Commit c02ca66

Browse files
kangzjNikschavandognose24tellthemachinesaduth
authored
Stats: Release Navigation Improvements (#103367)
* flip the flag * Fix stats-navigation tab selectors for tests * Stats: Fix e2e tests by handling new selectors for the new nav header (#103384) * Add a new utility function for clicking on new navigation * Handle selectors for the new navigation header in e2e tests * Don't update the selector for other tests apart from stats * Adjust styling for summary nav on mobile (#103363) * Remove `preventWidows` from `client/components` (#103187) * Remove `preventWidows` from `client/components` * CardHeading * VisibleDaysLimitUpsell * Add new site for A4A and add styles * Remove preventWidows and disablePreventWidows from FormattedHeader * Happiness support * BackupGettingStarted * JetpackProductCardFeaturesItem * JetpackProductCard * Jetpack backups * Backup successful * IntroPricingBanner * JetpackDisconnected * JetpackDisconnectedWPCOM * LicensingActivation * PurchaseDetail * SeoPreviewNudge * Add new site popover * theme collection * Update test snapshots * Fix Storybook compilation in components package (#103362) * Add conditionNames for Storybook Webpack build * Editor: Stop preloading section (#103334) * Editor: Stop preloading section * Get rid of actionHoverCallback * Breadcrumbs: Add `renderItemLink ` prop (#103321) * SummaryButton: Add `renderLink` prop * Rename to renderItemLink, split Item vs BreadcrumbsItemProps, refactor implementation * Prevent flickering in Storybook when opning menu in compact mode * Add open for extension to docs * add a test and console.log in story * feedback --------- Co-authored-by: Marco Ciampini <[email protected]> * Update different A4A labels to sentence case (#103238) * Update different A4A labels to sentence case * Fix one more occurence * Showing multiple domain selection on new-hosted-site flow (#103359) * E2E Auth: Fix apple login flow to wpcom and woo (#103357) * Encript updated path * E2E auth apple: fix wpcom and woo auth flows * Follow up of #103321 (#103382) * WooCoreProfilerMasterbar: fix useSelector and useTranslate usages (#103373) * Fix/stop import redirect after failed wix (#103358) * Redirect to the correct step when a wix migration fails * remove hardcoded true --------- Co-authored-by: Andrés Blanco <[email protected]> * Notifications settings: change Publicized copy (#103265) * change copy for Jetpack Social notification setting (formerly Publicized) * do not translate brand name * Improves the design for the Migration Requested page (#103183) * Improves the design for the Migration Requested page * Remove card borders * A4A: Fix the background color (#103389) * Revert "Notifications settings: change Publicized copy (#103265)" (#103392) This reverts commit c320da3. * Apps: Fix Odyssey translation extraction. (#103393) * change Publicized copy to Jetpack Social brand, add translators comment (#103395) * Fix e2e onboarding new hosted site tests (#103383) * Upgrade importers to container v2 (#103024) * Upgrade importers to container v2 * remove test string * show title inside the import drag if not using container v2 * fix heading wp importer * fix progressbar * hacky but working * apply Gabriel's suggestions --------- Co-authored-by: Andrés Blanco <[email protected]> * Apps: Fix Odyssey widget reactivity. (#103400) * STATS-64: Don't dispatch legacy country data (#103376) * STATS-67 - Don't navigate to the current tab if we are already on the current tab (#103379) * STATS-67: Don't reload page if current tab is already the selected tab * Add comment as to why the tab selected conditionally * Stats: Fix styling on Odyssey Stats for Navigation Improvement (#103369) * Fix main navigation mobile dropdown item padding * Make mobile summary nav dropdown 100% width * Fix Locations summary mobile item list label padding * Fix stats-navigation tab selectors for tests * Stats: Fix e2e tests by handling new selectors for the new nav header (#103384) * Add a new utility function for clicking on new navigation * Handle selectors for the new navigation header in e2e tests * Don't update the selector for other tests apart from stats * remove has-fixed-nav when new nav enabled * avoid loading style conflicts --------- Co-authored-by: Nikhil <[email protected]> Co-authored-by: Dognose <[email protected]> Co-authored-by: Dognose <[email protected]> Co-authored-by: tellthemachines <[email protected]> Co-authored-by: Andrew Duthie <[email protected]> Co-authored-by: Marin Atanasov <[email protected]> Co-authored-by: Nik Tsekouras <[email protected]> Co-authored-by: Marco Ciampini <[email protected]> Co-authored-by: Wojtek Naruniec <[email protected]> Co-authored-by: Paulo Marcos Trentin <[email protected]> Co-authored-by: Bogdan Nikolic <[email protected]> Co-authored-by: Jarda Snajdr <[email protected]> Co-authored-by: Andrés Blanco <[email protected]> Co-authored-by: Andrés Blanco <[email protected]> Co-authored-by: Christian Gastrell <[email protected]> Co-authored-by: valterlorran <[email protected]> Co-authored-by: arthur791004 <[email protected]> Co-authored-by: sdnunca <[email protected]>
1 parent 1f38196 commit c02ca66

File tree

18 files changed

+103
-28
lines changed

18 files changed

+103
-28
lines changed

client/blocks/stats-navigation/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ const SelectNav = ( {
9999
}
100100
return (
101101
<NavItem
102-
className={ className }
102+
className={ clsx( className, {
103+
'is-active': selectedItem === item,
104+
} ) }
103105
key={ item }
104106
path={ itemPath }
105107
selected={ selectedItem === item }
@@ -131,7 +133,7 @@ const TabNav = ( { validNavItems, interval, slugPath, adminUrl, selectedItem, sh
131133
return {
132134
name: item,
133135
title: navItem.label + ( navItem.paywall && showLock ? ' 🔒' : '' ),
134-
className: 'stats-navigation__' + item,
136+
className: clsx( 'stats-navigation__' + item, 'navigation-tab' ),
135137
path: itemPath,
136138
};
137139
} );

client/components/section-nav/item.jsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ class NavItem extends PureComponent {
5656
<a
5757
href={ this.props.path }
5858
target={ target }
59-
className={ 'section-nav-' + itemClassPrefix + '__link' }
59+
className={ clsx(
60+
'section-nav-' + itemClassPrefix + '__link',
61+
this.props.className,
62+
'navigation-tab'
63+
) }
6064
onClick={ onClick }
6165
onMouseEnter={ this.preload }
6266
tabIndex={ this.props.tabIndex || 0 }

client/my-sites/stats/stats-email-detail/index.jsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,11 @@ class StatsEmailDetail extends Component {
232232

233233
return (
234234
<>
235-
<Main className="has-fixed-nav stats__email-detail stats">
235+
<Main
236+
className={ clsx( 'stats', 'stats__email-detail', {
237+
'has-fixed-nav': ! config.isEnabled( 'stats/navigation-improvement' ),
238+
} ) }
239+
>
236240
<QueryPosts siteId={ siteId } postId={ postId } />
237241
<QueryPostStats siteId={ siteId } postId={ postId } />
238242
<QueryEmailStats
@@ -395,7 +399,7 @@ class StatsEmailDetail extends Component {
395399
</div>
396400
</>
397401
) : (
398-
<Spinner />
402+
<Spinner baseClassName="calypso-spinner" />
399403
) }
400404
</Main>
401405
</>

client/my-sites/stats/stats-email-summary/index.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import config from '@automattic/calypso-config';
22
import { formatNumber } from '@automattic/number-formatters';
3+
import clsx from 'clsx';
34
import { useTranslate } from 'i18n-calypso';
45
import { useMemo } from 'react';
56
import JetpackColophon from 'calypso/components/jetpack-colophon';
@@ -71,7 +72,12 @@ const StatsEmailSummary = ( { period, query } ) => {
7172
};
7273

7374
return (
74-
<Main className="has-fixed-nav" fullWidthLayout>
75+
<Main
76+
className={ clsx( {
77+
'has-fixed-nav': ! config.isEnabled( 'stats/navigation-improvement' ),
78+
} ) }
79+
fullWidthLayout
80+
>
7581
<PageViewTracker path="/stats/emails/:site" title="Stats > Emails" />
7682
<div className="stats stats-summary-view">
7783
{ isStatsNavigationImprovementEnabled && (

client/my-sites/stats/stats-email-top-row/top-card.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const TopCardValue = ( { value, isLoading } ) => {
1010
const isNumber = Number.isFinite( value );
1111

1212
if ( isLoading ) {
13-
return <Spinner />;
13+
return <Spinner baseClassName="calypso-spinner" />;
1414
}
1515
if ( value === null ) {
1616
return <span className="highlight-card-count-value">-</span>;

client/my-sites/stats/stats-module/placeholder.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const StatsModulePlaceholder: React.FC< StatsModulePlaceholderProps > = ( {
2020

2121
return (
2222
<div className={ classes }>
23-
<Spinner />
23+
<Spinner baseClassName="calypso-spinner" />
2424
</div>
2525
);
2626
};

client/my-sites/stats/stats-post-detail/index.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,9 @@ class StatsPostDetail extends Component {
203203
}
204204

205205
const isWPAdmin = config.isEnabled( 'is_odyssey' );
206-
const postDetailPageClasses = clsx( 'stats has-fixed-nav', {
206+
const postDetailPageClasses = clsx( 'stats', {
207207
'is-odyssey-stats': isWPAdmin,
208+
'has-fixed-nav': ! config.isEnabled( 'stats/navigation-improvement' ),
208209
} );
209210

210211
// TODO: Refactor navigationItems to a single object with backLink and title attributes.

client/my-sites/stats/stats-subscribers-highlight-section/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ function SubscriberHighlightsStandard( {
104104

105105
function SubscriberHighlightsMobile( { highlights, isLoading }: SubscriberHighlightsRenderProps ) {
106106
if ( isLoading ) {
107-
return <Spinner />;
107+
return <Spinner baseClassName="calypso-spinner" />;
108108
}
109109

110110
return <MobileHighlightCardListing highlights={ highlights } />;

config/horizon.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@
127127
"stats/empty-module-traffic": true,
128128
"stats/paid-wpcom-v2": true,
129129
"stats/real-time-tab": false,
130-
"stats/navigation-improvement": false,
130+
"stats/navigation-improvement": true,
131131
"subscriber-importer": true,
132132
"subscribers-helper-library": true,
133133
"themes/block-theme-previews-premium-and-woo": true,

config/production.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@
163163
"stats/paid-wpcom-v2": true,
164164
"stats/paid-wpcom-v3": true,
165165
"stats/real-time-tab": false,
166-
"stats/navigation-improvement": false,
166+
"stats/navigation-improvement": true,
167167
"subscriber-importer": true,
168168
"subscribers-helper-library": true,
169169
"themes/block-theme-previews-premium-and-woo": true,

config/stage.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@
158158
"stats/paid-wpcom-v2": true,
159159
"stats/paid-wpcom-v3": true,
160160
"stats/real-time-tab": false,
161-
"stats/navigation-improvement": false,
161+
"stats/navigation-improvement": true,
162162
"subscriber-importer": true,
163163
"subscribers-helper-library": true,
164164
"themes/block-theme-previews-premium-and-woo": true,

config/test.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@
117117
"ssr/prefetch-timebox": true,
118118
"stats/chart-library": true,
119119
"stats/empty-module-traffic": true,
120-
"stats/navigation-improvement": false,
120+
"stats/navigation-improvement": true,
121121
"subscribers-helper-library": true,
122122
"themes/premium": true,
123123
"upgrades/redirect-payments": true,

config/wpcalypso.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@
160160
"stats/paid-wpcom-v2": true,
161161
"stats/paid-wpcom-v3": true,
162162
"stats/real-time-tab": false,
163-
"stats/navigation-improvement": false,
163+
"stats/navigation-improvement": true,
164164
"subscriber-importer": true,
165165
"subscribers-helper-library": true,
166166
"themes/block-theme-previews-premium-and-woo": true,

packages/calypso-e2e/src/element-helper.ts

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { Locator, Page, Frame } from 'playwright';
22
import envVariables from './env-variables';
33

4-
const navTabParent = 'div.section-nav';
4+
const navTabParent = 'div.stats-navigation__tabs';
5+
const legacyNavTabParent = 'div.section-nav';
56

67
const selectors = {
78
// clickNavTab
89
navTabItem: ( { name = '', selected = false }: { name?: string; selected?: boolean } = {} ) =>
9-
`${ navTabParent } a[aria-current="${ selected }"]:has(span:has-text("${ name }"))`,
10-
navTabMobileToggleButton: `${ navTabParent } button.section-nav__mobile-header`,
10+
envVariables.VIEWPORT_NAME === 'mobile'
11+
? `${ legacyNavTabParent } a[aria-current="${ selected }"]:has(span:has-text("${ name }"))`
12+
: `${ navTabParent } button[aria-selected="${ selected }"]:has-text("${ name }")`,
13+
navTabMobileToggleButton: `${ legacyNavTabParent } button.section-nav__mobile-header`,
1114
};
1215

1316
/**
@@ -59,41 +62,62 @@ export async function clickNavTab(
5962
page: Page,
6063
name: string,
6164
{ force }: { force?: boolean } = {}
65+
): Promise< void > {
66+
await clickNavTabBase( page, name, selectors.navTabItem, selectors.navTabMobileToggleButton, {
67+
force,
68+
} );
69+
}
70+
71+
/**
72+
* Locates and clicks on a specified tab on the NavTab.
73+
*
74+
* NavTabs are used throughout calypso to contain sub-pages within the parent page.
75+
* For instance, on the Media gallery page a NavTab is used to filter the gallery to
76+
* show a specific category of gallery items.
77+
*
78+
* @param {Page} page Underlying page on which interactions take place.
79+
* @param {string} name Name of the tab to be clicked.
80+
* @throws {Error} If the tab name is not the active tab.
81+
*/
82+
export async function clickNavTabBase(
83+
page: Page,
84+
name: string,
85+
tabSelector: ( params: { name?: string; selected?: boolean } ) => string,
86+
tabSelectorMobile: string,
87+
{ force }: { force?: boolean } = {}
6288
): Promise< void > {
6389
// Short circuit operation if the active tab and target tabs are the same.
6490
// Strip numerals from the extracted tab name to account for the slightly
6591
// different implementation in PostsPage.
66-
const selectedTabLocator = page.locator( selectors.navTabItem( { selected: true } ) );
92+
const selectedTabLocator = page.locator( tabSelector( { selected: true } ) );
6793
const selectedTabName = await selectedTabLocator.innerText();
6894
if ( selectedTabName.replace( /[0-9]|,/g, '' ) === name ) {
6995
return;
7096
}
7197

7298
// If force option is specified, force click using a `dispatchEvent`.
7399
if ( force ) {
74-
return await page.dispatchEvent( selectors.navTabItem( { name: name } ), 'click' );
100+
return await page.dispatchEvent( tabSelector( { name: name } ), 'click' );
75101
}
76102

77103
// Mobile view - navtabs become a dropdown and thus it must be opened first.
78104
if ( envVariables.VIEWPORT_NAME === 'mobile' ) {
79105
// Open the Navtabs which now act as a pseudo-dropdown menu.
80-
const navTabsButtonLocator = page.locator( selectors.navTabMobileToggleButton );
106+
const navTabsButtonLocator = page.locator( tabSelectorMobile );
81107
await navTabsButtonLocator.click( { noWaitAfter: true } );
82108

83-
const navTabIsOpenLocator = page.locator( `${ navTabParent }.is-open` );
109+
const navTabIsOpenLocator = page.locator( `${ legacyNavTabParent }.is-open` );
84110
await navTabIsOpenLocator.waitFor();
85111
}
86112

87113
// Click on the intended item and wait for navigation to finish.
88-
const navTabItem = page.locator( selectors.navTabItem( { name: name, selected: false } ) );
114+
const navTabItem = page.locator( tabSelector( { name: name, selected: false } ) );
89115

90116
const regex = new RegExp( `.*/${ name.toLowerCase() }/.*` );
91117
await Promise.all( [ page.waitForURL( regex ), navTabItem.click() ] );
92118

93119
// Final verification, check that we are now on the expected navtab.
94-
const newSelectedTabLocator = page.locator(
95-
selectors.navTabItem( { name: name, selected: true } )
96-
);
120+
const newSelectedTabLocator = page.locator( tabSelector( { name: name, selected: true } ) );
97121
const newSelectedTabName = await newSelectedTabLocator.innerText();
98122

99123
if ( newSelectedTabName.replace( /[0-9]|,/g, '' ) !== name ) {

packages/calypso-e2e/src/lib/pages/stats-page.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Locator, Page } from 'playwright';
22
import { envVariables } from '../..';
33
import { getCalypsoURL } from '../../data-helper';
4-
import { clickNavTab } from '../../element-helper';
4+
import { clickNavTab } from '../utils';
55

66
export type StatsTabs = 'Traffic' | 'Insights' | 'Subscribers' | 'Store';
77
type TrafficActivityType = 'Views' | 'Visitors' | 'Likes' | 'Comments';
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Page } from 'playwright';
2+
import { clickNavTabBase } from '../../element-helper';
3+
4+
const navTabParent = '.stats-navigation';
5+
6+
const selectors = {
7+
navTabItem: ( { name = '', selected = false }: { name?: string; selected?: boolean } = {} ) =>
8+
`${ navTabParent } .navigation-tab${ selected ? '.is-active' : '' }:has-text("${ name }")`,
9+
navTabMobileToggleButton: `${ navTabParent } button.section-nav__mobile-header`,
10+
};
11+
12+
/**
13+
* Locates and clicks on a specified tab on the NavTab.
14+
*
15+
* NavTabs are used throughout calypso to contain sub-pages within the parent page.
16+
* For instance, on the Media gallery page a NavTab is used to filter the gallery to
17+
* show a specific category of gallery items.
18+
*
19+
* @param {Page} page Underlying page on which interactions take place.
20+
* @param {string} name Name of the tab to be clicked.
21+
* @throws {Error} If the tab name is not the active tab.
22+
*/
23+
async function clickNavTab(
24+
page: Page,
25+
name: string,
26+
{ force }: { force?: boolean } = {}
27+
): Promise< void > {
28+
await clickNavTabBase( page, name, selectors.navTabItem, selectors.navTabMobileToggleButton, {
29+
force,
30+
} );
31+
}
32+
33+
export { clickNavTab };

packages/calypso-e2e/src/lib/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export * from './validate-translations';
33
export * from './get-test-account-by-feature';
44
export * from './translate';
55
export * from './social-connections-manager';
6+
export * from './click-nav-tab';
67

78
// Other items are exported for unit testing, we only care about the manager class.
89
export { EditorTracksEventManager } from './editor-tracks-event-manager';

packages/components/src/spinner/style.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
}
55
}
66

7-
.spinner {
7+
.calypso-spinner, .spinner {
88
display: flex;
99
align-items: center;
1010
}

0 commit comments

Comments
 (0)