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

Add E2E test to test checkout performance #4344

Merged
merged 29 commits into from
Jul 13, 2022

Conversation

harriswong
Copy link
Contributor

@harriswong harriswong commented Jun 10, 2022

Changes proposed in this Pull Request

We would like to create an E2E test to measure metrics such as first paint, first contentful paint, etc. The test will run 3 times to take an average. It measures 3 things on the /checkout page:

  • Stripe element checkout
  • UPE checkout
  • WooPay checkout

The PR uses a similar technique as woocommerce-blocks https://github.com/woocommerce/woocommerce-blocks/blob/trunk/tests/utils/performance.ts.

Testing instructions

  1. Follow E2E instructions here(https://github.com/Automattic/woocommerce-payments/tree/develop/tests/e2e) to setup.
  2. Make sure your tests/e2e/deps/wcp-dev-tools folder is up-to-date. You can do git pull to make sure it is the latest.
  3. Run npm run test:e2e-performance
  4. You should see the test passed and a new file is created under tests/e2e/reports/checkout-performance.txt. Each line of the file is a JSON record of a performance metric. It should look something like this:
{"description":"Stripe element: Average","serverResponse":3693.6966666641333,"firstPaint":76.56499991814296,"domContentLoaded":89.84833319361012,"loaded":372.0683332843085,"firstContentfulPaint":76.56499991814296,"firstBlock":2955.526666715741}
{"description":"Stripe UPE: Average","serverResponse":4223.398333260168,"firstPaint":90.24666668847203,"domContentLoaded":123.69833327829838,"loaded":465.96499998122454,"firstContentfulPaint":90.24666668847203,"firstBlock":3817.1183334973953}
{"description":"WooPay: Average","serverResponse":4126.750000131627,"firstPaint":77.12333323433995,"domContentLoaded":95.77999993537863,"loaded":338.5383333079517,"firstContentfulPaint":77.12333323433995,"firstBlock":3170.6916666589677}

  • Run npm run changelog to add a changelog file, choose patch to leave it empty if the change is not significant. You can add multiple changelog files in one PR by running this command a few times.
  • Covered with tests (or have a good reason not to test in description ☝️)
  • Tested on mobile (or does not apply)

Post merge

@@ -0,0 +1,37 @@
export async function getLoadingDurations() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Similar to the function from woocommerce-blocks https://github.com/woocommerce/woocommerce-blocks/blob/trunk/tests/utils/performance.ts. The differences are that I can't destruct the performance.getEntriesByType(..) assignment or use array prototype.find. I get the following errors:
ReferenceError: _slicedToArray2
ReferenceError: _find

It could be a puppeteer problem since these are used within page.evaulate(). Our puppeteer version is 2 and it relies on puppeteer-utils. Blocks uses jest-environment-puppeteer where its puppeteer is at 14. It doesn't seem to have these issues. I think it would be good to upgrade it to the newer puppeteer version.

In any case, I worked around the ReferenceError and this function works in this branch.

@harriswong harriswong changed the title POC: Add performance metrics WIP: Add performance metrics Jun 16, 2022
@harriswong harriswong changed the title WIP: Add performance metrics Add E2E test to test checkout performance Jun 22, 2022
@harriswong harriswong added category: e2e Issues and PRs related to e2e tests. category: performance The issue/PR is related to performance. labels Jun 22, 2022
@harriswong harriswong marked this pull request as ready for review June 22, 2022 21:51
@harriswong harriswong requested review from htdat and achyuthajoy June 22, 2022 21:55
@harriswong harriswong requested a review from brettshumaker June 22, 2022 21:55
@harriswong harriswong self-assigned this Jun 22, 2022
@harriswong
Copy link
Contributor Author

👋 @achyuthajoy @htdat I am adding an E2E test to measure /checkout performance. I want to check in with you both since you have reviewed some of the E2E PRs. Please let me know if I should ping someone else. Thanks for your time!

@achyuthajoy
Copy link
Contributor

Hey @harriswong I'll take a look at the PR today :).

Just had a couple of questions though.

  • Is there a specific reason why the results are stored as a file instead of outputting to the terminal?
  • Is there plans to run these tests periodically via Github actions? If yes, then storing results in file might not be ideal.

It could be a puppeteer problem since these are used within page.evaulate(). Our puppeteer version is 2 and it relies on puppeteer-utils. Blocks uses jest-environment-puppeteer where its puppeteer is at 14. It doesn't seem to have these issues. I think it would be good to upgrade it to the newer puppeteer version.

We can look into upgrading puppeteer to higher version. We're also looking into upgrading the node version so wp-scripts and e2e dependencies should be a part of it.

@harriswong
Copy link
Contributor Author

Is there a specific reason why the results are stored as a file instead of outputting to the terminal?

No. There isn't any specific reason to store it in a file. As long as we can get the metrics in our local dev/CI, then that should be enough for our needs. I saw woocommerce-blocks' PR (woocommerce/woocommerce-blocks#6119) which they stored in a file for output. I thought that was a pretty good idea and so I took that direction as well.

Is there plans to run these tests periodically via Github actions? If yes, then storing results in file might not be ideal.

I think it will be good to run this in Github Actions in the future, but maybe not for every PR. I was thinking it could be run manually from a trigger phrase in the comment, or per release candidate. In this case, would rendering output to the terminal be a better approach?

@harriswong
Copy link
Contributor Author

I saw woocommerce-blocks' PR (woocommerce/woocommerce-blocks#6119) which they stored in a file for output. I thought that was a pretty good idea and so I took that direction as well.

GitHub actions deletes artifacts uploaded after a specific period. So if you wish to have historic data, then it's best to log it to the console, which will be preserver. Or you can send the data to another service to get it recorded.

Ok thanks! For now, I don't think we are running it in CI and we don't need the historic data. If this changes, I will pursue a different approach so that we can preserve the results. Let me know what you think.

@achyuthajoy
Copy link
Contributor

I reverted the commit that introduced the "test:e2e-performance": "NODE_CONFIG_DIR='tests/e2e/config' wp-scripts test-e2e --config tests/e2e/config/jest.performance.config.js", command. Running npm run test:e2e will run the tests/e2e/specs/performance/payment-methods.spec.js though. Is it beneficial to use a technique similar to

export const RUN_SUBSCRIPTIONS_TESTS =
'1' !== process.env.SKIP_WC_SUBSCRIPTIONS_TESTS;
export const RUN_ACTION_SCHEDULER_TESTS =
'1' !== process.env.SKIP_WC_ACTION_SCHEDULER_TESTS;
export const RUN_WC_BLOCKS_TESTS = '1' !== process.env.SKIP_WC_BLOCKS_TESTS;

so that local dev can skip the performance tests?

updates I added a commit(b4ca77c) to introduce the SKIP_WC_PERFORMANCE_TESTS env variable. Let me know if this is undesired, I can revert the commit.

@harriswong It would be much cleaner if we keep a separate jest config for performance tests. That way, you don't need to exclude the test using environment variables and keep the NPM script to run just the performance test.

What are your thoughts?

@achyuthajoy
Copy link
Contributor

I saw woocommerce-blocks' PR (woocommerce/woocommerce-blocks#6119) which they stored in a file for output. I thought that was a pretty good idea and so I took that direction as well.

GitHub actions deletes artifacts uploaded after a specific period. So if you wish to have historic data, then it's best to log it to the console, which will be preserver. Or you can send the data to another service to get it recorded.

Ok thanks! For now, I don't think we are running it in CI and we don't need the historic data. If this changes, I will pursue a different approach so that we can preserve the results. Let me know what you think.

Sure. If historic data is not needed, writing to file or outputting to terminal works. I also noticed that terminal logs are also removed after a while.

@harriswong Do you plan to set up a Github workflow for running performance tests periodically/with manual trigger? Or just keep this for local testing.

For more accurate results I would suggest setting up a GitHub actions workflow. It's because running locally on mac with docker can be very slow and might not be the original performance.

@harriswong
Copy link
Contributor Author

I reverted the commit that introduced the "test:e2e-performance": "NODE_CONFIG_DIR='tests/e2e/config' wp-scripts test-e2e --config tests/e2e/config/jest.performance.config.js", command. Running npm run test:e2e will run the tests/e2e/specs/performance/payment-methods.spec.js though. Is it beneficial to use a technique similar to

export const RUN_SUBSCRIPTIONS_TESTS =
'1' !== process.env.SKIP_WC_SUBSCRIPTIONS_TESTS;
export const RUN_ACTION_SCHEDULER_TESTS =
'1' !== process.env.SKIP_WC_ACTION_SCHEDULER_TESTS;
export const RUN_WC_BLOCKS_TESTS = '1' !== process.env.SKIP_WC_BLOCKS_TESTS;

so that local dev can skip the performance tests?
updates I added a commit(b4ca77c) to introduce the SKIP_WC_PERFORMANCE_TESTS env variable. Let me know if this is undesired, I can revert the commit.

@harriswong It would be much cleaner if we keep a separate jest config for performance tests. That way, you don't need to exclude the test using environment variables and keep the NPM script to run just the performance test.

What are your thoughts?

@achyuthajoy To clarify, do you mean it is better to keep this commit a326f98?

@achyuthajoy
Copy link
Contributor

To clarify, do you mean it is better to keep this commit a326f98

@harriswong Yes. That would be best to keep the performance test separate from current E2E.

Was this commit removed based on our previous discussion? If yes, I'm so sorry, I might've missed something while checking the implementation.

@harriswong
Copy link
Contributor Author

I saw woocommerce-blocks' PR (woocommerce/woocommerce-blocks#6119) which they stored in a file for output. I thought that was a pretty good idea and so I took that direction as well.

GitHub actions deletes artifacts uploaded after a specific period. So if you wish to have historic data, then it's best to log it to the console, which will be preserver. Or you can send the data to another service to get it recorded.

Ok thanks! For now, I don't think we are running it in CI and we don't need the historic data. If this changes, I will pursue a different approach so that we can preserve the results. Let me know what you think.

Sure. If historic data is not needed, writing to file or outputting to terminal works. I also noticed that terminal logs are also removed after a while.

@harriswong Do you plan to set up a Github workflow for running performance tests periodically/with manual trigger? Or just keep this for local testing.

For more accurate results I would suggest setting up a GitHub actions workflow. It's because running locally on mac with docker can be very slow and might not be the original performance.

@achyuthajoy Thanks for the suggestion! I wasn't planning on setting up a GitHub action workflow as of yet. I was planning to run this locally so that we can measure a before-and-after effect on this other PR(#3968). We also don't know if we will be going forward with #3968. But you are right that the results may vary from machine to machine. Maybe creating a manual trigger is better. Even though #3968 is in draft, I can see some benefits in triggering it manually in the PR's comment. This way, the metric will be more consistent compared to each of our individual machines. I will look into adding a github action to this.

Can this be a follow-up or would you prefer to have these all in the same PR?

@achyuthajoy
Copy link
Contributor

Can this be a follow-up or would you prefer to have these all in the same PR?

The GH workflow can be another PR.

@harriswong
Copy link
Contributor Author

To clarify, do you mean it is better to keep this commit a326f98

@harriswong Yes. That would be best to keep the performance test separate from current E2E.

Was this commit removed based on our previous discussion? If yes, I'm so sorry, I might've missed something while checking the implementation.

No problem at all! git makes these super easy to do. Thanks for taking the time to review! 🙇 I do appreciate the feedback on this. Ok, I will bring back the a326f98 and revert the commit that introduces SKIP_WC_PERFORMANCE_TESTS. 👍

@harriswong
Copy link
Contributor Author

Can this be a follow-up or would you prefer to have these all in the same PR?

The GH workflow can be another PR.

Added follow up here: #4389

@harriswong
Copy link
Contributor Author

No problem at all! git makes these super easy to do. Thanks for taking the time to review! 🙇 I do appreciate the feedback on this. Ok, I will bring back the a326f98 and revert the commit that introduces SKIP_WC_PERFORMANCE_TESTS. 👍

Done. Running npm run test:e2e-performance should print something like this:
image

@achyuthajoy please take another look.

@@ -490,4 +490,62 @@ export const merchantWCP = {
await checkbox.click();
}
},

activateWooPay: async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally we shouldn't write flows for toggling Dev Tools flag and use WP-CLI instead. This can be ignored for now since I've opened an issue to address these - #4402

Copy link
Contributor Author

Choose a reason for hiding this comment

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

cli would be great! It will make it a lot faster! Thanks for the note.

recreatePerformanceFile();
} );

describe( 'Stripe element', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

@harriswong It would be best if the test spec contains only 1 describe group and multiple it groups. Or you could split the tests to multiple files which I don't think is required in this case.

Let me know your thoughts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason I did this was because I wanted to have a clean file per performance run. At the same time, I wanted each scenario (Stripe element, UPE, WooPay without UPE, etc) to have its own setup. As a result, I did

describe // first level to always wipe the file before we start a run
     describe // Stripe element setup
     describe // UPE setup
     describe // WooPay without UPE setup

Looking at this again, I wonder if I can mix beforeAll and beforeEach with 1 layer of describe, such that wiping the files execute only once. 👀

Copy link
Contributor

Choose a reason for hiding this comment

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

@harriswong I don't have a strong opinion here. I'm good to go with your approach.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The other thing I could do is to get rid of all the beforeEach and afterEach. That's because there is only 1 test case for now, all the setup and teardown can be part of the it(). Then, I can have just 1 describe, is this preferred or should I keep the nested describe code here?

Copy link
Contributor

@achyuthajoy achyuthajoy left a comment

Choose a reason for hiding this comment

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

@harriswong I've tested the changes locally and can confirm that it's working a expected. Awesome work on this one.

I've left a few comments. Once it's cleared, it's good to merge 👍

@achyuthajoy achyuthajoy self-requested a review July 8, 2022 07:18
Copy link
Contributor

@achyuthajoy achyuthajoy left a comment

Choose a reason for hiding this comment

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

@harriswong I noticed that the report file created is not added to gitignore. Can you add it?

Also, tested the changes on a linux machine against a local server instance. The results are much faster that running on a Mac.

Screenshot from 2022-07-08 12-46-10

@harriswong
Copy link
Contributor Author

Hi @achyuthajoy , I merged the latest develop and added a line to the .gitignore. Please take a look again!

Also, tested the changes on a linux machine against a local server instance. The results are much faster that running on a Mac.

Thanks for giving this a test! The power of linux 💪

@harriswong harriswong requested a review from achyuthajoy July 11, 2022 22:42
Copy link
Contributor

@achyuthajoy achyuthajoy left a comment

Choose a reason for hiding this comment

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

LGTM 🚢

Thanks for your awesome work on this 👍

@harriswong
Copy link
Contributor Author

@achyuthajoy The "PHP testing (7.1)" job is stuck but this recent PR https://github.com/Automattic/woocommerce-payments/pull/4425/files removed 7.1

Should we ignore this stuck test and merge?

@achyuthajoy
Copy link
Contributor

@harriswong Yes, please ignore the 7.1 test. It was removed when WP & WC versions were bumped as part of the next release

@achyuthajoy achyuthajoy merged commit 8074238 into develop Jul 13, 2022
@achyuthajoy achyuthajoy deleted the add/1021-performance-measure branch July 13, 2022 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: e2e Issues and PRs related to e2e tests. category: performance The issue/PR is related to performance.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants