From 06bb16bcfdd3079af4548f8569e7be6cd6734f4b Mon Sep 17 00:00:00 2001 From: Tam Mullen Date: Thu, 17 Feb 2022 21:45:21 +0000 Subject: [PATCH 1/4] Add k6 tests to the existing PR build and test action --- .github/workflows/pr-build-and-e2e-tests.yml | 64 ++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/.github/workflows/pr-build-and-e2e-tests.yml b/.github/workflows/pr-build-and-e2e-tests.yml index e0fbcc7e718..bca7a1f990d 100644 --- a/.github/workflows/pr-build-and-e2e-tests.yml +++ b/.github/workflows/pr-build-and-e2e-tests.yml @@ -134,3 +134,67 @@ jobs: USER_KEY: admin USER_SECRET: password run: pnpx wc-api-tests test api + + k6-tests-run: + name: Runs k6 Performance tests + runs-on: ubuntu-18.04 + needs: [build] + steps: + - name: Create dirs. + run: | + mkdir -p code/woocommerce + mkdir -p package/woocommerce + mkdir -p tmp/woocommerce + mkdir -p node_modules + - name: Checkout code. + uses: actions/checkout@v2 + with: + path: package/woocommerce + + - name: Install PNPM and install dependencies + working-directory: package/woocommerce + run: | + npm install -g pnpm + pnpm install + + - name: Workaround to use initialization file with prepopulated data. + working-directory: package/woocommerce/plugins/woocommerce/tests/e2e/docker + run: | + cp init-sample-products.sh initialize.sh + + - name: Load docker images and start containers. + working-directory: package/woocommerce/plugins/woocommerce + run: pnpx wc-e2e docker:up + + - name: Move current directory to code. We will install zip file in this dir later. + run: mv ./package/woocommerce/plugins/woocommerce/* ./code/woocommerce + + - name: Download WooCommerce ZIP. + uses: actions/download-artifact@v2 + with: + name: woocommerce + path: tmp + + - name: Extract and replace WooCommerce zip. + working-directory: tmp + run: | + unzip woocommerce.zip -d woocommerce + mv woocommerce/woocommerce/* ../package/woocommerce/plugins/woocommerce/ + + - name: Install dependencies again + working-directory: package/woocommerce + run: | + npm install -g pnpm + pnpm install + + - name: Wait for the Docker container to be built + working-directory: package/woocommerce/plugins/woocommerce + run: pnpx wc-e2e docker:wait + + - name: Install k6 + run: | + curl https://github.com/grafana/k6/releases/download/v0.33.0/k6-v0.33.0-linux-amd64.tar.gz -L | tar xvz --strip-components 1 + + - name: Run k6 tests + run: | + ./k6 run package/woocommerce/plugins/woocommerce/tests/performance/tests/gh-action-pr-requests.js From 67d6c063fd5bbfd05cb6379d3ac63621ab274fca Mon Sep 17 00:00:00 2001 From: Tam Mullen Date: Thu, 17 Feb 2022 22:09:11 +0000 Subject: [PATCH 2/4] Add k6 test scenario for all requests to run in PR action --- .../tests/gh-action-pr-requests.js | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 plugins/woocommerce/tests/performance/tests/gh-action-pr-requests.js diff --git a/plugins/woocommerce/tests/performance/tests/gh-action-pr-requests.js b/plugins/woocommerce/tests/performance/tests/gh-action-pr-requests.js new file mode 100644 index 00000000000..108f2330143 --- /dev/null +++ b/plugins/woocommerce/tests/performance/tests/gh-action-pr-requests.js @@ -0,0 +1,130 @@ +import { homePage } from '../requests/shopper/home.js'; +import { shopPage } from '../requests/shopper/shop-page.js'; +import { searchProduct } from '../requests/shopper/search-product.js'; +import { singleProduct } from '../requests/shopper/single-product.js'; +import { cart } from '../requests/shopper/cart.js'; +import { cartRemoveItem } from '../requests/shopper/cart-remove-item.js'; +import { checkoutGuest } from '../requests/shopper/checkout-guest.js'; +import { checkoutCustomerLogin } from '../requests/shopper/checkout-customer-login.js'; +import { myAccount } from '../requests/shopper/my-account.js'; +import { categoryPage } from '../requests/shopper/category-page.js'; +import { wpLogin } from '../requests/merchant/wp-login.js'; +import { products } from '../requests/merchant/products.js'; +import { addProduct } from '../requests/merchant/add-product.js'; +import { orders } from '../requests/merchant/orders.js'; +import { ordersSearch } from '../requests/merchant/orders-search.js'; +import { homeWCAdmin } from '../requests/merchant/home-wc-admin.js'; + +export let options = { + scenarios: { + homePageSmoke: { + executor: 'per-vu-iterations', + vus: 1, + iterations: 3, + maxDuration: '60s', + exec: 'homePageFlow', + }, + shopPageSmoke: { + executor: 'per-vu-iterations', + vus: 1, + iterations: 3, + maxDuration: '60s', + startTime: '5s', + exec: 'shopPageFlow', + }, + searchProductSmoke: { + executor: 'per-vu-iterations', + vus: 1, + iterations: 3, + maxDuration: '60s', + startTime: '10s', + exec: 'searchProductFlow', + }, + singleProductSmoke: { + executor: 'per-vu-iterations', + vus: 1, + iterations: 3, + maxDuration: '60s', + startTime: '15s', + exec: 'singleProductFlow', + }, + myAccountSmoke: { + executor: 'per-vu-iterations', + vus: 1, + iterations: 3, + maxDuration: '60s', + startTime: '20s', + exec: 'myAccountFlow', + }, + cartSmoke: { + executor: 'per-vu-iterations', + vus: 1, + iterations: 3, + maxDuration: '60s', + startTime: '25s', + exec: 'cartFlow', + }, + checkoutGuestSmoke: { + executor: 'per-vu-iterations', + vus: 1, + iterations: 3, + maxDuration: '120s', + startTime: '30s', + exec: 'checkoutGuestFlow', + }, + checkoutCustomerLoginSmoke: { + executor: 'per-vu-iterations', + vus: 1, + iterations: 3, + maxDuration: '120s', + startTime: '40s', + exec: 'checkoutCustomerLoginFlow', + }, + allMerchantSmoke: { + executor: 'per-vu-iterations', + vus: 1, + iterations: 3, + maxDuration: '360s', + exec: 'allMerchantFlow', + }, + }, + thresholds: { + checks: [ 'rate==1' ], + }, +}; + +export function homePageFlow() { + homePage(); +} +export function shopPageFlow() { + shopPage(); +} +export function searchProductFlow() { + searchProduct(); +} +export function singleProductFlow() { + singleProduct(); + categoryPage(); +} +export function checkoutGuestFlow() { + cart(); + checkoutGuest(); +} +export function checkoutCustomerLoginFlow() { + cart(); + checkoutCustomerLogin(); +} +export function myAccountFlow() { + myAccount(); +} +export function cartFlow() { + cartRemoveItem(); +} +export function allMerchantFlow() { + wpLogin(); + homeWCAdmin(); + orders(); + ordersSearch(); + products(); + addProduct(); +} From 74c72274a73c006d753b84804c37b8b56bea3d1a Mon Sep 17 00:00:00 2001 From: Tam Mullen Date: Thu, 17 Feb 2022 22:31:26 +0000 Subject: [PATCH 3/4] Add docker:wait to e2e env for waiting without running tests --- packages/js/e2e-environment/CHANGELOG.md | 1 + packages/js/e2e-environment/bin/wc-e2e.sh | 4 ++++ packages/js/e2e-environment/package.json | 1 + 3 files changed, 6 insertions(+) diff --git a/packages/js/e2e-environment/CHANGELOG.md b/packages/js/e2e-environment/CHANGELOG.md index 92147037877..039a7e6a5aa 100644 --- a/packages/js/e2e-environment/CHANGELOG.md +++ b/packages/js/e2e-environment/CHANGELOG.md @@ -15,6 +15,7 @@ - `WC_E2E_FOLDER` for mapping plugin root to path within repo - Added the `resolveSingleE2EPath()` method which builds a path to a specific E2E test - Added the ability to take screenshots from multiple test failures (when retried) in `utils/take-screenshot.js`. +- `docker:wait` to allow for waiting for env to be built without running tests ## Changed diff --git a/packages/js/e2e-environment/bin/wc-e2e.sh b/packages/js/e2e-environment/bin/wc-e2e.sh index b0a95270e76..1664c680b5a 100755 --- a/packages/js/e2e-environment/bin/wc-e2e.sh +++ b/packages/js/e2e-environment/bin/wc-e2e.sh @@ -9,6 +9,7 @@ usage() { echo 'scripts:' echo ' docker:up [initialization-script] - boot docker container' echo ' docker:down - shut down docker container' + echo ' docker:wait - wait for env to be built' echo ' docker:ssh - open SSH shell into docker container' echo ' docker:clear-all - remove all docker containers' echo ' test:e2e [test-script] - run e2e test suite or specific test-script' @@ -50,6 +51,9 @@ case $1 in 'docker:up') ./bin/docker-compose.sh up $2 ;; + 'docker:wait') + ./bin/wait-for-build.sh + ;; 'docker:down') ./bin/docker-compose.sh down ;; diff --git a/packages/js/e2e-environment/package.json b/packages/js/e2e-environment/package.json index 94d87eefc44..1db99034d85 100644 --- a/packages/js/e2e-environment/package.json +++ b/packages/js/e2e-environment/package.json @@ -66,6 +66,7 @@ "build": "pnpm run clean && pnpm run compile", "prepare": "pnpm run build", "docker:up": "./bin/docker-compose.sh up", + "docker:wait": "bash ./bin/wait-for-build.sh", "docker:down": "./bin/docker-compose.sh down", "docker:clear-all": "docker rmi --force $(docker images -q)", "docker:ssh": "docker exec -it $(node utils/get-app-name.js)_wordpress-www /bin/bash", From 579d491ca22a9b0bef731f1ed9c5736367180cfb Mon Sep 17 00:00:00 2001 From: Tam Mullen Date: Thu, 17 Feb 2022 22:34:09 +0000 Subject: [PATCH 4/4] Update orders and product k6 tests to be more robust --- .../tests/performance/requests/merchant/orders.js | 4 ++-- .../tests/performance/requests/shopper/single-product.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/woocommerce/tests/performance/requests/merchant/orders.js b/plugins/woocommerce/tests/performance/requests/merchant/orders.js index 697e0ea642d..bda0d3674cc 100644 --- a/plugins/woocommerce/tests/performance/requests/merchant/orders.js +++ b/plugins/woocommerce/tests/performance/requests/merchant/orders.js @@ -55,8 +55,8 @@ export function orders() { ); api_x_wp_nonce = findBetween( response.body, - 'wp-json\\/","nonce":"', - '",' + 'wp.apiFetch.createNonceMiddleware( "', + '" )' ); // Create request header with nonce value for use in subsequent requests. diff --git a/plugins/woocommerce/tests/performance/requests/shopper/single-product.js b/plugins/woocommerce/tests/performance/requests/shopper/single-product.js index 7dd2f13d0f0..9f310852f0f 100644 --- a/plugins/woocommerce/tests/performance/requests/shopper/single-product.js +++ b/plugins/woocommerce/tests/performance/requests/shopper/single-product.js @@ -5,7 +5,7 @@ import { randomIntBetween } from "https://jslib.k6.io/k6-utils/1.1.0/index.js"; import { base_url, product_url, - product_id, + product_sku, think_time_min, think_time_max, } from "../../config.js"; @@ -36,8 +36,8 @@ export function singleProduct() { productPageTrend.add(response.timings.duration); check(response, { "is status 200": (r) => r.status === 200, - "body contains: product ID": (response) => - response.body.includes(`id="product-${product_id}`), + "body contains: product SKU": (response) => + response.body.includes(`class="sku">${product_sku}`), }); });