Merge branch 'master' into e2e-shopper-pay-order

This commit is contained in:
Veljko 2021-02-10 22:30:55 +01:00
commit 1023075b75
9 changed files with 137 additions and 102 deletions

View File

@ -1,5 +1,6 @@
/** @format */ /** @format */
const { useE2EEsLintConfig } = require( '@woocommerce/e2e-environment' );
const { useE2EEsLintConfig } = require( './tests/e2e/env/config/use-config' );
module.exports = useE2EEsLintConfig( { module.exports = useE2EEsLintConfig( {
root: true, root: true,

View File

@ -10,7 +10,7 @@ rm -rf "$BUILD_PATH"
mkdir -p "$DEST_PATH" mkdir -p "$DEST_PATH"
echo "Installing PHP and JS dependencies..." echo "Installing PHP and JS dependencies..."
npm install npm run install:no-e2e
composer install || exit "$?" composer install || exit "$?"
echo "Running JS Build..." echo "Running JS Build..."
npm run build:core || exit "$?" npm run build:core || exit "$?"

View File

@ -25,17 +25,19 @@ output 3 "Updating autoloader classmaps..."
composer dump-autoload composer dump-autoload
output 2 "Done" output 2 "Done"
# Convert textdomains if [ -z "$SKIP_UPDATE_TEXTDOMAINS" ]; then
output 3 "Updating package PHP textdomains..." # Convert textdomains
output 3 "Updating package PHP textdomains..."
# Replace text domains within packages with woocommerce # Replace text domains within packages with woocommerce
npm run packages:fix:textdomain npm run packages:fix:textdomain
output 2 "Done!" output 2 "Done!"
output 3 "Updating package JS textdomains..." output 3 "Updating package JS textdomains..."
find ./packages/woocommerce-blocks -iname '*.js' -exec sed -i.bak -e "s/'woo-gutenberg-products-block'/'woocommerce'/g" -e "s/\"woo-gutenberg-products-block\"/'woocommerce'/g" {} \; find ./packages/woocommerce-blocks -iname '*.js' -exec sed -i.bak -e "s/'woo-gutenberg-products-block'/'woocommerce'/g" -e "s/\"woo-gutenberg-products-block\"/'woocommerce'/g" {} \;
find ./packages/woocommerce-blocks -iname '*.js' -exec sed -i.bak -e "s/'woocommerce-admin'/'woocommerce'/g" -e "s/\"woocommerce-admin\"/'woocommerce'/g" {} \; find ./packages/woocommerce-blocks -iname '*.js' -exec sed -i.bak -e "s/'woocommerce-admin'/'woocommerce'/g" -e "s/\"woocommerce-admin\"/'woocommerce'/g" {} \;
find ./packages/woocommerce-admin -iname '*.js' -exec sed -i.bak -e "s/'woocommerce-admin'/'woocommerce'/g" -e "s/\"woocommerce-admin\"/'woocommerce'/g" {} \; find ./packages/woocommerce-admin -iname '*.js' -exec sed -i.bak -e "s/'woocommerce-admin'/'woocommerce'/g" -e "s/\"woocommerce-admin\"/'woocommerce'/g" {} \;
fi
# Cleanup backup files # Cleanup backup files
find ./packages -name "*.bak" -type f -delete find ./packages -name "*.bak" -type f -delete

View File

@ -9,5 +9,5 @@ runOnChange() {
fi fi
} }
runOnChange "package-lock.json" "npm install" runOnChange "package-lock.json" "npm run install:no-e2e"
runOnChange "composer.lock" "composer install" runOnChange "composer.lock" "SKIP_UPDATE_TEXTDOMAINS=true composer install"

View File

@ -13,13 +13,16 @@
"wp_org_slug": "woocommerce" "wp_org_slug": "woocommerce"
}, },
"scripts": { "scripts": {
"install": "lerna bootstrap --hoist", "install": " if [ -z \"$SKIP_LERNA_BOOTSTRAP\" ]; then npx lerna bootstrap --hoist; fi",
"check:subset-installed": "npm list --depth 1 install-subset > /dev/null 2>&1",
"install:subset-only": "npm install --no-package-lock --no-save install-subset",
"install:no-e2e": "npm run check:subset-installed --silent || npm run install:subset-only && SKIP_LERNA_BOOTSTRAP=true npx install-subset i no-e2e",
"build": "./bin/build-zip.sh", "build": "./bin/build-zip.sh",
"build:core": "grunt && npm run makepot", "build:core": "grunt && npm run makepot",
"build:dev": "npm run build:core && npm run build:packages", "build:dev": "npm run build:core && npm run build:packages",
"build-watch": "grunt watch", "build-watch": "grunt watch",
"build:packages": "lerna run build", "build:packages": "lerna run build",
"build:zip": "npm run build && composer install && npm run build:dev", "build:zip": "npm run build",
"build:assets": "grunt assets", "build:assets": "grunt assets",
"lint:js": "eslint assets/js --ext=js", "lint:js": "eslint assets/js --ext=js",
"docker:down": "npx wc-e2e docker:down", "docker:down": "npx wc-e2e docker:down",
@ -125,5 +128,16 @@
"> 0.1%", "> 0.1%",
"ie 8", "ie 8",
"ie 9" "ie 9"
] ],
"subsets": {
"no-e2e": {
"exclude": [
"@woocommerce/api",
"@woocommerce/e2e-core-tests",
"@woocommerce/e2e-environment",
"@woocommerce/e2e-utils",
"@wordpress/e2e-test-utils"
]
}
}
} }

View File

@ -55,7 +55,7 @@ This section explains how e2e tests are working behind the scenes. These are not
### Test Environment ### Test Environment
We recommend using Docker for running tests locally in order for the test environment to match the setup on Travis CI (where Docker is also used for running tests). [An official WordPress Docker image](https://github.com/docker-library/docs/blob/master/wordpress/README.md) is used to build the site. Once the site using the WP Docker image is built, the current WooCommerce dev branch is being copied to the `plugins` folder of that newly built test site. No WooCommerce Docker image is being built or needed. We recommend using Docker for running tests locally in order for the test environment to match the setup on Travis CI (where Docker is also used for running tests). [An official WordPress Docker image](https://github.com/docker-library/docs/blob/master/wordpress/README.md) is used to build the site. Once the site using the WP Docker image is built, the current WooCommerce dev branch is mapped into the `plugins` folder of that newly built test site.
### Test Variables ### Test Variables
@ -81,9 +81,9 @@ If you need to modify the port for your local test environment (eg. port is alre
### Jest test sequencer ### Jest test sequencer
[Jest](https://jestjs.io/) is being used to run e2e tests. By default, jest runs tests ordered by the time it takes to run the test (the test that takes longer to run will be run first, the test that takes less time to run will run last). Jest sequencer introduces tools that can be used to specify the order in which the tests are being run. In our case, they are being run in alphabetical order of the directories where tests are located. This way, tests in the new directory `activate-and-setup` will run first. [Jest](https://jestjs.io/) is being used to run e2e tests. Jest sequencer introduces tools that can be used to specify the order in which the tests are being run. In our case, they are being run in alphabetical order of the directories where tests are located. This way, tests in the new directory `activate-and-setup` will run first. By default, jest runs tests ordered by the time it takes to run the test (the test that takes longer to run will be run first, the test that takes less time to run will run last).
Setup Wizard e2e test (located in `activate-and-setup` directory) will run before all other tests. This will allow making sure that WooCommerce is activated on the site and for the setup wizard to be completed on a brand new install of WooCommerce. The Setup Wizard e2e test (located in `activate-and-setup` directory) will run first. This ensures that WooCommerce is active and the setup wizard has been completed. This is necessary because `docker:up` creates a brand new install of WordPress and WooCommerce.
### Chromium Download ### Chromium Download
@ -111,7 +111,7 @@ Puppeteer will still automatically download Chromium when needed.
- Run `npm run build:assets` - Run `npm run build:assets`
- Run `npm install jest --global` - Run `npm install jest --global` (this only needs to be done once)
- Run `npx wc-e2e docker:up` - it will build the test site using Docker. - Run `npx wc-e2e docker:up` - it will build the test site using Docker.
@ -139,7 +139,7 @@ Username: admin
PW: password PW: password
``` ```
- Run `npx wc-e2e docker:down` when you are done with running e2e tests or when making any changes to test suite. - Run `npx wc-e2e docker:down` when you are done with running e2e tests and before making any changes to test site configuration.
Note that running `npx wc-e2e docker:down` and then `npx wc-e2e docker:up` re-initializes the test container. Note that running `npx wc-e2e docker:down` and then `npx wc-e2e docker:up` re-initializes the test container.
@ -153,15 +153,15 @@ npx wc-e2e test:e2e
### How to run tests in non-headless mode ### How to run tests in non-headless mode
Tests are run headless by default. However, sometimes it's useful to observe the browser while running tests. To do so, you can run tests in a non-headless (dev) mode: Tests run in headless mode by default. However, sometimes it's useful to observe the browser while running or developing tests. To do so, you can run tests in a non-headless (dev) mode:
```bash ```bash
npx wc-e2e test:e2e-dev npx wc-e2e test:e2e-dev
``` ```
The dev mode also enables SlowMo mode. SlowMo slows down Puppeteers operations so we can better see what is happening in the browser. The dev mode also enables SlowMo mode. SlowMo slows down Puppeteers operations. This makes it easier to see what is happening in the browser.
By default, SlowMo mode is set to slow down running of tests by 50 milliseconds. If you'd like to override it and have the tests run faster or slower in the `-dev` mode, pass `PUPPETEER_SLOWMO` variable when running tests as shown below: By default, SlowMo mode adds a 50 millisecond delay between test steps. If you'd like to override the length of the delay and have the tests run faster or slower in the `-dev` mode, pass `PUPPETEER_SLOWMO` variable when running tests as shown below:
``` ```
PUPPETEER_SLOWMO=10 npx wc-e2e test:e2e-dev PUPPETEER_SLOWMO=10 npx wc-e2e test:e2e-dev
@ -176,13 +176,13 @@ For example:
### How to run tests in debug mode ### How to run tests in debug mode
Tests are run headless by default. While writing tests it may be useful to have the debugger loaded while running a test in non-headless mode. To run tests in debug mode: Tests run in headless mode by default. While writing tests it may be useful to have the debugger loaded while running a test in non-headless mode. To run tests in debug mode:
```bash ```bash
npx wc-e2e test:e2e-debug npx wc-e2e test:e2e-debug
``` ```
When all tests have been completed the debugger is left active. Control doesn't return to the command line until the debugger is closed. Otherwise, debug mode functions the same as non-headless mode. When all tests have been completed the debugger remains active. Control doesn't return to the command line until the debugger is closed. Otherwise, debug mode functions the same as non-headless mode.
### How to run an individual test ### How to run an individual test
@ -240,7 +240,7 @@ describe.skip( 'Store owner can go through store Setup Wizard', () => {}
### How to run tests using custom WordPress, PHP and MariaDB versions ### How to run tests using custom WordPress, PHP and MariaDB versions
The following variables can be used to specify the versions of WordPress, PHP and MariaDB that you'd like to use to built your test site with Docker: The following variables can be used to specify the versions of WordPress, PHP and MariaDB that you'd like to use to build your test site with Docker:
- `WP_VERSION` - `WP_VERSION`
- `TRAVIS_PHP_VERSION` - `TRAVIS_PHP_VERSION`
@ -249,7 +249,7 @@ The following variables can be used to specify the versions of WordPress, PHP an
The full command to build the site will look as follows: The full command to build the site will look as follows:
``` ```
TRAVIS_MARIADB_VERSION=10.5.3 TRAVIS_PHP_VERSION=7.4.5 WP_VERSION=5.4.1 npm run docker:up TRAVIS_MARIADB_VERSION=10.5.3 TRAVIS_PHP_VERSION=7.4.5 WP_VERSION=5.4.1 npx wc-e2e docker:up
``` ```
## Guide for writing e2e tests ## Guide for writing e2e tests
@ -262,16 +262,16 @@ We use the following tools to write e2e tests:
- [jest-puppeteer](https://github.com/smooth-code/jest-puppeteer) provides all required configuration to run tests using Puppeteer - [jest-puppeteer](https://github.com/smooth-code/jest-puppeteer) provides all required configuration to run tests using Puppeteer
- [expect-puppeteer](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer) assertion library for Puppeteer - [expect-puppeteer](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer) assertion library for Puppeteer
In the WooCommerce Core repository the tests are kept in `tests/e2e/core-tests/specs/` folder. However, if you are writing tests in your own project using WooCommerce Core e2e packages, the tests should be located in `tests/e2e/specs/` folder. In the WooCommerce Core repository the tests are in `tests/e2e/core-tests/specs/` folder. However, if you are writing tests in your own project using WooCommerce Core e2e packages, the tests should be located in `tests/e2e/specs/` folder.
The following packages are used to write tests: The following packages are used in write tests:
- `@automattic/puppeteer-utils` - utilities and configuration for running puppeteer against WordPress. See details in the [package's repository](https://github.com/Automattic/puppeteer-utils). - `@automattic/puppeteer-utils` - utilities and configuration for running puppeteer against WordPress. See details in the [package's repository](https://github.com/Automattic/puppeteer-utils).
- `@woocommerce/e2e-utils` - this package contains utilities to simplify writing e2e tests specific to WooCommmerce. See details in the [package's repository](https://github.com/woocommerce/woocommerce/tree/master/tests/e2e/utils). - `@woocommerce/e2e-utils` - this package contains utilities to simplify writing e2e tests specific to WooCommmerce. See details in the [package's repository](https://github.com/woocommerce/woocommerce/tree/master/tests/e2e/utils).
### Creating test structure ### Creating test structure
It is a good practice to start working on the test by identifying what needs to be tested on the higher and lower levels. For example, if you are writing a test to verify that merchant can create virtual product, the overview of the test will be as follows: It is a good practice to start working on the test by identifying what needs to be tested on the higher and lower levels. For example, if you are writing a test to verify that merchant can create a virtual product, the overview of the test will be as follows:
- Merchant can create virtual product - Merchant can create virtual product
- Merchant can log in - Merchant can log in
@ -305,23 +305,23 @@ describe( 'Merchant can create virtual product', () => {
} ); } );
``` ```
Next, you can start filling up each section with relevant functions (test building blocks). Note, that we have the `@woocommerce/e2e-utils` package where many reusable helper functions can be found for writing tests. For example, `flows.js` of `@woocommerce/e2e-utils` package contains `StoreOwnerFlow` object that has `login` method. As a result, in the test it can be used as `await StoreOwnerFlow.login();` so the first `it()` section of the test will become: Next, you can start filling up each section with relevant functions (test building blocks). Note, that we have the `@woocommerce/e2e-utils` package where many reusable helper functions can be found for writing tests. For example, `flows.js` of `@woocommerce/e2e-utils` package contains `merchant` object that has `login` method. As a result, in the test it can be used as `await merchant.login();` so the first `it()` section of the test will become:
``` ```
it( 'merchant can log in', async () => { it( 'merchant can log in', async () => {
await StoreOwnerFlow.login(); await merchant.login();
} ); } );
``` ```
Moving to the next section where we need to actually create a product. You will find that we have a reusable function such as `createSimpleProduct()` in the `components.js` of `@woocommerce/e2e-utils` package. However, note that this function should not be used for this test because the way simple product is being created in this function is by using WooCommerce REST API. Because this is not how the merchant would typically create a virtual product, we would need to test it by writing actual steps for creating a product in the test. Moving to the next section where we need to actually create a product. You will find that we have a reusable function such as `createSimpleProduct()` in the `components.js` of `@woocommerce/e2e-utils` package. However, note that this function should not be used for testing creating a product because the simple product is created using WooCommerce REST API. This is not how the merchant would typically create a virtual product, we would need to test it by writing actual steps for creating a product in the test.
`createSimpleProduct()` should be used in tests where you need to test something else than creating a simple product. In other words, this function exists in order to quickly fill the site with test data required for running tests. For example, if you want to write a test that will verify that shopper can place a product to the cart on the site, you can use `createSimpleProduct()` to create a product to test the cart. `createSimpleProduct()` should be used in tests where you need to test something else than creating a simple product. In other words, this function exists in order to quickly fill the site with test data required for running tests. For example, if you want to write a test that will verify that shopper can place a product to the cart on the site, you can use `createSimpleProduct()` to create a product to test the cart.
Because `createSimpleProduct()` can't be used in the case of our example test, we'd need to navigate to the page where the user would usually create a product. To do that, there is `openNewProduct()` function of the `StoreOwnerFlow` object that we already used above. As a result, that part of the test will look as follows: Because `createSimpleProduct()` can't be used in the case of our example test, we'd need to navigate to the page where the user would usually create a product. To do that, there is `openNewProduct()` function of the `merchant` object that we already used above. As a result, that part of the test will look as follows:
``` ```
it( 'merchant can create virtual product', async () => { it( 'merchant can create virtual product', async () => {
await StoreOwnerFlow.openNewProduct(); await merchant.openNewProduct();
} ); } );
``` ```
@ -335,7 +335,7 @@ await waitAndClick( page, '#selector' );
### Best practices ### Best practices
- It is best to keep the tests inside `describe()` block granular as it helps to debug the test if it fails. When the test is done running, you will see the result along with the breakdown of how each of the test sections performed. If one of the tests within `describe()` block fails, it will be shown as follows: - It is best to keep the tests inside `describe()` block granular as it helps to debug the test if it fails. When the test has finished, you will see the result along with the breakdown of how each of the test sections performed. If one of the tests within `describe()` block fails, it will be shown as follows:
``` ```
FAIL ../specs/front-end/front-end-my-account.test.js (9.219s) FAIL ../specs/front-end/front-end-my-account.test.js (9.219s)

View File

@ -59,7 +59,9 @@ The functions to access the core tests are:
### Shopper ### Shopper
- `runShopperTests` - Run all shopper tests - `runShopperTests` - Run all shopper tests
- `runCartApplyCouponsTest` - Shopper can use coupons on cart
- `runCartPageTest` - Shopper can view and update cart - `runCartPageTest` - Shopper can view and update cart
- `runCheckoutApplyCouponsTest` - Shopper can use coupons on checkout
- `runCheckoutPageTest` - Shopper can complete checkout - `runCheckoutPageTest` - Shopper can complete checkout
- `runMyAccountPageTest` - Shopper can access my account page - `runMyAccountPageTest` - Shopper can access my account page
- `runSingleProductPageTest` - Shopper can view single product page in many variations (simple, variable, grouped) - `runSingleProductPageTest` - Shopper can view single product page in many variations (simple, variable, grouped)

View File

@ -7,7 +7,8 @@ const {
merchant, merchant,
createCoupon, createCoupon,
createSimpleProduct, createSimpleProduct,
uiUnblocked uiUnblocked,
clearAndFillInput,
} = require( '@woocommerce/e2e-utils' ); } = require( '@woocommerce/e2e-utils' );
/** /**
@ -19,11 +20,34 @@ const {
beforeAll, beforeAll,
} = require( '@jest/globals' ); } = require( '@jest/globals' );
/**
* Apply a coupon code to the cart.
*
* @param couponCode string
* @returns {Promise<void>}
*/
const applyCouponToCart = async ( couponCode ) => {
await clearAndFillInput('#coupon_code', couponCode);
await expect(page).toClick('button', {text: 'Apply coupon'});
await uiUnblocked();
};
/**
* Remove one coupon from the cart.
*
* @returns {Promise<void>}
*/
const removeCouponFromCart = async () => {
await expect(page).toClick('.woocommerce-remove-coupon', {text: '[Remove]'});
await uiUnblocked();
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon has been removed.'});
}
const runCartApplyCouponsTest = () => { const runCartApplyCouponsTest = () => {
describe('Cart applying coupons', () => { describe('Cart applying coupons', () => {
let couponFixedCart; let couponFixedCart;
let couponPercentage; let couponPercentage;
let couponFixedProduct; let couponFixedProduct;
beforeAll(async () => { beforeAll(async () => {
await merchant.login(); await merchant.login();
await createSimpleProduct(); await createSimpleProduct();
@ -31,76 +55,68 @@ const runCartApplyCouponsTest = () => {
couponPercentage = await createCoupon('50', 'Percentage discount'); couponPercentage = await createCoupon('50', 'Percentage discount');
couponFixedProduct = await createCoupon('5', 'Fixed product discount'); couponFixedProduct = await createCoupon('5', 'Fixed product discount');
await merchant.logout(); await merchant.logout();
});
it('allows customer to apply coupons in the cart', async () => {
await shopper.goToShop(); await shopper.goToShop();
await shopper.addToCartFromShopPage('Simple product'); await shopper.addToCartFromShopPage('Simple product');
await shopper.goToCart();
await shopper.productIsInCart('Simple product');
// Apply Fixed cart discount coupon
await expect(page).toFill('#coupon_code', couponFixedCart);
await expect(page).toClick('button', {text: 'Apply coupon'});
await uiUnblocked(); await uiUnblocked();
await page.waitForSelector('.woocommerce-message', {text: 'Coupon code applied successfully.'}); await shopper.goToCart();
});
// Wait for page to expand total calculations to avoid flakyness it('allows customer to apply fixed cart coupon', async () => {
await page.waitForSelector('.order-total'); await applyCouponToCart( couponFixedCart );
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
// Verify discount applied and order total // Verify discount applied and order total
await page.waitForSelector('.cart-discount .amount', {text: '$5.00'}); await page.waitForSelector('.order-total');
await page.waitForSelector('.order-total .amount', {text: '$4.99'}); await expect(page).toMatchElement('.cart-discount .amount', {text: '$5.00'});
await expect(page).toMatchElement('.order-total .amount', {text: '$4.99'});
await removeCouponFromCart();
});
// Remove coupon it('allows customer to apply percentage coupon', async () => {
await expect(page).toClick('.woocommerce-remove-coupon', {text: '[Remove]'}); await applyCouponToCart( couponPercentage );
await uiUnblocked(); await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
await page.waitForSelector('.woocommerce-message', {text: 'Coupon has been removed.'});
// Apply Percentage discount coupon // Verify discount applied and order total
await expect(page).toFill('#coupon_code', couponPercentage); await page.waitForSelector('.order-total');
await expect(page).toClick('button', {text: 'Apply coupon'}); await expect(page).toMatchElement('.cart-discount .amount', {text: '$4.99'});
await uiUnblocked(); await expect(page).toMatchElement('.order-total .amount', {text: '$5.00'});
await page.waitForSelector('.woocommerce-message', {text: 'Coupon code applied successfully.'}); await removeCouponFromCart();
await page.waitForSelector('.cart-discount .amount', {text: '$4.99'}); });
await page.waitForSelector('.order-total .amount', {text: '$5.00'});
// Remove coupon it('allows customer to apply fixed product coupon', async () => {
await expect(page).toClick('.woocommerce-remove-coupon', {text: '[Remove]'}); await applyCouponToCart( couponFixedProduct );
await uiUnblocked(); await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
await page.waitForSelector('.woocommerce-message', {text: 'Coupon has been removed.'});
// Apply Fixed product discount coupon // Verify discount applied and order total
await expect(page).toFill('#coupon_code', couponFixedProduct); await page.waitForSelector('.order-total');
await expect(page).toClick('button', {text: 'Apply coupon'}); await expect(page).toMatchElement('.cart-discount .amount', {text: '$5.00'});
await uiUnblocked(); await expect(page).toMatchElement('.order-total .amount', {text: '$4.99'});
await page.waitForSelector('.woocommerce-message', {text: 'Coupon code applied successfully.'}); await removeCouponFromCart();
await page.waitForSelector('.cart-discount .amount', {text: '$5.00'}); });
await page.waitForSelector('.order-total .amount', {text: '$4.99'});
// Try to apply the same coupon it('prevents customer applying same coupon twice', async () => {
await expect(page).toFill('#coupon_code', couponFixedProduct); await applyCouponToCart( couponFixedCart );
await expect(page).toClick('button', {text: 'Apply coupon'}); await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
await uiUnblocked(); await applyCouponToCart( couponFixedCart );
await page.waitForSelector('.woocommerce-error', { text: 'Coupon code already applied!' }); // Verify only one discount applied
// This is a work around for Puppeteer inconsistently finding 'Coupon code already applied'
await expect(page).toMatchElement('.cart-discount .amount', {text: '$5.00'});
await expect(page).toMatchElement('.order-total .amount', {text: '$4.99'});
});
// Try to apply multiple coupons it('allows customer to apply multiple coupons', async () => {
await expect(page).toFill('#coupon_code', couponFixedCart); await applyCouponToCart( couponFixedProduct );
await expect(page).toClick('button', {text: 'Apply coupon'}); await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
await uiUnblocked();
await page.waitForSelector('.woocommerce-message', {text: 'Coupon code applied successfully.'});
await page.waitForSelector('.order-total .amount', {text: '$0.00'});
// Remove coupon // Verify discount applied and order total
await expect(page).toClick('.woocommerce-remove-coupon', {text: '[Remove]'}); await page.waitForSelector('.order-total');
await uiUnblocked(); await expect(page).toMatchElement('.order-total .amount', {text: '$0.00'});
await page.waitForSelector('.woocommerce-message', {text: 'Coupon has been removed.'}); });
await expect(page).toClick('.woocommerce-remove-coupon', {text: '[Remove]'});
await uiUnblocked();
await page.waitForSelector('.woocommerce-message', {text: 'Coupon has been removed.'});
// Verify the total amount after all coupons removal it('restores cart total when coupons are removed', async () => {
await page.waitForSelector('.order-total .amount', {text: '$9.99'}); await removeCouponFromCart();
await removeCouponFromCart();
await expect(page).toMatchElement('.order-total .amount', {text: '$9.99'});
}); });
}); });
}; };

View File

@ -79,8 +79,8 @@ You can override these in `/tests/e2e/config/default.json`.
The built in container defaults to mapping the root folder of the repository to a folder in the `plugins` folder. For example `woocommerce` is mapped to `/var/www/html/wp-content/plugins/woocommerce`. Use the `WC_E2E_FOLDER_MAPPING` environment variable to override this mapping. The built in container defaults to mapping the root folder of the repository to a folder in the `plugins` folder. For example `woocommerce` is mapped to `/var/www/html/wp-content/plugins/woocommerce`. Use the `WC_E2E_FOLDER_MAPPING` environment variable to override this mapping.
- Storefront Theme - ```WC_E2E_FOLDER_MAPPING=/var/www/html/wp-content/themes/storefront npm explore @woocommerce/e2e-environment -- npm run docker:up``` - Storefront Theme - ```WC_E2E_FOLDER_MAPPING=/var/www/html/wp-content/themes/storefront npx wc-e2e docker:up```
- Site Project - ```WC_E2E_FOLDER_MAPPING=/var/www/html/wp-content/plugins npm explore @woocommerce/e2e-environment -- npm run docker:up``` - Site Project - ```WC_E2E_FOLDER_MAPPING=/var/www/html/wp-content npx wc-e2e docker:up```
### Travis CI Supported Versions ### Travis CI Supported Versions
@ -106,11 +106,11 @@ version: ~> 1.0
script: script:
- npm install jest --global - npm install jest --global
- npm explore @woocommerce/e2e-environment -- npm run docker:up - npx wc-e2e docker:up
- npm explore @woocommerce/e2e-environment -- npm run test:e2e - npx wc-e2e test:e2e
.... ....
after_script: after_script:
- npm explore @woocommerce/e2e-environment -- npm run docker:down - npx wc-e2e docker:down
``` ```