fix merge conflicts
This commit is contained in:
commit
1dc627bddc
81
.travis.yml
81
.travis.yml
|
@ -1,24 +1,24 @@
|
||||||
version: ~> 1.0
|
version: ~> 1.0
|
||||||
|
|
||||||
|
# Specifies that Travis should create builds for master and release branches and also tags.
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
- /^\d+\.\d+(\.\d+)?(-\S*)?$/
|
||||||
|
- /^release\//
|
||||||
|
|
||||||
language: php
|
language: php
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
dist: xenial
|
dist: xenial
|
||||||
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- $HOME/.composer/cache
|
|
||||||
|
|
||||||
# Since Xenial services are not started by default, we need to instruct it below to start.
|
|
||||||
services:
|
|
||||||
- mysql
|
|
||||||
- docker
|
|
||||||
|
|
||||||
# Test main supported versions of PHP against latest WP.
|
# Test main supported versions of PHP against latest WP.
|
||||||
php:
|
php:
|
||||||
- 7.0
|
- "7.0"
|
||||||
- 7.1
|
- "7.1"
|
||||||
- 7.2
|
- "7.2"
|
||||||
- 7.3
|
- "7.3"
|
||||||
- 7.4
|
- "7.4"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- WP_VERSION=latest WP_MULTISITE=0
|
- WP_VERSION=latest WP_MULTISITE=0
|
||||||
|
@ -35,30 +35,48 @@ jobs:
|
||||||
- npm install
|
- npm install
|
||||||
- composer install --no-dev
|
- composer install --no-dev
|
||||||
script:
|
script:
|
||||||
- npm run build:assets
|
- travis_retry npm run build:assets
|
||||||
- npm run docker:up
|
- travis_retry npm run docker:up
|
||||||
- npm run test:e2e
|
- travis_retry npm run test:e2e
|
||||||
after_script:
|
after_script:
|
||||||
- npm run docker:down
|
- npm run docker:down
|
||||||
- name: "WP Nightly"
|
- name: "WP Nightly"
|
||||||
php: 7.4
|
php: "7.4"
|
||||||
env: WP_VERSION=nightly WP_MULTISITE=0
|
env: WP_VERSION=nightly WP_MULTISITE=0
|
||||||
- name: "WP Latest - 1"
|
- name: "WP Latest - 1"
|
||||||
php: 7.2
|
php: "7.2"
|
||||||
env: WP_VERSION=5.4 WP_MULTISITE=0
|
env: WP_VERSION=5.4 WP_MULTISITE=0
|
||||||
- name: "WP Latest - 2"
|
- name: "WP Latest - 2"
|
||||||
php: 7.2
|
php: "7.2"
|
||||||
env: WP_VERSION=5.3 WP_MULTISITE=0
|
env: WP_VERSION=5.3 WP_MULTISITE=0
|
||||||
- name: "Code Standards"
|
- name: "Code Standards"
|
||||||
php: 7.4
|
php: "7.4"
|
||||||
env: WP_VERSION=latest WP_MULTISITE=0 RUN_PHPCS=1
|
env: WP_VERSION=latest WP_MULTISITE=0 RUN_PHPCS=1
|
||||||
- name: "Code Coverage"
|
- name: "Code Coverage"
|
||||||
php: 7.4
|
php: "7.4"
|
||||||
env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1
|
env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- php: 7.4
|
- php: "7.4"
|
||||||
env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1
|
env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1
|
||||||
|
|
||||||
|
# Git clone depth
|
||||||
|
# By default Travis CI clones repositories to a depth of 50 commits. Using a depth of 1 makes this step a bit faster.
|
||||||
|
git:
|
||||||
|
depth: 1
|
||||||
|
|
||||||
|
# Since Xenial services are not started by default, we need to instruct it below to start.
|
||||||
|
services:
|
||||||
|
- mysql
|
||||||
|
- docker
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $HOME/.composer/cache
|
||||||
|
|
||||||
|
# Composer 2.0.7 introduced a change that broke the jetpack autoloader in PHP 7.0 - 7.3.
|
||||||
|
before_install:
|
||||||
|
- composer self-update 2.0.6
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- export PATH="$HOME/.composer/vendor/bin:$PATH"
|
- export PATH="$HOME/.composer/vendor/bin:$PATH"
|
||||||
- |
|
- |
|
||||||
|
@ -81,20 +99,3 @@ script:
|
||||||
|
|
||||||
after_script:
|
after_script:
|
||||||
- bash tests/bin/travis.sh after
|
- bash tests/bin/travis.sh after
|
||||||
|
|
||||||
# Specifies that Travis should create builds for master and release branches and also tags.
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
- /^\d+\.\d+(\.\d+)?(-\S*)?$/
|
|
||||||
- /^release\//
|
|
||||||
|
|
||||||
# Composer 2.0.7 introduced a change that broke the jetpack autoloader in PHP 7.0 - 7.3.
|
|
||||||
before_install:
|
|
||||||
- composer self-update 2.0.6
|
|
||||||
|
|
||||||
# Git clone depth
|
|
||||||
# By default Travis CI clones repositories to a depth of 50 commits. Using a depth of 1 makes this step a bit faster.
|
|
||||||
git:
|
|
||||||
depth: 1
|
|
||||||
|
|
||||||
|
|
|
@ -360,7 +360,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.addons-button-solid {
|
.addons-button-solid {
|
||||||
background-color:#674399;
|
background-color: #674399;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3169,6 +3169,13 @@ table.wc_input_table {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.wc_tax_rates {
|
||||||
|
|
||||||
|
td.country {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
table.wc_gateways,
|
table.wc_gateways,
|
||||||
table.wc_emails,
|
table.wc_emails,
|
||||||
table.wc_shipping {
|
table.wc_shipping {
|
||||||
|
|
|
@ -62,6 +62,7 @@ class WC_Report_Customer_List extends WP_List_Table {
|
||||||
|
|
||||||
delete_user_meta( $user_id, '_money_spent' );
|
delete_user_meta( $user_id, '_money_spent' );
|
||||||
delete_user_meta( $user_id, '_order_count' );
|
delete_user_meta( $user_id, '_order_count' );
|
||||||
|
delete_user_meta( $user_id, '_last_order' );
|
||||||
/* translators: User display name */
|
/* translators: User display name */
|
||||||
echo '<div class="updated"><p>' . sprintf( esc_html__( 'Refreshed stats for %s', 'woocommerce' ), esc_html( $user->display_name ) ) . '</p></div>';
|
echo '<div class="updated"><p>' . sprintf( esc_html__( 'Refreshed stats for %s', 'woocommerce' ), esc_html( $user->display_name ) ) . '</p></div>';
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,8 +406,9 @@ class WC_Post_Data {
|
||||||
$customer->save();
|
$customer->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete order count meta.
|
// Delete order count and last order meta.
|
||||||
delete_user_meta( $customer_id, '_order_count' );
|
delete_user_meta( $customer_id, '_order_count' );
|
||||||
|
delete_user_meta( $customer_id, '_last_order' );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up items.
|
// Clean up items.
|
||||||
|
|
|
@ -64,6 +64,7 @@ class WC_Customer_Data_Store extends WC_Data_Store_WP implements WC_Customer_Dat
|
||||||
'syntax_highlighting',
|
'syntax_highlighting',
|
||||||
'_order_count',
|
'_order_count',
|
||||||
'_money_spent',
|
'_money_spent',
|
||||||
|
'_last_order',
|
||||||
'_woocommerce_tracks_anon_id',
|
'_woocommerce_tracks_anon_id',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -325,21 +326,30 @@ class WC_Customer_Data_Store extends WC_Data_Store_WP implements WC_Customer_Dat
|
||||||
* @return WC_Order|false
|
* @return WC_Order|false
|
||||||
*/
|
*/
|
||||||
public function get_last_order( &$customer ) {
|
public function get_last_order( &$customer ) {
|
||||||
global $wpdb;
|
$last_order = apply_filters(
|
||||||
|
'woocommerce_customer_get_last_order',
|
||||||
$last_order = $wpdb->get_var(
|
get_user_meta( $customer->get_id(), '_last_order', true ),
|
||||||
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
|
$customer
|
||||||
"SELECT posts.ID
|
|
||||||
FROM $wpdb->posts AS posts
|
|
||||||
LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id
|
|
||||||
WHERE meta.meta_key = '_customer_user'
|
|
||||||
AND meta.meta_value = '" . esc_sql( $customer->get_id() ) . "'
|
|
||||||
AND posts.post_type = 'shop_order'
|
|
||||||
AND posts.post_status IN ( '" . implode( "','", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' )
|
|
||||||
ORDER BY posts.ID DESC"
|
|
||||||
// phpcs:enable
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ( '' === $last_order ) {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$last_order = $wpdb->get_var(
|
||||||
|
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
|
||||||
|
"SELECT posts.ID
|
||||||
|
FROM $wpdb->posts AS posts
|
||||||
|
LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id
|
||||||
|
WHERE meta.meta_key = '_customer_user'
|
||||||
|
AND meta.meta_value = '" . esc_sql( $customer->get_id() ) . "'
|
||||||
|
AND posts.post_type = 'shop_order'
|
||||||
|
AND posts.post_status IN ( '" . implode( "','", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' )
|
||||||
|
ORDER BY posts.ID DESC"
|
||||||
|
// phpcs:enable
|
||||||
|
);
|
||||||
|
update_user_meta( $customer->get_id(), '_last_order', $last_order );
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! $last_order ) {
|
if ( ! $last_order ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -355,7 +365,11 @@ class WC_Customer_Data_Store extends WC_Data_Store_WP implements WC_Customer_Dat
|
||||||
* @return integer
|
* @return integer
|
||||||
*/
|
*/
|
||||||
public function get_order_count( &$customer ) {
|
public function get_order_count( &$customer ) {
|
||||||
$count = get_user_meta( $customer->get_id(), '_order_count', true );
|
$count = apply_filters(
|
||||||
|
'woocommerce_customer_get_order_count',
|
||||||
|
get_user_meta( $customer->get_id(), '_order_count', true ),
|
||||||
|
$customer
|
||||||
|
);
|
||||||
|
|
||||||
if ( '' === $count ) {
|
if ( '' === $count ) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
|
@ -456,11 +456,12 @@ function wc_delete_shop_order_transients( $order = 0 ) {
|
||||||
delete_transient( $transient );
|
delete_transient( $transient );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear money spent for user associated with order.
|
// Clear customer's order related caches.
|
||||||
if ( is_a( $order, 'WC_Order' ) ) {
|
if ( is_a( $order, 'WC_Order' ) ) {
|
||||||
$order_id = $order->get_id();
|
$order_id = $order->get_id();
|
||||||
delete_user_meta( $order->get_customer_id(), '_money_spent' );
|
delete_user_meta( $order->get_customer_id(), '_money_spent' );
|
||||||
delete_user_meta( $order->get_customer_id(), '_order_count' );
|
delete_user_meta( $order->get_customer_id(), '_order_count' );
|
||||||
|
delete_user_meta( $order->get_customer_id(), '_last_order' );
|
||||||
} else {
|
} else {
|
||||||
$order_id = 0;
|
$order_id = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -701,6 +701,7 @@ function wc_update_230_options() {
|
||||||
// _money_spent and _order_count may be out of sync - clear them
|
// _money_spent and _order_count may be out of sync - clear them
|
||||||
delete_metadata( 'user', 0, '_money_spent', '', true );
|
delete_metadata( 'user', 0, '_money_spent', '', true );
|
||||||
delete_metadata( 'user', 0, '_order_count', '', true );
|
delete_metadata( 'user', 0, '_order_count', '', true );
|
||||||
|
delete_metadata( 'user', 0, '_last_order', '', true );
|
||||||
|
|
||||||
// To prevent taxes being hidden when using a default 'no address' in a store with tax inc prices, set the woocommerce_default_customer_address to use the store base address by default.
|
// To prevent taxes being hidden when using a default 'no address' in a store with tax inc prices, set the woocommerce_default_customer_address to use the store base address by default.
|
||||||
if ( '' === get_option( 'woocommerce_default_customer_address', false ) && wc_prices_include_tax() ) {
|
if ( '' === get_option( 'woocommerce_default_customer_address', false ) && wc_prices_include_tax() ) {
|
||||||
|
|
|
@ -272,6 +272,7 @@ function wc_update_new_customer_past_orders( $customer_id ) {
|
||||||
update_user_meta( $customer_id, 'paying_customer', 1 );
|
update_user_meta( $customer_id, 'paying_customer', 1 );
|
||||||
update_user_meta( $customer_id, '_order_count', '' );
|
update_user_meta( $customer_id, '_order_count', '' );
|
||||||
update_user_meta( $customer_id, '_money_spent', '' );
|
update_user_meta( $customer_id, '_money_spent', '' );
|
||||||
|
delete_user_meta( $customer_id, '_last_order' );
|
||||||
}
|
}
|
||||||
|
|
||||||
return $linked;
|
return $linked;
|
||||||
|
@ -897,7 +898,7 @@ function wc_update_user_last_active( $user_id ) {
|
||||||
if ( ! $user_id ) {
|
if ( ! $user_id ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
update_user_meta( $user_id, 'wc_last_active', (string) strtotime( date( 'Y-m-d', time() ) ) );
|
update_user_meta( $user_id, 'wc_last_active', (string) strtotime( gmdate( 'Y-m-d', time() ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
- View Single Order test
|
- View Single Order test
|
||||||
- Update Order Status test
|
- Update Order Status test
|
||||||
- Update Order Details test
|
- Update Order Details test
|
||||||
|
- Merchant Order Status Filter tests
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ The functions to access the core tests are:
|
||||||
- `runUpdateGeneralSettingsTest` - Merchant can update general settings
|
- `runUpdateGeneralSettingsTest` - Merchant can update general settings
|
||||||
- `runProductSettingsTest` - Merchant can update product settings
|
- `runProductSettingsTest` - Merchant can update product settings
|
||||||
- `runTaxSettingsTest` - Merchant can update tax settings
|
- `runTaxSettingsTest` - Merchant can update tax settings
|
||||||
|
- `runOrderStatusFilterTest` - Merchant can filter orders by order status
|
||||||
|
|
||||||
### Shopper
|
### Shopper
|
||||||
|
|
||||||
|
|
|
@ -2,19 +2,26 @@
|
||||||
/*
|
/*
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Setup and onboarding tests
|
||||||
const runActivationTest = require( './activate-and-setup/activate.test' );
|
const runActivationTest = require( './activate-and-setup/activate.test' );
|
||||||
const { runOnboardingFlowTest, runTaskListTest } = require( './activate-and-setup/onboarding-tasklist.test' );
|
const { runOnboardingFlowTest, runTaskListTest } = require( './activate-and-setup/onboarding-tasklist.test' );
|
||||||
const runInitialStoreSettingsTest = require( './activate-and-setup/setup.test' );
|
const runInitialStoreSettingsTest = require( './activate-and-setup/setup.test' );
|
||||||
|
|
||||||
|
// Shopper tests
|
||||||
const runCartPageTest = require( './shopper/front-end-cart.test' );
|
const runCartPageTest = require( './shopper/front-end-cart.test' );
|
||||||
const runCheckoutPageTest = require( './shopper/front-end-checkout.test' );
|
const runCheckoutPageTest = require( './shopper/front-end-checkout.test' );
|
||||||
const runMyAccountPageTest = require( './shopper/front-end-my-account.test' );
|
const runMyAccountPageTest = require( './shopper/front-end-my-account.test' );
|
||||||
const runSingleProductPageTest = require( './shopper/front-end-single-product.test' );
|
const runSingleProductPageTest = require( './shopper/front-end-single-product.test' );
|
||||||
|
|
||||||
|
// Merchant tests
|
||||||
const runCreateCouponTest = require( './merchant/wp-admin-coupon-new.test' );
|
const runCreateCouponTest = require( './merchant/wp-admin-coupon-new.test' );
|
||||||
const runCreateOrderTest = require( './merchant/wp-admin-order-new.test' );
|
const runCreateOrderTest = require( './merchant/wp-admin-order-new.test' );
|
||||||
const { runAddSimpleProductTest, runAddVariableProductTest } = require( './merchant/wp-admin-product-new.test' );
|
const { runAddSimpleProductTest, runAddVariableProductTest } = require( './merchant/wp-admin-product-new.test' );
|
||||||
const runUpdateGeneralSettingsTest = require( './merchant/wp-admin-settings-general.test' );
|
const runUpdateGeneralSettingsTest = require( './merchant/wp-admin-settings-general.test' );
|
||||||
const runProductSettingsTest = require( './merchant/wp-admin-settings-product.test' );
|
const runProductSettingsTest = require( './merchant/wp-admin-settings-product.test' );
|
||||||
const runTaxSettingsTest = require( './merchant/wp-admin-settings-tax.test' );
|
const runTaxSettingsTest = require( './merchant/wp-admin-settings-tax.test' );
|
||||||
|
const runOrderStatusFiltersTest = require( './merchant/wp-admin-order-status-filters.test' );
|
||||||
|
|
||||||
const runSetupOnboardingTests = () => {
|
const runSetupOnboardingTests = () => {
|
||||||
runActivationTest();
|
runActivationTest();
|
||||||
|
@ -38,6 +45,7 @@ const runMerchantTests = () => {
|
||||||
runUpdateGeneralSettingsTest();
|
runUpdateGeneralSettingsTest();
|
||||||
runProductSettingsTest();
|
runProductSettingsTest();
|
||||||
runTaxSettingsTest();
|
runTaxSettingsTest();
|
||||||
|
runOrderStatusFiltersTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -58,5 +66,6 @@ module.exports = {
|
||||||
runUpdateGeneralSettingsTest,
|
runUpdateGeneralSettingsTest,
|
||||||
runProductSettingsTest,
|
runProductSettingsTest,
|
||||||
runTaxSettingsTest,
|
runTaxSettingsTest,
|
||||||
|
runOrderStatusFiltersTest,
|
||||||
runMerchantTests,
|
runMerchantTests,
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
/* eslint-disable jest/no-export, jest/no-disabled-tests */
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
const {
|
||||||
|
StoreOwnerFlow,
|
||||||
|
createSimpleOrder,
|
||||||
|
clickFilter,
|
||||||
|
moveAllItemsToTrash,
|
||||||
|
} = require( '@woocommerce/e2e-utils' );
|
||||||
|
|
||||||
|
const statusColumnTextSelector = 'mark.order-status > span';
|
||||||
|
|
||||||
|
// Define order statuses to filter against
|
||||||
|
const orderStatus = {
|
||||||
|
pending: {
|
||||||
|
name: 'wc-pending',
|
||||||
|
description: { text: 'Pending payment' },
|
||||||
|
},
|
||||||
|
processing: {
|
||||||
|
name: 'wc-processing',
|
||||||
|
description: { text: 'Processing' },
|
||||||
|
},
|
||||||
|
onHold: {
|
||||||
|
name: 'wc-on-hold',
|
||||||
|
description: { text: 'On hold' },
|
||||||
|
},
|
||||||
|
completed: {
|
||||||
|
name: 'wc-completed',
|
||||||
|
description: { text: 'Completed' },
|
||||||
|
},
|
||||||
|
cancelled: {
|
||||||
|
name: 'wc-cancelled',
|
||||||
|
description: { text: 'Cancelled' },
|
||||||
|
},
|
||||||
|
refunded: {
|
||||||
|
name: 'wc-refunded',
|
||||||
|
description: { text: 'Refunded' },
|
||||||
|
},
|
||||||
|
failed: {
|
||||||
|
name: 'wc-failed',
|
||||||
|
description: { text: 'Failed' },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const runOrderStatusFiltersTest = () => {
|
||||||
|
describe('WooCommerce Orders > Filter Orders by Status', () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
// First, let's login
|
||||||
|
await StoreOwnerFlow.login();
|
||||||
|
|
||||||
|
// Next, let's create some orders we can filter against
|
||||||
|
await createSimpleOrder(orderStatus.pending.description.text);
|
||||||
|
await createSimpleOrder(orderStatus.processing.description.text);
|
||||||
|
await createSimpleOrder(orderStatus.onHold.description.text);
|
||||||
|
await createSimpleOrder(orderStatus.completed.description.text);
|
||||||
|
await createSimpleOrder(orderStatus.cancelled.description.text);
|
||||||
|
await createSimpleOrder(orderStatus.refunded.description.text);
|
||||||
|
await createSimpleOrder(orderStatus.failed.description.text);
|
||||||
|
}, 40000);
|
||||||
|
|
||||||
|
afterAll( async () => {
|
||||||
|
// Make sure we're on the all orders view and cleanup the orders we created
|
||||||
|
await StoreOwnerFlow.openAllOrdersView();
|
||||||
|
await moveAllItemsToTrash();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by Pending payment', async () => {
|
||||||
|
await StoreOwnerFlow.openAllOrdersView();
|
||||||
|
await clickFilter('.' + orderStatus.pending.name);
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.pending.description);
|
||||||
|
|
||||||
|
// Verify other statuses don't show
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.processing.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.completed.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.cancelled.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.refunded.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.onHold.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.failed.description);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by Processing', async () => {
|
||||||
|
await StoreOwnerFlow.openAllOrdersView();
|
||||||
|
await clickFilter('.' + orderStatus.processing.name);
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.processing.description);
|
||||||
|
|
||||||
|
// Verify other statuses don't show
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.pending.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.completed.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.cancelled.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.refunded.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.onHold.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.failed.description);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by On hold', async () => {
|
||||||
|
await StoreOwnerFlow.openAllOrdersView();
|
||||||
|
await clickFilter('.' + orderStatus.onHold.name);
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.onHold.description);
|
||||||
|
|
||||||
|
// Verify other statuses don't show
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.pending.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.processing.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.completed.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.cancelled.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.refunded.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.failed.description);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by Completed', async () => {
|
||||||
|
await StoreOwnerFlow.openAllOrdersView();
|
||||||
|
await clickFilter('.' + orderStatus.completed.name);
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.completed.description);
|
||||||
|
|
||||||
|
// Verify other statuses don't show
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.pending.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.processing.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.cancelled.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.refunded.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.onHold.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.failed.description);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by Cancelled', async () => {
|
||||||
|
await StoreOwnerFlow.openAllOrdersView();
|
||||||
|
await clickFilter('.' + orderStatus.cancelled.name);
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.cancelled.description);
|
||||||
|
|
||||||
|
// Verify other statuses don't show
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.pending.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.processing.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.completed.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.refunded.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.onHold.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.failed.description);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by Refunded', async () => {
|
||||||
|
await StoreOwnerFlow.openAllOrdersView();
|
||||||
|
await clickFilter('.' + orderStatus.refunded.name);
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.refunded.description);
|
||||||
|
|
||||||
|
// Verify other statuses don't show
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.pending.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.processing.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.completed.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.cancelled.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.onHold.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.failed.description);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by Failed', async () => {
|
||||||
|
await StoreOwnerFlow.openAllOrdersView();
|
||||||
|
await clickFilter('.' + orderStatus.failed.name);
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.failed.description);
|
||||||
|
|
||||||
|
// Verify other statuses don't show
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.pending.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.processing.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.completed.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.cancelled.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.refunded.description);
|
||||||
|
await expect(page).not.toMatchElement(statusColumnTextSelector, orderStatus.onHold.description);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by All', async () => {
|
||||||
|
await StoreOwnerFlow.openAllOrdersView();
|
||||||
|
// Make sure all the order statuses that were created show in this list
|
||||||
|
await clickFilter('.all');
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.pending.description);
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.processing.description);
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.completed.description);
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.cancelled.description);
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.refunded.description);
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.onHold.description);
|
||||||
|
await expect(page).toMatchElement(statusColumnTextSelector, orderStatus.failed.description);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = runOrderStatusFiltersTest;
|
|
@ -1,5 +1,9 @@
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Insert a 12 hour delay in using new docker image tags
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
- Remove redundant `puppeteer` dependency
|
- Remove redundant `puppeteer` dependency
|
||||||
|
|
|
@ -36,12 +36,22 @@ async function fetchLatestTagFromPage( image, nameSearch, page ) {
|
||||||
if ( ! data.count ) {
|
if ( ! data.count ) {
|
||||||
reject( "No image '" + image + '" found' );
|
reject( "No image '" + image + '" found' );
|
||||||
} else {
|
} else {
|
||||||
|
// Implement a 12 hour delay on pulling newly released docker tags.
|
||||||
|
const delayMilliseconds = 12 * 3600 * 1000;
|
||||||
|
const currentTime = Date.now();
|
||||||
let latestTag = null;
|
let latestTag = null;
|
||||||
|
let lastUpdated = null;
|
||||||
for ( let tag of data.results ) {
|
for ( let tag of data.results ) {
|
||||||
tag.semver = tag.name.match( /^\d+\.\d+(.\d+)*$/ );
|
tag.semver = tag.name.match( /^\d+\.\d+(.\d+)*$/ );
|
||||||
if ( ! tag.semver ) {
|
if ( ! tag.semver ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastUpdated = Date.parse( tag.last_updated );
|
||||||
|
if ( currentTime - lastUpdated < delayMilliseconds ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
tag.semver = semver.coerce( tag.semver[0] );
|
tag.semver = semver.coerce( tag.semver[0] );
|
||||||
if ( ! latestTag || semver.gt( tag.semver, latestTag.semver ) ) {
|
if ( ! latestTag || semver.gt( tag.semver, latestTag.semver ) ) {
|
||||||
latestTag = tag;
|
latestTag = tag;
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
const { runOrderStatusFiltersTest } = require( '@woocommerce/e2e-core-tests' );
|
||||||
|
|
||||||
|
runOrderStatusFiltersTest();
|
|
@ -1,15 +1,18 @@
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
## Added
|
|
||||||
|
|
||||||
- `openOrder` for opening existing orders
|
|
||||||
- `getValueOfInputField` to get value of input field
|
|
||||||
- split `verifyPublishAndTrash` into separate functions.
|
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
- Missing `config` package dependency
|
- Missing `config` package dependency
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- `clickFilter()` util helper method that clicks on a list page filter
|
||||||
|
- `moveAllItemsToTrash()` util helper method that checks every item in a list page and moves them to the trash
|
||||||
|
- `createSimpleOrder( status )` component which accepts an order status string and creates a basic order with that status
|
||||||
|
- `openOrder` for opening existing orders
|
||||||
|
- `getValueOfInputField` to get value of input field
|
||||||
|
- split `verifyPublishAndTrash` into separate functions.
|
||||||
|
|
||||||
# 0.1.1
|
# 0.1.1
|
||||||
|
|
||||||
- Initial/beta release
|
- Initial/beta release
|
||||||
|
|
|
@ -91,6 +91,8 @@ describe( 'Cart page', () => {
|
||||||
| `verifyCheckboxIsSet` | `selector` | Verify that a checkbox is checked |
|
| `verifyCheckboxIsSet` | `selector` | Verify that a checkbox is checked |
|
||||||
| `verifyCheckboxIsUnset` | `selector` | Verify that a checkbox is unchecked |
|
| `verifyCheckboxIsUnset` | `selector` | Verify that a checkbox is unchecked |
|
||||||
| `verifyValueOfInputField` | `selector, value` | Verify an input contains the passed value |
|
| `verifyValueOfInputField` | `selector, value` | Verify an input contains the passed value |
|
||||||
|
| `clickFilter` | `selector` | Click on a list page filter |
|
||||||
|
| `moveAllItemsToTrash` | | Moves all items in a list view to the Trash |
|
||||||
|----------|------------|-------------|
|
|----------|------------|-------------|
|
||||||
|
|
||||||
### Test Utilities
|
### Test Utilities
|
||||||
|
|
|
@ -220,7 +220,7 @@ const createVariableProduct = async () => {
|
||||||
// Go to "add product" page
|
// Go to "add product" page
|
||||||
await StoreOwnerFlow.openNewProduct();
|
await StoreOwnerFlow.openNewProduct();
|
||||||
|
|
||||||
// Make sure we're on the add order page
|
// Make sure we're on the add product page
|
||||||
await expect( page.title() ).resolves.toMatch( 'Add new product' );
|
await expect( page.title() ).resolves.toMatch( 'Add new product' );
|
||||||
|
|
||||||
// Set product data
|
// Set product data
|
||||||
|
@ -344,9 +344,36 @@ const createVariableProduct = async () => {
|
||||||
return variablePostIdValue;
|
return variablePostIdValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a basic order with the provided order status.
|
||||||
|
*
|
||||||
|
* @param orderStatus Status of the new order. Defaults to `Pending payment`.
|
||||||
|
*/
|
||||||
|
const createSimpleOrder = async ( orderStatus = 'Pending payment' ) => {
|
||||||
|
// Go to 'Add new order' page
|
||||||
|
await StoreOwnerFlow.openNewOrder();
|
||||||
|
|
||||||
|
// Make sure we're on the add order page
|
||||||
|
await expect( page.title() ).resolves.toMatch( 'Add new order' );
|
||||||
|
|
||||||
|
// Set order status
|
||||||
|
await expect( page ).toSelect( '#order_status', orderStatus );
|
||||||
|
|
||||||
|
// Wait for auto save
|
||||||
|
await page.waitFor( 2000 );
|
||||||
|
|
||||||
|
// Create the order
|
||||||
|
await expect( page ).toClick( 'button.save_order' );
|
||||||
|
await page.waitForSelector( '#message' );
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
await expect( page ).toMatchElement( '#message', { text: 'Order updated.' } );
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
completeOnboardingWizard,
|
completeOnboardingWizard,
|
||||||
createSimpleProduct,
|
createSimpleProduct,
|
||||||
createVariableProduct,
|
createVariableProduct,
|
||||||
|
createSimpleOrder,
|
||||||
verifyAndPublish,
|
verifyAndPublish,
|
||||||
};
|
};
|
||||||
|
|
|
@ -182,6 +182,34 @@ const verifyValueOfInputField = async( selector, value ) => {
|
||||||
await expect( fieldValue ).toBe( value );
|
await expect( fieldValue ).toBe( value );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clicks on a filter on a list page, such as WooCommerce > Orders or Posts > All Posts.
|
||||||
|
*
|
||||||
|
* @param {string} selector Selector of the filter link to be clicked.
|
||||||
|
*/
|
||||||
|
const clickFilter = async( selector ) => {
|
||||||
|
await page.waitForSelector( selector );
|
||||||
|
await page.focus( selector );
|
||||||
|
await Promise.all( [
|
||||||
|
page.click( `.subsubsub > ${selector} > a` ),
|
||||||
|
page.waitForNavigation( { waitUntil: 'networkidle0' } ),
|
||||||
|
] );
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves all items in a list view to the trash.
|
||||||
|
*
|
||||||
|
* If there's more than 20 items, it moves all 20 items on the current page.
|
||||||
|
*/
|
||||||
|
const moveAllItemsToTrash = async() => {
|
||||||
|
await setCheckbox( '#cb-select-all-1' );
|
||||||
|
await expect( page ).toSelect( '#bulk-action-selector-top', 'Move to Trash' );
|
||||||
|
await Promise.all( [
|
||||||
|
page.click( '#doaction' ),
|
||||||
|
page.waitForNavigation( { waitUntil: 'networkidle0' } ),
|
||||||
|
] );
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
clearAndFillInput,
|
clearAndFillInput,
|
||||||
clickTab,
|
clickTab,
|
||||||
|
@ -197,4 +225,6 @@ export {
|
||||||
verifyCheckboxIsSet,
|
verifyCheckboxIsSet,
|
||||||
verifyCheckboxIsUnset,
|
verifyCheckboxIsUnset,
|
||||||
verifyValueOfInputField,
|
verifyValueOfInputField,
|
||||||
|
clickFilter,
|
||||||
|
moveAllItemsToTrash,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue