From 95eebff1675cc7bfaa6bac5122eab768a54435c1 Mon Sep 17 00:00:00 2001 From: GitHub actions Date: Thu, 14 Jul 2022 10:49:03 +0000 Subject: [PATCH 01/55] chore: release 1.0.0 --- internals/eslint-import/package.json | 2 +- internals/eslint-jest/package.json | 2 +- internals/eslint-typescript/package.json | 2 +- internals/eslint-vue/package.json | 2 +- internals/eslint/package.json | 2 +- packages/api-client/package.json | 2 +- packages/composables/package.json | 4 ++-- packages/load-tests/package.json | 2 +- packages/theme/package.json | 4 ++-- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/internals/eslint-import/package.json b/internals/eslint-import/package.json index 9ddecee01..168493894 100644 --- a/internals/eslint-import/package.json +++ b/internals/eslint-import/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/eslint-config-import", - "version": "1.0.0-rc.10", + "version": "1.0.0", "author": "Heitor Ramon Ribeiro ", "license": "MIT", "scripts": { diff --git a/internals/eslint-jest/package.json b/internals/eslint-jest/package.json index 315690f2b..16cdc9441 100644 --- a/internals/eslint-jest/package.json +++ b/internals/eslint-jest/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/eslint-config-jest", - "version": "1.0.0-rc.10", + "version": "1.0.0", "author": "Heitor Ramon Ribeiro ", "license": "MIT", "scripts": { diff --git a/internals/eslint-typescript/package.json b/internals/eslint-typescript/package.json index 7a85e108c..5ebdfc6c2 100644 --- a/internals/eslint-typescript/package.json +++ b/internals/eslint-typescript/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/eslint-config-typescript", - "version": "1.0.0-rc.10", + "version": "1.0.0", "author": "Heitor Ramon Ribeiro ", "license": "MIT", "scripts": { diff --git a/internals/eslint-vue/package.json b/internals/eslint-vue/package.json index 282e2461b..f0d8c7cfa 100644 --- a/internals/eslint-vue/package.json +++ b/internals/eslint-vue/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/eslint-config-vue", - "version": "1.0.0-rc.10", + "version": "1.0.0", "author": "Heitor Ramon Ribeiro ", "license": "MIT", "scripts": { diff --git a/internals/eslint/package.json b/internals/eslint/package.json index 327efbc5a..0c0256a19 100644 --- a/internals/eslint/package.json +++ b/internals/eslint/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/eslint-config-base", - "version": "1.0.0-rc.10", + "version": "1.0.0", "author": "Heitor Ramon Ribeiro ", "license": "MIT", "scripts": { diff --git a/packages/api-client/package.json b/packages/api-client/package.json index a861c06a2..ef197d4a6 100644 --- a/packages/api-client/package.json +++ b/packages/api-client/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/magento-api", - "version": "1.0.0-rc.10", + "version": "1.0.0", "sideEffects": false, "homepage": "https://github.com/vuestorefront/magento2", "bugs": { diff --git a/packages/composables/package.json b/packages/composables/package.json index 76c6a8d42..322b7e5f6 100644 --- a/packages/composables/package.json +++ b/packages/composables/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/magento", - "version": "1.0.0-rc.10", + "version": "1.0.0", "license": "MIT", "homepage": "https://github.com/vuestorefront/magento2", "bugs": { @@ -29,7 +29,7 @@ }, "dependencies": { "@vue-storefront/core": "~2.5.6", - "@vue-storefront/magento-api": "^1.0.0-rc.10", + "@vue-storefront/magento-api": "^1.0.0", "@vue/composition-api": "^1.4.1", "cookie-universal": "^2.1.5", "vue": "^2.6.14", diff --git a/packages/load-tests/package.json b/packages/load-tests/package.json index 63d5a94ba..aa8b7738f 100644 --- a/packages/load-tests/package.json +++ b/packages/load-tests/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/magento-load-tests", - "version": "1.0.0-rc.10", + "version": "1.0.0", "description": "Load tests for Magento 2 - VSF integration", "main": "index.js", "repository": "https://github.com/vuestorefront/magento2", diff --git a/packages/theme/package.json b/packages/theme/package.json index 18927de8e..42f7cf336 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/magento-theme", - "version": "1.0.0-rc.10", + "version": "1.0.0", "private": true, "license": "MIT", "homepage": "https://github.com/vuestorefront/magento2", @@ -38,7 +38,7 @@ "@pinia/nuxt": "^0.1.9", "@storefront-ui/vue": "^0.13.3", "@vue-storefront/cache": "~2.7.1", - "@vue-storefront/magento-api": "^1.0.0-rc.10", + "@vue-storefront/magento-api": "^1.0.0", "@vue-storefront/middleware": "~2.7.1", "@vue-storefront/nuxt": "~2.7.1", "@vue-storefront/redis-cache": "^1.0.1", From ce22a668bd697c6b9cc992a5a80d277056afdcc9 Mon Sep 17 00:00:00 2001 From: Marcin Kwiatkowski Date: Thu, 14 Jul 2022 15:57:44 +0200 Subject: [PATCH 02/55] docs: addd 1.0.0 release notes --- docs/index.md | 4 +- docs/migration-guides/1.0.0/1.0.0-bic.md | 25 ++++++++++ docs/migration-guides/1.0.0/index.md | 58 ++++++++++++++++++++++++ docs/migration-guides/index.md | 1 + 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 docs/migration-guides/1.0.0/1.0.0-bic.md create mode 100644 docs/migration-guides/1.0.0/index.md diff --git a/docs/index.md b/docs/index.md index 3ca31ebe8..07a8791d9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,7 +3,7 @@ height="100px" /> -# Vue Storefront 2 for Magento [BETA] +# Vue Storefront 2 for Magento Welcome to the documentation of Vue Storefront 2 integration for Magento 2. @@ -18,4 +18,4 @@ To get started, see the following guides: ## Demo -If you want to see the integration in action, check out our [demo environments](/guide/environments.html). \ No newline at end of file +If you want to see the integration in action, check out our [demo environments](/guide/environments.html). diff --git a/docs/migration-guides/1.0.0/1.0.0-bic.md b/docs/migration-guides/1.0.0/1.0.0-bic.md new file mode 100644 index 000000000..7b811b745 --- /dev/null +++ b/docs/migration-guides/1.0.0/1.0.0-bic.md @@ -0,0 +1,25 @@ +# 1.0.0 Backward incompatible changes reference + +In this document, you can see crucial breaking changes in the `1.0.0` comparing to `1.0.0-rc.10` release. +To see all changes, please take a look at [the release pull request](https://github.com/vuestorefront/magento2/pull/1261) + +| File | What is changed | +|------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| composables/useReview | The directory has been moved to the modules/customer/composables/useReview directory | +| getters/cartGetters | File has been moved to the modules/checkout/getters directory | +| enums/stockStatusEnum | The file has been removed. From now please use ProductStockStatus from '`modules/GraphQL/types' instead of enums/stockStatusEnum | +| test-utils/* | All files under the test-utils directory have been moved to the tests/unit directory | +| utilities/directives/click-outside/click-outside-directive | The file has been moved to the components/directives/click-outside directory | +| enums/imageEnums.js | The file has been deleted. Please use imageSizes object directly in the useImage composable packages/theme/composables/useImage/index.ts file | +| enums/cookieNameEnum.js | the file has been removed. Cookie names are part of the middleware.config.js from now | +| getters/_utils.ts | The file has been removed | +| getters/index.ts | The file has been removed. Please import getters from modules. | +| getters/storeConfigGetters.ts | The file has been removed. StoreConfig getters were not used | +| getters/storeGetters.ts | The file has been removed. Store getters were not used | +| getters/types.d.ts | The file has been removed. All types of getters are available in getters in modules. | +| getters/review | The file has been moved to the modules/review/getters directory | +| modules/magento | The Magento module has been renamed to the core module | +| pages/ResetPassword.vue | The file has been moved to the modules/customer/pages/MyAccount directory | +| pages/Checkout/ExternalCheckoutThankYou.vue | The file has been removed | +| routes.js | Definiton of the Reset password route has been moved to the customer module | +| nuxt.config.js | We added support for local HTTPS certificates and for now you need to install https certificate on your localhost and if you want to run app in production mode on localhost, you have to use the yarn start:local instead of yarn start. You can find more information about that in our docs: Installation → Configure integration → Generate certificate for a local development | diff --git a/docs/migration-guides/1.0.0/index.md b/docs/migration-guides/1.0.0/index.md new file mode 100644 index 000000000..4ebacf295 --- /dev/null +++ b/docs/migration-guides/1.0.0/index.md @@ -0,0 +1,58 @@ +# Vue Storefront for Magento 1.0.0 release notes + +Vue Storefront for Magento 1.0.0 contains backward-incompatible changes. To review these backward-incompatible changes, see + +[1.0.0 **Backward incompatible changes reference**](./1.0.0-bic) + +## Vue Storefront for Magento 1.0.0 highlights + +Vue Storefront for Magento comes out of the beta, and It's production-ready now. + +This release provides security enhancements, Volar support, dependencies updates, and bug fixes. + +Take a look at the detailed change log below. + +### New features + +- feat: add support for Volar [https://github.com/vuestorefront/magento2/pull/1255](https://github.com/vuestorefront/magento2/pull/1255) +- feat: added possibility to enable customer email confirmation [https://github.com/vuestorefront/magento2/pull/1237](https://github.com/vuestorefront/magento2/pull/1237) +- feat!: added support for https certificates on [localhost](http://localhost) [https://github.com/vuestorefront/magento2/pull/1248/files](https://github.com/vuestorefront/magento2/pull/1248/files) +- feat: added option to configure cookies [https://github.com/vuestorefront/magento2/pull/1232](https://github.com/vuestorefront/magento2/pull/1232) + +### Bugfix + +- fix: add missing german translations [https://github.com/vuestorefront/magento2/pull/1259](https://github.com/vuestorefront/magento2/pull/1259) +- fix: hide 'select prev added address labels for not logged-in customers [https://github.com/vuestorefront/magento2/pull/1257](https://github.com/vuestorefront/magento2/pull/1257) +- fix: added limit for product gallery size [https://github.com/vuestorefront/magento2/pull/1256](https://github.com/vuestorefront/magento2/pull/1256) +- fix: update cookies default settings [https://github.com/vuestorefront/magento2/pull/1250](https://github.com/vuestorefront/magento2/pull/1250) +- fix: fixed api-client import in the useMagentoConfiguration composable [https://github.com/vuestorefront/magento2/pull/1246](https://github.com/vuestorefront/magento2/pull/1246) +- fix: removed ssrMiddleware url binding [https://github.com/vuestorefront/magento2/pull/1245](https://github.com/vuestorefront/magento2/pull/1245) +- fix: server creation issues [https://github.com/vuestorefront/magento2/pull/1213](https://github.com/vuestorefront/magento2/pull/1213) + +### Refactors + +- refactor: changed default img placeholders for hero section and gallery [https://github.com/vuestorefront/magento2/pull/1260](https://github.com/vuestorefront/magento2/pull/1260) +- refactor: add missing http security headers [https://github.com/vuestorefront/magento2/pull/1254](https://github.com/vuestorefront/magento2/pull/1254) +- refactor!: rework directories structure [https://github.com/vuestorefront/magento2/pull/1252](https://github.com/vuestorefront/magento2/pull/1252) +- refactor: access control header [https://github.com/vuestorefront/magento2/pull/1253](https://github.com/vuestorefront/magento2/pull/1253) +- refactor: update behaviour of the addresses on the checkout [https://github.com/vuestorefront/magento2/pull/1251](https://github.com/vuestorefront/magento2/pull/1251) + +### Performance + +### Tests + +- test: refactored load-test files [https://github.com/vuestorefront/magento2/pull/1241](https://github.com/vuestorefront/magento2/pull/1241) + +### Chore + +- chore: updated docs of depracated integration package [https://github.com/vuestorefront/magento2/pull/1247](https://github.com/vuestorefront/magento2/pull/1247) +- chore: updated dependencies [https://github.com/vuestorefront/magento2/pull/1209](https://github.com/vuestorefront/magento2/pull/1209) + +### Repository + +- build: updated middleware URL[https://github.com/vuestorefront/magento2/pull/1234](https://github.com/vuestorefront/magento2/pull/1234) +- build: changed server-middleware URL[https://github.com/vuestorefront/magento2/pull/1215](https://github.com/vuestorefront/magento2/pull/1215) + +### Documentation + +- docs: updated installation guide [https://github.com/vuestorefront/magento2/pull/1239](https://github.com/vuestorefront/magento2/pull/1239) diff --git a/docs/migration-guides/index.md b/docs/migration-guides/index.md index fa332a625..bba312dbc 100644 --- a/docs/migration-guides/index.md +++ b/docs/migration-guides/index.md @@ -4,3 +4,4 @@ - [1.0.0-rc.8](./1.0.0-rc.8/) - [1.0.0-rc.9](./1.0.0-rc.9/) - [1.0.0-rc.10](./1.0.0-rc.10/) +- [1.0.0](./1.0.0/) From 286a4cae1ed3f47683573c24aa0907c06098cf50 Mon Sep 17 00:00:00 2001 From: Marcin Kwiatkowski Date: Fri, 15 Jul 2022 15:32:58 +0200 Subject: [PATCH 03/55] fix: fixed checkout issues --- packages/theme/modules/checkout/pages/Checkout/Billing.vue | 2 +- packages/theme/modules/checkout/pages/Checkout/ThankYou.vue | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/theme/modules/checkout/pages/Checkout/Billing.vue b/packages/theme/modules/checkout/pages/Checkout/Billing.vue index 69a6acd53..a1369dc56 100644 --- a/packages/theme/modules/checkout/pages/Checkout/Billing.vue +++ b/packages/theme/modules/checkout/pages/Checkout/Billing.vue @@ -55,7 +55,7 @@ class="form" >

@@ -103,7 +103,7 @@ export default defineComponent({ const route = useRoute(); const companyDetails = ref({ - name: 'Divante Headquarter', + name: 'Vue Storefront Headquarter', street: 'St. Dmowskiego 17, 53-534', city: 'Wroclaw, Poland', email: 'demo@vuestorefront.io', From ccf6e3cc783ce50a7cd4828074c1261084f29a9b Mon Sep 17 00:00:00 2001 From: Marcin Kwiatkowski Date: Fri, 15 Jul 2022 16:14:53 +0200 Subject: [PATCH 04/55] fix: fixed 404 blur error --- packages/theme/components/HeroSection.vue | 2 +- .../catalog/product/composables/useProductGallery/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/theme/components/HeroSection.vue b/packages/theme/components/HeroSection.vue index 35629c3b7..2ef7ea321 100644 --- a/packages/theme/components/HeroSection.vue +++ b/packages/theme/components/HeroSection.vue @@ -7,7 +7,7 @@ :width="imageWidth" :height="imageHeight" :nuxt-img-config="nuxtImgConfig" - placeholder="blur" + placeholder class="hero__image" />

diff --git a/packages/theme/modules/catalog/product/composables/useProductGallery/index.ts b/packages/theme/modules/catalog/product/composables/useProductGallery/index.ts index fa2c252a3..3f8e54b51 100644 --- a/packages/theme/modules/catalog/product/composables/useProductGallery/index.ts +++ b/packages/theme/modules/catalog/product/composables/useProductGallery/index.ts @@ -9,7 +9,7 @@ import type { UseProductGalleryInterface } from '~/modules/catalog/product/compo * * See the {@link UseProductGalleryInterface} page for more information. */ -export function useProductGallery(product: Ref, imgPlaceholder = 'blur'): UseProductGalleryInterface { +export function useProductGallery(product: Ref, imgPlaceholder = ''): UseProductGalleryInterface { const { getMagentoImage, imageSizes } = useImage(); const productGallery = computed(() => getProductGallery(product.value).map((img) => ({ mobile: { url: getMagentoImage(img.small) }, From 5f21f84d0f1df5d9831e7c855f1d086ea2e041b5 Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Fri, 15 Jul 2022 16:07:11 +0200 Subject: [PATCH 05/55] fix: store modal invalid action handler name --- packages/theme/components/StoreSwitcher/StoresModal.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/theme/components/StoreSwitcher/StoresModal.vue b/packages/theme/components/StoreSwitcher/StoresModal.vue index 525c2a75c..691dd862b 100644 --- a/packages/theme/components/StoreSwitcher/StoresModal.vue +++ b/packages/theme/components/StoreSwitcher/StoresModal.vue @@ -41,7 +41,7 @@ {{ $t('Cancel') }} From 6cec4b88b6ef5db41d0aadfe8061d40e0c37034e Mon Sep 17 00:00:00 2001 From: Artur Tagisow Date: Mon, 18 Jul 2022 14:52:40 +0200 Subject: [PATCH 06/55] fix: don't inclue query params in urlPathToFind this commit was made because if you went to a category and changed to the 2nd page, the currently active category's name would not appear after hard refreshing the page this was happening because activeCategory used route.value.fullPath, which includes the query params. So after the regex pipeline from urlPathToFind, the value passed to findActiveCategory() was "men?page=2" (expected query-param free "men") it was possible to fix this by adding another regex to the pipeline but it's cleaner to just use route.value.path as that's the intention of the implementation M2-1035 --- .../modules/catalog/category/helpers/useTraverseCategory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/theme/modules/catalog/category/helpers/useTraverseCategory.ts b/packages/theme/modules/catalog/category/helpers/useTraverseCategory.ts index d10799158..cf1c75865 100644 --- a/packages/theme/modules/catalog/category/helpers/useTraverseCategory.ts +++ b/packages/theme/modules/catalog/category/helpers/useTraverseCategory.ts @@ -18,7 +18,7 @@ export function useTraverseCategory() { const loadCategoryTree = () => categoryStore.load(); const activeCategory = computed(() => { // on localhost the default store is localhost:3000/default/ but in a multi-store Magento instance this can change - const urlPathToFind = route.value.fullPath + const urlPathToFind = route.value.path .replace(context.app.localePath('/c'), '') .replace(/^\//, '') .replace('.html', ''); From 77c2f40b20cce6df9c78c23478319d802e39660f Mon Sep 17 00:00:00 2001 From: Artur Tagisow Date: Mon, 18 Jul 2022 15:04:14 +0200 Subject: [PATCH 07/55] fix: show pagination arrows after category refresh before this commit pagination arrows on the category page would be hidden if you hard refreshed the page the culprit was the on-interaction prop on the LazyHydrate component M2-1034 --- packages/theme/modules/catalog/pages/category.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/theme/modules/catalog/pages/category.vue b/packages/theme/modules/catalog/pages/category.vue index 604f0f8b9..1602260bd 100644 --- a/packages/theme/modules/catalog/pages/category.vue +++ b/packages/theme/modules/catalog/pages/category.vue @@ -63,7 +63,7 @@ v-if="!$fetchState.pending" class="products__display-opt" > - + {{ $t('Show') }} - + Date: Mon, 18 Jul 2022 14:00:38 +0200 Subject: [PATCH 08/55] fix: images in product gallery are overlayed with main image - M2-1036 - added display:block for sf-image-loaded fixes the issue in the Safari browser --- .../catalog/product/components/product-types/styles.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/theme/modules/catalog/product/components/product-types/styles.scss b/packages/theme/modules/catalog/product/components/product-types/styles.scss index 93258a5cd..f20fd78ee 100644 --- a/packages/theme/modules/catalog/product/components/product-types/styles.scss +++ b/packages/theme/modules/catalog/product/components/product-types/styles.scss @@ -161,6 +161,12 @@ } } +::v-deep .sf-gallery__thumbs { + .sf-image-loaded { + display: block; + } +} + @keyframes moveicon { 0% { transform: translate3d(0, 0, 0) rotate(90deg) scale(1, -1); From 610975c3c4734cdbea95c07f5745af1481df9a80 Mon Sep 17 00:00:00 2001 From: Artur Tagisow Date: Mon, 18 Jul 2022 10:41:35 +0200 Subject: [PATCH 09/55] ci: simplify getting middleware url --- .../workflows/deploy-vue-storefront-cloud.yml | 30 +++++-------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/.github/workflows/deploy-vue-storefront-cloud.yml b/.github/workflows/deploy-vue-storefront-cloud.yml index e9c4d5c55..c778e1a7d 100644 --- a/.github/workflows/deploy-vue-storefront-cloud.yml +++ b/.github/workflows/deploy-vue-storefront-cloud.yml @@ -13,9 +13,10 @@ jobs: outputs: environment-name: ${{ steps.determine-environment.outputs.name }} environment-code: ${{ steps.determine-environment.outputs.code }} + environment-middleware-url: ${{ steps.determine-environment.outputs.middleware-url}} deployment_id: ${{ steps.deployment.outputs.deployment_id }} steps: - - name: Determine environment name + - name: Determine environment-specific variables id: determine-environment shell: bash run: | @@ -24,18 +25,22 @@ jobs: if [ $REF = 'refs/heads/main' ]; then ENVNAME='production' ENVCODE='demo-magento2' + MIDDLEWARE_URL='https://demo-magento2.europe-west1.gcp.vuestorefront.cloud/api/' elif [ $REF = 'refs/heads/develop' ]; then ENVNAME='dev' ENVCODE='demo-magento2-dev' + MIDDLEWARE_URL='https://demo-magento2-dev.europe-west1.gcp.storefrontcloud.io/api/' elif [[ $REF = refs/heads/release* ]]; then ENVNAME='canary' ENVCODE='demo-magento2-canary' + MIDDLEWARE_URL='https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io/api/' elif [ $REF = 'refs/heads/enterprise' ]; then ENVNAME='enterprise' ENVCODE='demo-magento2-enterprise' + MIDDLEWARE_URL='https://demo-magento2-enterprise.europe-west1.gcp.storefrontcloud.io/api/' else echo 'unrecognized branch name' @@ -44,6 +49,7 @@ jobs: echo ::set-output name=name::$ENVNAME echo ::set-output name=code::$ENVCODE + echo ::set-output name=middleware-url::$MIDDLEWARE_URL - name: Create GitHub deployment id: deployment @@ -56,26 +62,6 @@ jobs: needs: create-deployment runs-on: ubuntu-latest steps: - - name: Set env VSF_MIDDLEWARE_URL - run: | - REF=${{ github.ref }} - - if [ $REF = 'refs/heads/main' ]; then - echo "VSF_MIDDLEWARE_URL=https://demo-magento2.europe-west1.gcp.vuestorefront.cloud/api/" >> $GITHUB_ENV - - elif [ $REF = 'refs/heads/develop' ]; then - echo "VSF_MIDDLEWARE_URL=https://demo-magento2-dev.europe-west1.gcp.storefrontcloud.io/api/" >> $GITHUB_ENV - - elif [[ $REF = refs/heads/release* ]]; then - echo "VSF_MIDDLEWARE_URL=https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io/api/" >> $GITHUB_ENV - - elif [ $REF = 'refs/heads/enterprise' ]; then - echo "VSF_MIDDLEWARE_URL=https://demo-magento2-enterprise.europe-west1.gcp.storefrontcloud.io/api/" >> $GITHUB_ENV - - else - echo "https://demo-magento2-dev.europe-west1.gcp.storefrontcloud.io/api/" >> $GITHUB_ENV - exit 1 - fi - name: Checkout code uses: actions/checkout@v1 @@ -102,7 +88,7 @@ jobs: NPM_REGISTRY: https://registrynpm.storefrontcloud.io VSF_STORE_URL: '' - VSF_MIDDLEWARE_URL: ${{ env.VSF_MIDDLEWARE_URL }} + VSF_MIDDLEWARE_URL: ${{ needs.create-deployment.outputs.environment-middleware-url }} VSF_MAGENTO_BASE_URL: https://magento2-instance.vuestorefront.io/ VSF_MAGENTO_GRAPHQL_URL: https://magento2-instance.vuestorefront.io/graphql From b803a77253afaf50bae36a59b1b7251f7f2e6a11 Mon Sep 17 00:00:00 2001 From: Artur Tagisow Date: Tue, 19 Jul 2022 10:20:38 +0200 Subject: [PATCH 10/55] test: fix tests on release branch --- .../category/helpers/__tests__/useTraverseCategory.spec.ts | 2 +- packages/theme/tests/unit/mocks/useRoute.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/theme/modules/catalog/category/helpers/__tests__/useTraverseCategory.spec.ts b/packages/theme/modules/catalog/category/helpers/__tests__/useTraverseCategory.spec.ts index d27317be9..ea9699f9a 100644 --- a/packages/theme/modules/catalog/category/helpers/__tests__/useTraverseCategory.spec.ts +++ b/packages/theme/modules/catalog/category/helpers/__tests__/useTraverseCategory.spec.ts @@ -19,7 +19,7 @@ jest.mock('@nuxtjs/composition-api', () => { return { ...originalModule, useContext: jest.fn(() => ({ app: { localePath: (suffix: unknown) => `/default${suffix}` } })), - useRoute: jest.fn(() => ({ value: { fullPath: '/default/c/what-is-new.html' } })), + useRoute: jest.fn(() => ({ value: { path: '/default/c/what-is-new.html' } })), }; }); diff --git a/packages/theme/tests/unit/mocks/useRoute.ts b/packages/theme/tests/unit/mocks/useRoute.ts index 0d26bba3a..0200fb334 100644 --- a/packages/theme/tests/unit/mocks/useRoute.ts +++ b/packages/theme/tests/unit/mocks/useRoute.ts @@ -1,5 +1,6 @@ export const useRouteMock = (extend = {}) => ({ value: { + path: '/default/c/gear.html', fullPath: '/default/c/gear.html', }, ...extend, From 600d727c5e159b99c878bacdc78c0c4e6dd1659e Mon Sep 17 00:00:00 2001 From: Matt Maribojoc Date: Mon, 18 Jul 2022 08:27:27 -0400 Subject: [PATCH 11/55] docs: add vsf theme --- docs/.vuepress/config.js | 65 ++++------ docs/.vuepress/theme/index.js | 3 - docs/.vuepress/theme/layouts/Layout.vue | 162 ------------------------ docs/package.json | 3 +- docs/yarn.lock | 10 ++ 5 files changed, 36 insertions(+), 207 deletions(-) delete mode 100644 docs/.vuepress/theme/index.js delete mode 100644 docs/.vuepress/theme/layouts/Layout.vue diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index dde7c0a95..f253a89e3 100755 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -7,19 +7,25 @@ module.exports = { head: [ ['link', { rel: 'icon', href: '/favicon.png' }], // Google Tag Manager - ['script', {}, [` + [ + 'script', + {}, + [ + ` (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','${GTM_TAG}'); - `]], + `, + ], + ], ], /** * Ref:https://v1.vuepress.vuejs.org/config/#configurewebpack */ - configureWebpack: (config) => { + configureWebpack: (config) => { // Add support for webp images config.module.rules.push({ test: /\.(webp)(\?.*)?$/, @@ -28,52 +34,29 @@ module.exports = { loader: 'url-loader', options: { limit: 10000, - name: 'assets/img/[name].[hash:8].[ext]' - } - } - ] + name: 'assets/img/[name].[hash:8].[ext]', + }, + }, + ], }); // Fix image loading. Ref: https://github.com/vuejs/vue-loader/issues/1612#issuecomment-559366730 config.module.rules = config.module.rules.map((rule) => { - rule.use = rule.use && rule.use.map((useRule) => { - if (useRule.loader === 'url-loader') { - useRule.options.esModule = false; - } + rule.use = + rule.use && + rule.use.map((useRule) => { + if (useRule.loader === 'url-loader') { + useRule.options.esModule = false; + } - return useRule; - }); + return useRule; + }); return rule; }); }, - /** - * Ref:https://v1.vuepress.vuejs.org/plugin/ - */ - plugins: [ - '@vuepress/plugin-back-to-top', - [ - '@vuepress/plugin-medium-zoom', - { - // This selector excludes images from the "Integrations" page - selector: 'main :not(.tile-image) > img', - }, - ], - '@vuepress/active-header-links', - '@vuepress/search', - ], - - /** - * Ref: https://v1.vuepress.vuejs.org/config/#markdown - */ - markdown: { - extendMarkdown: md => { - md.use(require('markdown-it-video'), { - youtube: { width: 740, height: 416.25 }, // 16:9 ratio, where 740px is the width of the page content - }); - } - }, + theme: 'vsf-docs', themeConfig: { GTM_TAG, @@ -120,8 +103,8 @@ module.exports = { ['/getting-started/configuration', 'Configuration'], ['/getting-started/layouts-and-routing', 'Layouts and Routing'], ['/getting-started/theme', 'Theme'], - ['/getting-started/internationalization', 'Internationalization'] - ] + ['/getting-started/internationalization', 'Internationalization'], + ], }, { title: 'Composition', diff --git a/docs/.vuepress/theme/index.js b/docs/.vuepress/theme/index.js deleted file mode 100644 index cc636ec82..000000000 --- a/docs/.vuepress/theme/index.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extend: '@vuepress/theme-default' -}; diff --git a/docs/.vuepress/theme/layouts/Layout.vue b/docs/.vuepress/theme/layouts/Layout.vue deleted file mode 100644 index ef47d49f3..000000000 --- a/docs/.vuepress/theme/layouts/Layout.vue +++ /dev/null @@ -1,162 +0,0 @@ - - - diff --git a/docs/package.json b/docs/package.json index 776ac02e6..9f3519043 100755 --- a/docs/package.json +++ b/docs/package.json @@ -28,6 +28,7 @@ }, "dependencies": { "sass-loader": "^8.0.2", - "vue-multiselect": "^2.1.6" + "vue-multiselect": "^2.1.6", + "vuepress-theme-vsf-docs": "^1.0.13" } } diff --git a/docs/yarn.lock b/docs/yarn.lock index 23a06de7c..2b144ec85 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -8336,6 +8336,16 @@ vuepress-plugin-smooth-scroll@^0.0.3: dependencies: smoothscroll-polyfill "^0.4.3" +vuepress-theme-vsf-docs@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/vuepress-theme-vsf-docs/-/vuepress-theme-vsf-docs-1.0.13.tgz#949aa0adb1aa9de98774c19a4887e64994838aec" + integrity sha512-vvjA88XVu+a/DjyChzF4karIztDCqcmLbsfgyFPGGAIAmOx28g11xVx1Wg5nXzl89hDbSWyLzKtLoSP7g/JZyQ== + dependencies: + "@vuepress/plugin-active-header-links" "1.9.7" + "@vuepress/plugin-nprogress" "1.9.7" + "@vuepress/plugin-search" "1.9.7" + vuepress-plugin-container "^2.0.2" + vuepress@^1.9.7: version "1.9.7" resolved "https://registry.yarnpkg.com/vuepress/-/vuepress-1.9.7.tgz#2cd6709a2228f5cef588115aaeabf820ab9ed7cc" From c58815672ea21c785edbf512ae4ddbb84278ab7b Mon Sep 17 00:00:00 2001 From: Matt Maribojoc Date: Mon, 18 Jul 2022 09:05:14 -0400 Subject: [PATCH 12/55] docs: update installation --- docs/.vuepress/config.js | 15 +++++++------ docs/getting-started/introduction.md | 28 ++++++++++++------------- docs/guide/environments.md | 21 ------------------- docs/index.md | 20 +++++++++++++++++- docs/installation-setup/installation.md | 2 -- 5 files changed, 39 insertions(+), 47 deletions(-) delete mode 100644 docs/guide/environments.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index f253a89e3..d7efe31dd 100755 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -76,18 +76,17 @@ module.exports = { ], sidebar: [ { - title: 'Essentials', + title: '', collapsable: false, children: [ ['/', 'Introduction'], - ['/guide/environments', 'Demo environments'], ['/guide/supported-features', 'Supported features'], ['/guide/about', 'About'], ], }, { title: 'Installation & Setup', - collapsable: false, + collapsable: true, children: [ ['/installation-setup/installation', 'Installation'], ['/installation-setup/configure-magento', 'Configuring Magento'], @@ -96,7 +95,7 @@ module.exports = { }, { title: 'Getting started', - collapsable: false, + collapsable: true, children: [ ['/getting-started/introduction', 'Introduction'], ['/getting-started/project-structure', 'Project structure'], @@ -108,7 +107,7 @@ module.exports = { }, { title: 'Composition', - collapsable: false, + collapsable: true, children: [ ['/composition/composables', 'Composables'], ['/composition/list-of-composables', 'List of composables'], @@ -116,7 +115,7 @@ module.exports = { }, { title: 'Modules', - collapsable: false, + collapsable: true, sidebarDepth: 2, children: [ { @@ -131,7 +130,7 @@ module.exports = { }, { title: 'Guides', - collapsable: false, + collapsable: true, children: [ ['/guide/global-state-management', 'Global state management'], ['/guide/image-optimization', 'Image optimization'], @@ -142,7 +141,7 @@ module.exports = { }, { title: 'Performance', - collapsable: false, + collapsable: true, children: [ ['/guide/graphql-get', 'Varnish & GET for GraphQL Queries'], ['/guide/ssr', 'Server Side Rendering Cache'], diff --git a/docs/getting-started/introduction.md b/docs/getting-started/introduction.md index 55386a17e..bad4cc914 100644 --- a/docs/getting-started/introduction.md +++ b/docs/getting-started/introduction.md @@ -2,17 +2,19 @@ Without a proper understanding of the framework you're using, you might spend weeks or even months doing something that someone else has already done. That's why before we can dive deep into the project itself, we need to understand what powers it all under the hood. -@[youtube](MCN1rRwuIGs) + ## It's all Nuxt.js We didn't want to reinvent the wheel and introduce yet another framework that solves the same issues as its predecessors, which took them years to mature. That's why... - - -Vue Storefront is essentially a [Nuxt.js](https://nuxtjs.org/) project with some plugins and modules preinstalled, as well as a ready-to-use e-commerce theme. Nuxt.js handles most of the front-end work and [Server Side Rendering](https://nuxtjs.org/docs/concepts/server-side-rendering/), while Vue Storefront adds the e-commerce specific bits and integrations to various platforms. - - +> Vue Storefront is essentially a [Nuxt.js](https://nuxtjs.org/) project with some plugins and modules preinstalled, as well as a ready-to-use e-commerce theme. Nuxt.js handles most of the front-end work and [Server Side Rendering](https://nuxtjs.org/docs/concepts/server-side-rendering/), while Vue Storefront adds the e-commerce specific bits and integrations to various platforms. Some of the plugins and modules that come with the fresh installation were created by the Nuxt.js community, and others come from our core team specifically for Vue Storefront projects. @@ -26,17 +28,13 @@ You might be wondering why we choose Nuxt.js as our foundation. After all, it wa When you start using any new framework, you expect it to: -* have **plugins that solve common issues**, such as analytics, SEO, internationalization, etc., -* be **versatile and flexible** enough to allow extending it and creating custom integrations, -* have **active and diverse community**, which answers questions, writes articles, and promotes the framework. +- have **plugins that solve common issues**, such as analytics, SEO, internationalization, etc., +- be **versatile and flexible** enough to allow extending it and creating custom integrations, +- have **active and diverse community**, which answers questions, writes articles, and promotes the framework. Creating such an ecosystem from scratch takes years. But because we based Vue Storefront on Nuxt.js — the biggest Vue.js framework — it ticks all the boxes. Nuxt.js has a vast library of [ready-to-use modules](https://modules.nuxtjs.org/) and an active community of thousands of developers on the [Nuxt.js Discord server](https://discord.com/invite/ps2h6QT). It's also flexible enough to make it e-commerce ready with just a few plugins and modules. - - -Combining general-purpose modules from Nuxt.js and e-commerce specific modules from Vue Storefront significantly shortens the time-to-market. It allows you to focus on what's specific to your project. - - +> Combining general-purpose modules from Nuxt.js and e-commerce specific modules from Vue Storefront significantly shortens the time-to-market. It allows you to focus on what's specific to your project. ## Start with Vue.js @@ -46,4 +44,4 @@ We also encourage reading [Nuxt.js 2 documentation](https://nuxtjs.org/docs/). I ## What's next -Now that you understand what Vue Storefront is, it's time to understand the [Project structure](./project-structure.html) and learn how to navigate it and which files do what. +Now that you understand what Vue Storefront is, go to the [Installation](./installation.html) guide to set up a project. diff --git a/docs/guide/environments.md b/docs/guide/environments.md deleted file mode 100644 index 66dc8cf4e..000000000 --- a/docs/guide/environments.md +++ /dev/null @@ -1,21 +0,0 @@ -# Demo environments - -We have three demo environments where you can see and test Magento 2 integration for Vue Storefront in action. If you find a bug in any of them, please [create an issue](https://github.com/vuestorefront/magento2/issues/new/choose) in our repository to let us know about it. - -## Production environment - -In the production environment, you can see the latest **released and stable** version of the integration. It should be visually and feature-wise identical to the new project installed using our CLI. - -[Production demo](https://demo-magento2.europe-west1.gcp.vuestorefront.cloud) - -## Staging environment - -In the staging environment, we are testing new releases. It should be **relatively stable**, but you might still encounter some bugs. - -[Staging demo](https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io) - -## Development environment - -In the development environment, we are testing the `develop` branch, which might contain unfinished or experimental features. It might be **unstable** both visually and feature-wise. - -[Development environment](https://demo-magento2-dev.europe-west1.gcp.storefrontcloud.io) diff --git a/docs/index.md b/docs/index.md index 07a8791d9..f93021fdb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -18,4 +18,22 @@ To get started, see the following guides: ## Demo -If you want to see the integration in action, check out our [demo environments](/guide/environments.html). +If you want to see the integration in action, we have three demo environments where you can see and test Magento 2 integration for Vue Storefront in action. If you find a bug in any of them, please [create an issue](https://github.com/vuestorefront/magento2/issues/new/choose) in our repository to let us know about it. + +### Production environment + +In the production environment, you can see the latest **released and stable** version of the integration. It should be visually and feature-wise identical to the new project installed using our CLI. + +[Production demo](https://demo-magento2.europe-west1.gcp.vuestorefront.cloud) + +### Staging environment + +In the staging environment, we are testing new releases. It should be **relatively stable**, but you might still encounter some bugs. + +[Staging demo](https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io) + +### Development environment + +In the development environment, we are testing the `develop` branch, which might contain unfinished or experimental features. It might be **unstable** both visually and feature-wise. + +[Development environment](https://demo-magento2-dev.europe-west1.gcp.storefrontcloud.io) diff --git a/docs/installation-setup/installation.md b/docs/installation-setup/installation.md index 4ae833ca9..f0cfe6bc7 100644 --- a/docs/installation-setup/installation.md +++ b/docs/installation-setup/installation.md @@ -1,7 +1,5 @@ # Installation -[[toc]] - ## Prerequisites Before proceeding, make sure you have [Node 16](https://nodejs.org/en/) installed. You can check this by running the following command: From 8cf25b06dcfa3844b5b0f592b616df09ee2b94d5 Mon Sep 17 00:00:00 2001 From: Matt Maribojoc Date: Mon, 18 Jul 2022 09:50:59 -0400 Subject: [PATCH 13/55] docs: update theme for integration logos --- docs/installation-setup/installation.md | 2 +- docs/package.json | 2 +- docs/yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/installation-setup/installation.md b/docs/installation-setup/installation.md index f0cfe6bc7..ad4db862c 100644 --- a/docs/installation-setup/installation.md +++ b/docs/installation-setup/installation.md @@ -18,7 +18,7 @@ The easiest way to get started with Vue Storefront is to set up your project usi npx @vue-storefront/cli generate store ``` -It will ask you to enter the project's name and select the e-commerce platform you wish to use. Once selected, the CLI will create project files in the directory matching your project name. +It will ask you to enter the project's name and select `Magento 2` as your e-commerce platform. Once selected, the CLI will create project files in the directory matching your project name. ::: warning CLI will use the project name you enter to create a new directory, so avoid using special characters and spaces. diff --git a/docs/package.json b/docs/package.json index 9f3519043..9af3adf50 100755 --- a/docs/package.json +++ b/docs/package.json @@ -29,6 +29,6 @@ "dependencies": { "sass-loader": "^8.0.2", "vue-multiselect": "^2.1.6", - "vuepress-theme-vsf-docs": "^1.0.13" + "vuepress-theme-vsf-docs": "^1.0.14" } } diff --git a/docs/yarn.lock b/docs/yarn.lock index 2b144ec85..d63d8ffdc 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -8336,10 +8336,10 @@ vuepress-plugin-smooth-scroll@^0.0.3: dependencies: smoothscroll-polyfill "^0.4.3" -vuepress-theme-vsf-docs@^1.0.13: - version "1.0.13" - resolved "https://registry.yarnpkg.com/vuepress-theme-vsf-docs/-/vuepress-theme-vsf-docs-1.0.13.tgz#949aa0adb1aa9de98774c19a4887e64994838aec" - integrity sha512-vvjA88XVu+a/DjyChzF4karIztDCqcmLbsfgyFPGGAIAmOx28g11xVx1Wg5nXzl89hDbSWyLzKtLoSP7g/JZyQ== +vuepress-theme-vsf-docs@^1.0.14: + version "1.0.14" + resolved "https://registry.yarnpkg.com/vuepress-theme-vsf-docs/-/vuepress-theme-vsf-docs-1.0.14.tgz#87e9a4fd079f34548140cad7647d4cf04a02dc59" + integrity sha512-m57TPCuaA8iyEsk/Kvgg0Wi+ByLqPXgbPF7dwGSgqjGlcIjjW2bMoaFrI7yNNLxnKdfyYXhgR0rLsPVQTPmwgw== dependencies: "@vuepress/plugin-active-header-links" "1.9.7" "@vuepress/plugin-nprogress" "1.9.7" From 090ca5bb805e4af3e7099b9efc31b2d60d544c4b Mon Sep 17 00:00:00 2001 From: Marcin Kwiatkowski Date: Tue, 19 Jul 2022 17:17:17 +0200 Subject: [PATCH 14/55] build: disabled getBaseUrl function --- .../theme/helpers/integrationPlugin/_proxyUtils.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/packages/theme/helpers/integrationPlugin/_proxyUtils.ts b/packages/theme/helpers/integrationPlugin/_proxyUtils.ts index 7e147b4d0..54e970f0b 100644 --- a/packages/theme/helpers/integrationPlugin/_proxyUtils.ts +++ b/packages/theme/helpers/integrationPlugin/_proxyUtils.ts @@ -1,4 +1,3 @@ -import { IncomingMessage } from 'node:http'; import { Context as NuxtContext } from '@nuxt/types'; import { merge } from 'lodash-es'; @@ -10,17 +9,6 @@ interface CreateProxiedApiParams { tag: string; } -export const getBaseUrl = (req: IncomingMessage, basePath: string | undefined = '/'): string => { - if (!req) return `${basePath}api/`; - const { headers } = req; - // eslint-disable-next-line global-require, unicorn/prefer-module - const isHttps = require('is-https')(req); - const scheme = isHttps ? 'https' : 'http'; - const host = headers['x-forwarded-host'] || headers.host; - - return `${scheme}://${host}${basePath}api/`; -}; - export const createProxiedApi = ({ givenApi, client, tag }: CreateProxiedApiParams) => new Proxy(givenApi, { get: (target, prop, receiver) => { const functionName = String(prop); @@ -41,7 +29,6 @@ export const getIntegrationConfig = (context: NuxtContext, configuration: any) = const cookie = getCookies(context); const initialConfig = merge({ axios: { - baseURL: getBaseUrl(context?.req, context?.base), headers: { ...(cookie ? { cookie } : {}), }, From 0f63eaaf69bac43df53f9541fa79f6fee3611199 Mon Sep 17 00:00:00 2001 From: Marcin Kwiatkowski Date: Tue, 19 Jul 2022 20:26:26 +0200 Subject: [PATCH 15/55] build: enabled redis --- .github/workflows/deploy-vue-storefront-cloud.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-vue-storefront-cloud.yml b/.github/workflows/deploy-vue-storefront-cloud.yml index c778e1a7d..fdd14e225 100644 --- a/.github/workflows/deploy-vue-storefront-cloud.yml +++ b/.github/workflows/deploy-vue-storefront-cloud.yml @@ -100,7 +100,7 @@ jobs: VSF_IMAGE_PROVIDER_BASE_URL: https://res-4.cloudinary.com/dnozky7on/image/upload/ VSF_IMAGE_PROVIDER_DOMAIN: https://res-4.cloudinary.com - VSF_REDIS_ENABLED: false + VSF_REDIS_ENABLED: true VSF_REDIS_HOST: redis # VSF cloud specific VSF_REDIS_PORT: 6379 VSF_REDIS_KEY_PREFIX: ${{ github.sha }} From 901ede8c5fe3cdb2266513186ff8e57a60c8a520 Mon Sep 17 00:00:00 2001 From: Artur Tagisow <5359825+sethidden@users.noreply.github.com> Date: Tue, 19 Jul 2022 11:18:15 +0200 Subject: [PATCH 16/55] ci: align release branch name convention [ci skip] --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 71f1323d2..786daab63 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,12 +5,12 @@ on: branches: - main - develop - - release-** + - release/* pull_request: branches: - main - develop - - release-** + - release/* concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} From f0a7aeca41578734c4b825a404ecc5cff9680282 Mon Sep 17 00:00:00 2001 From: Marcin Kwiatkowski Date: Wed, 20 Jul 2022 07:01:50 +0200 Subject: [PATCH 17/55] docs: updated migration guides --- docs/migration-guides/index.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/migration-guides/index.md b/docs/migration-guides/index.md index bba312dbc..f8daf93f6 100644 --- a/docs/migration-guides/index.md +++ b/docs/migration-guides/index.md @@ -1,7 +1,13 @@ # Migration guides -- [1.0.0-rc.7](./1.0.0-rc.7/) -- [1.0.0-rc.8](./1.0.0-rc.8/) -- [1.0.0-rc.9](./1.0.0-rc.9/) -- [1.0.0-rc.10](./1.0.0-rc.10/) - [1.0.0](./1.0.0/) +- [1.0.0-rc.10](./1.0.0-rc.10/) +- [1.0.0-rc.9](./1.0.0-rc.9/) +- [1.0.0-rc.8](./1.0.0-rc.8/) +- [1.0.0-rc.7](./1.0.0-rc.7/) + + + + + + From 2af0267a12d7266fd9f174ff3f5a524197f42933 Mon Sep 17 00:00:00 2001 From: Marcin Kwiatkowski Date: Wed, 20 Jul 2022 10:05:18 +0200 Subject: [PATCH 18/55] chore: updated npm versions of vsf packages --- packages/api-client/package.json | 2 +- packages/composables/package.json | 4 ++-- packages/theme/package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/api-client/package.json b/packages/api-client/package.json index ef197d4a6..7c263a0f2 100644 --- a/packages/api-client/package.json +++ b/packages/api-client/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/magento-api", - "version": "1.0.0", + "version": "1.0.1", "sideEffects": false, "homepage": "https://github.com/vuestorefront/magento2", "bugs": { diff --git a/packages/composables/package.json b/packages/composables/package.json index 322b7e5f6..1d3f49bc9 100644 --- a/packages/composables/package.json +++ b/packages/composables/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/magento", - "version": "1.0.0", + "version": "1.0.1", "license": "MIT", "homepage": "https://github.com/vuestorefront/magento2", "bugs": { @@ -29,7 +29,7 @@ }, "dependencies": { "@vue-storefront/core": "~2.5.6", - "@vue-storefront/magento-api": "^1.0.0", + "@vue-storefront/magento-api": "^1.0.1", "@vue/composition-api": "^1.4.1", "cookie-universal": "^2.1.5", "vue": "^2.6.14", diff --git a/packages/theme/package.json b/packages/theme/package.json index 42f7cf336..2efadae55 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -38,7 +38,7 @@ "@pinia/nuxt": "^0.1.9", "@storefront-ui/vue": "^0.13.3", "@vue-storefront/cache": "~2.7.1", - "@vue-storefront/magento-api": "^1.0.0", + "@vue-storefront/magento-api": "^1.0.1", "@vue-storefront/middleware": "~2.7.1", "@vue-storefront/nuxt": "~2.7.1", "@vue-storefront/redis-cache": "^1.0.1", From 5e8b81eeea2e8e884ff0533280ca2203d79f2806 Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Wed, 20 Jul 2022 12:13:17 +0200 Subject: [PATCH 19/55] docs: fix formatting in `Override queries` guide --- docs/guide/override-queries.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/guide/override-queries.md b/docs/guide/override-queries.md index 988a97552..e04ecfe1a 100644 --- a/docs/guide/override-queries.md +++ b/docs/guide/override-queries.md @@ -82,6 +82,7 @@ Make sure you have `graphgl-tag` installed as dependency prior using this sample }, }, }; +``` 4. Now you can restart your dev environment and view the updated data queried. From 67d08709412e55f82864ae830f7a7df0d7f56079 Mon Sep 17 00:00:00 2001 From: Marcin Kwiatkowski Date: Thu, 21 Jul 2022 14:37:01 +0200 Subject: [PATCH 20/55] chore: release 1.0.1 --- docs/migration-guides/1.0.1/index.md | 7 +++++++ docs/migration-guides/index.md | 1 + internals/eslint-import/package.json | 2 +- internals/eslint-jest/package.json | 2 +- internals/eslint-typescript/package.json | 2 +- internals/eslint-vue/package.json | 2 +- internals/eslint/package.json | 2 +- packages/load-tests/package.json | 2 +- packages/theme/package.json | 2 +- 9 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 docs/migration-guides/1.0.1/index.md diff --git a/docs/migration-guides/1.0.1/index.md b/docs/migration-guides/1.0.1/index.md new file mode 100644 index 000000000..c1a5ea12f --- /dev/null +++ b/docs/migration-guides/1.0.1/index.md @@ -0,0 +1,7 @@ +# Vue Storefront for Magento 1.0.1 release notes + +## Docs +- docs: fix formatting in Override queries guide [#1289](https://github.com/vuestorefront/magento2/pull/1289) + +## Bugfix +- fix: fixed the Vue version in package.json to avoid upgrading to Vue 2.7 [#1294](https://github.com/vuestorefront/magento2/pull/1294) diff --git a/docs/migration-guides/index.md b/docs/migration-guides/index.md index f8daf93f6..332ff57ec 100644 --- a/docs/migration-guides/index.md +++ b/docs/migration-guides/index.md @@ -1,5 +1,6 @@ # Migration guides +- [1.0.1](./1.0.1/) - [1.0.0](./1.0.0/) - [1.0.0-rc.10](./1.0.0-rc.10/) - [1.0.0-rc.9](./1.0.0-rc.9/) diff --git a/internals/eslint-import/package.json b/internals/eslint-import/package.json index 168493894..61a67f11f 100644 --- a/internals/eslint-import/package.json +++ b/internals/eslint-import/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/eslint-config-import", - "version": "1.0.0", + "version": "1.0.1", "author": "Heitor Ramon Ribeiro ", "license": "MIT", "scripts": { diff --git a/internals/eslint-jest/package.json b/internals/eslint-jest/package.json index 16cdc9441..4d215697a 100644 --- a/internals/eslint-jest/package.json +++ b/internals/eslint-jest/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/eslint-config-jest", - "version": "1.0.0", + "version": "1.0.1", "author": "Heitor Ramon Ribeiro ", "license": "MIT", "scripts": { diff --git a/internals/eslint-typescript/package.json b/internals/eslint-typescript/package.json index 5ebdfc6c2..dd6184a71 100644 --- a/internals/eslint-typescript/package.json +++ b/internals/eslint-typescript/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/eslint-config-typescript", - "version": "1.0.0", + "version": "1.0.1", "author": "Heitor Ramon Ribeiro ", "license": "MIT", "scripts": { diff --git a/internals/eslint-vue/package.json b/internals/eslint-vue/package.json index f0d8c7cfa..046195b9b 100644 --- a/internals/eslint-vue/package.json +++ b/internals/eslint-vue/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/eslint-config-vue", - "version": "1.0.0", + "version": "1.0.1", "author": "Heitor Ramon Ribeiro ", "license": "MIT", "scripts": { diff --git a/internals/eslint/package.json b/internals/eslint/package.json index 0c0256a19..6510e16f5 100644 --- a/internals/eslint/package.json +++ b/internals/eslint/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/eslint-config-base", - "version": "1.0.0", + "version": "1.0.1", "author": "Heitor Ramon Ribeiro ", "license": "MIT", "scripts": { diff --git a/packages/load-tests/package.json b/packages/load-tests/package.json index aa8b7738f..4d2c02840 100644 --- a/packages/load-tests/package.json +++ b/packages/load-tests/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/magento-load-tests", - "version": "1.0.0", + "version": "1.0.1", "description": "Load tests for Magento 2 - VSF integration", "main": "index.js", "repository": "https://github.com/vuestorefront/magento2", diff --git a/packages/theme/package.json b/packages/theme/package.json index 2efadae55..1a9921434 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/magento-theme", - "version": "1.0.0", + "version": "1.0.1", "private": true, "license": "MIT", "homepage": "https://github.com/vuestorefront/magento2", From 9829fcea91f69a0740417ae1d77fb3efe6940f74 Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Thu, 21 Jul 2022 14:25:47 +0200 Subject: [PATCH 21/55] fix: update vue dependencies - lock dependencies on the last working version to avoid upgrade issues --- packages/theme/package.json | 7 +++++-- yarn.lock | 30 +++++++++++++++--------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/packages/theme/package.json b/packages/theme/package.json index 1a9921434..5e86d3d98 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -57,9 +57,12 @@ "pinia": "^2.0.14", "pm2": "^5.2.0", "vee-validate": "^3.4.14", - "vue": "^2.6.14", + "vue": "2.6.14", + "vue-demi": "0.13.1", "vue-lazy-hydration": "^2.0.0-beta.4", - "vue-scrollto": "^2.20.0" + "vue-scrollto": "^2.20.0", + "vue-server-renderer": "2.6.14", + "vue-template-compiler": "2.6.14" }, "devDependencies": { "@babel/core": "^7.18.6", diff --git a/yarn.lock b/yarn.lock index e1048f0be..d2aa78933 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1905,7 +1905,7 @@ tslib "~2.3.0" value-or-promise "1.0.11" -"@graphql-typed-document-node/core@^3.0.0": +"@graphql-typed-document-node/core@^3.1.1": version "3.1.1" resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.1.1.tgz#076d78ce99822258cf813ecc1e7fa460fa74d052" integrity sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg== @@ -5116,11 +5116,6 @@ resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.31.tgz#c90de7126d833dcd3a4c7534d534be2fb41faa4e" integrity sha512-ymN2pj6zEjiKJZbrf98UM2pfDd6F2H7ksKw7NDt/ZZ1fh5Ei39X5tABugtT03ZRlWd9imccoK0hE8hpjpU7irQ== -"@vue/shared@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.37.tgz#8e6adc3f2759af52f0e85863dfb0b711ecc5c702" - integrity sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw== - "@vue/test-utils@^1.1.0", "@vue/test-utils@^1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.3.0.tgz#d563decdcd9c68a7bca151d4179a2bfd6d5c3e15" @@ -11344,7 +11339,7 @@ graphql-sse@^1.0.1: resolved "https://registry.yarnpkg.com/graphql-sse/-/graphql-sse-1.0.6.tgz#4f98e0a06f2020542ed054399116108491263224" integrity sha512-y2mVBN2KwNrzxX2KBncQ6kzc6JWvecxuBernrl0j65hsr6MAS3+Yn8PTFSOgRmtolxugepxveyZVQEuaNEbw3w== -graphql-tag@^2.11.0, graphql-tag@^2.12.3, graphql-tag@^2.12.6: +graphql-tag@^2.11.0, graphql-tag@^2.12.6: version "2.12.6" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1" integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg== @@ -20530,10 +20525,10 @@ trim-newlines@^3.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== -ts-invariant@^0.9.4: - version "0.9.4" - resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.9.4.tgz#42ac6c791aade267dd9dc65276549df5c5d71cac" - integrity sha512-63jtX/ZSwnUNi/WhXjnK8kz4cHHpYS60AnmA6ixz17l7E12a5puCWFlNpkne5Rl0J8TBPVHpGjsj4fxs8ObVLQ== +ts-invariant@^0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.10.3.tgz#3e048ff96e91459ffca01304dbc7f61c1f642f6c" + integrity sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ== dependencies: tslib "^2.1.0" @@ -21376,6 +21371,11 @@ vue-demi@*: resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.12.1.tgz#f7e18efbecffd11ab069d1472d7a06e319b4174c" integrity sha512-QL3ny+wX8c6Xm1/EZylbgzdoDolye+VpCXRhI2hug9dJTP3OUJ3lmiKN3CsVV3mOJKwFi0nsstbgob0vG7aoIw== +vue-demi@0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.1.tgz#7604904c88be338418a10abbc94d5b8caa14cb8c" + integrity sha512-xmkJ56koG3ptpLnpgmIzk9/4nFf4CqduSJbUM0OdPoU87NwRuZ6x49OLhjSa/fC15fV+5CbEnrxU4oyE022svg== + vue-demi@^0.12.1: version "0.12.4" resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.12.4.tgz#420dd17628f95f1bbce1102ad3c51074713a8049" @@ -21474,7 +21474,7 @@ vue-scrollto@^2.20.0: dependencies: bezier-easing "2.1.0" -vue-server-renderer@^2.6.12: +vue-server-renderer@2.6.14, vue-server-renderer@^2.6.12: version "2.6.14" resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.6.14.tgz#c8bffff152df6b47b858818ef8d524d2fc351654" integrity sha512-HifYRa/LW7cKywg9gd4ZtvtRuBlstQBao5ZCWlg40fyB4OPoGfEXAzxb0emSLv4pBDOHYx0UjpqvxpiQFEuoLA== @@ -21496,7 +21496,7 @@ vue-style-loader@^4.1.0, vue-style-loader@^4.1.3: hash-sum "^1.0.2" loader-utils "^1.0.2" -vue-template-compiler@^2.6.12, vue-template-compiler@^2.6.14, vue-template-compiler@^2.6.x: +vue-template-compiler@2.6.14, vue-template-compiler@^2.6.12, vue-template-compiler@^2.6.14, vue-template-compiler@^2.6.x: version "2.6.14" resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz#a2f0e7d985670d42c9c9ee0d044fed7690f4f763" integrity sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g== @@ -21514,7 +21514,7 @@ vue2-leaflet@^2.5.2: resolved "https://registry.yarnpkg.com/vue2-leaflet/-/vue2-leaflet-2.7.1.tgz#2f95c287621bf778f10804c88223877f5c049257" integrity sha512-K7HOlzRhjt3Z7+IvTqEavIBRbmCwSZSCVUlz9u4Rc+3xGCLsHKz4TAL4diAmfHElCQdPPVdZdJk8wPUt2fu6WQ== -vue@^2.6.11, vue@^2.6.12, vue@^2.6.14: +vue@2.6.14, vue@^2.6.11, vue@^2.6.12, vue@^2.6.14: version "2.6.14" resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.14.tgz#e51aa5250250d569a3fbad3a8a5a687d6036e235" integrity sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ== @@ -22237,7 +22237,7 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -zen-observable-ts@^1.2.0: +zen-observable-ts@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz#6c6d9ea3d3a842812c6e9519209365a122ba8b58" integrity sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg== From 925b528024b43a5e86f27c6f00f68c066d140835 Mon Sep 17 00:00:00 2001 From: maaarghk Date: Mon, 25 Jul 2022 22:18:25 +0100 Subject: [PATCH 22/55] docs: fix several oversights on 1.0.0-rc.10 breaking changes doc --- .../migration-guides/1.0.0-rc.10/rc.10-bic.md | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/migration-guides/1.0.0-rc.10/rc.10-bic.md b/docs/migration-guides/1.0.0-rc.10/rc.10-bic.md index 2223ef84e..4facc9a1b 100644 --- a/docs/migration-guides/1.0.0-rc.10/rc.10-bic.md +++ b/docs/migration-guides/1.0.0-rc.10/rc.10-bic.md @@ -1,24 +1,24 @@ # 1.0.0-rc.10 Backward incompatible changes reference -In this document, you can see crucial breaking changes in the `1.0.0-rc.10` comparing to `1.0.0-rc.9` release. To see all changes, please take a look at the [release pull request](https://github.com/vuestorefront/magento2/pull/1110) +In this document, you can see crucial breaking changes in the `1.0.0-rc.10` comparing to `1.0.0-rc.9` release. To see all changes, please take a look at the [release pull request](https://github.com/vuestorefront/magento2/pull/1202) -| File | what and how it changed | -|--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------| -| packages/api-client/src/api/productDetail/productDetailsQuery.ts | some fields have been moved to the packages/theme/modules/catalog/product/queries/getProductPriceBySku.gql.ts file | -| packages/theme/components/Checkout/UserBillingAddresses.vue | File has been deleted | -| packages/theme/modules/catalog/category/composables/useCategorySearch/index.ts | The search method params have been changed | -| packages/theme/modules/catalog/category/composables/useFacet/index.ts | The search method params have been changed | -| packages/theme/modules/catalog/pages/product.vue | the way of fetching product data has been changed | -| packages/theme/modules/checkout/components/CartPreview.vue | Moved to packages/theme/modules/checkout/components/CartPreview.vue | -| packages/theme/modules/checkout/components/UserShippingAddresses.vue | Moved to packages/theme/modules/checkout/components/UserShippingAddresses.vue | -| packages/theme/modules/checkout/components/VsfPaymentProvider.vue | Moved to packages/theme/modules/checkout/components/VsfPaymentProvider.vue | -| packages/theme/modules/checkout/components/VsfShippingProvider.vue | packages/theme/modules/checkout/components/VsfShippingProvider.vue | -| packages/theme/modules/checkout/composables/useBilling/index.ts | Params of the search method have been changed | -| packages/theme/modules/checkout/composables/useMakeOrder/commands/placeOrderCommand.ts | Params of the execute method have been changed | -| packages/theme/modules/checkout/composables/useMakeOrder/index.ts | Params of the make method have been changed | -| packages/theme/modules/checkout/composables/usePaymentProvider/commands/getAvailablePaymentMethodsCommand.ts | Params of the execute method have been changed | -| packages/theme/modules/checkout/composables/useShippingProvider/commands/setShippingMethodsOnCartCommand.ts | Params of the execute method have been changed | -| packages/theme/modules/customer/composables/useUserAddress/commands/createCustomerAddressCommand.ts | Params of the execute method have been changed | -| packages/theme/modules/customer/composables/useUserAddress/commands/deleteCustomerAddressCommand.ts | Params of the execute method have been changed | -| packages/theme/modules/customer/composables/useUserAddress/commands/updateCustomerAddressCommand.ts | Params of the execute method have been changed | -| packages/theme/modules/checkout/composables/useShippingProvider/index.ts | Params of the save method have been changed | +| File | what and how it changed | +|--------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------| +| packages/api-client/src/api/productDetail/productDetailsQuery.ts | the price_range fields have been moved to the packages/theme/modules/catalog/product/queries/getProductPriceBySku.gql.ts file | +| packages/theme/components/Checkout/UserBillingAddresses.vue | Moved to packages/theme/modules/checkout/components/UserBillingAddresses.vue | +| packages/theme/modules/catalog/category/composables/useCategorySearch/index.ts | The search method params have been changed | +| packages/theme/modules/catalog/category/composables/useFacet/index.ts | The search method params have been changed | +| packages/theme/modules/catalog/pages/product.vue | the way of fetching product data has been changed | +| packages/theme/modules/checkout/components/CartPreview.vue | Moved from packages/theme/components/Checkout/CartPreview.vue | +| packages/theme/modules/checkout/components/UserShippingAddresses.vue | Moved from packages/theme/components/Checkout/UserShippingAddresses.vue | +| packages/theme/modules/checkout/components/VsfPaymentProvider.vue | Moved from packages/theme/components/Checkout/VsfPaymentProvider.vue | +| packages/theme/modules/checkout/components/VsfShippingProvider.vue | Moved from packages/theme/components/Checkout/VsfShippingProvider.vue | +| packages/theme/modules/checkout/composables/useBilling/index.ts | Params of the search method have been changed | +| packages/theme/modules/checkout/composables/useMakeOrder/commands/placeOrderCommand.ts | Params of the execute method have been changed | +| packages/theme/modules/checkout/composables/useMakeOrder/index.ts | Params of the make method have been changed | +| packages/theme/modules/checkout/composables/usePaymentProvider/commands/getAvailablePaymentMethodsCommand.ts | Params of the execute method have been changed | +| packages/theme/modules/checkout/composables/useShippingProvider/commands/setShippingMethodsOnCartCommand.ts | Params of the execute method have been changed | +| packages/theme/modules/customer/composables/useUserAddress/commands/createCustomerAddressCommand.ts | Params of the execute method have been changed | +| packages/theme/modules/customer/composables/useUserAddress/commands/deleteCustomerAddressCommand.ts | Params of the execute method have been changed | +| packages/theme/modules/customer/composables/useUserAddress/commands/updateCustomerAddressCommand.ts | Params of the execute method have been changed | +| packages/theme/modules/checkout/composables/useShippingProvider/index.ts | Params of the save method have been changed | From 969b7695ae5373a089862ec21898e23d0ff91228 Mon Sep 17 00:00:00 2001 From: Artur Tagisow Date: Wed, 20 Jul 2022 10:17:18 +0200 Subject: [PATCH 23/55] ci: unify environment-related env vars update k6 action to select environments instead of urls, because with K6 we'll probably need 3 separate urls (middleware, frontend app and graphql endpoint) which would be painful to type in manually now you just input the env name and it selects the 3 urls on its own M2-1033 ci: update k6 script with new variables ci: update envs with new naming convention --- .../workflows/deploy-vue-storefront-cloud.yml | 34 ++++++++----------- .github/workflows/public_env_info/canary | 5 +++ .github/workflows/public_env_info/dev | 5 +++ .github/workflows/public_env_info/enterprise | 5 +++ .github/workflows/public_env_info/production | 5 +++ .github/workflows/run-k6-load-test.yml | 16 ++++----- 6 files changed, 42 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/public_env_info/canary create mode 100644 .github/workflows/public_env_info/dev create mode 100644 .github/workflows/public_env_info/enterprise create mode 100644 .github/workflows/public_env_info/production diff --git a/.github/workflows/deploy-vue-storefront-cloud.yml b/.github/workflows/deploy-vue-storefront-cloud.yml index fdd14e225..89cb59d49 100644 --- a/.github/workflows/deploy-vue-storefront-cloud.yml +++ b/.github/workflows/deploy-vue-storefront-cloud.yml @@ -17,47 +17,43 @@ jobs: deployment_id: ${{ steps.deployment.outputs.deployment_id }} steps: - name: Determine environment-specific variables - id: determine-environment shell: bash run: | REF=${{ github.ref }} if [ $REF = 'refs/heads/main' ]; then - ENVNAME='production' - ENVCODE='demo-magento2' - MIDDLEWARE_URL='https://demo-magento2.europe-west1.gcp.vuestorefront.cloud/api/' + ENVINFO_FILE=production elif [ $REF = 'refs/heads/develop' ]; then - ENVNAME='dev' - ENVCODE='demo-magento2-dev' - MIDDLEWARE_URL='https://demo-magento2-dev.europe-west1.gcp.storefrontcloud.io/api/' + ENVINFO_FILE=dev elif [[ $REF = refs/heads/release* ]]; then - ENVNAME='canary' - ENVCODE='demo-magento2-canary' - MIDDLEWARE_URL='https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io/api/' + ENVINFO_FILE=canary elif [ $REF = 'refs/heads/enterprise' ]; then - ENVNAME='enterprise' - ENVCODE='demo-magento2-enterprise' - MIDDLEWARE_URL='https://demo-magento2-enterprise.europe-west1.gcp.storefrontcloud.io/api/' + ENVINFO_FILE=enterprise else - echo 'unrecognized branch name' - exit 1 + echo 'unrecognized branch name' + exit 1 fi - echo ::set-output name=name::$ENVNAME - echo ::set-output name=code::$ENVCODE - echo ::set-output name=middleware-url::$MIDDLEWARE_URL + cat .github/workflows/public_env_info/$ENVINFO_FILE >> $GITHUB_ENV + + - id: determine-environment + run: | + echo ::set-output name=name::${{ env.ENVNAME }} + echo ::set-output name=code::${{ env.ENVCODE }} + echo ::set-output name=middleware-url::${{ env.MIDDLEWARE_URL }} - name: Create GitHub deployment id: deployment uses: chrnorm/deployment-action@v2 with: token: ${{ secrets.DEPLOYMENT_PERSONAL_ACCESS_TOKEN }} - environment: ${{ steps.determine-environment.outputs.name }} + environment: ${{ env.ENVNAME }} initial-status: in_progress + build: needs: create-deployment runs-on: ubuntu-latest diff --git a/.github/workflows/public_env_info/canary b/.github/workflows/public_env_info/canary new file mode 100644 index 000000000..fddb3b3d7 --- /dev/null +++ b/.github/workflows/public_env_info/canary @@ -0,0 +1,5 @@ +ENVNAME=canary +ENVCODE=demo-magento2-canary +BASE_URL=https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io +MIDDLEWARE_URL=https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io/api +MAGENTO_GRAPHQL_URL=https://magento2-instance.vuestorefront.io:8443/graphql diff --git a/.github/workflows/public_env_info/dev b/.github/workflows/public_env_info/dev new file mode 100644 index 000000000..e3aec0cb5 --- /dev/null +++ b/.github/workflows/public_env_info/dev @@ -0,0 +1,5 @@ +ENVNAME=dev +ENVCODE=demo-magento2-dev +BASE_URL=https://demo-magento2-dev.europe-west1.gcp.storefrontcloud.io +MIDDLEWARE_URL=https://demo-magento2-dev.europe-west1.gcp.storefrontcloud.io/api +MAGENTO_GRAPHQL_URL=https://magento2-instance.vuestorefront.io:8443/graphql diff --git a/.github/workflows/public_env_info/enterprise b/.github/workflows/public_env_info/enterprise new file mode 100644 index 000000000..4d7efada1 --- /dev/null +++ b/.github/workflows/public_env_info/enterprise @@ -0,0 +1,5 @@ +ENVNAME=enterprise +ENVCODE=demo-magento2-enterprise +BASE_URL=https://demo-magento2-enterprise.europe-west1.gcp.storefrontcloud.io +MIDDLEWARE_URL=https://demo-magento2-enterprise.europe-west1.gcp.storefrontcloud.io/api +MAGENTO_GRAPHQL_URL=https://magento2-instance.vuestorefront.io:8443/graphql diff --git a/.github/workflows/public_env_info/production b/.github/workflows/public_env_info/production new file mode 100644 index 000000000..d9696b5f6 --- /dev/null +++ b/.github/workflows/public_env_info/production @@ -0,0 +1,5 @@ +ENVNAME=production +ENVCODE=demo-magento2 +BASE_URL=https://demo-magento2.europe-west1.gcp.vuestorefront.cloud +MIDDLEWARE_URL=https://demo-magento2.europe-west1.gcp.vuestorefront.cloud/api +MAGENTO_GRAPHQL_URL=https://magento2-instance.vuestorefront.io:8443/graphql diff --git a/.github/workflows/run-k6-load-test.yml b/.github/workflows/run-k6-load-test.yml index 19388bf31..44e8501f0 100644 --- a/.github/workflows/run-k6-load-test.yml +++ b/.github/workflows/run-k6-load-test.yml @@ -17,13 +17,8 @@ on: environment: description: The full URL of the environment on which load tests will be ran required: true - default: 'https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io' - type: choice - options: - - 'https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io' - - 'https://demo-magento2-dev.europe-west1.gcp.storefrontcloud.io' - - 'https://demo-magento2.europe-west1.gcp.storefrontcloud.cloud' - - 'https://demo-magento2-enterprise.europe-west1.gcp.storefrontcloud.io' + default: canary + type: environment flags: description: Additional argument and flags to provide to the k6 CLI. See https://k6.io/docs/using-k6/options for details. @@ -40,10 +35,13 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Run k6 cloud test + - run: | + cat .github/workflows/public_env_info/${{ inputs.environment }} >> $GITHUB_ENV + + - name: Run k6 test uses: grafana/k6-action@v0.2.0 with: cloud: ${{ github.event.inputs.cloud }} token: ${{ secrets.K6_CLOUD_API_TOKEN }} filename: ${{ github.event.inputs.filename }} - flags: -e BASE_URL=${{ github.event.inputs.environment }} ${{ github.event.inputs.flags }} + flags: -e BASE_URL=${{ env.BASE_URL }} -e MIDDLEWARE_URL=${{ env.MIDDLEWARE_URL }} -e MAGENTO_GRAPHQL_URL=${{ env.MAGENTO_GRAPHQL_URL }} ${{ github.event.inputs.flags }} From a599404011340eb565cfe756376eee0c541459d3 Mon Sep 17 00:00:00 2001 From: Matt Maribojoc Date: Tue, 2 Aug 2022 08:17:26 -0500 Subject: [PATCH 24/55] docs: fix wording + add installation video (#1319) --- docs/.vuepress/config.js | 24 +-- docs/getting-started/configuration.md | 108 ------------- docs/getting-started/internationalization.md | 158 ------------------- docs/getting-started/introduction.md | 47 ------ docs/getting-started/layouts-and-routing.md | 145 ----------------- docs/getting-started/project-structure.md | 45 ------ docs/getting-started/theme.md | 109 ------------- docs/guide/graphql-get.md | 8 +- docs/guide/override-queries.md | 97 ++++++------ docs/guide/ssr.md | 26 +-- docs/index.md | 9 +- docs/installation-setup/installation.md | 4 + docs/package.json | 2 +- docs/plugins/index.md | 27 +--- docs/yarn.lock | 8 +- 15 files changed, 99 insertions(+), 718 deletions(-) delete mode 100644 docs/getting-started/configuration.md delete mode 100644 docs/getting-started/internationalization.md delete mode 100644 docs/getting-started/introduction.md delete mode 100644 docs/getting-started/layouts-and-routing.md delete mode 100644 docs/getting-started/project-structure.md delete mode 100644 docs/getting-started/theme.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index d7efe31dd..d6d6fc1f7 100755 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -93,18 +93,6 @@ module.exports = { ['/installation-setup/configure-integration', 'Configuring Vue Storefront'], ], }, - { - title: 'Getting started', - collapsable: true, - children: [ - ['/getting-started/introduction', 'Introduction'], - ['/getting-started/project-structure', 'Project structure'], - ['/getting-started/configuration', 'Configuration'], - ['/getting-started/layouts-and-routing', 'Layouts and Routing'], - ['/getting-started/theme', 'Theme'], - ['/getting-started/internationalization', 'Internationalization'], - ], - }, { title: 'Composition', collapsable: true, @@ -164,6 +152,18 @@ module.exports = { ['/improvements/analytics/', 'Analytics'], ], }, + { + title: 'Learn Vue Storefront', + collapsable: true, + children: [ + ['https://docs.vuestorefront.io/v2/getting-started/introduction.html', 'What is Vue Storefront?'], + ['https://docs.vuestorefront.io/v2/getting-started/project-structure.html', 'Project structure'], + ['https://docs.vuestorefront.io/v2/getting-started/configuration.html', 'Configuration'], + ['https://docs.vuestorefront.io/v2/getting-started/layouts-and-routing.html', 'Layouts and Routing'], + ['https://docs.vuestorefront.io/v2/getting-started/theme.html', 'Theme'], + ['https://docs.vuestorefront.io/v2/getting-started/internationalization.html', 'Internationalization'], + ], + }, ], }, }; diff --git a/docs/getting-started/configuration.md b/docs/getting-started/configuration.md deleted file mode 100644 index ca16eb327..000000000 --- a/docs/getting-started/configuration.md +++ /dev/null @@ -1,108 +0,0 @@ -# Configuration - -Whenever starting a new project or jumping into an existing one, you should look into the configuration files first. They control almost every aspect of the application, including installed integrations. - -## Mandatory configuration files - -Every Vue Storefront project must contain two configuration files described below. They control both client and server parts of the application. - -### `nuxt.config.js` - -**The `nuxt.config.js` file is the starting point of every project.** It contains general configuration, including routes, global middlewares, internationalization, or build information. This file also registers modules and plugins to add or extend framework features. Because almost every Vue Storefront integration has a module or plugin, you can identify which integrations are used by looking at this file. - -You can learn more about this file and available configuration options on the [Nuxt configuration file](https://nuxtjs.org/docs/directory-structure/nuxt-config/) page. - -### `middleware.config.js` - -The `middleware.config.js` file is as essential as `nuxt.config.js`, but much simpler and likely smaller. It configures the Server Middleware used for communication with e-commerce platforms and contains sensitive credentials, custom endpoints, queries, etc. - -### `.env` - -The `.env` file contains environmental variables used in both `nuxt.config.js` and `middleware.config.js` files for configuration that differs per environment. New projects come with a `.env.example` that you can rename (or clone) to the `.env` file and configure. - -## Optional configuration files - -Your project might include some additional configuration files not described above. Let's walk through the most common ones. - -- [`tsconfig.json`](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) configures compiler used to strongly type the project using TypeScript language. It defines a list of files and directories to be included and excluded from analysis and compiling. - -- [`babel.config.js`](https://babeljs.io/docs/en/config-files) configures Babel compiler used to make the code backward compatible with older browsers and environments. - -- [`ecosystem.config.js`](https://pm2.keymetrics.io/docs/usage/application-declaration/) configures PM2 Process Management that runs and manages Node application. - -- [`jest.config.js`](https://jestjs.io/docs/configuration) configures Jest testing framework, used for writing and running unit tests. - -## Magento Configuration - -In some cases Magento doesn't provide configuration values by GraphQL API. Then we recommend to set up a configuration -fields and values in the `middleware.config.js` file. Example: - -```javascript -customer: { - customer_create_account_confirm: true -} -``` - -### How to set a config flag in the middleware.config.js -When you want to set a new flag, you need to: -1. declare field in the `integrations.magento` object: -```javascript -module.exports = { - integrations: { - magento: { - // (...) other fields - foo: { // your new area of config - your_new_config_value: true // your new flag - } - } - } -} -``` -2. Get a new field in the `nuxt.config.js` file from the middleware config: -```javascript -import middleware from './middleware.config'; - -const { - integrations: { - magento: { - configuration: { - cookies, - externalCheckout, - // (...) other fields - foo // your new object - }, - }, - }, -} = middleware; -``` -3. Pass the new field to the `'~/modules/magento'` module configuration: -```javascript -['~/modules/magento', { - cookies, - externalCheckout, - // (...) other fields - foo // your new object -}], -``` -4. Now you can get the value of your config object in a composable/compoonent like this: -```javascript -import { useContext } from '@nuxtjs/composition-api'; -// (...) -const { app } = useContext(); -const { foo } = app.context.$vsf.$magento.config; // here you go -``` - -#### Predefined Magento config fields -##### Customer -`customer_create_account_confirm` - it correspond to the Magento **Require Emails Confirmation** config flag: - -**Magento config:** `Stores -> Configuration -> Customers -> Customers configuration -> Require Emails Confirmation` -**Possible values:** `boolean` - -**Consequences:** -- when is set to true, then email confirmation is required after customer registration. -- when is set to false, user can register and then is immediately logged-in as a customer. - -## What's next - -As the next step, we will learn about [Layouts and Routing](./layouts-and-routing.html) and show what routes come predefined in every Vue Storefront project and how to register custom ones. diff --git a/docs/getting-started/internationalization.md b/docs/getting-started/internationalization.md deleted file mode 100644 index 97a6638d5..000000000 --- a/docs/getting-started/internationalization.md +++ /dev/null @@ -1,158 +0,0 @@ -# Internationalization - -If you're building a shop for an international brand, you likely want it translated to different languages and using different currencies. In this document, you will learn how we're approaching internationalization in Vue Storefront and how to configure your application to use it. - -::: warning i18n is not multi-tenancy! -This document only explains how to make a single shop instance available for multiple countries. If you need to build a system for multiple tenants, we suggest creating an instance of Vue Storefront for each tenant and sharing common resources through an NPM package. -::: - -## How it works by default? - -By default, we are using the [`nuxt-i18n`](https://i18n.nuxtjs.org/) module for handling both translations and currencies. It's preinstalled in the [default theme](/getting-started/theme.html#what-s-makes-a-default-theme) and is configured for English and German translations out of the box. - -The `nuxt-i18n` module adds the `$t('key')` and `$n(number)` helpers to translate strings and format the currencies. - -You can find the translation keys in the `lang` directory of your project and configuration for currencies in `nuxt.config.js`. - -::: tip -Even though the module is included in the default theme, it's not required. You can [disable it](#configuring-modules-separately) and handle internationalization yourself. -::: - -To provide a unified way to configure internationalization across the application for different modules and integrations, we have introduced the `i18n` field in each module's configuration. It has the same format as the `nuxt-i18n` options. You can add any configuration there, and it will be propagated to all other Vue Storefront modules. - -All Vue Storefront integrations have the `useNuxtI18nConfig` property set to `true`. It means that they will use the same configuration as you provided for `nuxt-i18n` in the `i18n` field of your `nuxt.config.js`. - -```js -// nuxt.config.js - -export default { - buildModules: [ - [ - '@vue-storefront/{INTEGRATION}/nuxt', - { - // other comfiguration options - i18n: { - useNuxtI18nConfig: true, - }, - }, - ], - ], - i18n: { - locales: [ - { - code: 'en', - label: 'English', - file: 'en.js', - iso: 'en', - }, - { - code: 'de', - label: 'German', - file: 'de.js', - iso: 'de', - }, - ], - defaultLocale: 'en', - }, -}; -``` - -## Configuring modules separately - -You can provide your own i18n configuration for a specific module by setting `useNuxtI18nConfig` to `false`. - -```js -// nuxt.config.js - -export default { - [ - '@vue-storefront/{INTEGRATION}/nuxt', - { - i18n: { - useNuxtI18nConfig: false, - locales: [ - { - code: 'en', - label: 'English', - file: 'en.js', - iso: 'en', - }, - { - code: 'de', - label: 'German', - file: 'de.js', - iso: 'de', - }, - ], - defaultLocale: 'en' - } - } - ]; -} -``` - -## CDN and cookies - -The server's response cannot contain the `Set-Cookie` header to make CDNs cache the website correctly. - -To achieve that, we've made our own mechanism for handling cookies responsible for storing `locale`, `currency`, and `country`. This mechanism also handles language detection and redirecting to the proper locale. For this reason, `@nuxtjs/i18n` language detection is disabled by default. - -```js -// nuxt.config.js -export default { - i18n: { - detectBrowserLanguage: false, - }, -}; -``` - -If you don't want to redirect users, you can disable this mechanism, as described in the section below. - -## Disabling the auto-redirect mechanism - -The `@vue-storefront/nuxt` module includes an auto-redirect mechanism that performs a server-side redirect to different URLs based on the target locale. - -You can disable this by setting `autoRedirectByLocale` to `false` in the `i18n` configuration object. - -```js -// nuxt.config.js - -export default { - i18n: { - autoRedirectByLocale: false, - }, -}; -``` - -## Currency detection - -In addition to language detection, we also set currency based on locale. You can configure it in `nuxt.config.js` with the `vueI18n.numberFormats` property. - -For more configuration options of `numberFormats` entries, check the [Intl.NumberFormat()](https://developer.mozilla.org/en-US/docs/web/javascript/reference/global_objects/intl/numberformat) documentation. - -```js -// nuxt.config.js - -export default { - i18n: { - vueI18n: { - numberFormats: { - en: { - currency: { - style: 'currency', - currency: 'USD', - currencyDisplay: 'symbol', - }, - }, - // ...other locales - }, - }, - }, -}; -``` - -**Please note that only one currency can be set for each locale.** - -If this is a limitation for you, or if you don't want to have currencies tied to locales, you can disable this mechanism and provide your own. - -To disable it, set `autoChangeCookie.currency` to `false` as described in the section below. diff --git a/docs/getting-started/introduction.md b/docs/getting-started/introduction.md deleted file mode 100644 index bad4cc914..000000000 --- a/docs/getting-started/introduction.md +++ /dev/null @@ -1,47 +0,0 @@ -# Introduction to Vue Storefront - -Without a proper understanding of the framework you're using, you might spend weeks or even months doing something that someone else has already done. That's why before we can dive deep into the project itself, we need to understand what powers it all under the hood. - - - -## It's all Nuxt.js - -We didn't want to reinvent the wheel and introduce yet another framework that solves the same issues as its predecessors, which took them years to mature. That's why... - -> Vue Storefront is essentially a [Nuxt.js](https://nuxtjs.org/) project with some plugins and modules preinstalled, as well as a ready-to-use e-commerce theme. Nuxt.js handles most of the front-end work and [Server Side Rendering](https://nuxtjs.org/docs/concepts/server-side-rendering/), while Vue Storefront adds the e-commerce specific bits and integrations to various platforms. - -Some of the plugins and modules that come with the fresh installation were created by the Nuxt.js community, and others come from our core team specifically for Vue Storefront projects. - -The default theme mainly consists of components from the [Storefront UI](http://storefrontui.io/) — an e-commerce focused UI library maintained by the Vue Storefront team. - -We described plugins, modules, and the theme in more detail on the following pages. - -### But why? - -You might be wondering why we choose Nuxt.js as our foundation. After all, it wasn't created with e-commerce in mind. - -When you start using any new framework, you expect it to: - -- have **plugins that solve common issues**, such as analytics, SEO, internationalization, etc., -- be **versatile and flexible** enough to allow extending it and creating custom integrations, -- have **active and diverse community**, which answers questions, writes articles, and promotes the framework. - -Creating such an ecosystem from scratch takes years. But because we based Vue Storefront on Nuxt.js — the biggest Vue.js framework — it ticks all the boxes. Nuxt.js has a vast library of [ready-to-use modules](https://modules.nuxtjs.org/) and an active community of thousands of developers on the [Nuxt.js Discord server](https://discord.com/invite/ps2h6QT). It's also flexible enough to make it e-commerce ready with just a few plugins and modules. - -> Combining general-purpose modules from Nuxt.js and e-commerce specific modules from Vue Storefront significantly shortens the time-to-market. It allows you to focus on what's specific to your project. - -## Start with Vue.js - -If you are new to the Vue.js ecosystem, the best place to start learning is the [Vue.js 2 documentation](https://v2.vuejs.org/). **In our documentation, we assume prior knowledge of Vue.js (with some exceptions)**. While we do our best to explain each topic in detail, a lack of this knowledge might cause you to get lost. - -We also encourage reading [Nuxt.js 2 documentation](https://nuxtjs.org/docs/). In most places, we don't assume this knowledge and add links to related documents, but having it will make you more confident and let you work faster and more efficiently. - -## What's next - -Now that you understand what Vue Storefront is, go to the [Installation](./installation.html) guide to set up a project. diff --git a/docs/getting-started/layouts-and-routing.md b/docs/getting-started/layouts-and-routing.md deleted file mode 100644 index a4515ba4e..000000000 --- a/docs/getting-started/layouts-and-routing.md +++ /dev/null @@ -1,145 +0,0 @@ -# Layouts and Routing - -Layouts and Routing in Vue Storefront are entirely powered by Nuxt.js. We will only give a brief overview of these features on this page, but you can learn more on the [Views](https://nuxtjs.org/docs/concepts/views/) page in the Nuxt.js documentation. - -## View hierarchy - -Every page consists of layers — some layers are shared between many routes, others are used in one specific route. We described each layer in detail in the sections below. - -### HTML document - -At the root of the hierarchy is the HTML document. By default, the framework provides one, but you can customize it by creating an `app.html` file in the root directory of your project. It has special tags used to insert parts of the documents, and by default, looks like this: - -```html - - - - {{ HEAD }} - - - {{ APP }} - - -``` - -### Layouts - -Nuxt.js automatically registers all `.vue` files inside of the `layouts` directory as layouts. Unless configured otherwise, pages use the `default.vue` component as their layout. Open the `layouts/default.vue` component to get the general idea of how the page looks like, what components it imports and what data it loads within the `setup` function. - -Layout components include a special `` component that displays the page's content based on the current URL. Those pages are Vue.js components, too, explained in the next section. - -There is also an `error.vue` layout — used when an error occurs. It doesn't use the `` component but receives the `error` prop, which you can use to get an error code or message. - -The convention is to use `lowercase` when naming components inside of the `layouts` directory, e.g., `blog.vue`. - -### Pages - -Nuxt.js automatically registers all `.vue` files inside the `pages` directory as application routes. For example, creating an `AboutUs.vue` component will create an `/aboutus` route. In the same way, creating this component inside a nested directory called `company` will create the `/company/aboutus` route. It's all thanks to the [File System Routing](https://nuxtjs.org/docs/2.x/features/file-system-routing/) feature available in Nuxt.js. In the sections below, we describe how to modify routes manually. - -Pages can define a custom [layout](https://nuxtjs.org/docs/directory-structure/pages#layout) property to change the default used for this view. - -The convention is to use `PascalCase` when naming components inside of the `pages` directory, e.g., `MyAccount.vue`. - -## Manually adding and modifying routes - -If you want to manually add your custom routes or modify some already provided, use the `extendRoutes` function in the `nuxt.config.js`. This function has two properties: - -* `routes` — an array of already registered routes. You can `push` or delete entries from it. -* `resolve` — helper function for resolving Vue.js components based on their paths in the project. - -For the sake of example, let's assume that we created a `pages/AboutUs.vue` component, but we want to use the `/company/about-us` route instead of auto-registered `/aboutus`. There are two approaches we could take. - -The first approach is to **delete existing route** and **register new route** with a different path. - -```javascript -// nuxt.config.js - -export default { - router: { - extendRoutes(routes, resolve) { - // Delete automatically registered route - routes.splice( - routes.findIndex(route => route.path === '/AboutUs'), - 1 - ); - - // Re-register the same component but with different path - routes.push({ - name: 'AboutUs', - path: '/company/about-us', - component: resolve(__dirname, 'pages/AboutUs.vue') - }); - } - } -}; -``` - -Alternatively, we can **modify the `path` property of the existing entry** like so: - -```javascript -// nuxt.config.js - -export default { - router: { - extendRoutes(routes, resolve) { - // Find route index - const index = routes.findIndex(route => route.path === '/AboutUs'); - - // Modify route path - routes[index].path = '/company/about-us'; - } - } -}; -``` - -## Changing base path - -There are cases when your store is served under a specific path, eg. `example.com/shop/`. To make Vue.js router aware of this, you need to update the configuration in the `nuxt.config.js`: - -```javascript -// nuxt.config.js - -export default { - router: { - base: "/shop/" - } -}; -``` - -Unfortunately not all links in your application will detect this. You can fix it, by wrap all relative links and paths to assets in `addBasePath` helper. - -```vue - - - -``` - -## Navigating between pages - -To navigate between pages within your application, use the [NuxtLink](https://nuxtjs.org/docs/features/nuxt-components/#the-nuxtlink-component) component, instead of the traditional `` tag. While you can use the `` tag for external links, using the `` for internal links will ensure that you make use of the Single-Page Navigation capabilities that Nuxt.js provides. - -Single-Page Navigation (SPA) provides many benefits, such as: - -* much faster and more responsive navigation compared to the traditional server navigation, -* framework is initialized only once, -* components shared between the pages are rendered only once (if they use the same layout), -* fewer requests and data sent over the network. - -## What's next - -Layouts and pages are one thing, but in the end, they must display components and styles. Otherwise, we would only serve blank pages. - -New projects come with a default [Theme](./theme.html), so the next step is to understand what makes it look like this. diff --git a/docs/getting-started/project-structure.md b/docs/getting-started/project-structure.md deleted file mode 100644 index c9a109ca4..000000000 --- a/docs/getting-started/project-structure.md +++ /dev/null @@ -1,45 +0,0 @@ -# Project structure - -If you followed our [Installation](/installation-setup/installation.html) guide, you should have a Vue Storefront project with some Magento already integrated. This project has a bunch of directories, Vue components, and files, but what does what? - -In this section, you will learn how to navigate the Vue Storefront project and where to start developing. - -## Structure basics - -As described on the [Introduction to Vue Storefront](./introduction.html) page, Vue Storefront is just a Nuxt.js project under the hood. For this reason, our project structure inherits from Nuxt.js but has some additional files. - -To learn about it in-depth, you can refer to the [Directory Structure in Nuxt.js project](https://nuxtjs.org/docs/get-started/directory-structure/) document, but the gist of it is: - -* [**.nuxt**](https://nuxtjs.org/docs/2.x/directory-structure/nuxt) is a dynamically generated build directory. You should **not** manually modify it, nor synchronize it using version control like GIT. - -* [**assets**](https://nuxtjs.org/docs/2.x/directory-structure/assets) contains uncompiled assets such as your styles, images, or fonts. - -* [**components**](https://nuxtjs.org/docs/2.x/directory-structure/components) contains Vue.js components used on different pages or parts of your application. You can import these components from pages, layouts, and other components. - -* **composables** provides business logic that can be used in any place in the app. - -* **getters** are functions that help to get commonly used data. - -* **helpers** are utility functions that help resolve some common tasks like for example format currency - -* [**lang**](https://docs.vuestorefront.io/v2/getting-started/internationalization.html) contains translations for your application. Available locales are configured in the `nuxt.config.js` file. - -* [**layouts**](https://nuxtjs.org/docs/2.x/directory-structure/layouts) contains Vue.js components that act as a UI base for the whole application or specific pages. - -* [**middleware**](https://nuxtjs.org/docs/2.x/directory-structure/middleware) contains JavaScript files that contain custom functions run before rendering a whole application or just a specific layout or page. These can be used, for example, to protect pages from unauthorized access or redirect if some conditions are not met. - -* **modules** contains code related to specific area of the app like customer, checkout and so on. Each module can have components, helpers, composables and other files and services - -* [**pages**](https://nuxtjs.org/docs/2.x/directory-structure/pages) contains Vue.js components that Nuxt.js automatically registers as routes. - -* [**static**](https://nuxtjs.org/docs/2.x/directory-structure/static) contains files that likely won't change, such as favicon, `robots.txt`, sitemap, or company logos. - -* **test-utils** contains utilities and helpers for unit testing. - -* **types** provides global TypeScript types - -* **middleware.config.js** and **nuxt.config.js** configurations file are described in detail in the [Configuration](./configuration.html) document. - -## What's next - -With a basic understanding of the project structure, it's time to learn about the [Configuration](./configuration.html) files that control the application and installed integrations. They are a crucial part of every Vue Storefront application. diff --git a/docs/getting-started/theme.md b/docs/getting-started/theme.md deleted file mode 100644 index bb108c12f..000000000 --- a/docs/getting-started/theme.md +++ /dev/null @@ -1,109 +0,0 @@ -# Theme - -A project without any theme would just show a blank page, but if you have seen any of Vue Storefront demos or created a project using our CLI, you know that's not the case. So what makes it look like it does? - -This page will describe what makes the default theme, how to customize it, and what tricks we use to improve the performance. - -## What's makes a default theme - -### Preinstalled modules and libraries - -Every new Vue Storefront project comes with a set of preinstalled Nuxt.js modules and plugins, as well as Vue.js libraries. These packages offer a variety of features from cookie handling to form validation and are used by the base theme. You can remove some of them, but only if you decide to create a custom theme from scratch. - -#### Nuxt.js modules and plugins - -- [`@nuxt/typescript-build`](https://typescript.nuxtjs.org/) - for TypeScript support, - -- [`@nuxtjs/pwa`](https://pwa.nuxtjs.org/) - for PWA functionalities, - -- [`@nuxtjs/composition-api`](https://composition-api.nuxtjs.org/) - for Composition API support, - -- [`@nuxtjs/style-resources`](https://www.npmjs.com/package/@nuxtjs/style-resources) - for importing SASS variables globally, - -- [`nuxt-i18n`](https://i18n-legacy.nuxtjs.org/) - for internationalization (translations and price formatting), - -- [`nuxt-purgecss`](https://purgecss.com/guides/nuxt.html) - for removing unused CSS from the final build, - -- [`cookie-universal-nuxt`](https://www.npmjs.com/package/cookie-universal-nuxt) - for handling cookies on the server (SSR) and client (browser). - -#### Vue.js libraries - -- [`vee-validate`](https://vee-validate.logaretm.com/v3) - for frontend form validation, - -- [`vue-scrollto/nuxt`](https://www.npmjs.com/package/vue-scrollto) - for smooth scrolling to HTML elements, - -- [`vue-lazy-hydration`](https://www.npmjs.com/package/vue-lazy-hydration) - for delaying hydration and improving performance. - -### Storefront UI - -
- StorefrontUI logo and default theme -
(Click to zoom)
-
- -Almost every page in our default theme uses components whose names start with `Sf`. These come from the [Storefront UI](http://storefrontui.io/) — a design system and library of Vue.js components dedicated to e-commerce, maintained by the Vue Storefront team. Every component can be heavily customized using [props](https://v2.vuejs.org/v2/guide/components-props.html) and [slots](https://v2.vuejs.org/v2/guide/components-slots.html). - -Please check [Storefront UI documentation](https://docs.storefrontui.io/) to learn more and interactively customize and test the components. - -::: tip Want to use another UI library? No problem! -If you don't want to use Storefront UI, feel free to remove it from your project. It's just a UI layer, and the project can work with any other UI library or a custom code. -::: - -## How to customize the theme - -Every default theme will need customization at some point. Regardless of how complex the changes are, we recommend reusing as much from the default theme as possible. This will not only save you time but will likely reduce the number of bugs, thanks to the time we spend on stabilization and testing. - -### Updating layouts, pages, and components - -To update the existing component, you need to identify it first, and Vue.js Devtools is invaluable in this. Open the Vue.js Devtools, right-click the DOM element you want to update, and select `Inspect Vue component`. One of the components in the tree in Vue.js Devtools should get highlighted. You can look for the component with the same name in the `layout`, `pages`, or `components` directories and update it to your needs. However, there are a few exceptions to this rule described below. - -#### `Sf` components - -If the component's name starts with `Sf`, it means that it comes from [StorefrontUI](https://storefrontui.io/) library. The look and behavior of such components are controlled using props and slots passed from the direct **parent** component. - -#### `LazyHydrate` and `Anonymous Component` components - -These two components come from the [vue-lazy-hydration](https://github.com/maoberlehner/vue-lazy-hydration) library and are wrappers around other components. They are used to improve the performance by deferring the hydration process (making components interactive) and don't affect the look of other components. The behavior of such components is controlled using props passed from the direct **parent** component. - -### Updating styles - -There are a few ways of updating the default styles. Below we describe the most optimal methods for the most common cases. - -#### Adding global styleheet - -To add global styles applied to all pages, use the [css property](https://nuxtjs.org/docs/2.x/configuration-glossary/configuration-css/) in `nuxt.config.js`. - -#### Adding stylesheet to specific layout, page, or component - -To add a stylesheet to a specific component, use `@import` regardless of whether you are using CSS, SCSS, or LESS. - -```vue - -``` - -#### Using variables, mixins, and function in components - -Usually, to access style variables, mixins, and functions, we import them in every component separately. Thanks to the [@nuxtjs/style-resources](https://github.com/nuxt-community/style-resources-module#readme) module, we can register them in `nuxt.config.js` and access them without extra `@import` statements. - -:::danger Be careful -Stylesheets in `styleResources` should **only** contain variables, mixins, and functions. During the build process, the components import these stylesheets. Any **styles** declared in them are added to every component, significantly impacting the performance and application size. -::: - -We use this approach to have access to StorefrontUI helpers in all components: - -```javascript -// nuxt.config.js - -export default { - styleResources: { - scss: [ - require.resolve('@storefront-ui/shared/styles/_helpers.scss', { paths: [process.cwd()] }) - ] - }, -}; -``` diff --git a/docs/guide/graphql-get.md b/docs/guide/graphql-get.md index 88cb721f8..7d93a5994 100644 --- a/docs/guide/graphql-get.md +++ b/docs/guide/graphql-get.md @@ -1,12 +1,13 @@ # Use GET for GraphQL Queries -In Magento we can leverage the power of GET requests caching, to improve the performance of your GrpahQL API. In order to do this, you need to setup your Magento backend and configure the Vue Storefront Magento integration. +In Magento we can leverage the power of GET requests caching, to improve the performance of your GrpahQL API. In order to do this, you need to setup your Magento backend and configure the Vue Storefront Magento integration. ## Enabling GraphQL Caching on Magento with Varnish To enable the GraphQL caching on Magento, first you need to have installed the Varnish and have it configured into your environment. 1. Edit the `default.vcl` file on your system, and update the `vcl_hash` subroutine, to check whether the request URL contains `graphql`, as follows: + ``` sub vcl_hash { if (req.http.cookie ~ "X-Magento-Vary=") { @@ -30,7 +31,9 @@ sub vcl_hash { } } ``` + 2. Then you need to add the `process_graphql_headers` subroutine to the `default.vcl` file: + ``` sub process_graphql_headers { if (req.http.Store) { @@ -41,9 +44,10 @@ sub process_graphql_headers { } } ``` + > Query results should not be cached for logged in customers, because it cannot be guaranteed that these results are applicable to all customers. For example, you can create multiple customer groups and set up different product prices for each group. Caching results like these might cause customers to see the prices of another customer group. -You can find more information about this topic at [https://devdocs.magento.com/guides/v2.4/graphql/caching.html#caching-with-varnish] +You can find more information about this topic [on the Magento docs](https://devdocs.magento.com/guides/v2.4/graphql/caching.html#caching-with-varnish) 3. Open the `middleware.config.js` file, it should be located on the root folder of your store, there you will change the flag `useGETForQueries` to `true` to enable the usage of GET request for queries diff --git a/docs/guide/override-queries.md b/docs/guide/override-queries.md index e04ecfe1a..bf4f21b00 100644 --- a/docs/guide/override-queries.md +++ b/docs/guide/override-queries.md @@ -16,44 +16,43 @@ In order to query `cld_data`, you need to have [Cloudinary Magento extension](ht --- -1. Inside the theme's root let's create a `customQueries` directory, and [copy the content of the default `productsList` query from `vuestorefront/magento2/packages/api-client/src/api/products/productsList.ts` file](https://github.com/vuestorefront/magento2/blob/main/packages/api-client/src/api/products/productsList.ts) into the newly created directory. +1. Inside the theme's root let's create a `customQueries` directory, and copy the content of the default `productsList` query from the `/productsList.ts` file ([Source](https://github.com/vuestorefront/magento2/blob/main/packages/api-client/src/api/products/productsList.ts)) into the newly created directory. You can modify the query inside this file by adding `cld_data` with fields to the existing query as below: - ```typescript - import gql from 'graphql-tag'; +```typescript +import gql from 'graphql-tag'; - export default gql` - query productsList($search: String = "", $filter: ProductAttributeFilterInput, $pageSize: Int = 10, $currentPage: Int = 1, $sort: ProductAttributeSortInput) { - products(search: $search, filter: $filter, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) { - aggregations { - attribute_code +export default gql` + query productsList($search: String = "", $filter: ProductAttributeFilterInput, $pageSize: Int = 10, $currentPage: Int = 1, $sort: ProductAttributeSortInput) { + products(search: $search, filter: $filter, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) { + aggregations { + attribute_code + label + options { label - options { - label - value - count - } + value + count } - items { - //... - cld_data { - image - thumbnail - } - //... - } - page_info { - current_page - page_size - total_pages + } + items { + //... + cld_data { + image + thumbnail } - total_count + //... + } + page_info { + current_page + page_size + total_pages } + total_count } - `; - - ``` + } +`; +``` ::: warning Make sure you have `graphgl-tag` installed as dependency prior using this sample code. @@ -61,37 +60,37 @@ Make sure you have `graphgl-tag` installed as dependency prior using this sample 2. In `middleware.config.js`, import the modified query - ```js - import customProductsQuery from './customQueries/productList'; - ``` +```js +import customProductsQuery from './customQueries/productList'; +``` 3. Add a new property field `customQueries` under `integrations.magento` with the following code: - ```js - module.exports = { - integrations: { - magento: { - customQueries: { - /* This is where we override the default query */ - products: (context) => ({ - ...context, - query: customProductsQuery, // Your custom query - }) - }, - //... - }, +```js +module.exports = { + integrations: { + magento: { + customQueries: { + /* This is where we override the default query */ + products: (context) => ({ + ...context, + query: customProductsQuery, // Your custom query + }), }, - }; + //... + }, + }, +}; ``` 4. Now you can restart your dev environment and view the updated data queried. ::: warning -`thumbnail` is a must-have field to query. It is used for our default image rendering (for Nuxt image). DO NOT remove it from the query in any circumstance. +`thumbnail` is a must-have field to query. It is used for our default image rendering via Nuxt Image. Do not remove it from the query in any circumstance. ::: ### Important notes -**Only** attributes presented on `ProductInterface` are accessible via GraphQL without any additional modification on the Magento side. +Only attributes presented on `ProductInterface` are accessible via GraphQL without any additional modification on the Magento side. -To be able to get any custom attributes you must extend GraphQL schema in the Magento2. Follow [Magento 2 documentation](https://devdocs.magento.com/guides/v2.4/graphql/develop/extend-existing-schema.html) to achieve that. +To be able to get any custom attributes, you must extend the GraphQL schema in Magento 2. Follow [Magento 2 documentation](https://devdocs.magento.com/guides/v2.4/graphql/develop/extend-existing-schema.html) to achieve that. diff --git a/docs/guide/ssr.md b/docs/guide/ssr.md index 069d7d4ca..641994091 100644 --- a/docs/guide/ssr.md +++ b/docs/guide/ssr.md @@ -6,20 +6,22 @@ VueStorefront 2 - Magento 2 integrations use @vue-storefront/cache module that a rendered pages. ### What is cached + The cached pages are: -* Home page with the `Vhome` tag. -* All CMS pages with the `V${page.identifier}` tag -* Category page with the `Vcategory` tag and tags for products: `P${product.uid}` as well as categories `C${category.slug}` -* Product page with the `Vproduct-${route.value.params.id}` tag and tags for the main product `P${product.uid}` as well as categories `C${cat.id}` +- Home page with the `Vhome` tag. +- All CMS pages with the `V${page.identifier}` tag +- Category page with the `Vcategory` tag and tags for products: `P${product.uid}` as well as categories `C${category.slug}` +- Product page with the `Vproduct-${route.value.params.id}` tag and tags for the main product `P${product.uid}` as well as categories `C${cat.id}` ## Invalidating tags To invalidate a tag and remove pages associated with that tag, use the [Invalidation endpoint](https://docs.vuestorefront.io/v2/performance/ssr-cache.html#invalidating-tags). Go to the route configured in the `.env` file under the `VSF_REDIS_CACHE_INVALIDATE_KEY` key with two query parameters: -* `key` — string matching the `VSF_REDIS_CACHE_INVALIDATE_KEY` key in the `.env` file. -* `tags` — a comma-separated list of tags for invalidation. + +- `key` — string matching the `VSF_REDIS_CACHE_INVALIDATE_KEY` key in the `.env` file. +- `tags` — a comma-separated list of tags for invalidation. Assuming that you are running the application locally, the `VSF_REDIS_CACHE_INVALIDATE_URL` key is equal to `/cache-invalidate,` and the `VSF_REDIS_CACHE_INVALIDATE_KEY` key is equal to `secret_key`, and you want to invalidate the `Vhome` tag, the full URL will look like this: @@ -33,16 +35,16 @@ You don't need to add any additional packages to cache more pages — just add o ## Cache drivers -@vue-storefront/cache module is open source and provided Out Of The Box by Magento 2 integration. +`@vue-storefront/cache` module is open source and provided Out Of The Box by Magento 2 integration. To set up caching in your store, you must install and configure a cache driver. You can use our enterprise `@vsf-enterprise/redis-cache` module, or build your cache driver. ### Redis cache (enterprise) + Once you have access to the [Vue Storefront npm registry](https://docs.vuestorefront.io/v2/general/enterprise.htm), you can install the Redis cache driver by running this command in a console: -``yarn add @vsf-enterprise/redis-cache`` - +`yarn add @vsf-enterprise/redis-cache` #### redis cache configuration @@ -85,6 +87,6 @@ Then you have to update `nuxt.config.js file` and add this to the `modules` obje ## Useful links -- https://docs.vuestorefront.io/v2/performance/ssr-cache.html -- https://docs.vuestorefront.io/v2/integrations/redis-cache.html -- https://docs.vuestorefront.io/v2/integrate/cache-driver.html +- [Server Side Rendering Cache](https://docs.vuestorefront.io/v2/performance/ssr-cache.html) +- [Redis cache](https://docs.vuestorefront.io/v2/integrations/redis-cache.html) +- [Integrating cache driver](https://docs.vuestorefront.io/v2/integrate/cache-driver.html) diff --git a/docs/index.md b/docs/index.md index f93021fdb..383e13057 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,8 +1,3 @@ - - # Vue Storefront 2 for Magento Welcome to the documentation of Vue Storefront 2 integration for Magento 2. @@ -13,8 +8,8 @@ It's part of our ecosystem of integrations and extensions, which you can learn m To get started, see the following guides: -- [Introduction](/getting-started/introduction.html) to learn what is Vue Storefront, -- [Installation](/installation-setup/installation.html) to install and setup new Vue Storefront project. +- [Introduction](https://docs.vuestorefront.io/v2/getting-started/introduction.html) to learn what is Vue Storefront +- [Installation](/installation-setup/installation.html) to install and setup new Vue Storefront project for Magento 2. ## Demo diff --git a/docs/installation-setup/installation.md b/docs/installation-setup/installation.md index ad4db862c..0cf98a437 100644 --- a/docs/installation-setup/installation.md +++ b/docs/installation-setup/installation.md @@ -1,5 +1,9 @@ # Installation +If you prefer a video guide - here's a quick start guide to get your project up and running. + + + ## Prerequisites Before proceeding, make sure you have [Node 16](https://nodejs.org/en/) installed. You can check this by running the following command: diff --git a/docs/package.json b/docs/package.json index 9af3adf50..4f18a89e9 100755 --- a/docs/package.json +++ b/docs/package.json @@ -29,6 +29,6 @@ "dependencies": { "sass-loader": "^8.0.2", "vue-multiselect": "^2.1.6", - "vuepress-theme-vsf-docs": "^1.0.14" + "vuepress-theme-vsf-docs": "^1.0.16" } } diff --git a/docs/plugins/index.md b/docs/plugins/index.md index 096145217..377b6e083 100644 --- a/docs/plugins/index.md +++ b/docs/plugins/index.md @@ -10,20 +10,6 @@ It checks if locale in i18n module is changes and update `vsf-store` and `vsf-lo client and server side. ### Flow -1. Start: load middleware -2. Read current Magento Store Code from vsf-store cookie -3. Is store code found? - 2. No: Set default locale if isn't already set - 1. End -4. Yes: Check if current store code has corresponding locale in Nuxt.config.js - 1. No: Set default locale if isn't already set - 1. End -5. Yes: If corresponded locale is different than current locale - 1. No: End -6. Yes: set new locale -7. Go forward (load the page with correct locale and date) -8. End - ![i18n flow](./i18n-plugin-diagram.png) @@ -31,19 +17,22 @@ client and server side. We expose `$fc` (format currency) function as a plugin to allow you to convert any number or string into a formatted currency string. Under the hood plugins uses Intl.NumberFormat class to handle formatting and therefore exposes the same options configuration. Here are few examples of how you can use it in templates. + ```javascript -$fc(productGetters.getPrice(product).regular) // by default vsf-currency cookie is used to define target currency -$fc(productGetters.getPrice(product).regular, { currency: 'USD' }) // you can easily override this behaviour by passing configuration object +$fc(productGetters.getPrice(product).regular); // by default vsf-currency cookie is used to define target currency +$fc(productGetters.getPrice(product).regular, { currency: 'USD' }); // you can easily override this behaviour by passing configuration object ``` Configuration object is an interface Intl.NumberFormatOptions, check it for all available options. --- -***NOTE*** -Why we are not using built-in i18n package currency configuration and $n function to cover currency displaying? The answer is because we must be able to handle multiple currencies within one store but in i18n package, currency and locale are in 1:1 relation when in Magento one store can have multiple languages and currencies set. Currency and locale are necessarily disjointed which is not true for i18n plugin. +**_NOTE_** + +Why we are not using built-in i18n package currency configuration and $n function to cover currency displaying? + +The answer is because we must be able to handle multiple currencies within one store but in i18n package, currency and locale are in 1:1 relation when in Magento one store can have multiple languages and currencies set. Currency and locale are necessarily disjointed which is not true for i18n plugin. You can still use all i18n native functions to perform any formatting though. --- - diff --git a/docs/yarn.lock b/docs/yarn.lock index d63d8ffdc..4acd9b14b 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -8336,10 +8336,10 @@ vuepress-plugin-smooth-scroll@^0.0.3: dependencies: smoothscroll-polyfill "^0.4.3" -vuepress-theme-vsf-docs@^1.0.14: - version "1.0.14" - resolved "https://registry.yarnpkg.com/vuepress-theme-vsf-docs/-/vuepress-theme-vsf-docs-1.0.14.tgz#87e9a4fd079f34548140cad7647d4cf04a02dc59" - integrity sha512-m57TPCuaA8iyEsk/Kvgg0Wi+ByLqPXgbPF7dwGSgqjGlcIjjW2bMoaFrI7yNNLxnKdfyYXhgR0rLsPVQTPmwgw== +vuepress-theme-vsf-docs@^1.0.16: + version "1.0.16" + resolved "https://registry.yarnpkg.com/vuepress-theme-vsf-docs/-/vuepress-theme-vsf-docs-1.0.16.tgz#453225d147e1b3440ec05312f33b1877804cf3ad" + integrity sha512-qVb+TvW5y914S+SB9BhoX1ulo5xOw/2JS8pwqEWPoM8mAfdLwqglBgPUFb1HrRQhgY0I11rSI7couWl6ENh7mQ== dependencies: "@vuepress/plugin-active-header-links" "1.9.7" "@vuepress/plugin-nprogress" "1.9.7" From 844fc1a96a4d0fa3a70bf49d3ff0b55c9f6a64d8 Mon Sep 17 00:00:00 2001 From: Artur Tagisow Date: Sat, 6 Aug 2022 12:26:52 +0200 Subject: [PATCH 25/55] ci: fix code not checked out --- .github/workflows/deploy-vue-storefront-cloud.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-vue-storefront-cloud.yml b/.github/workflows/deploy-vue-storefront-cloud.yml index 89cb59d49..fc6d58420 100644 --- a/.github/workflows/deploy-vue-storefront-cloud.yml +++ b/.github/workflows/deploy-vue-storefront-cloud.yml @@ -16,6 +16,9 @@ jobs: environment-middleware-url: ${{ steps.determine-environment.outputs.middleware-url}} deployment_id: ${{ steps.deployment.outputs.deployment_id }} steps: + - name: Checkout code + uses: actions/checkout@v1 + - name: Determine environment-specific variables shell: bash run: | @@ -50,7 +53,7 @@ jobs: id: deployment uses: chrnorm/deployment-action@v2 with: - token: ${{ secrets.DEPLOYMENT_PERSONAL_ACCESS_TOKEN }} + token: ${{ github.token }} environment: ${{ env.ENVNAME }} initial-status: in_progress @@ -133,7 +136,7 @@ jobs: if: ${{ !(contains(join(needs.*.result, ','), 'failure') || contains(join(needs.*.result, ','), 'cancelled')) }} uses: chrnorm/deployment-status@v2 with: - token: ${{ secrets.DEPLOYMENT_PERSONAL_ACCESS_TOKEN }} + token: ${{ github.token }} deployment-id: ${{ needs.create-deployment.outputs.deployment_id }} state: success @@ -141,6 +144,6 @@ jobs: if: ${{ contains(join(needs.*.result, ','), 'failure') || contains(join(needs.*.result, ','), 'cancelled') }} uses: chrnorm/deployment-status@v2 with: - token: ${{ secrets.DEPLOYMENT_PERSONAL_ACCESS_TOKEN }} + token: ${{ github.token }} deployment-id: ${{ needs.create-deployment.outputs.deployment_id }} state: failure From b694e4f4372bdab4db7f2746b5a107a212a32cc1 Mon Sep 17 00:00:00 2001 From: Beniamin Sinca Date: Fri, 15 Jul 2022 11:17:40 +0100 Subject: [PATCH 26/55] Fix bug when media_gallery array is empty In `getGallery` rather check the length of an array to get an accurate bool value than simple the array which will always return true. --- .../theme/modules/catalog/product/getters/productGetters.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/theme/modules/catalog/product/getters/productGetters.ts b/packages/theme/modules/catalog/product/getters/productGetters.ts index 524255fee..209f52e94 100644 --- a/packages/theme/modules/catalog/product/getters/productGetters.ts +++ b/packages/theme/modules/catalog/product/getters/productGetters.ts @@ -92,11 +92,11 @@ export const getPrice = (product: ProductInterface): Price => { export const getGallery = (product: Product, maxGallerySize = 4): MediaGalleryItem[] => { const images = []; - if (!product?.media_gallery && !product?.configurable_product_options_selection?.media_gallery) { + if (!product?.media_gallery.length && !product?.configurable_product_options_selection?.media_gallery.length) { return images; } - const selectedGallery = product.configurable_product_options_selection?.media_gallery + const selectedGallery = product.configurable_product_options_selection?.media_gallery.length ? product.configurable_product_options_selection.media_gallery : product.media_gallery; From f280132e184aacbcdb10bd0f85311a45396a9926 Mon Sep 17 00:00:00 2001 From: Artur Tagisow Date: Mon, 18 Jul 2022 11:31:10 +0200 Subject: [PATCH 27/55] ci: poll farmer for pod deployment status ci: add polling farmer for deploy status ci: fix extra parentheses --- .github/workflows/deployment-template.yml | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deployment-template.yml b/.github/workflows/deployment-template.yml index ded9778b4..c869c15c0 100644 --- a/.github/workflows/deployment-template.yml +++ b/.github/workflows/deployment-template.yml @@ -28,9 +28,17 @@ jobs: exit 1 fi - # the above curl only *asks* for the container to be deployed - # we don't know when the newly built Docker image replaces the old one - # but it takes less than 5 minutes - - name: 'Wait for container deployed on VSF Cloud to come online' - run: 'sleep 300' - shell: 'bash' + - name: 'Poll for Farmer pod deployment status' + timeout-minutes: 5 + run: | + query_deploy_check_endpoint () { + NAMESPACE=${{ inputs.environment-code }}-europe-west1-gcp-storefrontcloud-io + curl -s \ + -H 'X-User-Id: ${{ secrets.cloud-username }}' \ + -H 'X-Api-Key: ${{ secrets.cloud-password }}' \ + -H 'Content-Type: application/json' \ + https://farmer.storefrontcloud.io/deploy_check/$NAMESPACE/${{ github.sha }} + } + until $( query_deploy_check_endpoint | tee /dev/stderr | grep -q '{"code":200,"ready":"1","deployed":"1"}' ); do + sleep 10; + done; From 3f321f8f3002ee6b2721f215740baaa392c70ecd Mon Sep 17 00:00:00 2001 From: Marcin Kwiatkowski Date: Thu, 14 Jul 2022 15:57:44 +0200 Subject: [PATCH 28/55] docs: addd 1.0.0 release notes --- docs/index.md | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/docs/index.md b/docs/index.md index 383e13057..e2148b546 100644 --- a/docs/index.md +++ b/docs/index.md @@ -13,22 +13,4 @@ To get started, see the following guides: ## Demo -If you want to see the integration in action, we have three demo environments where you can see and test Magento 2 integration for Vue Storefront in action. If you find a bug in any of them, please [create an issue](https://github.com/vuestorefront/magento2/issues/new/choose) in our repository to let us know about it. - -### Production environment - -In the production environment, you can see the latest **released and stable** version of the integration. It should be visually and feature-wise identical to the new project installed using our CLI. - -[Production demo](https://demo-magento2.europe-west1.gcp.vuestorefront.cloud) - -### Staging environment - -In the staging environment, we are testing new releases. It should be **relatively stable**, but you might still encounter some bugs. - -[Staging demo](https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io) - -### Development environment - -In the development environment, we are testing the `develop` branch, which might contain unfinished or experimental features. It might be **unstable** both visually and feature-wise. - -[Development environment](https://demo-magento2-dev.europe-west1.gcp.storefrontcloud.io) +If you want to see the integration in action, check out our [demo environments](/guide/environments.html). From 1591c0ced31acb8b0bb359a2379106d7c7181dd0 Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Thu, 21 Jul 2022 11:22:18 +0200 Subject: [PATCH 29/55] fix: images are not loaded properly with ipx - add images extensions for a proper rendering --- packages/theme/pages/Home.vue | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/theme/pages/Home.vue b/packages/theme/pages/Home.vue index 26a782f55..826b28ea3 100644 --- a/packages/theme/pages/Home.vue +++ b/packages/theme/pages/Home.vue @@ -100,7 +100,7 @@ export default defineComponent({ title: app.i18n.t('Colorful summer dresses are already in store'), subtitle: app.i18n.t('SUMMER COLLECTION {year}', { year }), buttonText: app.i18n.t('Learn more'), - imageSrc: '/homepage/bannerB', + imageSrc: '/homepage/bannerB.webp', imageWidth: isDesktop ? 1240 : 328, imageHeight: isDesktop ? 400 : 224, imageConfig: { @@ -120,9 +120,9 @@ export default defineComponent({ buttonText: app.i18n.t('Shop now'), image: { mobile: - '/homepage/bannerB', + '/homepage/bannerB.webp', desktop: - '/homepage/bannerF', + '/homepage/bannerF.webp', }, imageConfig: { fit: 'cover', @@ -141,7 +141,7 @@ export default defineComponent({ 'Find stunning women\'s cocktail dresses and party dresses. Stand out in lace and metallic cocktail dresses from all your favorite brands.', ), buttonText: app.i18n.t('Shop now'), - image: '/homepage/bannerE', + image: '/homepage/bannerE.webp', imageConfig: { fit: 'cover', width: isDesktop ? 496 : 328, @@ -155,7 +155,7 @@ export default defineComponent({ slot: 'banner-C', subtitle: app.i18n.t('T-Shirts'), title: app.i18n.t('The Office Life'), - image: '/homepage/bannerC', + image: '/homepage/bannerC.webp', imageConfig: { fit: 'cover', width: isDesktop ? 332 : 328, @@ -169,7 +169,7 @@ export default defineComponent({ slot: 'banner-D', subtitle: app.i18n.t('Summer Sandals'), title: app.i18n.t('Eco Sandals'), - image: '/homepage/bannerG', + image: '/homepage/bannerG.webp', imageConfig: { fit: 'cover', width: isDesktop ? 332 : 328, @@ -184,7 +184,7 @@ export default defineComponent({ title: app.i18n.t('Subscribe to Newsletters'), description: app.i18n.t('Be aware of upcoming sales and events. Receive gifts and special offers!'), buttonText: app.i18n.t('Subscribe'), - imageSrc: '/homepage/newsletter', + imageSrc: '/homepage/newsletter.webp', imageWidth: isDesktop ? 1240 : 400, imageHeight: isDesktop ? 202 : 200, imageConfig: { From de74a571ba934e703919b1d130782ae522982f7a Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Wed, 20 Jul 2022 11:37:08 +0200 Subject: [PATCH 30/55] fix: env export for windows os environments --- packages/theme/.env.example | 2 ++ packages/theme/nuxt.config.js | 2 +- packages/theme/package.json | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/theme/.env.example b/packages/theme/.env.example index d1fc42c14..a9f09937a 100644 --- a/packages/theme/.env.example +++ b/packages/theme/.env.example @@ -27,3 +27,5 @@ VSF_RECAPTCHA_HIDE_BADGE= VSF_RECAPTCHA_SIZE=invisible VSF_RECAPTCHA_MIN_SCORE=0.5 VSF_RECAPTCHA_VERSION=3 + +NODE_TLS_REJECT_UNAUTHORIZED=0 diff --git a/packages/theme/nuxt.config.js b/packages/theme/nuxt.config.js index f72d586c8..2a305497f 100755 --- a/packages/theme/nuxt.config.js +++ b/packages/theme/nuxt.config.js @@ -285,7 +285,7 @@ export default () => { }; } - if (process.env.NODE_ENV === 'development' || process.env.IS_ENV_LOCAL) { + if (process.env.NODE_ENV === 'development' || process.env.VSF_NUXT_APP_ENV === 'development') { baseConfig.server = { https: { key: fs.readFileSync(path.resolve(__dirname, 'localhost-key.pem')), diff --git a/packages/theme/package.json b/packages/theme/package.json index 5e86d3d98..82d6c8839 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -10,14 +10,14 @@ "scripts": { "build": "nuxt build --modern=client", "build:analyze": "nuxt build -a --modern=client", - "dev": "export NODE_TLS_REJECT_UNAUTHORIZED=0 && nuxt --env.NODE_TLS_REJECT_UNAUTHORIZED=0", + "dev": "nuxt --env.NODE_TLS_REJECT_UNAUTHORIZED=0", "dev:debug": "node --inspect ../../node_modules/.bin/nuxt dev", "generate": "nuxt generate", "lint": "eslint . --ext .ts,.vue", "lint:fix": "eslint . --ext .ts,.vue --fix", "precommit": "lint-staged", "start": "nuxt start --modern=client", - "start:local": "export NODE_TLS_REJECT_UNAUTHORIZED=0 && export IS_ENV_LOCAL=1 && nuxt start --modern=client --env.NODE_TLS_REJECT_UNAUTHORIZED=0", + "start:local": "nuxt start --modern=client --env.NODE_TLS_REJECT_UNAUTHORIZED=0", "test": "jest", "test:watch": "jest --watch", "test:coverage": "jest --coverage", From 7fdc601aec968ce332734c32d8bd2111f5a6b2fc Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Mon, 18 Jul 2022 10:01:49 +0200 Subject: [PATCH 31/55] feat: load tests - add magento store config load test - add create empty guest cart load test - add magento create customer --- .../src/mutation/addProductsToCart.js | 191 ++++++++++++++++++ .../load-tests/src/mutation/createCustomer.js | 45 +++++ .../src/mutation/createEmptyCart.js | 7 + .../load-tests/src/query/storeConfig.gql.js | 17 ++ .../tests/magento/addSimpleProductToCart.js | 52 +++++ .../src/tests/magento/createCustomer.js | 51 +++++ .../src/tests/magento/createEmptyGuestCart.js | 46 +++++ .../src/tests/magento/storeConfig.js | 41 ++++ .../src/tests/magento/utils/customerData.js | 16 ++ .../src/tests/magento/utils/getHeaders.js | 5 + .../src/tests/middleware/createCustomer.js | 48 +++++ .../tests/middleware/createEmptyGuestCart.js | 47 +++++ .../src/tests/middleware/storeConfig.js | 40 ++++ .../tests/middleware/utils/customerData.js | 16 ++ .../src/tests/middleware/utils/getHeaders.js | 7 + packages/load-tests/src/utils/getCookies.js | 7 + 16 files changed, 636 insertions(+) create mode 100644 packages/load-tests/src/mutation/addProductsToCart.js create mode 100644 packages/load-tests/src/mutation/createCustomer.js create mode 100644 packages/load-tests/src/mutation/createEmptyCart.js create mode 100644 packages/load-tests/src/query/storeConfig.gql.js create mode 100644 packages/load-tests/src/tests/magento/addSimpleProductToCart.js create mode 100644 packages/load-tests/src/tests/magento/createCustomer.js create mode 100644 packages/load-tests/src/tests/magento/createEmptyGuestCart.js create mode 100644 packages/load-tests/src/tests/magento/storeConfig.js create mode 100644 packages/load-tests/src/tests/magento/utils/customerData.js create mode 100644 packages/load-tests/src/tests/magento/utils/getHeaders.js create mode 100644 packages/load-tests/src/tests/middleware/createCustomer.js create mode 100644 packages/load-tests/src/tests/middleware/createEmptyGuestCart.js create mode 100644 packages/load-tests/src/tests/middleware/storeConfig.js create mode 100644 packages/load-tests/src/tests/middleware/utils/customerData.js create mode 100644 packages/load-tests/src/tests/middleware/utils/getHeaders.js create mode 100644 packages/load-tests/src/utils/getCookies.js diff --git a/packages/load-tests/src/mutation/addProductsToCart.js b/packages/load-tests/src/mutation/addProductsToCart.js new file mode 100644 index 000000000..97b581093 --- /dev/null +++ b/packages/load-tests/src/mutation/addProductsToCart.js @@ -0,0 +1,191 @@ +export const AddProductsToCart = ` +mutation addProductsToCart($cartId: String!, $cartItems: [CartItemInput!]!) { + addProductsToCart(cartId,: $cartId, cartItems,: $cartItems) { + cart { + id + email + is_virtual + applied_coupons { + code + } + prices { + subtotal_excluding_tax { + value + }, + subtotal_including_tax { + value + }, + applied_taxes { + amount { + value + }, + label + } + discounts { + amount { + value + }, + label + } + grand_total { + value + } + } + items { + uid + product { + uid + __typename + sku + name + stock_status + only_x_left_in_stock + rating_summary + thumbnail { + url + position + disabled + label + } + url_key + url_rewrites { + url + } + price_range { + maximum_price { + final_price { + currency + value + } + regular_price { + currency + value + } + } + minimum_price { + final_price { + currency + value + } + regular_price { + currency + value + } + } + } + categories { + uid + name + url_suffix + url_path + breadcrumbs { + category_name, + category_url_path + } + } + review_count + reviews { + items { + average_rating + ratings_breakdown { + name + value + } + } + } + } + prices { + row_total { + value + } + row_total_including_tax { + value + } + total_item_discount { + value + } + } + quantity + ... on ConfigurableCartItem { + configurable_options { + configurable_product_option_uid + option_label + configurable_product_option_value_uid + value_label + } + configured_variant { + sku + thumbnail { + url + } + } + } + ... on BundleCartItem { + bundle_options { + uid + label + type + values { + id + label + price + quantity + } + } + } + } + total_quantity + shipping_addresses { + firstname + lastname + street + city + company + region { + code + region_id + label + } + postcode + telephone + country { + code + label + } + selected_shipping_method { + carrier_code + carrier_title + method_code + method_title + amount { + value + currency + } + } + } + billing_address { + firstname + lastname + street + city + company + region { + code + region_id + label + } + postcode + telephone + country { + code + label + } + } + } + user_errors { + code + message + } + } + } +`; diff --git a/packages/load-tests/src/mutation/createCustomer.js b/packages/load-tests/src/mutation/createCustomer.js new file mode 100644 index 000000000..aab1d7a13 --- /dev/null +++ b/packages/load-tests/src/mutation/createCustomer.js @@ -0,0 +1,45 @@ +export const CreateCustomer = ` + mutation createCustomer($input: CustomerCreateInput!) { + createCustomerV2(input: $input) { + customer { + date_of_birth + default_billing + default_shipping + email + firstname + is_subscribed + lastname + middlename + prefix + suffix + taxvat + addresses { + city + country_code + default_billing + default_shipping + extension_attributes { + attribute_code + value + } + firstname + id + lastname + postcode + prefix + region { + region_code + region_id + region + } + street + suffix + telephone + vat_id + } + } + } + } +`; + +export default CreateCustomer; diff --git a/packages/load-tests/src/mutation/createEmptyCart.js b/packages/load-tests/src/mutation/createEmptyCart.js new file mode 100644 index 000000000..28d399306 --- /dev/null +++ b/packages/load-tests/src/mutation/createEmptyCart.js @@ -0,0 +1,7 @@ +export const CreateEmptyCartMutation = ` + mutation { + createEmptyCart + } +`; + +export default CreateEmptyCartMutation; diff --git a/packages/load-tests/src/query/storeConfig.gql.js b/packages/load-tests/src/query/storeConfig.gql.js new file mode 100644 index 000000000..367c7886a --- /dev/null +++ b/packages/load-tests/src/query/storeConfig.gql.js @@ -0,0 +1,17 @@ +export const StoreConfigQuery = ` + query storeConfig { + storeConfig { + store_code, + default_title, + store_name, + default_display_currency_code, + locale, + header_logo_src, + logo_width, + logo_height, + logo_alt + } + } +`; + +export const StoreConfigQueryString = 'query=query%20storeConfig%20%7B%0A%20%20%20%20storeConfig%20%7B%0A%20%20%20%20%20%20%20%20store_code,%0A%20%20%20%20%20%20%20%20default_title,%0A%20%20%20%20%20%20%20%20store_name,%0A%20%20%20%20%20%20%20%20default_display_currency_code,%0A%20%20%20%20%20%20%20%20locale,%0A%20%20%20%20%20%20%20%20header_logo_src,%0A%20%20%20%20%20%20%20%20logo_width,%0A%20%20%20%20%20%20%20%20logo_height,%0A%20%20%20%20%20%20%20%20logo_alt%0A%20%20%20%20%7D%0A%20%20%7D&variables=%7B%7D&operationName=storeConfig'; diff --git a/packages/load-tests/src/tests/magento/addSimpleProductToCart.js b/packages/load-tests/src/tests/magento/addSimpleProductToCart.js new file mode 100644 index 000000000..9f6de3f65 --- /dev/null +++ b/packages/load-tests/src/tests/magento/addSimpleProductToCart.js @@ -0,0 +1,52 @@ +// Creator: k6 Browser Recorder 0.6.2 (+ handmade cleanups) +import { group, check } from 'k6'; +import http from 'k6/http'; + +import getHeaders from './utils/getHeaders.js'; +import { AddProductsToCart } from '../../mutation/addProductsToCart.js'; +import CreateEmptyGuestCart from './createEmptyGuestCart.js'; + +/** + * @type {import('k6/options').Options} + */ +export const options = { + vus: 150, + duration: '1m', +}; + +const { BASE_URL } = __ENV; +let response; + +if (BASE_URL === undefined) { + throw new Error('BASE_URL is not set'); +} + +export default function main() { + const params = { + headers: getHeaders(), + }; + + group('[Magento] addSimpleProductToGuestCart', () => { + const { cartId } = CreateEmptyGuestCart(); + + group('add a simple product to the cart', () => { + response = http.post( + `${BASE_URL}`, + JSON.stringify({ + query: AddProductsToCart, + variables: { + cartId, + cartItems: [{ quantity: Math.floor(Math.random() * 10), sku: '24-WG02' }], + }, + }), + params, + ); + + check(response, { + 'is status 200': (r) => r.status === 200, + 'does not have errors': (r) => !r.json().errors, + 'includes cart data': (r) => r.body.includes('addProductsToCart'), + }); + }); + }); +} diff --git a/packages/load-tests/src/tests/magento/createCustomer.js b/packages/load-tests/src/tests/magento/createCustomer.js new file mode 100644 index 000000000..b4d7c831a --- /dev/null +++ b/packages/load-tests/src/tests/magento/createCustomer.js @@ -0,0 +1,51 @@ +// Creator: k6 Browser Recorder 0.6.2 (+ handmade cleanups) +import { group, check } from 'k6'; +import http from 'k6/http'; + +import getHeaders from './utils/getHeaders.js'; +import { CreateCustomer } from '../../mutation/createCustomer.js'; +import { customerData } from './utils/customerData.js'; + +/** + * @type {import('k6/options').Options} + */ +export const options = { + vus: 150, + duration: '1m', +}; + +const { BASE_URL } = __ENV; +let response; + +if (BASE_URL === undefined) { + throw new Error('BASE_URL is not set'); +} + +export default function main() { + const params = { + headers: getHeaders(), + }; + + group('[Magento] create a customer account', () => { + response = http.post( + `${BASE_URL}`, + JSON.stringify({ + query: CreateCustomer, + variables: { + input: { + email: customerData.getEmail(), + password: 'Abcd123!', + firstname: 'Load', + lastname: 'Test', + }, + }, + }), + params, + ); + + check(response, { + 'is status 200': (r) => r.status === 200, + 'does not have errors': (r) => !r.json().errors, + }); + }); +} diff --git a/packages/load-tests/src/tests/magento/createEmptyGuestCart.js b/packages/load-tests/src/tests/magento/createEmptyGuestCart.js new file mode 100644 index 000000000..64e850e4c --- /dev/null +++ b/packages/load-tests/src/tests/magento/createEmptyGuestCart.js @@ -0,0 +1,46 @@ +// Creator: k6 Browser Recorder 0.6.2 (+ handmade cleanups) +import { sleep, group, check } from 'k6'; +import http from 'k6/http'; + +import jsonpath from 'https://jslib.k6.io/jsonpath/1.0.2/index.js'; +import getHeaders from './utils/getHeaders.js'; +import { CreateEmptyCartMutation } from '../../mutation/createEmptyCart.js'; + +/** + * @type {import('k6/options').Options} + */ +export const options = { + vus: 150, + duration: '1m', +}; + +const { BASE_URL } = __ENV; +const vars = {}; +let response; +if (BASE_URL === undefined) { + throw new Error('BASE_URL is not set'); +} + +export default function main() { + const params = { + headers: getHeaders(), + }; + + group('[Magento] create an empty cart', () => { + response = http.post( + `${BASE_URL}`, + JSON.stringify({ query: CreateEmptyCartMutation }), + params, + ); + sleep(0.2); + [vars.cartId] = jsonpath.query(response.json(), '$.data.createEmptyCart'); + + check(response, { + 'is status 200': (r) => r.status === 200, + 'does not have errors': (r) => !r.json().errors, + 'includes cart id': () => vars.cartId, + }); + }); + + return { cartId: vars.cartId }; +} diff --git a/packages/load-tests/src/tests/magento/storeConfig.js b/packages/load-tests/src/tests/magento/storeConfig.js new file mode 100644 index 000000000..1e1285d92 --- /dev/null +++ b/packages/load-tests/src/tests/magento/storeConfig.js @@ -0,0 +1,41 @@ +// Creator: k6 Browser Recorder 0.6.2 (+ handmade cleanups) +import { sleep, check, group } from 'k6'; +import http from 'k6/http'; + +import getHeaders from './utils/getHeaders.js'; +import { StoreConfigQueryString } from '../../query/storeConfig.gql.js'; + +/** + * @type {import('k6/options').Options} + */ +export const options = { + vus: 150, + duration: '1m', +}; + +const { BASE_URL } = __ENV; + +if (BASE_URL === undefined) { + throw new Error('BASE_URL is not set'); +} + +export default function main() { + const params = { + headers: getHeaders(), + }; + + group('[Magento] storeConfig', () => { + const response = http.get( + `${BASE_URL}/graphql?${StoreConfigQueryString}`, + params, + ); + + sleep(0.5); + + check(response, { + 'is status 200': (r) => r.status === 200, + 'does not have errors': (r) => !r.json().errors, + 'includes storeConfig data': (r) => r.body.includes('storeConfig'), + }); + }); +} diff --git a/packages/load-tests/src/tests/magento/utils/customerData.js b/packages/load-tests/src/tests/magento/utils/customerData.js new file mode 100644 index 000000000..59ed2defb --- /dev/null +++ b/packages/load-tests/src/tests/magento/utils/customerData.js @@ -0,0 +1,16 @@ +const chars = 'abcdefghijklmnopqrstuvwxyz1234567890'; + +export const getEmail = (length = 15) => { + let string = ''; + for (let i = 0; i < length; i++) { + string += chars[Math.floor(Math.random() * chars.length)]; + } + + return `${string}@gmail.com`; +}; + +export const customerData = { + getEmail, +}; + +export default customerData; diff --git a/packages/load-tests/src/tests/magento/utils/getHeaders.js b/packages/load-tests/src/tests/magento/utils/getHeaders.js new file mode 100644 index 000000000..7f21f7703 --- /dev/null +++ b/packages/load-tests/src/tests/magento/utils/getHeaders.js @@ -0,0 +1,5 @@ +const getHeaders = () => ({ + 'Content-Type': 'application/json', +}); + +export default getHeaders; diff --git a/packages/load-tests/src/tests/middleware/createCustomer.js b/packages/load-tests/src/tests/middleware/createCustomer.js new file mode 100644 index 000000000..c85a174ce --- /dev/null +++ b/packages/load-tests/src/tests/middleware/createCustomer.js @@ -0,0 +1,48 @@ +// Creator: k6 Browser Recorder 0.6.2 (+ handmade cleanups) +import { sleep, group, check } from 'k6'; +import http from 'k6/http'; + +import getHeaders from './utils/getHeaders.js'; +import { customerData } from './utils/customerData.js'; + +/** + * @type {import('k6/options').Options} + */ +export const options = { + vus: 150, + duration: '1m', +}; + +const { BASE_URL } = __ENV; +let response; + +if (BASE_URL === undefined) { + throw new Error('BASE_URL is not set'); +} + +export default function main() { + const params = { + headers: getHeaders(), + }; + + group('[Middleware] create a customer account', () => { + response = http.post( + `${BASE_URL}/magento/createCustomer`, + JSON.stringify([{ + email: customerData.getEmail(), + password: 'Abcd123!', + firstname: 'Load', + lastname: 'Test', + recaptchaToken: '12345', + }]), + params, + ); + + sleep(2); + + check(response, { + 'is status 200': (r) => r.status === 200, + 'does not have errors': (r) => !r.json().errors, + }); + }); +} diff --git a/packages/load-tests/src/tests/middleware/createEmptyGuestCart.js b/packages/load-tests/src/tests/middleware/createEmptyGuestCart.js new file mode 100644 index 000000000..6eae6a2f0 --- /dev/null +++ b/packages/load-tests/src/tests/middleware/createEmptyGuestCart.js @@ -0,0 +1,47 @@ +// Creator: k6 Browser Recorder 0.6.2 (+ handmade cleanups) +import { sleep, group, check } from 'k6'; +import http from 'k6/http'; + +import jsonpath from 'https://jslib.k6.io/jsonpath/1.0.2/index.js'; +import getHeaders from './utils/getHeaders.js'; + +/** + * @type {import('k6/options').Options} + */ +export const options = { + vus: 1, + duration: '1s', +}; + +const { BASE_URL } = __ENV; +const vars = {}; +let response; +if (BASE_URL === undefined) { + throw new Error('BASE_URL is not set'); +} + +export default function main() { + const params = { + headers: getHeaders(), + }; + + group('[Middleware] create an empty cart', () => { + response = http.post( + `${BASE_URL}/magento/createEmptyCart`, + '[]', + params, + ); + + sleep(1); + + [vars.cartId] = jsonpath.query(response.json(), '$.data.createEmptyCart'); + + check(response, { + 'is status 200': (r) => r.status === 200, + 'does not have errors': (r) => !r.json().errors, + 'includes cart id': () => vars.cartId, + }); + }); + + return { cartId: vars.cartId }; +} diff --git a/packages/load-tests/src/tests/middleware/storeConfig.js b/packages/load-tests/src/tests/middleware/storeConfig.js new file mode 100644 index 000000000..96a128a89 --- /dev/null +++ b/packages/load-tests/src/tests/middleware/storeConfig.js @@ -0,0 +1,40 @@ +// Creator: k6 Browser Recorder 0.6.2 (+ handmade cleanups) +import { sleep, check, group } from 'k6'; +import http from 'k6/http'; +import getHeaders from './utils/getHeaders.js'; + +/** + * @type {import('k6/options').Options} + */ +export const options = { + vus: 150, + duration: '1m', +}; + +const { BASE_URL } = __ENV; + +if (BASE_URL === undefined) { + throw new Error('BASE_URL is not set'); +} + +export default function main() { + const params = { + headers: getHeaders(), + }; + + group('[Middleware] storeConfig', () => { + const response = http.post( + `${BASE_URL}/git magento/customQuery`, + '[{"query":"\\n query storeConfig {\\n storeConfig {\\n store_code,\\n default_title,\\n store_name,\\n default_display_currency_code,\\n locale,\\n header_logo_src,\\n logo_width,\\n logo_height,\\n logo_alt\\n }\\n }\\n"}]', + params, + ); + + sleep(0.5); + + check(response, { + 'is status 200': (r) => r.status === 200, + 'does not have errors': (r) => !r.json().errors, + 'includes storeConfig data': (r) => r.body.includes('storeConfig'), + }); + }); +} diff --git a/packages/load-tests/src/tests/middleware/utils/customerData.js b/packages/load-tests/src/tests/middleware/utils/customerData.js new file mode 100644 index 000000000..59ed2defb --- /dev/null +++ b/packages/load-tests/src/tests/middleware/utils/customerData.js @@ -0,0 +1,16 @@ +const chars = 'abcdefghijklmnopqrstuvwxyz1234567890'; + +export const getEmail = (length = 15) => { + let string = ''; + for (let i = 0; i < length; i++) { + string += chars[Math.floor(Math.random() * chars.length)]; + } + + return `${string}@gmail.com`; +}; + +export const customerData = { + getEmail, +}; + +export default customerData; diff --git a/packages/load-tests/src/tests/middleware/utils/getHeaders.js b/packages/load-tests/src/tests/middleware/utils/getHeaders.js new file mode 100644 index 000000000..b70f2919c --- /dev/null +++ b/packages/load-tests/src/tests/middleware/utils/getHeaders.js @@ -0,0 +1,7 @@ +const getHeaders = () => ({ + 'content-type': 'application/json', + accept: 'application/json, text/plain, */*', + cookie: 'vsf-store=default; vsf-locale=default; vsf-currency=USD', +}); + +export default getHeaders; diff --git a/packages/load-tests/src/utils/getCookies.js b/packages/load-tests/src/utils/getCookies.js new file mode 100644 index 000000000..fefd5d14f --- /dev/null +++ b/packages/load-tests/src/utils/getCookies.js @@ -0,0 +1,7 @@ +const getCookies = () => ({ + 'vsf-store': 'default', + 'vsf-locale': 'default', + 'vsf-currency': 'USD', +}); + +export default getCookies; From b132b5ef3c09b71d6b0957d8113daff4b764047c Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Mon, 18 Jul 2022 10:01:49 +0200 Subject: [PATCH 32/55] fix: product review form offscreen issue --- .../catalog/product/components/ProductAddReviewForm.vue | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/theme/modules/catalog/product/components/ProductAddReviewForm.vue b/packages/theme/modules/catalog/product/components/ProductAddReviewForm.vue index 92bedc9b8..f04bc17fb 100644 --- a/packages/theme/modules/catalog/product/components/ProductAddReviewForm.vue +++ b/packages/theme/modules/catalog/product/components/ProductAddReviewForm.vue @@ -308,6 +308,12 @@ export default defineComponent({ margin-right: 0; margin-bottom: 0; } + textarea { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 100%; + } } } } From a10720fa19cda7284ebcdb70466d69eda93f6775 Mon Sep 17 00:00:00 2001 From: Shankar Konar Date: Mon, 25 Jul 2022 14:17:57 +0530 Subject: [PATCH 33/55] fix: feedback changes --- .../modules/catalog/product/components/ProductAddReviewForm.vue | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/theme/modules/catalog/product/components/ProductAddReviewForm.vue b/packages/theme/modules/catalog/product/components/ProductAddReviewForm.vue index f04bc17fb..173aa0613 100644 --- a/packages/theme/modules/catalog/product/components/ProductAddReviewForm.vue +++ b/packages/theme/modules/catalog/product/components/ProductAddReviewForm.vue @@ -309,8 +309,6 @@ export default defineComponent({ margin-bottom: 0; } textarea { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; box-sizing: border-box; width: 100%; } From a502a1d67b07a63644779b65bc348cc07dd87d14 Mon Sep 17 00:00:00 2001 From: Shankar Konar Date: Fri, 22 Jul 2022 20:42:27 +0530 Subject: [PATCH 34/55] fix: command correction according to markshust script --- docs/installation-setup/configure-magento.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/installation-setup/configure-magento.md b/docs/installation-setup/configure-magento.md index f394b7eff..5fb5d71a2 100644 --- a/docs/installation-setup/configure-magento.md +++ b/docs/installation-setup/configure-magento.md @@ -70,11 +70,11 @@ For security reasons, Magento 2, by default, allows maximum GraphQL query comple To install the Magento 2 GraphQL Config module, run the following commands on your Magento installation: ```bash -composer require caravelx/module-graphql-config -php bin/magento module:enable Caravel_GraphQlConfig -php bin/magento setup:upgrade -php bin/magento setup:di:compile -php bin/magento setup:static-content:deploy +bin/composer require caravelx/module-graphql-config +bin/magento module:enable Caravel_GraphQlConfig +bin/magento setup:upgrade +bin/magento setup:di:compile +bin/magento setup:static-content:deploy -f ``` Then go to the admin panel, find the configuration panel of the `GraphQL CustomConfig` module, and set: From f4dc22dc0f7959a8ec423db72f218ae9d4c5a351 Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Mon, 25 Jul 2022 13:45:21 +0200 Subject: [PATCH 35/55] test: browsing product load test --- .eslintignore | 1 + .../src/scenarios/browsingProduct.js | 298 ++++++++++++++ .../load-tests/src/scenarios/searchProduct.js | 370 ------------------ .../src/scenarios/utils/setDefaultCookies.js | 8 + 4 files changed, 307 insertions(+), 370 deletions(-) create mode 100644 packages/load-tests/src/scenarios/browsingProduct.js delete mode 100644 packages/load-tests/src/scenarios/searchProduct.js create mode 100644 packages/load-tests/src/scenarios/utils/setDefaultCookies.js diff --git a/.eslintignore b/.eslintignore index 0fc6ca764..2a24330f7 100755 --- a/.eslintignore +++ b/.eslintignore @@ -5,4 +5,5 @@ packages/api-client/server packages/composables packages/api-client/lib packages/theme/static/sw.js +packages/load-tests/* .eslintrc.js diff --git a/packages/load-tests/src/scenarios/browsingProduct.js b/packages/load-tests/src/scenarios/browsingProduct.js new file mode 100644 index 000000000..da6aa49f6 --- /dev/null +++ b/packages/load-tests/src/scenarios/browsingProduct.js @@ -0,0 +1,298 @@ +// Creator: k6 Browser Recorder 0.6.2 + +import { check, sleep, group } from 'k6'; +import http from 'k6/http'; + +import jsonpath from 'https://jslib.k6.io/jsonpath/1.0.2/index.js'; +import { setDefaultCookies } from './utils/setDefaultCookies.js'; + +export const options = { + vus: 200, + duration: '5m', + thresholds: { + http_req_failed: ['rate<0.01'], // http errors should be less than 1% + http_req_duration: ['p(80)<250'], // 80% of requests should be below 250ms + }, +}; + +const { BASE_URL } = __ENV; + +if (BASE_URL === undefined) { + throw new Error('BASE_URL is not set'); +} + +const headers = { + accept: 'application/json, text/plain, */*', + 'content-type': 'application/json', + 'upgrade-insecure-requests': '1', + 'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"macOS"', +}; + +const executeCommonChecks = (res) => { + check(res, { + 'is status 200': (r) => r.status === 200, + 'has no errors': (r) => !r.json().errors, + }); +}; + +export default function main() { + let res; + + const vars = {}; + setDefaultCookies(BASE_URL); + + group('Browsing for a product', () => { + group('Visit the homepage', () => { + res = http.get( + `${BASE_URL}/default`, + { + headers, + }, + ); + + check(res, { + 'is status 200': (r) => r.status === 200, + }); + + sleep(0.9); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query storeConfig {\\n storeConfig {\\n store_code,\\n default_title,\\n store_name,\\n default_display_currency_code,\\n locale,\\n header_logo_src,\\n logo_width,\\n logo_height,\\n logo_alt\\n }\\n }\\n"}]', + { + headers, + }, + ); + + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getStoresAndCurrencies {\\n availableStores {\\n store_code\\n }\\n currency {\\n available_currency_codes\\n }\\n }\\n"}]', + { + headers, + }, + ); + + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getStoresAndCurrencies {\\n availableStores {\\n store_code\\n }\\n currency {\\n available_currency_codes\\n }\\n }\\n"}]', + { + headers, + }, + ); + + executeCommonChecks(res); + + sleep(2.2); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query categoryList {\\n categories {\\n items {\\n ...CategoryFields\\n children {\\n ...CategoryFields\\n children {\\n ...CategoryFields\\n children {\\n ...CategoryFields\\n }\\n }\\n }\\n }\\n }\\n }\\n \\n fragment CategoryFields on CategoryTree {\\n is_anchor\\n name\\n position\\n product_count\\n uid\\n url_path\\n url_suffix\\n include_in_menu\\n }\\n\\n"}]', + { + headers, + }, + ); + + executeCommonChecks(res); + }); + + group('Go to the Men category page', () => { + res = http.post( + `${BASE_URL}/api/magento/route`, + '["/men.html",null]', + { + headers, + }, + ); + check(res, { + 'is status 200': (r) => r.status === 200, + }); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query categoryList {\\n categories {\\n items {\\n ...CategoryFields\\n children {\\n ...CategoryFields\\n children {\\n ...CategoryFields\\n children {\\n ...CategoryFields\\n }\\n }\\n }\\n }\\n }\\n }\\n \\n fragment CategoryFields on CategoryTree {\\n is_anchor\\n name\\n position\\n product_count\\n uid\\n url_path\\n url_suffix\\n include_in_menu\\n }\\n\\n"}]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getCategoryContentData($filters: CategoryFilterInput) {\\n categoryList(filters: $filters) {\\n uid\\n display_mode\\n landing_page\\n cms_block {\\n identifier\\n content\\n }\\n }\\n }\\n","queryVariables":{"filters":{"category_uid":{"eq":"MTE="}}}}]', + { + headers, + }, + ); + executeCommonChecks(res); + + [vars.uid1] = jsonpath.query(res.json(), '$.data.categoryList[0].uid'); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + `[{"query":"\\n query getFacetData($search: String = \\"\\", $filter: ProductAttributeFilterInput, $pageSize: Int = 10, $currentPage: Int = 1, $sort: ProductAttributeSortInput) {\\n products(search: $search, filter: $filter, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) {\\n items {\\n __typename\\n uid\\n sku\\n name\\n stock_status\\n only_x_left_in_stock\\n thumbnail {\\n url\\n position\\n disabled\\n label\\n }\\n url_key\\n url_rewrites {\\n url\\n }\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n }\\n page_info {\\n current_page\\n page_size\\n total_pages\\n }\\n total_count\\n }\\n }\\n","queryVariables":{"pageSize":10,"search":"","filter":{"category_uid":{"in":["${vars.uid1}"]}},"sort":{},"currentPage":1}}]`, + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + `[{"query":"\\n query getProductFiltersByCategory($categoryIdFilter: FilterEqualTypeInput!) {\\n products(filter: { category_uid: $categoryIdFilter }) {\\n aggregations {\\n label\\n count\\n attribute_code\\n options {\\n count\\n label\\n value\\n __typename\\n }\\n position\\n __typename\\n }\\n __typename\\n }\\n }\\n","queryVariables":{"categoryIdFilter":{"eq":"${vars.uid1}"}}}]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(3); + }); + + group('Sort by name ASC', () => { + res = http.post( + `${BASE_URL}/api/magento/route`, + '["/men.html",null]', + { + headers, + }, + ); + check(res, { + 'is status 200': (r) => r.status === 200, + }); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + `[{"query":"\\n query getCategoryContentData($filters: CategoryFilterInput) {\\n categoryList(filters: $filters) {\\n uid\\n display_mode\\n landing_page\\n cms_block {\\n identifier\\n content\\n }\\n }\\n }\\n","queryVariables":{"filters":{"category_uid":{"eq":"${vars.uid1}"}}}}]`, + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + `[{"query":"\\n query getFacetData($search: String = \\"\\", $filter: ProductAttributeFilterInput, $pageSize: Int = 10, $currentPage: Int = 1, $sort: ProductAttributeSortInput) {\\n products(search: $search, filter: $filter, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) {\\n items {\\n __typename\\n uid\\n sku\\n name\\n stock_status\\n only_x_left_in_stock\\n thumbnail {\\n url\\n position\\n disabled\\n label\\n }\\n url_key\\n url_rewrites {\\n url\\n }\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n }\\n page_info {\\n current_page\\n page_size\\n total_pages\\n }\\n total_count\\n }\\n }\\n","queryVariables":{"pageSize":10,"search":"","filter":{"category_uid":{"in":["${vars.uid1}"]}},"sort":{"name":"DESC"},"currentPage":1}}]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(3); + }); + + group('Sort by Price ASC', () => { + res = http.post( + `${BASE_URL}/api/magento/route`, + '["/men.html",null]', + { + headers, + }, + ); + check(res, { + 'is status 200': (r) => r.status === 200, + }); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + `[{"query":"\\n query getCategoryContentData($filters: CategoryFilterInput) {\\n categoryList(filters: $filters) {\\n uid\\n display_mode\\n landing_page\\n cms_block {\\n identifier\\n content\\n }\\n }\\n }\\n","queryVariables":{"filters":{"category_uid":{"eq":"${vars.uid1}"}}}}]`, + { + headers, + }, + ); + executeCommonChecks(res); + [vars.uid2] = jsonpath.query(res.json(), '$.data.categoryList[0].uid'); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + `[{"query":"\\n query getFacetData($search: String = \\"\\", $filter: ProductAttributeFilterInput, $pageSize: Int = 10, $currentPage: Int = 1, $sort: ProductAttributeSortInput) {\\n products(search: $search, filter: $filter, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) {\\n items {\\n __typename\\n uid\\n sku\\n name\\n stock_status\\n only_x_left_in_stock\\n thumbnail {\\n url\\n position\\n disabled\\n label\\n }\\n url_key\\n url_rewrites {\\n url\\n }\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n }\\n page_info {\\n current_page\\n page_size\\n total_pages\\n }\\n total_count\\n }\\n }\\n","queryVariables":{"pageSize":10,"search":"","filter":{"category_uid":{"in":["${vars.uid1}"]}},"sort":{"price":"ASC"},"currentPage":1}}]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(3); + }); + + group('Filter list by the price', () => { + res = http.post( + `${BASE_URL}/api/magento/route`, + '["/men.html",null]', + { + headers, + }, + ); + check(res, { + 'is status 200': (r) => r.status === 200, + }); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + `[{"query":"\\n query getCategoryContentData($filters: CategoryFilterInput) {\\n categoryList(filters: $filters) {\\n uid\\n display_mode\\n landing_page\\n cms_block {\\n identifier\\n content\\n }\\n }\\n }\\n","queryVariables":{"filters":{"category_uid":{"eq":"${vars.uid2}"}}}}]`, + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + `[{"query":"\\n query getFacetData($search: String = \\"\\", $filter: ProductAttributeFilterInput, $pageSize: Int = 10, $currentPage: Int = 1, $sort: ProductAttributeSortInput) {\\n products(search: $search, filter: $filter, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) {\\n items {\\n __typename\\n uid\\n sku\\n name\\n stock_status\\n only_x_left_in_stock\\n thumbnail {\\n url\\n position\\n disabled\\n label\\n }\\n url_key\\n url_rewrites {\\n url\\n }\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n }\\n page_info {\\n current_page\\n page_size\\n total_pages\\n }\\n total_count\\n }\\n }\\n","queryVariables":{"pageSize":10,"search":"","filter":{"price":{"from":40,"to":50},"category_uid":{"in":["${vars.uid2}"]}},"sort":{"price":"ASC"},"currentPage":1}}]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(1.6); + }); + + group('Visit selected product', () => { + res = http.post( + `${BASE_URL}/api/magento/productDetail`, + '[{"filter":{"sku":{"eq":"MH06"}},"configurations":[]},{"productDetail":"productDetail"}]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getProductPriceBySku(\\n $filter: ProductAttributeFilterInput,\\n $configurations: [ID!]\\n ) {\\n products(filter: $filter) {\\n items {\\n price_range {\\n ...PriceRangeFields\\n }\\n\\n ... on ConfigurableProduct {\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n\\n configurable_product_options_selection(configurableOptionValueUids: $configurations) {\\n options_available_for_selection {\\n attribute_code\\n option_value_uids\\n }\\n media_gallery {\\n disabled\\n label\\n position\\n url\\n }\\n variant {\\n uid\\n sku\\n name\\n price_range {\\n ...PriceRangeFields\\n }\\n }\\n }\\n }\\n\\n ... on BundleProduct {\\n items {\\n position\\n required\\n sku\\n title\\n type\\n uid\\n options {\\n can_change_quantity\\n is_default\\n position\\n uid\\n quantity\\n product {\\n uid\\n sku\\n name\\n price_range {\\n ...PriceRangeFields\\n }\\n }\\n }\\n }\\n }\\n\\n ... on GroupedProduct {\\n items {\\n position\\n qty\\n product {\\n uid\\n sku\\n name\\n stock_status\\n only_x_left_in_stock\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n thumbnail {\\n url\\n position\\n disabled\\n label\\n }\\n }\\n }\\n }\\n\\n }\\n }\\n }\\n \\n fragment PriceRangeFields on PriceRange {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n\\n","queryVariables":{"filter":{"sku":{"eq":"MH06"}},"configurations":[]}}]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/upsellProduct`, + '[{"filter":{"sku":{"eq":"MH06"}}},null]', + { + headers, + }, + ); + + res = http.post( + `${BASE_URL}/api/magento/relatedProduct`, + '[{"filter":{"sku":{"eq":"MH06"}}},null]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/productReviewRatingsMetadata`, + '[null]', + { + headers, + }, + ); + }); + }); +} diff --git a/packages/load-tests/src/scenarios/searchProduct.js b/packages/load-tests/src/scenarios/searchProduct.js deleted file mode 100644 index c7384d1fc..000000000 --- a/packages/load-tests/src/scenarios/searchProduct.js +++ /dev/null @@ -1,370 +0,0 @@ -// Creator: k6 Browser Recorder 0.6.2 (+ handmade cleanups) -import { sleep, group } from 'k6'; -import http from 'k6/http'; - -import jsonpath from 'https://jslib.k6.io/jsonpath/1.0.2/index.js'; - -/** - * @type {import('k6/options').Options} - */ -export const options = { - vus: 200, - duration: '5m', - ext: { - loadimpact: { - name: 'Search products', - note: 'Guest user browsing through a product', - // eslint-disable-next-line unicorn/numeric-separators-style - projectID: 3591701, - }, - }, -}; - -const { BASE_URL } = __ENV; - -if (BASE_URL === undefined) { - throw new Error('BASE_URL is not set'); -} - -export default function main() { - let response; - - const vars = {}; - - group(`page_1 - ${BASE_URL}/default`, () => { - response = http.get(`${BASE_URL}/default`); - sleep(0.5); - - response = http.post( - `${BASE_URL}/api/magento/customQuery`, - `[{"query":" - query storeConfig { - storeConfig { - store_code, - default_title, - store_name, - default_display_currency_code, - locale, - header_logo_src, - logo_width, - logo_height, - logo_alt - } - } -"}]`, - ); - - response = http.post( - `${BASE_URL}/api/magento/customQuery`, - `[{"query":" - query getStoresAndCurrencies { - availableStores { - store_code - } - currency { - available_currency_codes - } - } -"}]`, - ); - sleep(2.6); - - response = http.post( - `${BASE_URL}/api/magento/route`, - '["/women/tops-women/jackets-women.html",null]', - ); - - [vars.uid1] = jsonpath.query(response.json(), '$.data.route.uid'); - - response = http.post( - `${BASE_URL}/api/magento/customQuery`, - `[{"query":" - query categoryList { - categories { - items { - ...CategoryFields - children { - ...CategoryFields - children { - ...CategoryFields - children { - ...CategoryFields - } - } - } - } - } - } - - fragment CategoryFields on CategoryTree { - is_anchor - name - position - product_count - uid - url_path - url_suffix - include_in_menu - } - -"}]`, - ); - - response = http.post( - `${BASE_URL}/api/magento/customQuery`, - `[{"query":" - query getCategoryContentData($filters: CategoryFilterInput) { - categoryList(filters: $filters) { - uid - display_mode - landing_page - cms_block { - identifier - content - } - } - } -","queryVariables":{"filters":{"category_uid":{"eq":"${vars.uid1}"}}}}]`, - ); - - response = http.post( - `${BASE_URL}/api/magento/customQuery`, - `[{"query":" - query getFacetData($search: String = \\"\\", $filter: ProductAttributeFilterInput, $pageSize: Int = 10, $currentPage: Int = 1, $sort: ProductAttributeSortInput) { - products(search: $search, filter: $filter, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) { - items { - __typename - uid - sku - name - stock_status - only_x_left_in_stock - thumbnail { - url - position - disabled - label - } - url_key - url_rewrites { - url - } - price_range { - maximum_price { - final_price { - currency - value - } - regular_price { - currency - value - } - } - minimum_price { - final_price { - currency - value - } - regular_price { - currency - value - } - } - } - } - page_info { - current_page - page_size - total_pages - } - total_count - } - } -","queryVariables":{"pageSize":10,"search":"","filter":{"category_uid":{"in":["${vars.uid1}"]}},"sort":{},"currentPage":1}}]`, - ); - sleep(0.5); - - response = http.post( - `${BASE_URL}/api/magento/customQuery`, - `[{"query":" - query getProductFiltersByCategory($categoryIdFilter: FilterEqualTypeInput!) { - products(filter: { category_uid: $categoryIdFilter }) { - aggregations { - label - count - attribute_code - options { - count - label - value - __typename - } - position - __typename - } - __typename - } - } -","queryVariables":{"categoryIdFilter":{"eq":"${vars.uid1}"}}}]`, - ); - sleep(1.8); - - response = http.post( - `${BASE_URL}/api/magento/productDetail`, - '[{"filter":{"sku":{"eq":"WJ12"}},"configurations":[]},{"productDetail":"productDetail"}]', - ); - - response = http.post( - `${BASE_URL}/api/magento/customQuery`, - `[{"query":" - query getProductPriceBySku($sku: String) { - products(filter: {sku: {eq: $sku}}) { - items { - price_range { - ...PriceRangeFields - } - - ... on BundleProduct { - items { - position - required - sku - title - type - uid - options { - can_change_quantity - is_default - position - uid - quantity - product { - uid - sku - name - price_range { - maximum_price { - final_price { - currency - value - } - regular_price { - currency - value - } - } - minimum_price { - final_price { - currency - value - } - regular_price { - currency - value - } - } - } - } - } - } - } - - ... on GroupedProduct { - items { - position - qty - product { - uid - sku - name - stock_status - only_x_left_in_stock - price_range { - maximum_price { - final_price { - currency - value - } - regular_price { - currency - value - } - } - minimum_price { - final_price { - currency - value - } - regular_price { - currency - value - } - } - } - thumbnail { - url - position - disabled - label - } - } - } - } - - } - } - } - - fragment PriceRangeFields on PriceRange { - maximum_price { - final_price { - currency - value - } - regular_price { - currency - value - } - } - minimum_price { - final_price { - currency - value - } - regular_price { - currency - value - } - } - } - -","queryVariables":{"sku":"WJ12"}}]`, - ); - - response = http.post( - `${BASE_URL}/api/magento/upsellProduct`, - '[{"filter":{"sku":{"eq":"WJ12"}}},null]', - ); - - response = http.post( - `${BASE_URL}/api/magento/relatedProduct`, - '[{"filter":{"sku":{"eq":"WJ12"}}},null]', - ); - - response = http.post( - `${BASE_URL}/api/magento/productReviewRatingsMetadata`, - '[null]', - ); - sleep(2.3); - - response = http.post( - `${BASE_URL}/api/magento/productReview`, - '[{"filter":{"sku":{"eq":"WJ12"}}},null]', - ); - - response = http.post( - `${BASE_URL}/api/magento/productReviewRatingsMetadata`, - '[null]', - ); - }); -} diff --git a/packages/load-tests/src/scenarios/utils/setDefaultCookies.js b/packages/load-tests/src/scenarios/utils/setDefaultCookies.js new file mode 100644 index 000000000..328461ac0 --- /dev/null +++ b/packages/load-tests/src/scenarios/utils/setDefaultCookies.js @@ -0,0 +1,8 @@ +import http from 'k6/http'; + +export const setDefaultCookies = (url) => { + const jar = http.cookieJar(); + jar.set(url, 'vsf-store', 'default'); + jar.set(url, 'vsf-locale', 'default'); + jar.set(url, 'vsf-currency', 'USD'); +}; From f67b9b8fce8dd526a366c8af6d45c5fab44bc326 Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Tue, 26 Jul 2022 08:43:58 +0200 Subject: [PATCH 36/55] test: add search product load tests --- .eslintignore | 1 - .../{ => tests}/scenarios/browsingProduct.js | 3 +- .../src/tests/scenarios/searchProduct.js | 125 ++++++++++++++++++ .../scenarios/utils/setDefaultCookies.js | 1 + 4 files changed, 127 insertions(+), 3 deletions(-) rename packages/load-tests/src/{ => tests}/scenarios/browsingProduct.js (99%) create mode 100644 packages/load-tests/src/tests/scenarios/searchProduct.js rename packages/load-tests/src/{ => tests}/scenarios/utils/setDefaultCookies.js (91%) diff --git a/.eslintignore b/.eslintignore index 2a24330f7..0fc6ca764 100755 --- a/.eslintignore +++ b/.eslintignore @@ -5,5 +5,4 @@ packages/api-client/server packages/composables packages/api-client/lib packages/theme/static/sw.js -packages/load-tests/* .eslintrc.js diff --git a/packages/load-tests/src/scenarios/browsingProduct.js b/packages/load-tests/src/tests/scenarios/browsingProduct.js similarity index 99% rename from packages/load-tests/src/scenarios/browsingProduct.js rename to packages/load-tests/src/tests/scenarios/browsingProduct.js index da6aa49f6..264bb2f0b 100644 --- a/packages/load-tests/src/scenarios/browsingProduct.js +++ b/packages/load-tests/src/tests/scenarios/browsingProduct.js @@ -42,8 +42,7 @@ export default function main() { const vars = {}; setDefaultCookies(BASE_URL); - - group('Browsing for a product', () => { + group(`Browsing for a product - page ${BASE_URL}`, () => { group('Visit the homepage', () => { res = http.get( `${BASE_URL}/default`, diff --git a/packages/load-tests/src/tests/scenarios/searchProduct.js b/packages/load-tests/src/tests/scenarios/searchProduct.js new file mode 100644 index 000000000..80fba2341 --- /dev/null +++ b/packages/load-tests/src/tests/scenarios/searchProduct.js @@ -0,0 +1,125 @@ +// Creator: k6 Browser Recorder 0.6.2 + +import { check, sleep, group } from 'k6'; +import http from 'k6/http'; +import { setDefaultCookies } from './utils/setDefaultCookies.js'; + +export const options = { + vus: 200, + duration: '5m', + thresholds: { + http_req_failed: ['rate<0.01'], // http errors should be less than 1% + http_req_duration: ['p(80)<250'], // 80% of requests should be below 250ms + }, +}; + +const { BASE_URL } = __ENV; + +if (BASE_URL === undefined) { + throw new Error('BASE_URL is not set'); +} + +const headers = { + accept: 'application/json, text/plain, */*', + 'content-type': 'application/json', + 'upgrade-insecure-requests': '1', + 'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"macOS"', +}; + +const executeCommonChecks = (res) => { + check(res, { + 'is status 200': (r) => r.status === 200, + 'has no errors': (r) => !r.json().errors, + }); +}; + +export default function main() { + let res; + setDefaultCookies(BASE_URL); + + group( + `Search Product - page ${BASE_URL}`, + () => { + group('Visit the homepage', () => { + res = http.get( + `${BASE_URL}/default`, + { headers }, + ); + check(res, { + 'is status 200': (r) => r.status === 200, + }); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query storeConfig {\\n storeConfig {\\n store_code,\\n default_title,\\n store_name,\\n default_display_currency_code,\\n locale,\\n header_logo_src,\\n logo_width,\\n logo_height,\\n logo_alt\\n }\\n }\\n"}]', + { headers }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getStoresAndCurrencies {\\n availableStores {\\n store_code\\n }\\n currency {\\n available_currency_codes\\n }\\n }\\n"}]', + { headers }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getStoresAndCurrencies {\\n availableStores {\\n store_code\\n }\\n currency {\\n available_currency_codes\\n }\\n }\\n"}]', + { headers }, + ); + executeCommonChecks(res); + sleep(4.1); + }); + + group('Search for a product', () => { + res = http.post( + `${BASE_URL}/api/magento/products`, + '[{"pageSize":12,"search":"erika"},{"products":"products"}]', + { headers }, + ); + executeCommonChecks(res); + sleep(1.9); + }); + + group('Visit the found product', () => { + res = http.post( + `${BASE_URL}/api/magento/productDetail`, + '[{"filter":{"sku":{"eq":"WSH12"}},"configurations":[]},{"productDetail":"productDetail"}]', + { headers }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getProductPriceBySku(\\n $filter: ProductAttributeFilterInput,\\n $configurations: [ID!]\\n ) {\\n products(filter: $filter) {\\n items {\\n price_range {\\n ...PriceRangeFields\\n }\\n\\n ... on ConfigurableProduct {\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n\\n configurable_product_options_selection(configurableOptionValueUids: $configurations) {\\n options_available_for_selection {\\n attribute_code\\n option_value_uids\\n }\\n media_gallery {\\n disabled\\n label\\n position\\n url\\n }\\n variant {\\n uid\\n sku\\n name\\n price_range {\\n ...PriceRangeFields\\n }\\n }\\n }\\n }\\n\\n ... on BundleProduct {\\n items {\\n position\\n required\\n sku\\n title\\n type\\n uid\\n options {\\n can_change_quantity\\n is_default\\n position\\n uid\\n quantity\\n product {\\n uid\\n sku\\n name\\n price_range {\\n ...PriceRangeFields\\n }\\n }\\n }\\n }\\n }\\n\\n ... on GroupedProduct {\\n items {\\n position\\n qty\\n product {\\n uid\\n sku\\n name\\n stock_status\\n only_x_left_in_stock\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n thumbnail {\\n url\\n position\\n disabled\\n label\\n }\\n }\\n }\\n }\\n\\n }\\n }\\n }\\n \\n fragment PriceRangeFields on PriceRange {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n\\n","queryVariables":{"filter":{"sku":{"eq":"WSH12"}},"configurations":[]}}]', + { headers }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/relatedProduct`, + '[{"filter":{"sku":{"eq":"WSH12"}}},null]', + { headers }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/upsellProduct`, + '[{"filter":{"sku":{"eq":"WSH12"}}},null]', + { headers }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/productReviewRatingsMetadata`, + '[null]', + { headers }, + ); + executeCommonChecks(res); + }); + }, + ); +} diff --git a/packages/load-tests/src/scenarios/utils/setDefaultCookies.js b/packages/load-tests/src/tests/scenarios/utils/setDefaultCookies.js similarity index 91% rename from packages/load-tests/src/scenarios/utils/setDefaultCookies.js rename to packages/load-tests/src/tests/scenarios/utils/setDefaultCookies.js index 328461ac0..2b143868d 100644 --- a/packages/load-tests/src/scenarios/utils/setDefaultCookies.js +++ b/packages/load-tests/src/tests/scenarios/utils/setDefaultCookies.js @@ -1,3 +1,4 @@ +/* eslint-disable */ import http from 'k6/http'; export const setDefaultCookies = (url) => { From d373d53e0dea348cfabd5808c7c207b5b4bc7f0f Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Tue, 26 Jul 2022 11:35:53 +0200 Subject: [PATCH 37/55] test: add buy product as a guest user load test --- .../src/tests/magento/createCustomer.js | 2 +- .../tests/scenarios/buyProductAsAGuestUser.js | 448 ++++++++++++++++++ .../{tests/magento => }/utils/customerData.js | 0 3 files changed, 449 insertions(+), 1 deletion(-) create mode 100644 packages/load-tests/src/tests/scenarios/buyProductAsAGuestUser.js rename packages/load-tests/src/{tests/magento => }/utils/customerData.js (100%) diff --git a/packages/load-tests/src/tests/magento/createCustomer.js b/packages/load-tests/src/tests/magento/createCustomer.js index b4d7c831a..a382e3ab9 100644 --- a/packages/load-tests/src/tests/magento/createCustomer.js +++ b/packages/load-tests/src/tests/magento/createCustomer.js @@ -4,7 +4,7 @@ import http from 'k6/http'; import getHeaders from './utils/getHeaders.js'; import { CreateCustomer } from '../../mutation/createCustomer.js'; -import { customerData } from './utils/customerData.js'; +import { customerData } from '../../utils/customerData.js'; /** * @type {import('k6/options').Options} diff --git a/packages/load-tests/src/tests/scenarios/buyProductAsAGuestUser.js b/packages/load-tests/src/tests/scenarios/buyProductAsAGuestUser.js new file mode 100644 index 000000000..bf9437d8b --- /dev/null +++ b/packages/load-tests/src/tests/scenarios/buyProductAsAGuestUser.js @@ -0,0 +1,448 @@ +// Creator: k6 Browser Recorder 0.6.2 +import { check, sleep, group } from 'k6'; +import http from 'k6/http'; +import jsonpath from 'https://jslib.k6.io/jsonpath/1.0.2/index.js'; +import { setDefaultCookies } from './utils/setDefaultCookies.js'; + +export const options = { + vus: 200, + duration: '5m', + thresholds: { + http_req_failed: ['rate<0.01'], // http errors should be less than 1% + http_req_duration: ['p(80)<250'], // 80% of requests should be below 250ms + }, +}; + +const { BASE_URL } = __ENV; + +if (BASE_URL === undefined) { + throw new Error('BASE_URL is not set'); +} + +const headers = { + accept: 'application/json, text/plain, */*', + 'content-type': 'application/json', + 'upgrade-insecure-requests': '1', + 'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"macOS"', +}; + +const executeCommonChecks = (res) => { + check(res, { + 'is status 200': (r) => r.status === 200, + 'has no errors': (r) => !r.json().errors, + }); +}; + +export default function main() { + let res; + + const vars = {}; + setDefaultCookies(BASE_URL); + + group(`Buy product as a guest user - page ${BASE_URL}`, () => { + group('Visit the homepage', () => { + res = http.get( + `${BASE_URL}/default`, + { + headers, + }, + ); + sleep(0.8); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query storeConfig {\\n storeConfig {\\n store_code,\\n default_title,\\n store_name,\\n default_display_currency_code,\\n locale,\\n header_logo_src,\\n logo_width,\\n logo_height,\\n logo_alt\\n }\\n }\\n"}]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getStoresAndCurrencies {\\n availableStores {\\n store_code\\n }\\n currency {\\n available_currency_codes\\n }\\n }\\n"}]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getStoresAndCurrencies {\\n availableStores {\\n store_code\\n }\\n currency {\\n available_currency_codes\\n }\\n }\\n"}]', + { + headers, + }, + ); + executeCommonChecks(res); + sleep(2.7); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query categoryList {\\n categories {\\n items {\\n ...CategoryFields\\n children {\\n ...CategoryFields\\n children {\\n ...CategoryFields\\n children {\\n ...CategoryFields\\n }\\n }\\n }\\n }\\n }\\n }\\n \\n fragment CategoryFields on CategoryTree {\\n is_anchor\\n name\\n position\\n product_count\\n uid\\n url_path\\n url_suffix\\n include_in_menu\\n }\\n\\n"}]', + { + headers, + }, + ); + executeCommonChecks(res); + }); + + group('Select the a category', () => { + res = http.post( + `${BASE_URL}/api/magento/route`, + '["/women.html",null]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query categoryList {\\n categories {\\n items {\\n ...CategoryFields\\n children {\\n ...CategoryFields\\n children {\\n ...CategoryFields\\n children {\\n ...CategoryFields\\n }\\n }\\n }\\n }\\n }\\n }\\n \\n fragment CategoryFields on CategoryTree {\\n is_anchor\\n name\\n position\\n product_count\\n uid\\n url_path\\n url_suffix\\n include_in_menu\\n }\\n\\n"}]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getCategoryContentData($filters: CategoryFilterInput) {\\n categoryList(filters: $filters) {\\n uid\\n display_mode\\n landing_page\\n cms_block {\\n identifier\\n content\\n }\\n }\\n }\\n","queryVariables":{"filters":{"category_uid":{"eq":"MjA="}}}}]', + { + headers, + }, + ); + executeCommonChecks(res); + [vars.uid1] = jsonpath.query(res.json(), '$.data.categoryList[0].uid'); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + `[{"query":"\\n query getFacetData($search: String = \\"\\", $filter: ProductAttributeFilterInput, $pageSize: Int = 10, $currentPage: Int = 1, $sort: ProductAttributeSortInput) {\\n products(search: $search, filter: $filter, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) {\\n items {\\n __typename\\n uid\\n sku\\n name\\n stock_status\\n only_x_left_in_stock\\n thumbnail {\\n url\\n position\\n disabled\\n label\\n }\\n url_key\\n url_rewrites {\\n url\\n }\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n }\\n page_info {\\n current_page\\n page_size\\n total_pages\\n }\\n total_count\\n }\\n }\\n","queryVariables":{"pageSize":10,"search":"","filter":{"category_uid":{"in":["${vars.uid1}"]}},"sort":{},"currentPage":1}}]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(0.5); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + `[{"query":"\\n query getProductFiltersByCategory($categoryIdFilter: FilterEqualTypeInput!) {\\n products(filter: { category_uid: $categoryIdFilter }) {\\n aggregations {\\n label\\n count\\n attribute_code\\n options {\\n count\\n label\\n value\\n __typename\\n }\\n position\\n __typename\\n }\\n __typename\\n }\\n }\\n","queryVariables":{"categoryIdFilter":{"eq":"${vars.uid1}"}}}]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(2.1); + }); + + group('configure the product', () => { + res = http.post( + `${BASE_URL}/api/magento/productDetail`, + '[{"filter":{"sku":{"eq":"WSH11"}},"configurations":[]},{"productDetail":"productDetail"}]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getProductPriceBySku(\\n $filter: ProductAttributeFilterInput,\\n $configurations: [ID!]\\n ) {\\n products(filter: $filter) {\\n items {\\n price_range {\\n ...PriceRangeFields\\n }\\n\\n ... on ConfigurableProduct {\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n\\n configurable_product_options_selection(configurableOptionValueUids: $configurations) {\\n options_available_for_selection {\\n attribute_code\\n option_value_uids\\n }\\n media_gallery {\\n disabled\\n label\\n position\\n url\\n }\\n variant {\\n uid\\n sku\\n name\\n price_range {\\n ...PriceRangeFields\\n }\\n }\\n }\\n }\\n\\n ... on BundleProduct {\\n items {\\n position\\n required\\n sku\\n title\\n type\\n uid\\n options {\\n can_change_quantity\\n is_default\\n position\\n uid\\n quantity\\n product {\\n uid\\n sku\\n name\\n price_range {\\n ...PriceRangeFields\\n }\\n }\\n }\\n }\\n }\\n\\n ... on GroupedProduct {\\n items {\\n position\\n qty\\n product {\\n uid\\n sku\\n name\\n stock_status\\n only_x_left_in_stock\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n thumbnail {\\n url\\n position\\n disabled\\n label\\n }\\n }\\n }\\n }\\n\\n }\\n }\\n }\\n \\n fragment PriceRangeFields on PriceRange {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n\\n","queryVariables":{"filter":{"sku":{"eq":"WSH11"}},"configurations":[]}}]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/upsellProduct`, + '[{"filter":{"sku":{"eq":"WSH11"}}},null]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/relatedProduct`, + '[{"filter":{"sku":{"eq":"WSH11"}}},null]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/productReviewRatingsMetadata`, + '[null]', + { + headers, + }, + ); + executeCommonChecks(res); + sleep(1.1); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getProductPriceBySku(\\n $filter: ProductAttributeFilterInput,\\n $configurations: [ID!]\\n ) {\\n products(filter: $filter) {\\n items {\\n price_range {\\n ...PriceRangeFields\\n }\\n\\n ... on ConfigurableProduct {\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n\\n configurable_product_options_selection(configurableOptionValueUids: $configurations) {\\n options_available_for_selection {\\n attribute_code\\n option_value_uids\\n }\\n media_gallery {\\n disabled\\n label\\n position\\n url\\n }\\n variant {\\n uid\\n sku\\n name\\n price_range {\\n ...PriceRangeFields\\n }\\n }\\n }\\n }\\n\\n ... on BundleProduct {\\n items {\\n position\\n required\\n sku\\n title\\n type\\n uid\\n options {\\n can_change_quantity\\n is_default\\n position\\n uid\\n quantity\\n product {\\n uid\\n sku\\n name\\n price_range {\\n ...PriceRangeFields\\n }\\n }\\n }\\n }\\n }\\n\\n ... on GroupedProduct {\\n items {\\n position\\n qty\\n product {\\n uid\\n sku\\n name\\n stock_status\\n only_x_left_in_stock\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n thumbnail {\\n url\\n position\\n disabled\\n label\\n }\\n }\\n }\\n }\\n\\n }\\n }\\n }\\n \\n fragment PriceRangeFields on PriceRange {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n\\n","queryVariables":{"filter":{"sku":{"eq":"WSH11"}},"configurations":["Y29uZmlndXJhYmxlLzkzLzU4"]}}]', + { + headers, + }, + ); + executeCommonChecks(res); + + [vars.index01] = jsonpath.query( + res.json(), + '$.data.products.items[0].configurable_product_options_selection.options_available_for_selection[1].option_value_uids[0]', + ); + + [vars.index11] = jsonpath.query( + res.json(), + '$.data.products.items[0].configurable_product_options_selection.options_available_for_selection[0].option_value_uids[1]', + ); + + sleep(1.6); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + `[{"query":"\\n query getProductPriceBySku(\\n $filter: ProductAttributeFilterInput,\\n $configurations: [ID!]\\n ) {\\n products(filter: $filter) {\\n items {\\n price_range {\\n ...PriceRangeFields\\n }\\n\\n ... on ConfigurableProduct {\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n\\n configurable_product_options_selection(configurableOptionValueUids: $configurations) {\\n options_available_for_selection {\\n attribute_code\\n option_value_uids\\n }\\n media_gallery {\\n disabled\\n label\\n position\\n url\\n }\\n variant {\\n uid\\n sku\\n name\\n price_range {\\n ...PriceRangeFields\\n }\\n }\\n }\\n }\\n\\n ... on BundleProduct {\\n items {\\n position\\n required\\n sku\\n title\\n type\\n uid\\n options {\\n can_change_quantity\\n is_default\\n position\\n uid\\n quantity\\n product {\\n uid\\n sku\\n name\\n price_range {\\n ...PriceRangeFields\\n }\\n }\\n }\\n }\\n }\\n\\n ... on GroupedProduct {\\n items {\\n position\\n qty\\n product {\\n uid\\n sku\\n name\\n stock_status\\n only_x_left_in_stock\\n price_range {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n thumbnail {\\n url\\n position\\n disabled\\n label\\n }\\n }\\n }\\n }\\n\\n }\\n }\\n }\\n \\n fragment PriceRangeFields on PriceRange {\\n maximum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n minimum_price {\\n final_price {\\n currency\\n value\\n }\\n regular_price {\\n currency\\n value\\n }\\n }\\n }\\n\\n","queryVariables":{"filter":{"sku":{"eq":"WSH11"}},"configurations":["${vars.index01}","${vars.index11}"]}}]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(0.5); + }); + + group('Add product to the cart', () => { + res = http.post( + `${BASE_URL}/api/magento/createEmptyCart`, + '[]', + { + headers, + }, + ); + executeCommonChecks(res); + + [vars.cart_id] = jsonpath.query( + res.json(), + '$.data.createEmptyCart', + ); + + res = http.post( + `${BASE_URL}/api/magento/cart`, + `["${vars.cart_id}"]`, + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/addProductsToCart`, + `[{"cartId":"${vars.cart_id}","cartItems":[{"quantity":1,"sku":"WSH11","selected_options":["${vars.index01}","${vars.index11}"]}]},null]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(3); + }); + + group('Go through the checkout', () => { + res = http.post( + `${BASE_URL}/api/magento/cart`, + `["${vars.cart_id}"]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(5.3); + + res = http.post( + `${BASE_URL}/api/magento/setGuestEmailOnCart`, + `[{"email":"john.loadtest@gmail.com","cart_id":"${vars.cart_id}"},null]`, + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/cart`, + `["${vars.cart_id}"]`, + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/cart`, + `["${vars.cart_id}"]`, + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/countries`, + '[]', + { + headers, + }, + ); + executeCommonChecks(res); + sleep(2.2); + + res = http.post( + `${BASE_URL}/api/magento/country`, + '["PL",null]', + { + headers, + }, + ); + executeCommonChecks(res); + sleep(3.9); + + res = http.post( + `${BASE_URL}/api/magento/setShippingAddressesOnCart`, + `[{"cart_id":"${vars.cart_id}","shipping_addresses":[{"address":{"firstname":"john","lastname":"LoadTest","street":["Load Test 11","11"],"city":"Load Test","region":"PL-10","country_code":"PL","postcode":"11-111","telephone":"123123123","save_in_address_book":false}}]}]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(1.6); + + res = http.post( + `${BASE_URL}/api/magento/setShippingMethodsOnCart`, + `[{"cart_id":"${vars.cart_id}","shipping_methods":[{"carrier_code":"flatrate","method_code":"flatrate"}]},null]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(1.3); + + res = http.post( + `${BASE_URL}/api/magento/cart`, + `["${vars.cart_id}"]`, + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/cart`, + `["${vars.cart_id}"]`, + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/countries`, + '[]', + { + headers, + }, + ); + executeCommonChecks(res); + sleep(1.7); + + res = http.post( + `${BASE_URL}/api/magento/country`, + '["PL",null]', + { + headers, + }, + ); + + res = http.post( + `${BASE_URL}/api/magento/country`, + '["PL",null]', + { + headers, + }, + ); + executeCommonChecks(res); + sleep(1.4); + + res = http.post( + `${BASE_URL}/api/magento/setBillingAddressOnCart`, + `[{"cart_id":"${vars.cart_id}","billing_address":{"address":{"firstname":"john","lastname":"LoadTest","street":["Load Test 11","11"],"city":"Load Test","region":"PL-10","country_code":"PL","postcode":"11-111","telephone":"123123123","save_in_address_book":false},"same_as_shipping":true}},null]`, + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/setShippingMethodsOnCart`, + `[{"cart_id":"${vars.cart_id}","shipping_methods":[{"carrier_code":"flatrate","method_code":"flatrate"}]},null]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(0.5); + + res = http.post( + `${BASE_URL}/api/magento/cart`, + `["${vars.cart_id}"]`, + { + headers, + }, + ); + + res = http.post( + `${BASE_URL}/api/magento/cart`, + `["${vars.cart_id}"]`, + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/getAvailablePaymentMethods`, + `[{"cartId":"${vars.cart_id}"},null]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(1.2); + + res = http.post( + `${BASE_URL}/api/magento/setPaymentMethodOnCart`, + `[{"cart_id":"${vars.cart_id}","payment_method":{"code":"checkmo"}},null]`, + { + headers, + }, + ); + executeCommonChecks(res); + sleep(1.5); + }); + + group('Place the order', () => { + res = http.post( + `${BASE_URL}/api/magento/placeOrder`, + `[{"cart_id":"${vars.cart_id}"},null]`, + { + headers, + }, + ); + executeCommonChecks(res); + }); + }); +} diff --git a/packages/load-tests/src/tests/magento/utils/customerData.js b/packages/load-tests/src/utils/customerData.js similarity index 100% rename from packages/load-tests/src/tests/magento/utils/customerData.js rename to packages/load-tests/src/utils/customerData.js From adf0abed83bda1f901176e2fb83b8736a9f59228 Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Thu, 28 Jul 2022 08:55:08 +0200 Subject: [PATCH 38/55] feat: add i18n base url configuration - set baseUrl to env variable --- packages/theme/nuxt.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/theme/nuxt.config.js b/packages/theme/nuxt.config.js index 2a305497f..9eb8a6f23 100755 --- a/packages/theme/nuxt.config.js +++ b/packages/theme/nuxt.config.js @@ -135,6 +135,7 @@ export default () => { ], i18n: { country: 'US', + baseUrl: process.env.VSF_STORE_URL, strategy: 'prefix', locales: [ { From f3513aefd5401074b74641800d91780d53bd18ab Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Wed, 27 Jul 2022 08:31:17 +0200 Subject: [PATCH 39/55] test: add load test for a new user registration --- .../tests/scenarios/newUserRegistration.js | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 packages/load-tests/src/tests/scenarios/newUserRegistration.js diff --git a/packages/load-tests/src/tests/scenarios/newUserRegistration.js b/packages/load-tests/src/tests/scenarios/newUserRegistration.js new file mode 100644 index 000000000..d35bf8c53 --- /dev/null +++ b/packages/load-tests/src/tests/scenarios/newUserRegistration.js @@ -0,0 +1,95 @@ +// Creator: k6 Browser Recorder 0.6.2 +import { check, sleep, group } from 'k6'; +import http from 'k6/http'; +import { setDefaultCookies } from './utils/setDefaultCookies.js'; +import { customerData } from '../../utils/customerData.js'; + +export const options = { + vus: 200, + duration: '5m', + thresholds: { + http_req_failed: ['rate<0.01'], // http errors should be less than 1% + }, +}; + +const { BASE_URL } = __ENV; + +if (BASE_URL === undefined) { + throw new Error('BASE_URL is not set'); +} + +const headers = { + accept: 'application/json, text/plain, */*', + 'content-type': 'application/json', + 'upgrade-insecure-requests': '1', + 'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"macOS"', +}; + +const executeCommonChecks = (res) => { + check(res, { + 'is status 200': (r) => r.status === 200, + 'has no errors': (r) => !r.json().errors, + }); +}; + +export default function main() { + let res; + setDefaultCookies(BASE_URL); + + group( + `New user registration - page ${BASE_URL}`, + () => { + res = http.get( + `${BASE_URL}/default`, + { + headers, + }, + ); + sleep(0.6); + + group('Input user data', () => { + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query storeConfig {\\n storeConfig {\\n store_code,\\n default_title,\\n store_name,\\n default_display_currency_code,\\n locale,\\n header_logo_src,\\n logo_width,\\n logo_height,\\n logo_alt\\n }\\n }\\n"}]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getStoresAndCurrencies {\\n availableStores {\\n store_code\\n }\\n currency {\\n available_currency_codes\\n }\\n }\\n"}]', + { + headers, + }, + ); + executeCommonChecks(res); + + res = http.post( + `${BASE_URL}/api/magento/customQuery`, + '[{"query":"\\n query getStoresAndCurrencies {\\n availableStores {\\n store_code\\n }\\n currency {\\n available_currency_codes\\n }\\n }\\n"}]', + { + headers, + }, + ); + executeCommonChecks(res); + sleep(8); + }); + + group('Save new user', () => { + res = http.post( + `${BASE_URL}/api/magento/createCustomer`, + `[{"email":"${customerData.getEmail()}","password":"Admin123!","recaptchaToken":"recaptcha_bypass_code","firstname":"load","lastname":"test","is_subscribed":false},{}]`, + { + headers, + }, + ); + }); + + executeCommonChecks(res); + }, + ); +} From deb3e922fd60cc0a7674558d9c42ae2518d3aa85 Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Wed, 27 Jul 2022 07:47:26 +0200 Subject: [PATCH 40/55] fix: update installation guide - change npm -> yarn because npm does not work for our app --- docs/installation-setup/installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/installation-setup/installation.md b/docs/installation-setup/installation.md index 0cf98a437..ecd93b690 100644 --- a/docs/installation-setup/installation.md +++ b/docs/installation-setup/installation.md @@ -35,7 +35,7 @@ Go to the newly created directory and install the required dependencies: ```bash cd -npm install +yarn install ``` ### Step 2. Setup and configure Magento @@ -51,7 +51,7 @@ With the Magento instance setup and configured, you can connect your project to The project is now ready. You can start the application in development mode using the command below. You can read more about available commands and environments on the [Commands and deployment](https://nuxtjs.org/docs/2.x/get-started/commands/) page in Nuxt.js documentation. ```bash -npm run dev +yarn run dev ``` ## Recommended tools From 8164c49daaa49523626cf4a0d36f7e1ad79f79b1 Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Tue, 26 Jul 2022 09:17:21 +0200 Subject: [PATCH 41/55] refactor: remove style duplication in my account route components --- .../AddressesDetails/AddressEdit.vue | 8 ++---- .../MyAccount/AddressesDetails/AddressNew.vue | 7 +---- .../AddressesDetails/AddressesDetails.vue | 7 +---- .../customer/pages/MyAccount/MyNewsletter.vue | 8 +----- .../customer/pages/MyAccount/MyReviews.vue | 27 ++----------------- .../customer/pages/MyAccount/MyWishlist.vue | 9 +------ .../pages/MyAccount/ResetPassword.vue | 4 +++ .../modules/customer/pages/styles/shared.scss | 26 ++++++++++++++++++ 8 files changed, 38 insertions(+), 58 deletions(-) create mode 100644 packages/theme/modules/customer/pages/styles/shared.scss diff --git a/packages/theme/modules/customer/pages/MyAccount/AddressesDetails/AddressEdit.vue b/packages/theme/modules/customer/pages/MyAccount/AddressesDetails/AddressEdit.vue index a7df3bbed..2a93eefc0 100644 --- a/packages/theme/modules/customer/pages/MyAccount/AddressesDetails/AddressEdit.vue +++ b/packages/theme/modules/customer/pages/MyAccount/AddressesDetails/AddressEdit.vue @@ -69,10 +69,6 @@ export default defineComponent({ diff --git a/packages/theme/modules/customer/pages/MyAccount/AddressesDetails/AddressNew.vue b/packages/theme/modules/customer/pages/MyAccount/AddressesDetails/AddressNew.vue index 44fc40e46..b7f0cd0b6 100644 --- a/packages/theme/modules/customer/pages/MyAccount/AddressesDetails/AddressNew.vue +++ b/packages/theme/modules/customer/pages/MyAccount/AddressesDetails/AddressNew.vue @@ -43,10 +43,5 @@ export default defineComponent({ diff --git a/packages/theme/modules/customer/pages/MyAccount/AddressesDetails/AddressesDetails.vue b/packages/theme/modules/customer/pages/MyAccount/AddressesDetails/AddressesDetails.vue index f5efb8ccc..f50f59019 100644 --- a/packages/theme/modules/customer/pages/MyAccount/AddressesDetails/AddressesDetails.vue +++ b/packages/theme/modules/customer/pages/MyAccount/AddressesDetails/AddressesDetails.vue @@ -179,12 +179,7 @@ export default defineComponent({