Merge branch 'trunk' into standardize-config-files
This commit is contained in:
commit
f7c93a6823
|
@ -4,6 +4,7 @@
|
|||
|
||||
- A `specs/data` folder to store page element data.
|
||||
- Tests to verify that different top-level menu and their associated sub-menus load successfully.
|
||||
- Test scaffolding via `npx wc-e2e install @woocommerce/e2e-core-tests`
|
||||
|
||||
## Changed
|
||||
|
||||
|
|
|
@ -20,6 +20,18 @@ Follow [E2E setup instructions](https://github.com/woocommerce/woocommerce/blob/
|
|||
|
||||
### Setting up core tests
|
||||
|
||||
#### Version 0.2.0 or newer
|
||||
|
||||
Version 0.2.0 added a test installer that will populate the `tests/e2e/specs` folder with test scripts for all the current core test suite. It also creates sample configuration files including all the configuration data needed to run the core tests.
|
||||
|
||||
- Install the e2e-environment `npm install @woocommerce/e2e-environment --save-dev`
|
||||
- Run the installer `npx wc-e2e install @woocommerce/e2e-core-tests`
|
||||
- Merge the sample configuration files:
|
||||
- `tests/e2e/docker/woocommerce.e2e-core-tests.sh` => `initialize.sh`
|
||||
- `tests/e2e/config/default-woocommerce.e2e-core-tests.json` => `default.json`
|
||||
|
||||
#### Version 0.1.X or other test runner
|
||||
|
||||
- Create the folder `tests/e2e/specs` in your repository if it does not exist.
|
||||
- To add a core test to your test suite, create a new `.test.js` file within `tests/e2e/specs` . Example code to run all the shopper tests:
|
||||
```js
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
{
|
||||
"url": "http://localhost:8084/",
|
||||
"users": {
|
||||
"admin": {
|
||||
"username": "admin",
|
||||
"password": "password"
|
||||
},
|
||||
"customer": {
|
||||
"username": "customer",
|
||||
"password": "password"
|
||||
}
|
||||
},
|
||||
"products": {
|
||||
"simple": {
|
||||
"name": "Simple product"
|
||||
},
|
||||
"variable": {
|
||||
"name": "Variable Product with Three Attributes",
|
||||
"defaultAttributes": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "Size",
|
||||
"option": "Medium"
|
||||
},
|
||||
{
|
||||
"id": 0,
|
||||
"name": "Colour",
|
||||
"option": "Blue"
|
||||
}
|
||||
],
|
||||
"attributes": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "Colour",
|
||||
"isVisibleOnProductPage": true,
|
||||
"isForVariations": true,
|
||||
"options": [
|
||||
"Red",
|
||||
"Green",
|
||||
"Blue"
|
||||
],
|
||||
"sortOrder": 0
|
||||
},
|
||||
{
|
||||
"id": 0,
|
||||
"name": "Size",
|
||||
"isVisibleOnProductPage": true,
|
||||
"isForVariations": true,
|
||||
"options": [
|
||||
"Small",
|
||||
"Medium",
|
||||
"Large"
|
||||
],
|
||||
"sortOrder": 0
|
||||
},
|
||||
{
|
||||
"id": 0,
|
||||
"name": "Logo",
|
||||
"isVisibleOnProductPage": true,
|
||||
"isForVariations": true,
|
||||
"options": [
|
||||
"Woo",
|
||||
"WordPress"
|
||||
],
|
||||
"sortOrder": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"variations": [
|
||||
{
|
||||
"regularPrice": "19.99",
|
||||
"attributes": [
|
||||
{
|
||||
"name": "Size",
|
||||
"option": "Large"
|
||||
},
|
||||
{
|
||||
"name": "Colour",
|
||||
"option": "Red"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"regularPrice": "18.99",
|
||||
"attributes": [
|
||||
{
|
||||
"name": "Size",
|
||||
"option": "Medium"
|
||||
},
|
||||
{
|
||||
"name": "Colour",
|
||||
"option": "Green"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"regularPrice": "17.99",
|
||||
"attributes": [
|
||||
{
|
||||
"name": "Size",
|
||||
"option": "Small"
|
||||
},
|
||||
{
|
||||
"name": "Colour",
|
||||
"option": "Blue"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"grouped": {
|
||||
"name": "Grouped Product with Three Children",
|
||||
"groupedProducts": [
|
||||
{
|
||||
"name": "Base Unit",
|
||||
"regularPrice": "29.99"
|
||||
},
|
||||
{
|
||||
"name": "Add-on A",
|
||||
"regularPrice": "11.95"
|
||||
},
|
||||
{
|
||||
"name": "Add-on B",
|
||||
"regularPrice": "18.97"
|
||||
}
|
||||
]
|
||||
},
|
||||
"external": {
|
||||
"name": "External product",
|
||||
"regularPrice": "24.99",
|
||||
"buttonText": "Buy now",
|
||||
"externalUrl": "https://wordpress.org/plugins/woocommerce"
|
||||
}
|
||||
},
|
||||
"coupons": {
|
||||
"percentage": {
|
||||
"code": "20percent",
|
||||
"discountType": "percent",
|
||||
"amount": "20.00"
|
||||
}
|
||||
},
|
||||
"addresses": {
|
||||
"admin": {
|
||||
"store": {
|
||||
"email": "admin@woocommercecoree2etestsuite.com",
|
||||
"firstname": "John",
|
||||
"lastname": "Doe",
|
||||
"company": "Automattic",
|
||||
"country": "United States (US)",
|
||||
"addressfirstline": "addr 1",
|
||||
"addresssecondline": "addr 2",
|
||||
"countryandstate": "United States (US) — California",
|
||||
"city": "San Francisco",
|
||||
"state": "CA",
|
||||
"postcode": "94107"
|
||||
}
|
||||
},
|
||||
"customer": {
|
||||
"billing": {
|
||||
"firstname": "John",
|
||||
"lastname": "Doe",
|
||||
"company": "Automattic",
|
||||
"country": "United States (US)",
|
||||
"addressfirstline": "addr 1",
|
||||
"addresssecondline": "addr 2",
|
||||
"city": "San Francisco",
|
||||
"state": "CA",
|
||||
"postcode": "94107",
|
||||
"phone": "123456789",
|
||||
"email": "john.doe@example.com"
|
||||
},
|
||||
"shipping": {
|
||||
"firstname": "John",
|
||||
"lastname": "Doe",
|
||||
"company": "Automattic",
|
||||
"country": "United States (US)",
|
||||
"addressfirstline": "addr 1",
|
||||
"addresssecondline": "addr 2",
|
||||
"city": "San Francisco",
|
||||
"state": "CA",
|
||||
"postcode": "94107"
|
||||
}
|
||||
}
|
||||
},
|
||||
"orders": {
|
||||
"basicPaidOrder": {
|
||||
"paymentMethod": "cod",
|
||||
"status": "processing",
|
||||
"billing": {
|
||||
"firstName": "John",
|
||||
"lastName": "Doe",
|
||||
"email": "john.doe@example.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
testSpecs: 'installFiles/scaffold-tests.json',
|
||||
defaultJson: 'installFiles/default-test-config.json',
|
||||
initializeSh: 'installFiles/initialize.sh.default',
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "Initializing WooCommerce E2E"
|
||||
|
||||
# This is a workaround to accommodate different directory names.
|
||||
wp plugin activate --all
|
||||
wp plugin deactivate akismet
|
||||
wp plugin deactivate hello
|
||||
|
||||
wp theme install twentynineteen --activate
|
||||
wp user create customer customer@woocommercecoree2etestsuite.com \
|
||||
--user_pass=password \
|
||||
--role=subscriber \
|
||||
--first_name='Jane' \
|
||||
--last_name='Smith' \
|
||||
--path=/var/www/html
|
||||
|
||||
# we cannot create API keys for the API, so we using basic auth, this plugin allows that.
|
||||
wp plugin install https://github.com/WP-API/Basic-Auth/archive/master.zip --activate
|
||||
|
||||
# install the WP Mail Logging plugin to test emails
|
||||
wp plugin install wp-mail-logging --activate
|
||||
|
||||
# initialize pretty permalinks
|
||||
wp rewrite structure /%postname%/
|
|
@ -0,0 +1,138 @@
|
|||
{
|
||||
"active": [
|
||||
{
|
||||
"name": "front-end",
|
||||
"description": "Shopper tests",
|
||||
"testFiles": [
|
||||
{
|
||||
"name": "cart-begin",
|
||||
"functions": [ "runCartPageTest" ]
|
||||
}, {
|
||||
"name": "cart-calculate-shipping",
|
||||
"functions": [ "runCartCalculateShippingTest" ]
|
||||
}, {
|
||||
"name": "cart-coupons",
|
||||
"functions": [ "runCartApplyCouponsTest" ]
|
||||
}, {
|
||||
"name": "checkout-begin",
|
||||
"functions": [ "runCheckoutPageTest" ]
|
||||
}, {
|
||||
"name": "checkout-coupons",
|
||||
"functions": [ "runCheckoutApplyCouponsTest" ]
|
||||
}, {
|
||||
"name": "checkout-create-account",
|
||||
"functions": [ "runCheckoutCreateAccountTest" ]
|
||||
}, {
|
||||
"name": "checkout-login-account",
|
||||
"functions": [ "runCheckoutLoginAccountTest" ]
|
||||
}, {
|
||||
"name": "my-account-create-account",
|
||||
"functions": [ "runMyAccountCreateAccountTest" ]
|
||||
}, {
|
||||
"name": "my-account-pay-order",
|
||||
"functions": [ "runMyAccountPayOrderTest" ]
|
||||
}, {
|
||||
"name": "my-account",
|
||||
"functions": [ "runMyAccountPageTest" ]
|
||||
}, {
|
||||
"name": "order-email-receiving",
|
||||
"functions": [ "runOrderEmailReceivingTest" ]
|
||||
}, {
|
||||
"name": "product-browse-search-sort",
|
||||
"functions": [ "runProductBrowseSearchSortTest" ]
|
||||
}, {
|
||||
"name": "single-product-page",
|
||||
"functions": [ "runSingleProductPageTest" ]
|
||||
}, {
|
||||
"name": "variable-product-updates",
|
||||
"functions": [ "runVariableProductUpdateTest" ]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"name": "rest-api",
|
||||
"description": "REST API tests",
|
||||
"testFiles": [
|
||||
{
|
||||
"name": "api",
|
||||
"functions": [ "runApiTests" ]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"name": "wp-admin",
|
||||
"description": "Merchant tests",
|
||||
"testFiles": [
|
||||
{
|
||||
"name": "create-coupon",
|
||||
"functions": [ "runCreateCouponTest" ]
|
||||
}, {
|
||||
"name": "create-order",
|
||||
"functions": [ "runCreateOrderTest" ]
|
||||
}, {
|
||||
"name": "create-shipping-classes",
|
||||
"functions": [ "runAddShippingClassesTest" ]
|
||||
}, {
|
||||
"name": "create-shipping-zones",
|
||||
"functions": [ "runAddNewShippingZoneTest" ]
|
||||
}, {
|
||||
"name": "create-simple-product",
|
||||
"functions": [ "runAddSimpleProductTest" ]
|
||||
}, {
|
||||
"name": "create-variable-product",
|
||||
"functions": [ "runAddVariableProductTest" ]
|
||||
}, {
|
||||
"name": "order-coupon",
|
||||
"functions": [ "runOrderApplyCouponTest" ]
|
||||
}, {
|
||||
"name": "order-customer-payment-page",
|
||||
"functions": [ "runMerchantOrdersCustomerPaymentPage" ]
|
||||
}, {
|
||||
"name": "order-edit",
|
||||
"functions": [ "runEditOrderTest" ]
|
||||
}, {
|
||||
"name": "order-emails",
|
||||
"functions": [ "runMerchantOrderEmailsTest" ]
|
||||
}, {
|
||||
"name": "order-refund",
|
||||
"functions": [ "runOrderRefundTest" ]
|
||||
}, {
|
||||
"name": "order-searching",
|
||||
"functions": [ "runOrderSearchingTest" ]
|
||||
}, {
|
||||
"name": "order-status-filters",
|
||||
"functions": [ "runOrderStatusFiltersTest" ]
|
||||
}, {
|
||||
"name": "product-edit",
|
||||
"functions": [ "runProductEditDetailsTest" ]
|
||||
}, {
|
||||
"name": "product-import-csv",
|
||||
"functions": [ "runImportProductsTest" ]
|
||||
}, {
|
||||
"name": "product-search",
|
||||
"functions": [ "runProductSearchTest" ]
|
||||
}, {
|
||||
"name": "update-general-settings",
|
||||
"functions": [ "runUpdateGeneralSettingsTest" ]
|
||||
}, {
|
||||
"name": "update-product-settings",
|
||||
"functions": [ "runProductSettingsTest" ]
|
||||
}, {
|
||||
"name": "update-tax-settings",
|
||||
"functions": [ "runTaxSettingsTest" ]
|
||||
}, {
|
||||
"name": "wccom-connect",
|
||||
"functions": [ "runInitiateWccomConnectionTest" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"deprecated": [
|
||||
{
|
||||
"name": "example-folder",
|
||||
"testFiles": [
|
||||
{ "name": "any-filename-to-deprecate" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -3,10 +3,12 @@
|
|||
## Added
|
||||
|
||||
- Added `await` for every call to `shopper.logout`
|
||||
- Test setup, scaffolding, and removal via `wc-e2e install` and `wc-e2e uninstall`
|
||||
|
||||
## Fixed
|
||||
|
||||
- Updated the browserViewport in `jest.setup.js` to match the `defaultViewport` dimensions defined in `jest-puppeteer.config.js`
|
||||
|
||||
## Added
|
||||
|
||||
- Added quotes around `WORDPRESS_TITLE` value in .env file to address issue with docker compose 2 "key cannot contain a space" error.
|
||||
|
|
|
@ -9,6 +9,19 @@ npm install @woocommerce/e2e-environment --save
|
|||
npm install jest --global
|
||||
```
|
||||
|
||||
### Version 0.3.0 and newer
|
||||
|
||||
Version 0.3.0 added a test installer that will populate the `tests/e2e/*` folder with test scripts and configuration files. The installer will create test scripts for E2E test packages that include support for the installer.
|
||||
|
||||
- [Adding test scaffolding to E2E test packages](https://github.com/woocommerce/woocommerce/tree/trunk/packages/js/e2e-environment/test-packages.md)
|
||||
|
||||
#### Using the installer
|
||||
|
||||
- Install a default test environment: `npx wc-e2e install`
|
||||
- Install test specs from an E2E tests package: `npx wc-e2e install @woocommerce-e2e-tests [--format cjs] [--ext spec.js]`
|
||||
- The default test spec format and extension are `ES6` and `test.js`
|
||||
- Remove test specs for an E2E tests package: `npx wc-e2e uninstall @woocommerce-e2e-tests`
|
||||
|
||||
## Configuration
|
||||
|
||||
The `@woocommerce/e2e-environment` package exports configuration objects that can be consumed in JavaScript config files in your project. Additionally, it includes a basic hosting container for running tests and includes instructions for creating your Travis CI setup.
|
||||
|
@ -60,10 +73,10 @@ The E2E environment uses Jest as a test runner. Extending the base config is nec
|
|||
|
||||
```js
|
||||
const path = require( 'path' );
|
||||
const { useE2EJestConfig } = require( '@woocommerce/e2e-environment' );
|
||||
const { useE2EJestConfig, resolveLocalE2ePath } = require( '@woocommerce/e2e-environment' );
|
||||
|
||||
const jestConfig = useE2EJestConfig( {
|
||||
roots: [ path.resolve( __dirname, '../specs' ) ],
|
||||
roots: [ resolveLocalE2ePath( 'specs' ) ],
|
||||
} );
|
||||
|
||||
module.exports = jestConfig;
|
||||
|
|
|
@ -11,6 +11,7 @@ const {
|
|||
getAppName,
|
||||
getTestConfig,
|
||||
resolveLocalE2ePath,
|
||||
resolvePackagePath,
|
||||
} = require( '../utils' );
|
||||
|
||||
const dockerArgs = [];
|
||||
|
@ -63,7 +64,7 @@ if ( appPath ) {
|
|||
if ( fs.existsSync( appInitFile ) ) {
|
||||
fs.copyFileSync(
|
||||
appInitFile,
|
||||
path.resolve( __dirname, '../docker/wp-cli/initialize.sh' )
|
||||
resolvePackagePath( 'docker/wp-cli/initialize.sh' )
|
||||
);
|
||||
console.log( 'Initializing ' + appInitFile );
|
||||
}
|
||||
|
@ -90,7 +91,7 @@ if ( ! process.env.WORDPRESS_URL ) {
|
|||
}
|
||||
|
||||
// Ensure that the first Docker compose file loaded is from our local env.
|
||||
dockerArgs.unshift( '-f', path.resolve( __dirname, '../docker-compose.yaml' ) );
|
||||
dockerArgs.unshift( '-f', resolvePackagePath( 'docker-compose.yaml' ) );
|
||||
|
||||
const dockerProcess = spawnSync( 'docker-compose', dockerArgs, {
|
||||
stdio: 'inherit',
|
||||
|
|
|
@ -4,7 +4,11 @@ const { spawnSync } = require( 'child_process' );
|
|||
const program = require( 'commander' );
|
||||
const path = require( 'path' );
|
||||
const fs = require( 'fs' );
|
||||
const { getAppRoot, resolveLocalE2ePath } = require( '../utils' );
|
||||
const {
|
||||
getAppRoot,
|
||||
resolveLocalE2ePath,
|
||||
resolvePackagePath,
|
||||
} = require( '../utils' );
|
||||
const {
|
||||
WC_E2E_SCREENSHOTS,
|
||||
JEST_PUPPETEER_CONFIG,
|
||||
|
@ -30,7 +34,7 @@ if ( WC_E2E_SCREENSHOTS ) {
|
|||
}
|
||||
}
|
||||
|
||||
const nodeConfigDirs = [ path.resolve( __dirname, '../config' ) ];
|
||||
const nodeConfigDirs = [ resolvePackagePath( 'config' ) ];
|
||||
|
||||
if ( appPath ) {
|
||||
nodeConfigDirs.unshift( resolveLocalE2ePath( 'config' ) );
|
||||
|
@ -51,10 +55,7 @@ if ( ! JEST_PUPPETEER_CONFIG ) {
|
|||
// Use local Puppeteer config if there is one.
|
||||
// Load test configuration file into an object.
|
||||
const localJestConfigFile = resolveLocalE2ePath( 'config/jest-puppeteer.config.js' );
|
||||
const jestConfigFile = path.resolve(
|
||||
__dirname,
|
||||
'../config/jest-puppeteer.config.js'
|
||||
);
|
||||
const jestConfigFile = resolvePackagePath( 'config/jest-puppeteer.config.js' );
|
||||
|
||||
testEnvVars.JEST_PUPPETEER_CONFIG = fs.existsSync( localJestConfigFile )
|
||||
? localJestConfigFile
|
||||
|
@ -88,7 +89,7 @@ if ( program.debug ) {
|
|||
|
||||
const envVars = Object.assign( {}, process.env, testEnvVars );
|
||||
|
||||
let configPath = path.resolve( __dirname, '../config/jest.config.js' );
|
||||
let configPath = resolvePackagePath( 'config/jest.config.js' );
|
||||
|
||||
// Look for a Jest config in the dependent app's path.
|
||||
if ( appPath ) {
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
const fs = require( 'fs' );
|
||||
const path = require( 'path' );
|
||||
const sprintf = require( 'sprintf-js' ).sprintf;
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
const {
|
||||
resolvePackage,
|
||||
resolvePackagePath,
|
||||
} = require( '../utils' );
|
||||
const {
|
||||
createLocalE2ePath,
|
||||
confirm,
|
||||
confirmLocalCopy,
|
||||
confirmLocalDelete,
|
||||
getPackageData,
|
||||
installDefaults
|
||||
} = require( '../utils/scaffold' );
|
||||
|
||||
const args = process.argv.slice( 2 );
|
||||
const [ command, packageName ] = args;
|
||||
|
||||
// Allow multiple spec file extensions and formats.
|
||||
let testExtension = 'test.js';
|
||||
let testFormat = '';
|
||||
for ( let a = 2; a < args.length; a++ ) {
|
||||
const nextArg = a + 1;
|
||||
if ( nextArg >= args.length ) {
|
||||
break;
|
||||
}
|
||||
switch ( args[ a ] ) {
|
||||
case '--format':
|
||||
testFormat = args[ nextArg ];
|
||||
break;
|
||||
case '--ext':
|
||||
testExtension = args[ nextArg ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the test scripts and sample default.json configuration
|
||||
*/
|
||||
if ( command == 'install' ) {
|
||||
// Install some environment defaults if no package is requested.
|
||||
if ( ! packageName ) {
|
||||
installDefaults();
|
||||
return;
|
||||
}
|
||||
|
||||
// `package` is a reserved word
|
||||
const pkg = resolvePackage( packageName ).name;
|
||||
if ( ! pkg.length ) {
|
||||
//@todo add error message
|
||||
return;
|
||||
}
|
||||
const { packageSlug, testSpecs, defaultJson, initializeSh } = getPackageData( pkg );
|
||||
|
||||
// Write sample default.json
|
||||
if ( defaultJson ) {
|
||||
const defaultJsonName = `config${path.sep}default-${packageSlug}.json`;
|
||||
createLocalE2ePath( 'config' );
|
||||
if ( confirmLocalCopy( defaultJsonName, defaultJson, pkg ) ) {
|
||||
console.log( `Created sample test configuration to 'tests/e2e/${defaultJsonName}'.` );
|
||||
}
|
||||
}
|
||||
|
||||
// Write sample initialize.sh
|
||||
if ( initializeSh ) {
|
||||
const defaultInitName = `docker${path.sep}${packageSlug}.sh`;
|
||||
createLocalE2ePath( 'docker' );
|
||||
if ( confirmLocalCopy( defaultInitName, initializeSh, pkg ) ) {
|
||||
console.log( `Created sample test container initialization script to 'tests/e2e/${defaultInitName}'.` );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! testSpecs ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Write test files
|
||||
const testsSpecFile = resolvePackagePath( testSpecs, pkg );
|
||||
const specs = fs.readFileSync( testsSpecFile );
|
||||
const tests = JSON.parse( specs );
|
||||
const { active, deprecated } = tests;
|
||||
|
||||
if ( active && active.length ) {
|
||||
const blankLine = '';
|
||||
const eol = "\n";
|
||||
const autoGenerate = sprintf( '/* This file was auto-generated by the command `npx wc-e2e install %s`. */', packageName );
|
||||
let importLineFormat;
|
||||
let overwriteFiles;
|
||||
let confirmPrompt;
|
||||
if ( testFormat.toLowerCase() == 'cjs' ) {
|
||||
importLineFormat = sprintf( "const {%%s} = require( '%s' );", pkg );
|
||||
} else {
|
||||
importLineFormat = sprintf( "import {%%s} from '%s';", pkg );
|
||||
}
|
||||
|
||||
// Create the specs folder if not present
|
||||
let specFolderPath = createLocalE2ePath( 'specs' );
|
||||
|
||||
// Loop through folders and files to write test scripts.
|
||||
for ( let f = 0; f < active.length; f++ ) {
|
||||
if ( overwriteFiles == 'q' ) {
|
||||
overwriteFiles = '';
|
||||
break;
|
||||
}
|
||||
|
||||
const testFolder = active[ f ];
|
||||
const { testFiles } = testFolder;
|
||||
|
||||
if ( ! testFiles || ! testFiles.length ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let specFolder;
|
||||
if ( testFolder.name.length ) {
|
||||
specFolder = createLocalE2ePath( `specs${path.sep}${testFolder.name}` );
|
||||
} else {
|
||||
specFolder = specFolderPath;
|
||||
}
|
||||
|
||||
// Create the test files.
|
||||
for ( let t = 0; t < testFiles.length; t++ ) {
|
||||
const testFile = testFiles[ t ];
|
||||
if ( ! testFile.functions.length ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const testFileName = `${testFolder.name}${path.sep}${testFile.name}.${testExtension}`;
|
||||
const testFilePath = `${specFolder}${path.sep}${testFile.name}.${testExtension}`;
|
||||
|
||||
// Check to see if file exists.
|
||||
if ( fs.existsSync( testFilePath ) ) {
|
||||
if ( overwriteFiles != 'a' ) {
|
||||
confirmPrompt = `${testFileName} already exists. Overwrite? [y]es/[n]o/[a]ll/[q]uit: `;
|
||||
overwriteFiles = confirm( confirmPrompt, 'anqy' );
|
||||
overwriteFiles = overwriteFiles.toLowerCase();
|
||||
}
|
||||
|
||||
if ( overwriteFiles == 'q' ) {
|
||||
break;
|
||||
}
|
||||
if ( overwriteFiles != 'a' && overwriteFiles != 'y' ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
console.log( 'Writing tests/e2e/specs/' + testFileName );
|
||||
let buffer = [ autoGenerate ];
|
||||
let testSeparator, testTerminator, importPrefix;
|
||||
|
||||
// Add the import line.
|
||||
if ( testFile.functions.length > 3 ) {
|
||||
testSeparator = ',' + eol;
|
||||
testTerminator = eol;
|
||||
importPrefix = eol;
|
||||
} else {
|
||||
testSeparator = ', ';
|
||||
testTerminator = ' ';
|
||||
importPrefix = ' ';
|
||||
}
|
||||
const testImport = testFile.functions.join( testSeparator ) + testTerminator;
|
||||
buffer.push( sprintf( importLineFormat, importPrefix + testImport ), blankLine );
|
||||
|
||||
// Add test function calls and write the file
|
||||
let functionCalls = testFile.functions.map( functionName => functionName + '();' );
|
||||
buffer.push( ...functionCalls, blankLine );
|
||||
fs.writeFileSync( testFilePath, buffer.join( eol ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
// @todo: deprecated files.
|
||||
} else if ( command == 'uninstall' ) {
|
||||
if ( ! packageName ) {
|
||||
// @todo: write error message
|
||||
return;
|
||||
}
|
||||
|
||||
const pkg = resolvePackage( packageName ).name;
|
||||
const { packageSlug, testSpecs, defaultJson, initializeSh } = getPackageData( pkg );
|
||||
|
||||
// Delete sample default.json
|
||||
if ( defaultJson ) {
|
||||
const defaultJsonName = `config${path.sep}default-${packageSlug}.json`;
|
||||
confirmLocalDelete( defaultJsonName );
|
||||
}
|
||||
|
||||
// Delete sample initialize.sh
|
||||
if ( initializeSh ) {
|
||||
const defaultInitName = `docker${path.sep}${packageSlug}.sh`;
|
||||
confirmLocalDelete( defaultInitName );
|
||||
}
|
||||
|
||||
if ( ! testSpecs ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const testsSpecFile = resolvePackagePath( testSpecs, pkg );
|
||||
const specs = fs.readFileSync( testsSpecFile );
|
||||
const tests = JSON.parse( specs );
|
||||
const { active } = tests;
|
||||
|
||||
if ( ! active || ! active.length ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop through folders and files to delete test scripts.
|
||||
for ( let f = 0; f < active.length; f++ ) {
|
||||
const testFolder = active[ f ];
|
||||
const { testFiles } = testFolder;
|
||||
|
||||
if ( ! testFiles || ! testFiles.length ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const specFolder = testFolder.name.length ? `specs${path.sep}${testFolder.name}` : 'specs';
|
||||
for ( let t = 0; t < testFiles.length; t++ ) {
|
||||
const testFile = testFiles[ t ];
|
||||
const testFilePath = `${specFolder}${path.sep}${testFile.name}.${testExtension}`;
|
||||
|
||||
confirmLocalDelete( testFilePath );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -71,6 +71,10 @@ case $1 in
|
|||
./bin/wait-for-build.sh && ./bin/e2e-test-integration.js --dev --debug $2
|
||||
TESTRESULT=$?
|
||||
;;
|
||||
'install' | \
|
||||
'uninstall')
|
||||
./bin/scaffold.js $@
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "Initializing WooCommerce E2E"
|
||||
|
||||
# This is a workaround to accommodate different directory names.
|
||||
wp plugin activate --all
|
||||
wp plugin deactivate akismet
|
||||
wp plugin deactivate hello
|
||||
|
||||
wp theme install twentynineteen --activate
|
||||
wp user create customer customer@woocommercecoree2etestsuite.com \
|
||||
--user_pass=password \
|
||||
--role=subscriber \
|
||||
--first_name='Jane' \
|
||||
--last_name='Smith' \
|
||||
--path=/var/www/html
|
||||
|
||||
# we cannot create API keys for the API, so we using basic auth, this plugin allows that.
|
||||
wp plugin install https://github.com/WP-API/Basic-Auth/archive/master.zip --activate
|
||||
|
||||
# install the WP Mail Logging plugin to test emails
|
||||
wp plugin install wp-mail-logging --activate
|
||||
|
||||
# initialize pretty permalinks
|
||||
wp rewrite structure /%postname%/
|
|
@ -0,0 +1,8 @@
|
|||
const path = require( 'path' );
|
||||
const { useE2EJestConfig, getAppRoot } = require( '@woocommerce/e2e-environment' );
|
||||
|
||||
const jestConfig = useE2EJestConfig( {
|
||||
roots: [ path.resolve( __dirname, '../specs' ) ],
|
||||
} );
|
||||
|
||||
module.exports = jestConfig;
|
|
@ -0,0 +1,80 @@
|
|||
import {
|
||||
clearLocalStorage,
|
||||
setBrowserViewport,
|
||||
withRestApi,
|
||||
WP_ADMIN_LOGIN
|
||||
} from '@woocommerce/e2e-utils';
|
||||
|
||||
const config = require( 'config' );
|
||||
const { HTTPClientFactory } = require( '@woocommerce/api' );
|
||||
const { addConsoleSuppression, updateReadyPageStatus } = require( '@woocommerce/e2e-environment' );
|
||||
const { DEFAULT_TIMEOUT_OVERRIDE } = process.env;
|
||||
|
||||
// @todo: remove this once https://github.com/woocommerce/woocommerce-admin/issues/6992 has been addressed
|
||||
addConsoleSuppression( 'woocommerce_shared_settings', false );
|
||||
|
||||
/**
|
||||
* Uses the WordPress API to delete all existing posts
|
||||
*/
|
||||
async function trashExistingPosts() {
|
||||
const apiUrl = config.get('url');
|
||||
const wpPostsEndpoint = '/wp/v2/posts';
|
||||
const adminUsername = config.get('users.admin.username');
|
||||
const adminPassword = config.get('users.admin.password');
|
||||
const client = HTTPClientFactory.build(apiUrl)
|
||||
.withBasicAuth(adminUsername, adminPassword)
|
||||
.create();
|
||||
|
||||
// List all existing posts
|
||||
const response = await client.get(wpPostsEndpoint);
|
||||
const posts = response.data;
|
||||
|
||||
// Delete each post
|
||||
for (const post of posts) {
|
||||
await client.delete(`${wpPostsEndpoint}/${post.id}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Before every test suite run, delete all content created by the test. This ensures
|
||||
// other posts/comments/etc. aren't dirtying tests and tests don't depend on
|
||||
// each other's side-effects.
|
||||
beforeAll(async () => {
|
||||
|
||||
if ( DEFAULT_TIMEOUT_OVERRIDE ) {
|
||||
page.setDefaultNavigationTimeout( DEFAULT_TIMEOUT_OVERRIDE );
|
||||
page.setDefaultTimeout( DEFAULT_TIMEOUT_OVERRIDE );
|
||||
}
|
||||
|
||||
try {
|
||||
// Update the ready page to prevent concurrent test runs
|
||||
await updateReadyPageStatus('draft');
|
||||
await trashExistingPosts();
|
||||
await withRestApi.deleteAllProducts();
|
||||
await withRestApi.deleteAllCoupons();
|
||||
await withRestApi.deleteAllOrders();
|
||||
} catch ( error ) {
|
||||
// Prevent an error here causing tests to fail.
|
||||
}
|
||||
|
||||
await page.goto(WP_ADMIN_LOGIN);
|
||||
await clearLocalStorage();
|
||||
await setBrowserViewport( {
|
||||
width: 1280,
|
||||
height: 800,
|
||||
});
|
||||
});
|
||||
|
||||
// Clear browser cookies and cache using DevTools.
|
||||
// This is to ensure that each test ends with no user logged in.
|
||||
afterAll(async () => {
|
||||
// Reset the ready page to published to allow future test runs
|
||||
try {
|
||||
await updateReadyPageStatus('publish');
|
||||
} catch ( error ) {
|
||||
// Prevent an error here causing tests to fail.
|
||||
}
|
||||
|
||||
const client = await page.target().createCDPSession();
|
||||
await client.send('Network.clearBrowserCookies');
|
||||
await client.send('Network.clearBrowserCache');
|
||||
});
|
|
@ -33,7 +33,9 @@
|
|||
"jest-each": "25.5.0",
|
||||
"jest-puppeteer": "^4.4.0",
|
||||
"node-stream-zip": "^1.13.6",
|
||||
"request": "^2.88.2"
|
||||
"readline-sync": "^1.4.10",
|
||||
"request": "^2.88.2",
|
||||
"sprintf-js": "^1.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "7.12.8",
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
# WooCommerce End-to-End Test Packages
|
||||
|
||||
There are two limitations which significantly impact the architecture of E2E test packages:
|
||||
|
||||
- Referencing the `jest` functions `describe`, `it`, `beforeAll`, etc. throws a fatal error outside the `jest` environment.
|
||||
- `jest` will not scan for tests in any path containing `node_mdules`.
|
||||
|
||||
## Creating a tests package
|
||||
|
||||
The way to create a tests package with the above limitations is
|
||||
|
||||
- **In the tests package**, wrap each test in a function
|
||||
|
||||
```js
|
||||
/**
|
||||
* Require the necessary jest functions to prevent the package build from referencing them
|
||||
* `import` references imported functions during package build
|
||||
*/
|
||||
|
||||
const { describe, it, beforeAll } = require( '@jest/globals' );
|
||||
|
||||
const testMyCriticalFlow = () => {
|
||||
describe( 'My Critical Flow', () => {
|
||||
beforeAll( async () => {
|
||||
// Test setup
|
||||
} );
|
||||
it( 'can complete first step', async () => {
|
||||
// Do stuff
|
||||
expect( someValue ).toBeTruthy();
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
||||
modules.exports = testMyFlow;
|
||||
```
|
||||
|
||||
- **In the `tests/e2e/specs` folder**, create a test spec that calls the test function
|
||||
|
||||
```js
|
||||
import { testMyCriticalFlow } from 'MyTestsPackage';
|
||||
|
||||
testMyCriticalFlow();
|
||||
```
|
||||
|
||||
## Adding the scaffolds for the test installer
|
||||
|
||||
To work with the limitations outlined above, the test installer needs to access the test scaffolding information without accessing the package index. As a result, the `installFiles` is a required path in the steps below
|
||||
|
||||
- Create an `installFiles` folder in the root of the package
|
||||
- Add an `index.js` to the folder which exports an object with some or all of three properties
|
||||
```js
|
||||
module.exports = {
|
||||
defaultJson: 'installFiles/default-test-config.json',
|
||||
initializeSh: 'installFiles/initialize.sh.default',
|
||||
testSpecs: 'installFiles/scaffold-tests.json',
|
||||
};
|
||||
```
|
||||
- The value of each of the properties should be a relative path from the package `index.js`. The test installer will remove `dist`, `build`, and `build-modules` from the end of the package index path.
|
||||
- `defaultJson`: Path to a JSON file containing all `default.json` entries needed for the tests in the package.
|
||||
- `initializeSh`: Path to a bash script containing the WP CLI commands needed to initialize the `e2e-environment` test container.
|
||||
- `testSpecs`: Path to a JSON file containing a nested object
|
||||
```json
|
||||
{
|
||||
"active": [
|
||||
{
|
||||
"name": "first-folder-name",
|
||||
"description": "First tests",
|
||||
"testFiles": [
|
||||
{
|
||||
"name": "test-name-a",
|
||||
"functions": [
|
||||
"testMyCriticalFlow"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "test-name-b",
|
||||
"functions": [
|
||||
"testSecondCriticalFlow",
|
||||
"testThirdCriticalFlow"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "second-folder-name",
|
||||
"description": "Second tests",
|
||||
"testFiles": [
|
||||
....
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The test installer uses the `testSpecs` nested object to create test specs. Using the example above, create `tests/e2e/specs/first-folder-name/test-name-b.test.js`:
|
||||
|
||||
```js
|
||||
/* This file was auto-generated by the command `npx wc-e2e install your-package-name`. */
|
||||
import { testSecondCriticalFlow, testThirdCriticalFlow } from 'your-package-name';
|
||||
|
||||
testSecondCriticalFlow();
|
||||
testThirdCriticalFlow();
|
||||
```
|
||||
|
|
@ -13,10 +13,7 @@ const StreamZip = require( 'node-stream-zip' );
|
|||
*/
|
||||
const getRemotePluginZip = async ( fileUrl ) => {
|
||||
const appPath = getAppRoot();
|
||||
const savePath = path.resolve(
|
||||
appPath,
|
||||
'plugins/woocommerce/tests/e2e/plugins'
|
||||
);
|
||||
const savePath = resolveLocalE2ePath( 'plugins' );
|
||||
mkdirp.sync( savePath );
|
||||
|
||||
// Pull the filename from the end of the URL
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const getAppRoot = require( './app-root' );
|
||||
const { getAppName, getAppBase } = require( './app-name' );
|
||||
const { getTestConfig, getAdminConfig, resolveLocalE2ePath } = require( './test-config' );
|
||||
const testConfig = require( './test-config' );
|
||||
const { getRemotePluginZip, getLatestReleaseZipUrl } = require('./get-plugin-zip');
|
||||
const takeScreenshotFor = require( './take-screenshot' );
|
||||
const updateReadyPageStatus = require('./update-ready-page');
|
||||
|
@ -10,12 +10,10 @@ module.exports = {
|
|||
getAppBase,
|
||||
getAppRoot,
|
||||
getAppName,
|
||||
getTestConfig,
|
||||
getAdminConfig,
|
||||
resolveLocalE2ePath,
|
||||
getRemotePluginZip,
|
||||
getLatestReleaseZipUrl,
|
||||
takeScreenshotFor,
|
||||
updateReadyPageStatus,
|
||||
...testConfig,
|
||||
...consoleUtils,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
const fs = require( 'fs' );
|
||||
const path = require( 'path' );
|
||||
const readlineSync = require( 'readline-sync' );
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
const { resolveLocalE2ePath, resolvePackagePath } = require( './test-config' );
|
||||
|
||||
/**
|
||||
* Create a path relative to the local `tests/e2e` folder.
|
||||
* @param relativePath
|
||||
* @return {string}
|
||||
*/
|
||||
const createLocalE2ePath = ( relativePath ) => {
|
||||
let specFolderPath = '';
|
||||
const folders = [ `..${path.sep}..${path.sep}tests`, `..${path.sep}e2e`, relativePath ];
|
||||
folders.forEach( ( folder ) => {
|
||||
specFolderPath = resolveLocalE2ePath( folder );
|
||||
if ( ! fs.existsSync( specFolderPath ) ) {
|
||||
console.log( `Creating folder ${specFolderPath}` );
|
||||
fs.mkdirSync( specFolderPath );
|
||||
}
|
||||
} );
|
||||
|
||||
return specFolderPath;
|
||||
};
|
||||
|
||||
/**
|
||||
* Prompt the console for confirmation.
|
||||
*
|
||||
* @param {string} prompt Prompt for the user.
|
||||
* @param {string} choices valid responses.
|
||||
* @return {string}
|
||||
*/
|
||||
const confirm = ( prompt, choices ) => {
|
||||
const answer = readlineSync.keyIn( prompt, choices );
|
||||
return answer;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} localE2ePath Destination path
|
||||
* @param {string} packageE2ePath Source path
|
||||
* @param {string} packageName Source package. Default @woocommerce/e2e-environment package.
|
||||
* @return {boolean}
|
||||
*/
|
||||
const confirmLocalCopy = ( localE2ePath, packageE2ePath, packageName = '' ) => {
|
||||
const localPath = resolveLocalE2ePath( localE2ePath );
|
||||
const packagePath = resolvePackagePath( packageE2ePath, packageName );
|
||||
const confirmPrompt = `${localE2ePath} already exists. Overwrite? [Y]es/[n]o: `;
|
||||
|
||||
let overwriteFiles;
|
||||
if ( fs.existsSync( localPath ) ) {
|
||||
overwriteFiles = confirm( confirmPrompt, 'ny' );
|
||||
overwriteFiles = overwriteFiles.toLowerCase();
|
||||
} else {
|
||||
overwriteFiles = 'y';
|
||||
}
|
||||
if ( overwriteFiles == 'y' ) {
|
||||
fs.copyFileSync( packagePath, localPath );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Prompt for confirmation before deleting a local E2E file.
|
||||
*
|
||||
* @param {string} localE2ePath Relative path to local E2E file.
|
||||
*/
|
||||
const confirmLocalDelete = ( localE2ePath ) => {
|
||||
const localPath = resolveLocalE2ePath( localE2ePath );
|
||||
if ( ! fs.existsSync( localPath ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const confirmPrompt = `${localE2ePath} exists. Delete? [y]es/[n]o: `;
|
||||
const deleteFile = confirm( confirmPrompt, 'ny' );
|
||||
if ( deleteFile == 'y' ) {
|
||||
fs.unlinkSync( localPath );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the install data for a tests package.
|
||||
*
|
||||
* @param {string} packageName npm package name
|
||||
* @return {string}
|
||||
*/
|
||||
const getPackageData = ( packageName ) => {
|
||||
const packageSlug = packageName.replace( '@', '' ).replace( /\//g, '.' );
|
||||
const installFiles = require( `${packageName}${path.sep}installFiles` );
|
||||
|
||||
return { packageSlug, ...installFiles };
|
||||
};
|
||||
|
||||
/**
|
||||
* Install test runner and test container defaults
|
||||
*/
|
||||
const installDefaults = () => {
|
||||
createLocalE2ePath( 'docker' );
|
||||
console.log( 'Writing tests/e2e/docker/initialize.sh' );
|
||||
confirmLocalCopy( `docker${path.sep}initialize.sh`, `installFiles${path.sep}initialize.sh` );
|
||||
|
||||
createLocalE2ePath( 'config' );
|
||||
console.log( 'Writing tests/e2e/config/jest.config.js' );
|
||||
confirmLocalCopy( `config${path.sep}jest.config.js`, `installFiles${path.sep}jest.config.js` );
|
||||
console.log( 'Writing tests/e2e/config/jest.setup.js' );
|
||||
confirmLocalCopy( `config${path.sep}jest.setup.js`, `installFiles${path.sep}jest.setup.js` );
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
createLocalE2ePath,
|
||||
confirm,
|
||||
confirmLocalCopy,
|
||||
confirmLocalDelete,
|
||||
getPackageData,
|
||||
installDefaults,
|
||||
};
|
|
@ -19,15 +19,84 @@ const resolveLocalE2ePath = ( filename = '' ) => {
|
|||
);
|
||||
|
||||
return resolvedPath;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolve a package name installable by npm install.
|
||||
*
|
||||
* @param {string} packageName Name of the installed package.
|
||||
* @param {boolean} allowRecurse Allow a recursive call. Default true.
|
||||
* @return {object}
|
||||
*/
|
||||
const resolvePackage = ( packageName, allowRecurse = true ) => {
|
||||
const resolvedPackage = {};
|
||||
|
||||
try {
|
||||
const resolvedPath = path.dirname( require.resolve( packageName ) );
|
||||
const buildPaths = [ 'dist', 'build', 'build-modules' ];
|
||||
|
||||
// Remove build paths from the resolved path.
|
||||
let resolvedParts = resolvedPath.split( path.sep );
|
||||
for ( let rp = resolvedParts.length - 1; rp >= 0; rp-- ) {
|
||||
if ( buildPaths.includes( resolvedParts[ rp ] ) ) {
|
||||
resolvedParts = resolvedParts.slice( 0, -1 );
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
resolvedPackage.path = resolvedParts.join( path.sep );
|
||||
resolvedPackage.name = packageName;
|
||||
} catch ( e ) {
|
||||
// Package name installed is not the package name.
|
||||
resolvedPackage.path = '';
|
||||
resolvedPackage.name = '';
|
||||
}
|
||||
|
||||
// Attempt to find the package through the project package lock file.
|
||||
if ( ! resolvedPackage.path.length && allowRecurse ) {
|
||||
const packageLockPath = path.resolve( appPath, 'package-lock.json' );
|
||||
const packageLockContent = fs.readFileSync( packageLockPath );
|
||||
const { dependencies } = JSON.parse( packageLockContent );
|
||||
|
||||
for ( const [ key, value ] of Object.entries( dependencies ) ) {
|
||||
if ( value.version.indexOf( packageName ) == 0 ) {
|
||||
resolvedPackage = resolvePackage( key, false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resolvedPackage;
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolve a file in a package.
|
||||
*
|
||||
* @param {string} filename Filename to append to the path.
|
||||
* @param {string} packageName Name of the installed package. Default @woocommerce/e2e-environment.
|
||||
* @return {string}
|
||||
*/
|
||||
const resolvePackagePath = ( filename, packageName = '' ) => {
|
||||
let packagePath;
|
||||
if ( ! packageName.length ) {
|
||||
packagePath = path.resolve( __dirname, '../' );
|
||||
} else {
|
||||
const pkg = resolvePackage( packageName );
|
||||
packagePath = pkg.path;
|
||||
}
|
||||
|
||||
const resolvedPath = path.resolve(
|
||||
packagePath,
|
||||
filename.indexOf( '/' ) == 0 ? filename.slice( 1 ) : filename
|
||||
);
|
||||
|
||||
return resolvedPath;
|
||||
};
|
||||
|
||||
// Copy local test configuration file if it exists.
|
||||
const localTestConfigFile = resolveLocalE2ePath( 'config/default.json' );
|
||||
const defaultConfigFile = path.resolve(
|
||||
__dirname,
|
||||
'../config/default/default.json'
|
||||
);
|
||||
const testConfigFile = path.resolve( __dirname, '../config/default.json' );
|
||||
const defaultConfigFile = resolvePackagePath( 'config/default/default.json' );
|
||||
const testConfigFile = resolvePackagePath( 'config/default.json' );
|
||||
|
||||
if ( fs.existsSync( localTestConfigFile ) ) {
|
||||
fs.copyFileSync( localTestConfigFile, testConfigFile );
|
||||
|
@ -94,4 +163,6 @@ module.exports = {
|
|||
getTestConfig,
|
||||
getAdminConfig,
|
||||
resolveLocalE2ePath,
|
||||
resolvePackage,
|
||||
resolvePackagePath,
|
||||
};
|
||||
|
|
|
@ -78,7 +78,7 @@ export const withRestApi = {
|
|||
};
|
||||
|
||||
const response = await client.put( onboardingProfileEndpoint, onboardingReset );
|
||||
expect( response.status ).toEqual( 200 );
|
||||
expect( response.statusCode ).toEqual( 200 );
|
||||
},
|
||||
/**
|
||||
* Use api package to delete coupons.
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
"pelago/emogrifier": "3.1.0",
|
||||
"psr/container": "1.0.0",
|
||||
"woocommerce/action-scheduler": "3.4.0",
|
||||
"woocommerce/woocommerce-admin": "2.9.3",
|
||||
"woocommerce/woocommerce-admin": "3.0.0-rc.1",
|
||||
"woocommerce/woocommerce-blocks": "6.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "8c4f8b290830d85dce9e69de46ca72ce",
|
||||
"content-hash": "c4f41955bfde1a0a4e2d6d7428b8ee58",
|
||||
"packages": [
|
||||
{
|
||||
"name": "automattic/jetpack-autoloader",
|
||||
|
@ -543,16 +543,16 @@
|
|||
},
|
||||
{
|
||||
"name": "woocommerce/woocommerce-admin",
|
||||
"version": "2.9.3",
|
||||
"version": "3.0.0-rc.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/woocommerce/woocommerce-admin.git",
|
||||
"reference": "0c4f1e637ad03178999ff53ae930b8258ca95962"
|
||||
"reference": "7c0cdd01ae98be058d684dd19023b0f40094cb63"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/0c4f1e637ad03178999ff53ae930b8258ca95962",
|
||||
"reference": "0c4f1e637ad03178999ff53ae930b8258ca95962",
|
||||
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/7c0cdd01ae98be058d684dd19023b0f40094cb63",
|
||||
"reference": "7c0cdd01ae98be058d684dd19023b0f40094cb63",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -608,9 +608,9 @@
|
|||
"homepage": "https://github.com/woocommerce/woocommerce-admin",
|
||||
"support": {
|
||||
"issues": "https://github.com/woocommerce/woocommerce-admin/issues",
|
||||
"source": "https://github.com/woocommerce/woocommerce-admin/tree/v2.9.3"
|
||||
"source": "https://github.com/woocommerce/woocommerce-admin/tree/v3.0.0-rc.1"
|
||||
},
|
||||
"time": "2021-12-15T03:02:58+00:00"
|
||||
"time": "2021-12-14T23:55:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "woocommerce/woocommerce-blocks",
|
||||
|
@ -2926,5 +2926,5 @@
|
|||
"platform-overrides": {
|
||||
"php": "7.0.33"
|
||||
},
|
||||
"plugin-api-version": "2.1.0"
|
||||
"plugin-api-version": "2.0.0"
|
||||
}
|
||||
|
|
|
@ -149,11 +149,10 @@ class WC_Geolocation {
|
|||
}
|
||||
|
||||
if ( empty( $ip_address ) ) {
|
||||
$ip_address = self::get_ip_address();
|
||||
$ip_address = self::get_ip_address();
|
||||
$country_code = self::get_country_code_from_headers();
|
||||
}
|
||||
|
||||
$country_code = self::get_country_code_from_headers();
|
||||
|
||||
/**
|
||||
* Get geolocation filter.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue