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

Checkout: Remove CartStore from checkout #50681

Merged
merged 7 commits into from
Mar 12, 2021

Conversation

sirbrillig
Copy link
Member

@sirbrillig sirbrillig commented Mar 3, 2021

Changes proposed in this Pull Request

As a final piece to remove the deprecated CartStore (see #24019) we need to remove the CartData wrapper around CheckoutSystemDecider. That wrapper was added to guard against race conditions where other parts of calypso might be using the CartStore to modify the cart and the new checkout (specifically the CalypsoShoppingCartProvider) needed to wait until those transactions completed before initializing. Since no other parts of calypso still use CartStore to modify the cart, this race condition guard can be removed.

However, after the guard was put in place, it was also used in #44206 as a mechanism to inject cart items from localStorage as the initial cart. This was done so that siteless and registrationless signup could prepare items to be added to the cart before the shopping-cart endpoint would allow adding those items. The way this works (if I understand it correctly) is that signup writes the temporary items to localStorage and those items are then read by the CartStore into its internal cache which it then posts to the shopping-cart endpoint (every 20 seconds, endlessly, I believe). CheckoutSystemDecider then replaces the CalypsoShoppingCartProvider fetcher with a hard-coded Promise that resolves to the updated card from the CartStore, so that when checkout goes to pull in the initial copy of the cart, it receives the products written by signup instead.

This strategy has a problem as we try to migrate it away from using CartStore. The cart items written to localStorage (and indeed the rest of the cart) are missing many required properties set by the shopping-cart endpoint (they do not match the ResponseCartProduct type), and therefore cannot be safely used in checkout without a round-trip to the endpoint first. Since this PR removes CartData from checkout, that round-trip no longer occurs anywhere.

However, we have a mechanism already that handles this sort of situation when checkout loads, usePrepareProductsForCart, which currently takes products from the URL and adds them to the cart. To that end, I think it makes more sense to read them from localStorage directly inside this hook. This PR does just that.

Testing instructions

To test the no-user flow:

  • Start logged-out of WordPress.com
  • Visit /start/onboarding-registrationless/domains
  • Enter text to search for a domain name and click to select one from the results.
  • You should see a plans page. Click to select a plan.
  • Verify that you are redirected to checkout and that both the plan and domain you chose are in the cart.

I'm not sure how to test the no-site flow. Ping @Automattic/martech for help there.

@matticbot
Copy link
Contributor

@sirbrillig sirbrillig self-assigned this Mar 3, 2021
@sirbrillig sirbrillig added the [Feature] Checkout The checkout screen and process for purchases made on WordPress.com. label Mar 3, 2021
@matticbot
Copy link
Contributor

matticbot commented Mar 3, 2021

Here is how your PR affects size of JS and CSS bundles shipped to the user's browser:

App Entrypoints (~58 bytes removed 📉 [gzipped])

name                   parsed_size           gzip_size
entry-main                  -105 B  (-0.0%)      -21 B  (-0.0%)
entry-login                 -105 B  (-0.0%)      -19 B  (-0.0%)
entry-gutenboarding         -105 B  (-0.0%)      -16 B  (-0.0%)
entry-domains-landing       -105 B  (-0.0%)      -23 B  (-0.0%)

Common code that is always downloaded and parsed every time the app is loaded, no matter which route is used.

Sections (~468 bytes removed 📉 [gzipped])

name      parsed_size           gzip_size
checkout      -1716 B  (-0.1%)     -331 B  (-0.1%)
domains        -779 B  (-0.1%)      -54 B  (-0.0%)
signup         -524 B  (-0.2%)     -163 B  (-0.2%)
plans          -442 B  (-0.1%)      +53 B  (+0.0%)
email          -442 B  (-0.1%)      +27 B  (+0.0%)

Sections contain code specific for a given set of routes. Is downloaded and parsed only when a particular route is navigated to.

Async-loaded Components (~264 bytes added 📈 [gzipped])

name                                             parsed_size           gzip_size
async-load-calypso-blocks-editor-checkout-modal       +597 B  (+0.1%)     +264 B  (+0.1%)
async-load-signup-steps-domains                       -442 B  (-0.2%)      +27 B  (+0.0%)
async-load-calypso-my-sites-sidebar-unified           -442 B  (-0.3%)      +27 B  (+0.1%)
async-load-calypso-my-sites-sidebar                   -442 B  (-0.2%)      +27 B  (+0.0%)
async-load-calypso-components-jetpack-sidebar         -442 B  (-0.4%)      +27 B  (+0.1%)

React components that are loaded lazily, when a certain part of UI is displayed for the first time.

Legend

What is parsed and gzip size?

Parsed Size: Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory.
Gzip Size: Compressed size of the JS and CSS files. This much data needs to be downloaded over network.

Generated by performance advisor bot at iscalypsofastyet.com.

@sirbrillig sirbrillig mentioned this pull request Mar 3, 2021
@sirbrillig
Copy link
Member Author

@Automattic/martech-decepticons and @southp I could really use your assistance with this PR. I don't know enough about how siteless and registrationless checkout works to be able to test or debug these changes.

@sirbrillig sirbrillig marked this pull request as ready for review March 3, 2021 21:53
@sirbrillig sirbrillig requested a review from a team as a code owner March 3, 2021 21:53
@matticbot matticbot added the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Mar 3, 2021
@sirbrillig sirbrillig requested review from a team and southp and removed request for a team March 3, 2021 22:36
Copy link
Member

@michaeldcain michaeldcain left a comment

Choose a reason for hiding this comment

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

Code-wise, this looks great.

I tested the /no-user/ flow using the instructions provided, purchasing both a domain and plan, and then repeated purchasing a plan and a post-Checkout concierge session. Everything worked as expected.

Screen Shot 2021-03-11 at 1 18 54 PM

I then tested the /no-site/ variant by visiting /start/domain and selecting "just a domain" in the second step. Everything worked as expected.

Screen Shot 2021-03-11 at 1 15 59 PM

If there are no objections from @niranjan-uma-shankar, I'd say that we're good to merge this.

@michaeldcain michaeldcain added [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. and removed [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Mar 11, 2021
@sirbrillig sirbrillig merged commit 7b55642 into trunk Mar 12, 2021
@sirbrillig sirbrillig deleted the remove/cart-data-from-checkout branch March 12, 2021 15:38
@matticbot matticbot removed the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Mar 12, 2021
@a8ci18n
Copy link

a8ci18n commented Mar 12, 2021

This Pull Request is now available for translation here: https://translate.wordpress.com/deliverables/5577880

Hi @sirbrillig, could you please edit the description of this PR and add a screenshot for our translators? Ideally it'd include this string: I tried and failed to create products from signup

Thank you in advance!

@niranjan-uma-shankar
Copy link
Contributor

To test the no-user flow:

The testing instructions worked. Here are a few more scenarios I tried:

Scenario 1 - Log in to an account with no site

  1. Go to wordpress.com/start, signup for a new account, and exit at the domain step. At this point, a user account with no site is created.
  2. Go to /start/onboarding-registrationless, select a paid plan, and proceed to the checkout page
  3. In the email field, enter the email of the account you created in step 1 and press continue.
  4. You will be asked to log in to this account, follow the link and log in to this account.
  5. You should be taken to the logged in checkout for this account, and you should be able to complete the purchase

❌ Scenario 2 - Log in to an account with a single site

  1. Go to wordpress.com/start and create a site on the free plan.
  2. Go to /start/onboarding-registrationless, select a paid plan, and proceed to the checkout page
  3. In the email field, enter the email of the account you created in step 1 and press continue.
  4. You will be asked to log in to this account, follow the link and log in to this account.
  5. You should be taken to the logged in checkout for this account, however the checkout page says that the cart is empty.

❌ Scenario 3 - Reload on the logged out checkout page

  1. Go to /start/onboarding-registrationless, select a paid plan, and proceed to the checkout page
  2. Reload the checkout page.
  3. The checkout page should load with the cart intact, however it redirects to the log in page.

@sirbrillig
Copy link
Member Author

Thank you! I followed the testing instructions for both of the failing cases above with a commit before this was merged (2c01dc5142), and the behavior is the same as you describe here, so I don't think those are regressions caused by this PR. If those are flows that should work, we should create issues for each one and determine when they became broken. Can this be a task for your team, @niranjan-uma-shankar, since I don't know how this functionality was supposed to work in the first place?

Alternatively, if you could describe how the underlying functionality worked, I can try to debug it myself, but there's a lot I don't understand right now.

@niranjan-uma-shankar
Copy link
Contributor

I followed the testing instructions for both of the failing cases above with a commit before this was merged (2c01dc5), and the behavior is the same as you describe here, so I don't think those are regressions caused by this PR

Ah okay, if that's the case, then we can ignore it.

Can this be a task for your team, @niranjan-uma-shankar, since I don't know how this functionality was supposed to work in the first place?
Alternatively, if you could describe how the underlying functionality worked, I can try to debug it myself, but there's a lot I don't understand right now.

Appreciate your offer to debug it, but I agree with your first statement that it should be a task for MarTech, so please don't bother 😄 . There's a lot that has changed in the checkout code and other places since the time registrationless checkout was first implemented, so it's not surprising that it breaks for some cases. I'll debug it as part of our upcoming efforts to re-launch registrationless checkout(discussed in pau2Xa-2JW-p2).

@a8ci18n
Copy link

a8ci18n commented Mar 18, 2021

Translation for this Pull Request has now been finished.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Estimate] 3 [Feature] Checkout The checkout screen and process for purchases made on WordPress.com.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants