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

Remove the billing setup page from the Ads setup flow #2577

Open
wants to merge 35 commits into
base: feature/2459-campaign-creation-flow
Choose a base branch
from

Conversation

kt-12
Copy link
Collaborator

@kt-12 kt-12 commented Sep 4, 2024

Changes proposed in this Pull Request:

Closes #2536 .

Billing setup page should be removed and also Launch Paid Campaign should be possible from second step.

Screenshots:

Detailed test instructions:

  1. delete any residual DELETE FROM `wp_options` WHERE `option_name` = 'gla_ads_setup_completed_at';
  2. Click on Add paid campaign
    Screenshot 2024-09-04 at 17 55 11
  3. Click on continue on Set up your accounts page
    Screenshot 2024-09-04 at 17 55 23
  4. You should be able to see disabled Launch Paid Campaign button which enables on adding Daily Average Cost
    Screenshot 2024-09-04 at 17-56-39 Setup Google Ads ‹ Google for WooCommerce ‹ Marketing ‹ WooCommerce ‹ google-woo — WooCommerce

Additional details:

Changelog entry

Update - Remove the billing setup step from the paid campaign setup flow.

@kt-12 kt-12 marked this pull request as draft September 4, 2024 12:34
@kt-12 kt-12 changed the base branch from develop to feature/2460-simplify-paid-ads-setup September 4, 2024 12:39
@kt-12 kt-12 marked this pull request as ready for review September 4, 2024 17:06
@kt-12
Copy link
Collaborator Author

kt-12 commented Sep 4, 2024

@joemcgill Based on your comment on issue, I have not modified Jest tests here.

Copy link
Collaborator

@asvinb asvinb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kt-12 Thanks for the PR! Works well. I suggested a couple of improvements though. Can you kindly let me know what you think?
Also, let's update the tracking comments here:

* @fires gla_setup_ads with `{ triggered_by: 'step1-continue-button' | 'step2-continue-button' , action: 'go-to-step2' | 'go-to-step3' }`.
* @fires gla_setup_ads with `{ triggered_by: 'stepper-step1-button' | 'stepper-step2-button', action: 'go-to-step1' | 'go-to-step2' }`.

It should be:

 * @fires gla_setup_ads with `{ triggered_by: 'step1-continue-button', action: 'go-to-step2' }`.
 * @fires gla_setup_ads with `{ triggered_by: 'stepper-step1-button', action: 'go-to-step1'}`.

js/src/components/paid-ads/ads-campaign.js Outdated Show resolved Hide resolved
js/src/setup-ads/ads-stepper/index.js Outdated Show resolved Hide resolved
Comment on lines 92 to 95
submitButtonText={ __(
'Launch paid campaign',
'google-listings-and-ads'
) }
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AdsCampaign component is used in 2 flow. One setting up our first paid campaign flow (here). And another for the setting up other paid campaing.

Next is once the first campaign set up you see a button in the right hand side of dashboard- Add paid campaign ,
Screenshot 2024-09-06 at 18 01 35

once you click that you see a different flow where AdsCampaign is the first component in the flow.

Screenshot 2024-09-06 at 18-05-51 Dashboard ‹ Google for WooCommerce ‹ Marketing ‹ WooCommerce ‹ google-woo — WooCommerce

submitButtonText was introduced to make change to button text in a way it doesn't effect the other flow.

@joemcgill

Copy link
Collaborator

@asvinb asvinb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kt-12 Can you kindly check my comment about the default value for the submitButtonText parameter please?

js/src/components/paid-ads/ads-campaign.js Outdated Show resolved Hide resolved
@kt-12
Copy link
Collaborator Author

kt-12 commented Sep 11, 2024

@kt-12 Can you kindly check my comment about the default value for the submitButtonText parameter please?

Done. I have addressed other open review comments too.

Copy link
Collaborator

@asvinb asvinb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kt-12 I left some more comments. Can you check them out please?
Also why we have this error message for the PR?
Check failure on line 90 in js/src/setup-ads/ads-stepper/index.test.js

js/src/components/paid-ads/ads-campaign.js Outdated Show resolved Hide resolved
js/src/setup-ads/ads-stepper/index.js Show resolved Hide resolved
@asvinb
Copy link
Collaborator

asvinb commented Sep 13, 2024

@kt-12 Can you please fix the linting and unit tests errors please?

@kt-12
Copy link
Collaborator Author

kt-12 commented Sep 13, 2024

@kt-12 Can you please fix the linting and unit tests errors please.

Unit test changes are not handled in this ticket. It is handled in a separate ticket 2579, which merges 2534, 2536 and 2535

@asvinb
Copy link
Collaborator

asvinb commented Sep 23, 2024

@eason9487 This is ready for review please.
Thanks!

@eason9487
Copy link
Member

eason9487 commented Sep 24, 2024

Hi @kt-12 and @asvinb, I haven't looked into the code changes as the JS unit testing and e2e testing didn't pass.

Could you help with ensuring a PR passes all testing before passing its ticket to Woo CR stage?

@kt-12
Copy link
Collaborator Author

kt-12 commented Sep 24, 2024

Hi @eason9487, Test changes were not done in this ticket as it will be handled in #2579, where we have changes from #2534, #2535, #2536 is merged (see first AC #2536 ).

@eason9487
Copy link
Member

Hi @kt-12

Test changes were not done in this ticket as it will be handled in #2579, where we have changes from #2534, #2535, #2536 is merged (see first AC #2536 ).

Not sure if I missed anything but they don't seem to include postponing the update to e2e testing

@kt-12
Copy link
Collaborator Author

kt-12 commented Sep 26, 2024

@joemcgill @asvinb I have updated e2e to support new flow. E2E is currently failing at form submit. While most of the flow worked fine clicking on Launch Paid Campaign is working differently in e2e than when tested manually.

Few observation:

  • Click of button gives an alert 'You have unsaved campaign data. Are you sure you want to leave?', which related to incomplete form.
  • URL on the button click is a bit different than the one we do manually.
  • I am also getting following error in API call made
{
    "message": "Please reconnect your Jetpack account.",
    "status": 401,
    "code": "JETPACK_DISCONNECTED"
}

I tried recconecting to jetpack again just before the click of button but it filed too.

Curl extracted from E2E :-

curl 'http://localhost:8889/wp-json/wc/gla/ads/campaigns?_locale=user' \
  -H 'Accept: application/json, */*;q=0.1' \
  -H 'Accept-Language: en-US' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Content-Type: application/json' \
  -H 'Cookie: wordpress_test_cookie=WP%20Cookie%20check; wordpress_logged_in_23778236db82f19306f247e20a353a99=admin%7C1727504916%7CbP9l9wZZLAEhjXSgSnYIKLoqAFkUkIChMNtDV3Qxaw9%7Cb8843a1de830928d1d4215d5c310740c13de29e72c8e30e81285da9d6d5ad988; tk_ai=woo%3AxSUpIUAfZ0IfZUDBI8ZCAVpW; wp-settings-time-1=1727332131' \
  -H 'Origin: http://localhost:8889' \
  -H 'Pragma: no-cache' \
  -H 'Referer: http://localhost:8889/wp-admin/admin.php?page=wc-admin&path=%2Fgoogle%2Fsetup-ads' \
  -H 'Sec-Fetch-Dest: empty' \
  -H 'Sec-Fetch-Mode: cors' \
  -H 'Sec-Fetch-Site: same-origin' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.4 Safari/537.36' \
  -H 'X-WP-Nonce: 431d70c3b8' \
  -H 'sec-ch-ua: "Chromium";v="123", "Not:A-Brand";v="8"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'sec-ch-ua-platform: "Windows"' \
  --data-raw '{"amount":1,"targeted_locations":["US"],"label":"wc-web"}'

@kt-12
Copy link
Collaborator Author

kt-12 commented Sep 27, 2024

Hi @kt-12

Test changes were not done in this ticket as it will be handled in #2579, where we have changes from #2534, #2535, #2536 is merged (see first AC #2536 ).

Not sure if I missed anything but they don't seem to include postponing the update to e2e testing

Hi @eason9487,

Sorry for the initial confusion. I have fixed e2e for this task and it did run without any failure (run). Jest changes will still be handled separately as we see some overlap within other sister tasks. I feel this is good for WooTeam review now, adding this back to Woo CR. Thanks.

Copy link
Member

@eason9487 eason9487 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the work. The main concern is whether there is a better way to composite the continue button for the AdsCampaign component rather than passing 5 props.

Comment on lines 111 to 120
disabled={
! isValidForm ||
( trackingContext === 'setup-ads' &&
billingStatus?.status !==
GOOGLE_ADS_BILLING_STATUS.APPROVED )
}
loading={ isLoading }
onClick={ onContinue }
>
{ __( 'Continue', 'google-listings-and-ads' ) }
{ submitButtonText }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering this button now requires 5 props to render and its only internal dependency is on one of those conditions, its degree of customization makes it unsuitable to be part of this component. It's better to externalize it as a single prop such as continueButton to composite this component.

<StepContentFooter>
	{ continueButton }
</StepContentFooter>

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eason9487 I believe this continue button is only temporarily going to need to handle this many conditions until #2535 is completed, to ensure that the current flow could still be tested properly. I'd like to avoid making any additional modifications to the AdsCampaign component in this PR, which is really only meant to remove the billing step because it will be handled during step 3 once we've consolidated the form from the onboarding flow.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let continueButtonProps = {
text: __( 'Continue', 'google-listings-and-ads' ),
};
if ( isOnboardingFlow ) {
continueButtonProps = {
'data-action': ACTION_COMPLETE,
text: __( 'Complete setup', 'google-listings-and-ads' ),
eventName: 'gla_onboarding_complete_with_paid_ads_button_click',
eventProps: {
budget: paidAds.amount,
audiences: countryCodes?.join( ',' ),
},
};
}

<AppButton
isPrimary
disabled={ disabledComplete }
onClick={ handleCompleteClick }
loading={ completing === ACTION_COMPLETE }
{ ...continueButtonProps }
/>

From the current revision of AdsCampaign in #2623, I couldn't figure out how this button only temporarily needs to handle 5 props, because both PRs currently increase the complexity and conditional branching of this button to varying degrees.

All of these changes convinced me that both PRs should try to see if it's possible to move this button out of the AdsCampaign component sooner rather than having to resolve more code conflicts and re-test all button scenarios when merging them with each other.

tests/e2e/utils/pages/setup-ads/setup-budget.js Outdated Show resolved Hide resolved
Comment on lines 396 to 398
await setupBudgetPage.mockCampaignCreation( budget, {} );

await expect(
page.getByText(
'Great! You already have billing information saved for this'
)
).toBeVisible();
await setupBudgetPage.getLaunchPaidCampaignButton().click();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonder why the test was changed to not wait for the campaign creation request? (setupBudgetPage.mockCampaignCreationAndAdsSetupCompletion)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setupBudgetPage.mockCampaignCreationAndAdsSetupCompletion was waiting indefinitely. We only needed the campaign to created to get the button clickable, hence the split.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see waiting indefinitely if it's used similarly to

const campaignCreation =
setupBudgetPage.mockCampaignCreationAndAdsSetupCompletion(
'1',
[ 'US' ]
);
await page
.getByRole( 'button', { name: 'Launch paid campaign' } )
.click();
await campaignCreation;

Without that check, the "It should show the campaign creation success message" test case can still pass after skipping the campaign creation by replacing the following line with return Promise.resolve():

return createAdsCampaign( amount, countryCodes )

This makes it not fulfill the purpose of the test case it describes.

@eason9487 eason9487 added the changelog: update Big changes to something that wasn't broken. label Sep 30, 2024
@joemcgill joemcgill deleted the branch feature/2459-campaign-creation-flow September 30, 2024 19:27
@joemcgill joemcgill closed this Sep 30, 2024
@joemcgill joemcgill reopened this Sep 30, 2024
@joemcgill joemcgill changed the base branch from feature/2460-simplify-paid-ads-setup to feature/2459-campaign-creation-flow September 30, 2024 20:08
@joemcgill
Copy link
Collaborator

I'm updating this PR to point to the new consolidated feature branch feature/2459-campaign-creation-flow. We'll need to resolve the merge conflicts and then send it back for review.

@joemcgill
Copy link
Collaborator

@eason9487 besides the changes requested for the continue button, I think this is ready for another look.

Comment on lines 90 to 118
/**
* Extract budget recommendation value.
*
* @param {string} text
*
* @return {string} The budget recommendation value.
*/
extractBudgetRecommendationValue( text ) {
const match = text.match( /set a daily budget of (\d+)/ );
if ( match ) {
return match[ 1 ];
}
return '';
}

/**
* Register the responses when removing an ads audience.
*
* @return {Promise<import('@playwright/test').Response>} The response.
*/
registerBudgetRecommendationResponse() {
return this.page.waitForResponse(
( response ) =>
response
.url()
.includes( '/gla/ads/campaigns/budget-recommendation' ) &&
response.status() === 200
);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like these two methods that had been removed from #2551 were added back when resolving code conflicts.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Comment on lines 396 to 398
await setupBudgetPage.mockCampaignCreation( budget, {} );

await expect(
page.getByText(
'Great! You already have billing information saved for this'
)
).toBeVisible();
await setupBudgetPage.getLaunchPaidCampaignButton().click();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see waiting indefinitely if it's used similarly to

const campaignCreation =
setupBudgetPage.mockCampaignCreationAndAdsSetupCompletion(
'1',
[ 'US' ]
);
await page
.getByRole( 'button', { name: 'Launch paid campaign' } )
.click();
await campaignCreation;

Without that check, the "It should show the campaign creation success message" test case can still pass after skipping the campaign creation by replacing the following line with return Promise.resolve():

return createAdsCampaign( amount, countryCodes )

This makes it not fulfill the purpose of the test case it describes.

Comment on lines 194 to 200
* Mock the campaign creation process.
*
* @param {string} budget The campaign budget.
* @param {string} budget The campaign budget.
* @param {Array} targetLocations The targeted locations.
* @return {Promise<void>}
*/
async mockCampaignCreationAndAdsSetupCompletion( budget, targetLocations ) {
async mockCampaignCreation( budget, targetLocations ) {
Copy link
Member

@eason9487 eason9487 Oct 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Referring to #2577 (comment), although I don't think this method needs to be extracted, the name of this method doesn't match its implementation because it still includes the mocking of Ads setup completion.

await this.fulfillRequest(
/\/wc\/gla\/ads\/setup\/complete\b/,
null,
200,
[ 'POST' ]
);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the function. Test working with early function when await was moved to after the button click.

Comment on lines 111 to 120
disabled={
! isValidForm ||
( trackingContext === 'setup-ads' &&
billingStatus?.status !==
GOOGLE_ADS_BILLING_STATUS.APPROVED )
}
loading={ isLoading }
onClick={ onContinue }
>
{ __( 'Continue', 'google-listings-and-ads' ) }
{ submitButtonText }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let continueButtonProps = {
text: __( 'Continue', 'google-listings-and-ads' ),
};
if ( isOnboardingFlow ) {
continueButtonProps = {
'data-action': ACTION_COMPLETE,
text: __( 'Complete setup', 'google-listings-and-ads' ),
eventName: 'gla_onboarding_complete_with_paid_ads_button_click',
eventProps: {
budget: paidAds.amount,
audiences: countryCodes?.join( ',' ),
},
};
}

<AppButton
isPrimary
disabled={ disabledComplete }
onClick={ handleCompleteClick }
loading={ completing === ACTION_COMPLETE }
{ ...continueButtonProps }
/>

From the current revision of AdsCampaign in #2623, I couldn't figure out how this button only temporarily needs to handle 5 props, because both PRs currently increase the complexity and conditional branching of this button to varying degrees.

All of these changes convinced me that both PRs should try to see if it's possible to move this button out of the AdsCampaign component sooner rather than having to resolve more code conflicts and re-test all button scenarios when merging them with each other.

@kt-12
Copy link
Collaborator Author

kt-12 commented Oct 2, 2024

@eason9487 #2577 (comment)

Thank you, you were correct. awating after button is clicked did solve waiting indefinitely issue. I have also removed the newly introduced function.

@kt-12
Copy link
Collaborator Author

kt-12 commented Oct 2, 2024

@eason9487 we have addressed your review comments and also moved continue button out of AdsCampaign. Moving it back to you for CR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog: update Big changes to something that wasn't broken.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Remove the billing setup page from the Ads setup flow
5 participants