Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show Ads value prop in Paid Campaign performance card #2650

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
d544759
remove free credits
kt-12 Oct 22, 2024
62d124c
add paid-features.js
kt-12 Oct 22, 2024
19ef7b1
remove translations
kt-12 Oct 22, 2024
90ea27a
e2e
kt-12 Oct 22, 2024
2a7af58
style fixes and e2e
kt-12 Oct 22, 2024
1ed56b8
fix e2e button clicking
kt-12 Oct 22, 2024
cd2521c
fix old e2e
kt-12 Oct 22, 2024
d8cb4cc
address review feedback.
kt-12 Oct 28, 2024
cd58bca
doc updated.
kt-12 Oct 28, 2024
cfa279c
Update js/src/dashboard/summary-section/paid-features/free-ad-credit.js
kt-12 Nov 1, 2024
96e4162
Update js/src/dashboard/summary-section/paid-features/free-ad-credit.js
kt-12 Nov 1, 2024
d5d1d2f
remove usage of sections, fix styling
kt-12 Nov 1, 2024
e4fa585
Merge branch 'feature/2538-performance-card-sep' of https://github.co…
kt-12 Nov 1, 2024
d043e81
remove margin
kt-12 Nov 1, 2024
b77f18e
seperate file for paid-features test
kt-12 Nov 1, 2024
cd7ec9f
fix button name
kt-12 Nov 1, 2024
6fe5003
update variable names and cleanup
kt-12 Nov 1, 2024
51d5187
cleanup
kt-12 Nov 1, 2024
ccc7edc
Merge branch 'feature/2460-google-ads-value-prop' into feature/2538-p…
kt-12 Nov 1, 2024
2d77db8
check when ads complete is set
kt-12 Nov 1, 2024
0fcba0f
change variable name
kt-12 Nov 1, 2024
38318b2
avoide flakyness
kt-12 Nov 1, 2024
2297982
change variable name
kt-12 Nov 4, 2024
f8f9c4a
remove additional assignement
kt-12 Nov 4, 2024
d7d17ad
style changes
kt-12 Nov 4, 2024
311a850
update E2E
kt-12 Nov 4, 2024
f899c31
jest update
kt-12 Nov 5, 2024
ff4376e
fix review changes.
kt-12 Nov 5, 2024
f46e880
fix jest
kt-12 Nov 5, 2024
f0ab0f6
fix unused variable
kt-12 Nov 5, 2024
9caf01d
remove only
kt-12 Nov 5, 2024
5a27b75
fix jest
kt-12 Nov 6, 2024
f8c3339
remove unnecessary typecasting.
kt-12 Nov 6, 2024
0e80569
css changes
kt-12 Nov 6, 2024
64eaab6
div -> component
kt-12 Nov 6, 2024
b0c712e
Style fixes
joemcgill Nov 7, 2024
64eb3b4
More style adjustments
joemcgill Nov 7, 2024
d1fe9eb
add new Fulfill for ad report.
kt-12 Nov 7, 2024
c7bbc72
check for text content in Summary+ mock add empty campaign.
kt-12 Nov 7, 2024
0f809f3
update variable name.
kt-12 Nov 7, 2024
c724767
remove margin
kt-12 Nov 7, 2024
1a516c7
remove size attribute.
kt-12 Nov 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@
import CampaignPreview from '.~/components/paid-ads/campaign-preview';
import FreeAdCredit from '.~/components/free-ad-credit';
import VerticalGapLayout from '.~/components/vertical-gap-layout';
import useFreeAdCredit from '.~/hooks/useFreeAdCredit';
kt-12 marked this conversation as resolved.
Show resolved Hide resolved
import './paid-ads-features-section.scss';

function FeatureList() {

Check warning on line 19 in js/src/components/paid-ads/ads-campaign/paid-ads-features-section.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/paid-ads/ads-campaign/paid-ads-features-section.js#L19

Added line #L19 was not covered by tests
const featuresItems = [
{
Icon: GridiconCheckmark,
Expand Down Expand Up @@ -48,9 +47,7 @@
* Renders a section layout to elaborate on the features of paid ads and show the buttons
* for the next actions: skip or continue the paid ads setup.
*/
export default function PaidAdsFeaturesSection() {

Check warning on line 50 in js/src/components/paid-ads/ads-campaign/paid-ads-features-section.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/paid-ads/ads-campaign/paid-ads-features-section.js#L50

Added line #L50 was not covered by tests
const hasFreeAdCredit = useFreeAdCredit();

return (
<Section
className="gla-paid-ads-features-section"
Expand Down Expand Up @@ -111,8 +108,7 @@
<CampaignPreview />
</FlexItem>
</Flex>

{ hasFreeAdCredit && <FreeAdCredit /> }
kt-12 marked this conversation as resolved.
Show resolved Hide resolved
<FreeAdCredit />
</VerticalGapLayout>
</Section.Card.Body>
</Section.Card>
Expand Down
35 changes: 2 additions & 33 deletions js/src/dashboard/summary-section/paid-campaign-promotion-card.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,20 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { Spinner } from '@woocommerce/components';

/**
* Internal dependencies
*/
import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount';
import AddPaidCampaignButton from '.~/components/paid-ads/add-paid-campaign-button';
import { GOOGLE_ADS_ACCOUNT_STATUS } from '.~/constants';

const PromotionContent = ( { adsAccount } ) => {
const showFreeCredit =
adsAccount.sub_account ||
adsAccount.status === GOOGLE_ADS_ACCOUNT_STATUS.DISCONNECTED;

return (
<>
<p>
{ showFreeCredit
? __(
'Create your first campaign and get $500 in ad credit*',
'google-listings-and-ads'
)
: __(
'Create your first campaign',
'google-listings-and-ads'
) }
</p>
<AddPaidCampaignButton
eventProps={ { context: 'add-paid-campaign-promotion' } }
/>
</>
);
};
import PaidFeatures from './paid-features';

function PaidCampaignPromotionCard() {
const { googleAdsAccount } = useGoogleAdsAccount();

return (
<div className="gla-summary-card__body">
{ googleAdsAccount ? (
<PromotionContent adsAccount={ googleAdsAccount } />
) : (
<Spinner />
) }
{ googleAdsAccount ? <PaidFeatures /> : <Spinner /> }

Check warning on line 17 in js/src/dashboard/summary-section/paid-campaign-promotion-card.js

View check run for this annotation

Codecov / codecov/patch

js/src/dashboard/summary-section/paid-campaign-promotion-card.js#L17

Added line #L17 was not covered by tests
</div>
);
}
Expand Down
101 changes: 101 additions & 0 deletions js/src/dashboard/summary-section/paid-features/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { createInterpolateElement } from '@wordpress/element';
import { Flex, FlexBlock, FlexItem, Card } from '@wordpress/components';
import GridiconCheckmark from 'gridicons/dist/checkmark';

/**
* Internal dependencies
*/
import { ContentLink } from '.~/components/guide-page-content';
import CampaignPreview from '.~/components/paid-ads/campaign-preview';
import AddPaidCampaignButton from '.~/components/paid-ads/add-paid-campaign-button';
import FreeAdCredit from '.~/components/free-ad-credit';
import VerticalGapLayout from '.~/components/vertical-gap-layout';
import './index.scss';

function FeatureList() {
const featuresItems = [

Check warning on line 20 in js/src/dashboard/summary-section/paid-features/index.js

View check run for this annotation

Codecov / codecov/patch

js/src/dashboard/summary-section/paid-features/index.js#L19-L20

Added lines #L19 - L20 were not covered by tests
{
Icon: GridiconCheckmark,
content: __(
'Reach more customer by advertising your products across Google Ads channels like Search, YouTube and Discover.',
'google-listings-and-ads'
),
},
{
Icon: GridiconCheckmark,
content: __(
'Set a daily budget and only pay when people click on your ads.',
'google-listings-and-ads'
),
},
{
Icon: GridiconCheckmark,
content: createInterpolateElement(
__(
"Performance Max uses the best of Google's AI to show the most impactful ads for your products at the right time and place. <link>Learn more about Performance Max technology.</link>",
'google-listings-and-ads'
),
{
link: (
<ContentLink
href="https://support.google.com/google-ads/answer/10724817"
context="campaign-creation-performance-max"
/>
),
}
),
},
];

return (

Check warning on line 54 in js/src/dashboard/summary-section/paid-features/index.js

View check run for this annotation

Codecov / codecov/patch

js/src/dashboard/summary-section/paid-features/index.js#L54

Added line #L54 was not covered by tests
<div className="gla-paid-features-section__feature-list">
{ featuresItems.map( ( { Icon, content }, idx ) => (
<Flex key={ idx } align="flex-start">

Check warning on line 57 in js/src/dashboard/summary-section/paid-features/index.js

View check run for this annotation

Codecov / codecov/patch

js/src/dashboard/summary-section/paid-features/index.js#L57

Added line #L57 was not covered by tests
<Icon size="18" />
<FlexBlock>{ content }</FlexBlock>
</Flex>
) ) }
</div>
);
}

/**
* Returns a Card with the given content.
*
* @return {Card} Card with title and content.
eason9487 marked this conversation as resolved.
Show resolved Hide resolved
*/
const PaidFeatures = () => {
return (

Check warning on line 72 in js/src/dashboard/summary-section/paid-features/index.js

View check run for this annotation

Codecov / codecov/patch

js/src/dashboard/summary-section/paid-features/index.js#L72

Added line #L72 was not covered by tests
<VerticalGapLayout size="medium" className="gla-paid-features-section">
<Flex
align="center"
gap={ 9 }
className="gla-paid-features-section__content"
>
<FlexItem>
<CampaignPreview />
</FlexItem>
<FlexBlock>
<FeatureList />
</FlexBlock>
</Flex>
<FreeAdCredit />
joemcgill marked this conversation as resolved.
Show resolved Hide resolved
<AddPaidCampaignButton
isPrimary
isSecondary={ false }
isSmall={ false }
eventProps={ {
context: 'add-paid-campaign-promotion',
} }
>
{ __( 'Create Campaign', 'google-listings-and-ads' ) }
</AddPaidCampaignButton>
</VerticalGapLayout>
);
};

export default PaidFeatures;
30 changes: 30 additions & 0 deletions js/src/dashboard/summary-section/paid-features/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.gla-paid-features-section {
@media (max-width: $break-small) {
&__content {
flex-direction: column;
gap: $grid-unit-20;
}
}

&__feature-list {
display: flex;
flex-direction: column;
gap: $grid-unit-20;
margin: $grid-unit-30 0 $grid-unit-20;
eason9487 marked this conversation as resolved.
Show resolved Hide resolved
line-height: $gla-line-height-smaller;
color: $gray-800;
text-align: left;

.gridicon {
fill: #5ec862;
}
}

.gla-free-ad-credit {
text-align: left;
}

.components-button {
align-self: flex-end;
}
}
4 changes: 1 addition & 3 deletions js/src/setup-ads/ads-stepper/setup-accounts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import FreeAdCredit from '.~/components/free-ad-credit';
import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount';
import useGoogleAdsAccountStatus from '.~/hooks/useGoogleAdsAccountStatus';
import useGoogleAccount from '.~/hooks/useGoogleAccount';
import useFreeAdCredit from '.~/hooks/useFreeAdCredit';
import AppSpinner from '.~/components/app-spinner';
import Section from '.~/wcdl/section';

Expand All @@ -27,7 +26,6 @@ const SetupAccounts = ( props ) => {
const { google } = useGoogleAccount();
const { googleAdsAccount, hasGoogleAdsConnection } = useGoogleAdsAccount();
const { hasAccess, step } = useGoogleAdsAccountStatus();
const hasFreeAdCredit = useFreeAdCredit();

if ( ! google || ( google.active === 'yes' && ! googleAdsAccount ) ) {
return <AppSpinner />;
Expand Down Expand Up @@ -72,7 +70,7 @@ const SetupAccounts = ( props ) => {
) }
/>
<GoogleAdsAccountCard />
{ hasFreeAdCredit && <FreeAdCredit /> }
<FreeAdCredit />
</VerticalGapLayout>
</Section>
<StepContentFooter>
Expand Down
31 changes: 26 additions & 5 deletions tests/e2e/specs/add-paid-campaigns/add-paid-campaigns.test.js
eason9487 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,37 @@ test.describe( 'Set up Ads account', () => {
} );

test( 'Dashboard page contains Add Paid campaign buttons', async () => {
//Add page campaign in the Performance (Paid Campaigns) section
await expect(
dashboardPage.getAdsConnectionAllProgramsButton( 'summary-card' )
).toBeEnabled();

//Add page campaign in the programs section.
adsConnectionButton = dashboardPage.getAdsConnectionAllProgramsButton();
await expect( adsConnectionButton ).toBeEnabled();
} );

test( 'Dashboard page contains Paid Features section with feature list and Create Campaign button', async () => {
await expect(
page.getByText(
'Reach more customer by advertising your products across Google Ads channels like Search, YouTube and Discover.'
)
).toBeVisible();

await expect(
page.getByText(
'New to Google Ads? Get $500 in ad credit when you spend $500 within your first 60 days.'
)
).toBeVisible();

await expect( dashboardPage.getCreateCampaignButton() ).toBeEnabled();
await dashboardPage.getCreateCampaignButton().click();
await page.waitForLoadState( LOAD_STATE.DOM_CONTENT_LOADED );
await expect(
page.getByRole( 'heading', {
name: 'Set up your accounts',
} )
).toBeVisible();

await dashboardPage.goto();
await page.waitForLoadState( LOAD_STATE.DOM_CONTENT_LOADED );
} );

test.describe( 'Set up your accounts page', async () => {
test.beforeAll( async () => {
await setupAdsAccounts.mockAdsAccountsResponse( [] );
Expand Down
40 changes: 16 additions & 24 deletions tests/e2e/specs/setup-mc/step-4-complete-campaign.test.js
eason9487 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { test, expect } = require( '@playwright/test' );
import SetupBudgetPage from '../../utils/pages/setup-ads/setup-budget';
import CompleteCampaign from '../../utils/pages/setup-mc/step-4-complete-campaign';
import SetupAdsAccountPage from '../../utils/pages/setup-ads/setup-ads-accounts';
import DashboardPage from '../../utils/pages/dashboard';
import {
checkFAQExpandable,
getFAQPanelTitle,
Expand All @@ -35,6 +36,11 @@ let completeCampaign = null;
*/
let setupAdsAccountPage = null;

/**
* @type {import('../../utils/pages/dashboard.js').default} dashboardPage
*/
let dashboardPage = null;

/**
* @type {import('@playwright/test').Page} page
*/
Expand All @@ -44,6 +50,7 @@ test.describe( 'Complete your campaign', () => {
test.beforeAll( async ( { browser } ) => {
page = await browser.newPage();
setupBudgetPage = new SetupBudgetPage( page );
dashboardPage = new DashboardPage( page );
completeCampaign = new CompleteCampaign( page );
setupAdsAccountPage = new SetupAdsAccountPage( page );
await Promise.all( [
Expand Down Expand Up @@ -321,16 +328,16 @@ test.describe( 'Complete your campaign', () => {
test( 'should see buttons on Dashboard for Google Ads onboarding', async () => {
await page.keyboard.press( 'Escape' );
await page.getByRole( 'tab', { name: 'Dashboard' } ).click();
const addPaidCampaignButton =
await dashboardPage.getAdsConnectionAllProgramsButton();

const buttons = page.getByRole( 'button', {
name: 'Add paid campaign',
} );
await expect( addPaidCampaignButton ).toBeVisible();
await expect( addPaidCampaignButton ).toBeEnabled();

await expect( buttons ).toHaveCount( 2 );
for ( const button of await buttons.all() ) {
await expect( button ).toBeVisible();
await expect( button ).toBeEnabled();
}
const createCampaignButton =
await dashboardPage.getCreateCampaignButton();
await expect( createCampaignButton ).toBeVisible();
await expect( createCampaignButton ).toBeEnabled();
} );
} );

Expand Down Expand Up @@ -360,7 +367,7 @@ test.describe( 'Complete your campaign', () => {
} );

test.describe( 'Free Ad Credit', () => {
test( 'should not see the Free Ad Credit section if the account is not eligible', async () => {
test( 'should see the Free Ad Credit section always', async () => {
await setupAdsAccountPage.mockAdsAccountConnected();
await completeCampaign.goto();
await setupAdsAccountPage.awaitAdsConnectionResponse();
Expand All @@ -370,21 +377,6 @@ test.describe( 'Complete your campaign', () => {
page.getByText( 'Create a campaign to advertise your products' )
).toBeVisible();

await expect(
page.getByText(
'Spend $500 to get $500 in Google Ads credits!'
)
).not.toBeVisible();
} );

test( 'should see the Free Ad Credit section if the account is eligible', async () => {
await setupAdsAccountPage.mockAdsAccountConnected( 12345, {
sub_account: true,
created_timestamp: Math.floor( Date.now() / 1000 ),
} );
await completeCampaign.goto();
await setupAdsAccountPage.awaitAdsConnectionResponse();

await expect(
page.getByText(
'Spend $500 to get $500 in Google Ads credits!'
Expand Down
Loading
Loading