Merge branch 'trunk' into add/50916-product-reference
This commit is contained in:
commit
b719343f4b
|
@ -691,7 +691,7 @@
|
||||||
"post_title": "Integrating with coming soon mode",
|
"post_title": "Integrating with coming soon mode",
|
||||||
"tags": "how-to, coming-soon",
|
"tags": "how-to, coming-soon",
|
||||||
"edit_url": "https://github.com/woocommerce/woocommerce/edit/trunk/docs/extension-development/integrating-coming-soon-mode.md",
|
"edit_url": "https://github.com/woocommerce/woocommerce/edit/trunk/docs/extension-development/integrating-coming-soon-mode.md",
|
||||||
"hash": "910dbbab77c6fb4735e7704796242c38d86f3bf3b897de1075338eb47194f8f5",
|
"hash": "8c2087952ae79bb4c3e3977c57d9e933fcfaa418a5bc643b3827059daa5879a7",
|
||||||
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/docs/extension-development/integrating-coming-soon-mode.md",
|
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/docs/extension-development/integrating-coming-soon-mode.md",
|
||||||
"id": "787743efb6ef0ad509b17735eaf58b2a9a08afbc"
|
"id": "787743efb6ef0ad509b17735eaf58b2a9a08afbc"
|
||||||
},
|
},
|
||||||
|
@ -1804,5 +1804,5 @@
|
||||||
"categories": []
|
"categories": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"hash": "12e9abfbcdbeae7dd5cc12dc3af3818332f272cb4b3ad12993cc010299009013"
|
"hash": "8199f0d3c854474839300ed606f03f9f286ace35f65d7c47ffc6477762eaf51e"
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ post_title: Integrating with coming soon mode
|
||||||
tags: how-to, coming-soon
|
tags: how-to, coming-soon
|
||||||
---
|
---
|
||||||
|
|
||||||
This guide provides examples for third-party developers and hosting providers on how to integrate their systems with WooCommerce's coming soon mode. For more details, please read the [developer blog post](https://developer.woocommerce.com/2024/06/18/introducing-coming-soon-mode/).
|
This guide provides examples for third-party developers and hosting providers on how to integrate their systems with WooCommerce's coming soon mode. For more details, please read the [developer blog post](https://developer.woocommerce.com/2024/06/18/introducing-coming-soon-mode/). For site visibility settings, please refer to the [admin documentation](https://woocommerce.com/document/configuring-woocommerce-settings/coming-soon-mode/).
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
|
@ -49,8 +49,8 @@ function sync_coming_soon_to_other_plugins( $old_value, $new_value, $option ) {
|
||||||
$is_enabled = $new_value === 'yes';
|
$is_enabled = $new_value === 'yes';
|
||||||
|
|
||||||
// Implement your logic to sync coming soon status.
|
// Implement your logic to sync coming soon status.
|
||||||
if ( function_exists( 'set_your_plugin_status' ) ) {
|
if ( function_exists( 'your_plugin_set_coming_soon' ) ) {
|
||||||
set_your_plugin_status( $is_enabled );
|
your_plugin_set_coming_soon( $is_enabled );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -84,8 +84,8 @@ function sync_coming_soon_to_other_plugins( $old_value, $new_value, $option ) {
|
||||||
$is_enabled = $new_value === 'yes';
|
$is_enabled = $new_value === 'yes';
|
||||||
|
|
||||||
// Implement your logic to sync coming soon status.
|
// Implement your logic to sync coming soon status.
|
||||||
if ( function_exists( 'set_your_plugin_status' ) ) {
|
if ( function_exists( 'your_plugin_set_coming_soon' ) ) {
|
||||||
set_your_plugin_status( $is_enabled );
|
your_plugin_set_coming_soon( $is_enabled );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +108,38 @@ function sync_coming_soon_from_other_plugins( $is_enabled ) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### One-way binding with option override
|
||||||
|
|
||||||
|
We could also programmatically bind the coming soon option from another plugin by overriding the `woocommerce_coming_soon` option. This is advantageous since it simplifies state management and prevents possible out-of-sync issues.
|
||||||
|
|
||||||
|
In the following example, we're binding the coming soon option from another plugin by overriding the `woocommerce_coming_soon` option.
|
||||||
|
|
||||||
|
```php
|
||||||
|
add_filter( 'pre_option_woocommerce_coming_soon', 'override_option_woocommerce_coming_soon' );
|
||||||
|
|
||||||
|
function override_option_woocommerce_coming_soon( $current_value ) {
|
||||||
|
// Implement your logic to sync coming soon status.
|
||||||
|
if ( function_exists( 'your_plugin_is_coming_soon' ) ) {
|
||||||
|
return your_plugin_is_coming_soon() ? 'yes' : 'no';
|
||||||
|
}
|
||||||
|
return $current_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_filter( 'pre_update_option_woocommerce_coming_soon', 'override_update_woocommerce_coming_soon', 10, 2 );
|
||||||
|
|
||||||
|
function override_update_woocommerce_coming_soon( $new_value, $old_value ) {
|
||||||
|
// Check user capability.
|
||||||
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
|
wp_die( 'You do not have sufficient permissions to access this page.' );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement your logic to sync coming soon status.
|
||||||
|
if ( function_exists( 'your_plugin_set_coming_soon' ) ) {
|
||||||
|
your_plugin_set_coming_soon( $new_value === 'yes' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Custom exclusions filter
|
### Custom exclusions filter
|
||||||
|
|
||||||
It is possible for developers to add custom exclusions that bypass the coming soon protection. This is useful for exclusions like always bypassing the screen on a specific IP address, or making a specific landing page available.
|
It is possible for developers to add custom exclusions that bypass the coming soon protection. This is useful for exclusions like always bypassing the screen on a specific IP address, or making a specific landing page available.
|
||||||
|
@ -134,3 +166,35 @@ add_filter( 'woocommerce_coming_soon_exclude', function( $is_excluded ) {
|
||||||
return $is_excluded;
|
return $is_excluded;
|
||||||
}, 10 );
|
}, 10 );
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Custom share links
|
||||||
|
|
||||||
|
The following example shows how to integrate with a custom share code. We recommend using cookies or other storage to persist the access when users navigate across the site:
|
||||||
|
|
||||||
|
```php
|
||||||
|
add_filter( 'woocommerce_coming_soon_exclude', function( $exclude ) {
|
||||||
|
// Implement your logic to get and validate share code.
|
||||||
|
if ( function_exists( 'your_plugin_get_share_code' ) && function_exists( 'your_plugin_is_valid_share_code' ) ) {
|
||||||
|
$share_code = your_plugin_get_share_code();
|
||||||
|
if ( your_plugin_is_valid_share_code( $share_code ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $exclude;
|
||||||
|
} );
|
||||||
|
```
|
||||||
|
|
||||||
|
### Extend "Apply to store pages only" setting
|
||||||
|
|
||||||
|
When using the `Apply to store pages only` setting, you may want to add a custom page to the list of store pages which will be restricted by coming soon mode. You can use the following example to add a custom page:
|
||||||
|
|
||||||
|
```php
|
||||||
|
add_filter( 'woocommerce_store_pages', function( $pages ) {
|
||||||
|
$page = get_page_by_path( 'your-page-slug' );
|
||||||
|
if ( $page ) {
|
||||||
|
$pages[] = $page->ID;
|
||||||
|
}
|
||||||
|
return $pages;
|
||||||
|
} );
|
||||||
|
```
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Update storybook file format in support with Storybook 7 story indexer.
|
|
@ -132,18 +132,10 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.23.5",
|
"@babel/core": "^7.23.5",
|
||||||
"@babel/runtime": "^7.23.5",
|
"@babel/runtime": "^7.23.5",
|
||||||
"@storybook/addon-actions": "6.5.17-alpha.0",
|
|
||||||
"@storybook/addon-console": "^1.2.3",
|
"@storybook/addon-console": "^1.2.3",
|
||||||
"@storybook/addon-controls": "6.5.17-alpha.0",
|
"@storybook/addon-docs": "7.6.19",
|
||||||
"@storybook/addon-docs": "6.5.17-alpha.0",
|
"@storybook/addon-links": "7.6.19",
|
||||||
"@storybook/addon-knobs": "^6.4.0",
|
|
||||||
"@storybook/addon-links": "6.5.17-alpha.0",
|
|
||||||
"@storybook/addons": "6.5.17-alpha.0",
|
|
||||||
"@storybook/api": "6.5.17-alpha.0",
|
|
||||||
"@storybook/components": "6.5.17-alpha.0",
|
|
||||||
"@storybook/core-events": "6.5.17-alpha.0",
|
|
||||||
"@storybook/react": "6.5.17-alpha.0",
|
"@storybook/react": "6.5.17-alpha.0",
|
||||||
"@storybook/theming": "6.5.17-alpha.0",
|
|
||||||
"@testing-library/dom": "8.11.3",
|
"@testing-library/dom": "8.11.3",
|
||||||
"@testing-library/jest-dom": "5.16.2",
|
"@testing-library/jest-dom": "5.16.2",
|
||||||
"@testing-library/react": "12.1.3",
|
"@testing-library/react": "12.1.3",
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { createElement } from '@wordpress/element';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { Basic } from '../stories/index';
|
import { Basic } from '../stories/compare-filter.story';
|
||||||
import { CompareFilter } from '../index';
|
import { CompareFilter } from '../index';
|
||||||
import Search from '../../search';
|
import Search from '../../search';
|
||||||
import productAutocompleter from '../../search/autocompleters/product';
|
import productAutocompleter from '../../search/autocompleters/product';
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { createElement } from '@wordpress/element';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { Basic } from '../stories/index';
|
import { Basic } from '../stories/filter-picker.story';
|
||||||
import FilterPicker from '../index';
|
import FilterPicker from '../index';
|
||||||
import Search from '../../search';
|
import Search from '../../search';
|
||||||
import productAutocompleter from '../../search/autocompleters/product';
|
import productAutocompleter from '../../search/autocompleters/product';
|
||||||
|
|
|
@ -8,7 +8,7 @@ import React from 'react';
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { ImageGallery, ImageGalleryItem } from '../';
|
import { ImageGallery, ImageGalleryItem } from '../';
|
||||||
import { MockMediaUpload } from '../../media-uploader/stories/index.tsx';
|
import { MockMediaUpload } from '../../media-uploader/stories/mock-media-uploader';
|
||||||
|
|
||||||
export const Basic: React.FC = () => {
|
export const Basic: React.FC = () => {
|
||||||
return (
|
return (
|
|
@ -2,7 +2,7 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import React, { createElement } from 'react';
|
import React, { createElement } from 'react';
|
||||||
import { Modal, Notice } from '@wordpress/components';
|
import { Notice } from '@wordpress/components';
|
||||||
import { MediaItem } from '@wordpress/media-utils';
|
import { MediaItem } from '@wordpress/media-utils';
|
||||||
import { useState } from '@wordpress/element';
|
import { useState } from '@wordpress/element';
|
||||||
import { cloudUpload } from '@wordpress/icons';
|
import { cloudUpload } from '@wordpress/icons';
|
||||||
|
@ -12,59 +12,7 @@ import { cloudUpload } from '@wordpress/icons';
|
||||||
*/
|
*/
|
||||||
import { MediaUploader } from '../';
|
import { MediaUploader } from '../';
|
||||||
import { File } from '../types';
|
import { File } from '../types';
|
||||||
|
import { MockMediaUpload } from './mock-media-uploader';
|
||||||
const MockMediaUpload = ( { onSelect, render } ) => {
|
|
||||||
const [ isOpen, setOpen ] = useState( false );
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{ render( {
|
|
||||||
open: () => setOpen( true ),
|
|
||||||
} ) }
|
|
||||||
{ isOpen && (
|
|
||||||
<Modal
|
|
||||||
title="Media Modal"
|
|
||||||
onRequestClose={ ( event ) => {
|
|
||||||
setOpen( false );
|
|
||||||
event.stopPropagation();
|
|
||||||
} }
|
|
||||||
>
|
|
||||||
<p>
|
|
||||||
Use the default built-in{ ' ' }
|
|
||||||
<code>MediaUploadComponent</code> prop to render the WP
|
|
||||||
Media Modal.
|
|
||||||
</p>
|
|
||||||
{ Array( ...Array( 3 ) ).map( ( n, i ) => {
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
key={ i }
|
|
||||||
onClick={ ( event ) => {
|
|
||||||
onSelect( {
|
|
||||||
alt: 'Random',
|
|
||||||
url: `https://picsum.photos/200?i=${ i }`,
|
|
||||||
} );
|
|
||||||
setOpen( false );
|
|
||||||
event.stopPropagation();
|
|
||||||
} }
|
|
||||||
style={ {
|
|
||||||
marginRight: '16px',
|
|
||||||
} }
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src={ `https://picsum.photos/200?i=${ i }` }
|
|
||||||
alt="Random"
|
|
||||||
style={ {
|
|
||||||
maxWidth: '100px',
|
|
||||||
} }
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
} ) }
|
|
||||||
</Modal>
|
|
||||||
) }
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const ImageGallery = ( { images }: { images: File[] } ) => {
|
const ImageGallery = ( { images }: { images: File[] } ) => {
|
||||||
return (
|
return (
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import React, { createElement } from 'react';
|
||||||
|
import { Modal } from '@wordpress/components';
|
||||||
|
import { useState } from '@wordpress/element';
|
||||||
|
|
||||||
|
export const MockMediaUpload = ( { onSelect, render } ) => {
|
||||||
|
const [ isOpen, setOpen ] = useState( false );
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{ render( {
|
||||||
|
open: () => setOpen( true ),
|
||||||
|
} ) }
|
||||||
|
{ isOpen && (
|
||||||
|
<Modal
|
||||||
|
title="Media Modal"
|
||||||
|
onRequestClose={ ( event ) => {
|
||||||
|
setOpen( false );
|
||||||
|
event.stopPropagation();
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
Use the default built-in{ ' ' }
|
||||||
|
<code>MediaUploadComponent</code> prop to render the WP
|
||||||
|
Media Modal.
|
||||||
|
</p>
|
||||||
|
{ Array( ...Array( 3 ) ).map( ( n, i ) => {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={ i }
|
||||||
|
onClick={ ( event ) => {
|
||||||
|
onSelect( {
|
||||||
|
alt: 'Random',
|
||||||
|
url: `https://picsum.photos/200?i=${ i }`,
|
||||||
|
} );
|
||||||
|
setOpen( false );
|
||||||
|
event.stopPropagation();
|
||||||
|
} }
|
||||||
|
style={ {
|
||||||
|
marginRight: '16px',
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={ `https://picsum.photos/200?i=${ i }` }
|
||||||
|
alt="Random"
|
||||||
|
style={ {
|
||||||
|
maxWidth: '100px',
|
||||||
|
} }
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
} ) }
|
||||||
|
</Modal>
|
||||||
|
) }
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -11,7 +11,12 @@ import {
|
||||||
} from '@wordpress/element';
|
} from '@wordpress/element';
|
||||||
import { SyntheticEvent, useCallback } from 'react';
|
import { SyntheticEvent, useCallback } from 'react';
|
||||||
import { useDispatch, useSelect } from '@wordpress/data';
|
import { useDispatch, useSelect } from '@wordpress/data';
|
||||||
import { PLUGINS_STORE_NAME, InstallPluginsResponse } from '@woocommerce/data';
|
import { PLUGINS_STORE_NAME } from '@woocommerce/data';
|
||||||
|
import type {
|
||||||
|
InstallPluginsResponse,
|
||||||
|
PluginSelectors,
|
||||||
|
PluginActions,
|
||||||
|
} from '@woocommerce/data';
|
||||||
|
|
||||||
type PluginsProps = {
|
type PluginsProps = {
|
||||||
onComplete: (
|
onComplete: (
|
||||||
|
@ -52,10 +57,14 @@ export const Plugins = ( {
|
||||||
const [ hasErrors, setHasErrors ] = useState( false );
|
const [ hasErrors, setHasErrors ] = useState( false );
|
||||||
// Tracks action so that multiple instances of this button don't all light up when one is clicked
|
// Tracks action so that multiple instances of this button don't all light up when one is clicked
|
||||||
const [ hasBeenClicked, setHasBeenClicked ] = useState( false );
|
const [ hasBeenClicked, setHasBeenClicked ] = useState( false );
|
||||||
const { installAndActivatePlugins } = useDispatch( PLUGINS_STORE_NAME );
|
const { installAndActivatePlugins }: PluginActions =
|
||||||
|
useDispatch( PLUGINS_STORE_NAME );
|
||||||
const { isRequesting } = useSelect( ( select ) => {
|
const { isRequesting } = useSelect( ( select ) => {
|
||||||
const { getActivePlugins, getInstalledPlugins, isPluginsRequesting } =
|
const {
|
||||||
select( PLUGINS_STORE_NAME );
|
getActivePlugins,
|
||||||
|
getInstalledPlugins,
|
||||||
|
isPluginsRequesting,
|
||||||
|
}: PluginSelectors = select( PLUGINS_STORE_NAME );
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isRequesting:
|
isRequesting:
|
||||||
|
@ -64,7 +73,7 @@ export const Plugins = ( {
|
||||||
activePlugins: getActivePlugins(),
|
activePlugins: getActivePlugins(),
|
||||||
installedPlugins: getInstalledPlugins(),
|
installedPlugins: getInstalledPlugins(),
|
||||||
};
|
};
|
||||||
} );
|
}, [] );
|
||||||
|
|
||||||
const handleErrors = useCallback(
|
const handleErrors = useCallback(
|
||||||
( errors: unknown, response: InstallPluginsResponse ) => {
|
( errors: unknown, response: InstallPluginsResponse ) => {
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { useDispatch } from '@wordpress/data';
|
||||||
import { Plugins } from '../index';
|
import { Plugins } from '../index';
|
||||||
|
|
||||||
jest.mock( '@wordpress/data', () => ( {
|
jest.mock( '@wordpress/data', () => ( {
|
||||||
...jest.requireActual( '@wordpress/data' ),
|
__esModule: true,
|
||||||
useDispatch: jest
|
useDispatch: jest
|
||||||
.fn()
|
.fn()
|
||||||
.mockReturnValue( { installAndActivatePlugins: jest.fn() } ),
|
.mockReturnValue( { installAndActivatePlugins: jest.fn() } ),
|
||||||
|
|
|
@ -12,7 +12,6 @@ import * as actions from './actions';
|
||||||
import { STORE_NAME } from './constants';
|
import { STORE_NAME } from './constants';
|
||||||
|
|
||||||
export const store = createReduxStore( STORE_NAME, {
|
export const store = createReduxStore( STORE_NAME, {
|
||||||
// @ts-expect-error reducer has correct format.
|
|
||||||
reducer,
|
reducer,
|
||||||
selectors,
|
selectors,
|
||||||
actions,
|
actions,
|
||||||
|
|
|
@ -8,6 +8,7 @@ export type ProductFieldDefinition = {
|
||||||
type?: HTMLInputTypeAttribute;
|
type?: HTMLInputTypeAttribute;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
render?: ComponentType;
|
render?: ComponentType;
|
||||||
|
attributes?: Record< string, string >;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ProductFieldState = {
|
export type ProductFieldState = {
|
||||||
|
|
|
@ -43,7 +43,7 @@ export const EditorWritingFlow = ( {
|
||||||
editorMode: __unstableGetEditorMode(),
|
editorMode: __unstableGetEditorMode(),
|
||||||
selectedBlockClientIds: getSelectedBlockClientIds(),
|
selectedBlockClientIds: getSelectedBlockClientIds(),
|
||||||
};
|
};
|
||||||
} );
|
}, [] );
|
||||||
|
|
||||||
// This is a workaround to prevent focusing the block on initialization.
|
// This is a workaround to prevent focusing the block on initialization.
|
||||||
// Changing to a mode other than "edit" ensures that no initial position
|
// Changing to a mode other than "edit" ensures that no initial position
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { date, text } from '@storybook/addon-knobs';
|
|
||||||
import GridIcon from 'gridicons';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import Timeline, { orderByOptions } from '../';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'WooCommerce Admin/components/Timeline',
|
|
||||||
component: Timeline,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Empty = () => <Timeline />;
|
|
||||||
|
|
||||||
const itemDate = ( label, value ) => {
|
|
||||||
const d = date( label, value );
|
|
||||||
return new Date( d );
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Filled = () => (
|
|
||||||
<Timeline
|
|
||||||
orderBy={ orderByOptions.DESC }
|
|
||||||
items={ [
|
|
||||||
{
|
|
||||||
date: itemDate(
|
|
||||||
'event 1 date',
|
|
||||||
new Date( 2020, 0, 20, 1, 30 )
|
|
||||||
),
|
|
||||||
body: [
|
|
||||||
<p key={ '1' }>
|
|
||||||
{ text( 'event 1, first event', 'p element in body' ) }
|
|
||||||
</p>,
|
|
||||||
text( 'event 1, second event', 'string in body' ),
|
|
||||||
],
|
|
||||||
headline: (
|
|
||||||
<p>{ text( 'event 1, headline', 'p tag in headline' ) }</p>
|
|
||||||
),
|
|
||||||
icon: (
|
|
||||||
<GridIcon
|
|
||||||
className={ 'is-success' }
|
|
||||||
icon={ text( 'event 1 gridicon', 'checkmark' ) }
|
|
||||||
size={ 16 }
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
hideTimestamp: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
date: itemDate(
|
|
||||||
'event 2 date',
|
|
||||||
new Date( 2020, 0, 20, 23, 45 )
|
|
||||||
),
|
|
||||||
body: [],
|
|
||||||
headline: (
|
|
||||||
<span>
|
|
||||||
{ text( 'event 2, headline', 'span in headline' ) }
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
icon: (
|
|
||||||
<GridIcon
|
|
||||||
className={ 'is-warning' }
|
|
||||||
icon={ text( 'event 2 gridicon', 'refresh' ) }
|
|
||||||
size={ 16 }
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
date: itemDate(
|
|
||||||
'event 3 date',
|
|
||||||
new Date( 2020, 0, 22, 15, 13 )
|
|
||||||
),
|
|
||||||
body: [
|
|
||||||
<span key={ '1' }>
|
|
||||||
{ text( 'event 3, second event', 'span in body' ) }
|
|
||||||
</span>,
|
|
||||||
],
|
|
||||||
headline: text( 'event 3, headline', 'string in headline' ),
|
|
||||||
icon: (
|
|
||||||
<GridIcon
|
|
||||||
className={ 'is-error' }
|
|
||||||
icon={ text( 'event 3 gridicon', 'cross' ) }
|
|
||||||
size={ 16 }
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
date: itemDate(
|
|
||||||
'event 4 date',
|
|
||||||
new Date( 2020, 0, 17, 1, 45 )
|
|
||||||
),
|
|
||||||
headline: text(
|
|
||||||
'event 4, headline',
|
|
||||||
'undefined body and string headline'
|
|
||||||
),
|
|
||||||
icon: (
|
|
||||||
<GridIcon
|
|
||||||
icon={ text( 'event 4 gridicon', 'cross' ) }
|
|
||||||
size={ 16 }
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
] }
|
|
||||||
/>
|
|
||||||
);
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import GridIcon from 'gridicons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import Timeline, { orderByOptions } from '../';
|
||||||
|
|
||||||
|
export const Filled = () => {
|
||||||
|
return (
|
||||||
|
<Timeline
|
||||||
|
orderBy={ orderByOptions.DESC }
|
||||||
|
items={ [
|
||||||
|
{
|
||||||
|
date: new Date( 2020, 0, 20, 1, 30 ),
|
||||||
|
body: [
|
||||||
|
<p key="1">p element in body</p>,
|
||||||
|
'string in body',
|
||||||
|
],
|
||||||
|
headline: <p>p tag in headline</p>,
|
||||||
|
icon: (
|
||||||
|
<GridIcon
|
||||||
|
className="is-success"
|
||||||
|
icon="checkmark"
|
||||||
|
size={ 16 }
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
hideTimestamp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date( 2020, 0, 20, 23, 45 ),
|
||||||
|
body: [],
|
||||||
|
headline: <span>span in headline</span>,
|
||||||
|
icon: (
|
||||||
|
<GridIcon
|
||||||
|
className={ 'is-warning' }
|
||||||
|
icon="refresh"
|
||||||
|
size={ 16 }
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date( 2020, 0, 22, 15, 13 ),
|
||||||
|
body: [ <span key="1">span in body</span> ],
|
||||||
|
headline: 'string in headline',
|
||||||
|
icon: (
|
||||||
|
<GridIcon
|
||||||
|
className={ 'is-error' }
|
||||||
|
icon="cross"
|
||||||
|
size={ 16 }
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date( 2020, 0, 17, 1, 45 ),
|
||||||
|
headline: 'undefined body and string headline',
|
||||||
|
icon: <GridIcon icon="cross" size={ 16 } />,
|
||||||
|
},
|
||||||
|
] }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'WooCommerce Admin/components/Timeline',
|
||||||
|
component: Filled,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Empty = () => <Timeline />;
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Add wooPaymentsIncentiveId to the TaskType additionalData.
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Export plugin related data store types for selectors and actions.
|
|
@ -85,6 +85,8 @@ export {
|
||||||
} from './product-form/types';
|
} from './product-form/types';
|
||||||
export * from './onboarding/types';
|
export * from './onboarding/types';
|
||||||
export * from './plugins/types';
|
export * from './plugins/types';
|
||||||
|
export { PluginSelectors } from './plugins/selectors';
|
||||||
|
export { ActionDispatchers as PluginActions } from './plugins/actions';
|
||||||
export * from './products/types';
|
export * from './products/types';
|
||||||
export type {
|
export type {
|
||||||
PartialProductVariation,
|
PartialProductVariation,
|
||||||
|
|
|
@ -35,6 +35,7 @@ export type TaskType = {
|
||||||
stripeTaxActivated?: boolean;
|
stripeTaxActivated?: boolean;
|
||||||
woocommerceTaxActivated?: boolean;
|
woocommerceTaxActivated?: boolean;
|
||||||
woocommerceShippingActivated?: boolean;
|
woocommerceShippingActivated?: boolean;
|
||||||
|
wooPaymentsIncentiveId?: string;
|
||||||
};
|
};
|
||||||
// Possibly added in DeprecatedTasks.mergeDeprecatedCallbackFunctions
|
// Possibly added in DeprecatedTasks.mergeDeprecatedCallbackFunctions
|
||||||
isDeprecated?: boolean;
|
isDeprecated?: boolean;
|
||||||
|
|
|
@ -12,7 +12,8 @@ npm install @woocommerce/e2e-utils --save
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
~~~js
|
|
||||||
|
```js
|
||||||
import {
|
import {
|
||||||
shopper,
|
shopper,
|
||||||
merchant,
|
merchant,
|
||||||
|
@ -29,7 +30,7 @@ describe( 'Cart page', () => {
|
||||||
await expect( page ).toMatchElement( '.cart-empty', { text: 'Your cart is currently empty.' } );
|
await expect( page ).toMatchElement( '.cart-empty', { text: 'Your cart is currently empty.' } );
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
~~~
|
```
|
||||||
|
|
||||||
### Retries
|
### Retries
|
||||||
|
|
||||||
|
@ -86,7 +87,6 @@ This package provides support for enabling retries in tests:
|
||||||
|----------|-------------|------------|
|
|----------|-------------|------------|
|
||||||
| `addDownloadableProductPermission` | `productName` | Add a downloadable permission for product in order |
|
| `addDownloadableProductPermission` | `productName` | Add a downloadable permission for product in order |
|
||||||
| `collapseAdminMenu` | `collapse` | Collapse or expand the WP admin menu |
|
| `collapseAdminMenu` | `collapse` | Collapse or expand the WP admin menu |
|
||||||
| `dismissOnboardingWizard` | | Dismiss the onboarding wizard if present |
|
|
||||||
| `goToOrder` | `orderId` | Go to view a single order |
|
| `goToOrder` | `orderId` | Go to view a single order |
|
||||||
| `goToProduct` | `productId` | Go to view a single product |
|
| `goToProduct` | `productId` | Go to view a single product |
|
||||||
| `login` | | Log in as merchant |
|
| `login` | | Log in as merchant |
|
||||||
|
@ -100,7 +100,6 @@ This package provides support for enabling retries in tests:
|
||||||
| `openPermalinkSettings` | | Go to Settings -> Permalinks |
|
| `openPermalinkSettings` | | Go to Settings -> Permalinks |
|
||||||
| `openPlugins` | | Go to the Plugins screen |
|
| `openPlugins` | | Go to the Plugins screen |
|
||||||
| `openSettings` | | Go to WooCommerce -> Settings |
|
| `openSettings` | | Go to WooCommerce -> Settings |
|
||||||
| `runSetupWizard` | | Open the onboarding profiler |
|
|
||||||
| `updateOrderStatus` | `orderId, status` | Update the status of an order |
|
| `updateOrderStatus` | `orderId, status` | Update the status of an order |
|
||||||
| `openEmailLog` | | Open the WP Mail Log page |
|
| `openEmailLog` | | Open the WP Mail Log page |
|
||||||
| `openAnalyticsPage` | | Open any Analytics page |
|
| `openAnalyticsPage` | | Open any Analytics page |
|
||||||
|
@ -210,7 +209,6 @@ There is a general utilities object `utils` with the following functions:
|
||||||
| `clickFilter` | `selector` | helper method that clicks on a list page filter |
|
| `clickFilter` | `selector` | helper method that clicks on a list page filter |
|
||||||
| `clickTab` | `tabName` | Click on a WooCommerce -> Settings tab |
|
| `clickTab` | `tabName` | Click on a WooCommerce -> Settings tab |
|
||||||
| `clickUpdateOrder` | `noticeText`, `waitForSave` | Helper method to click the Update button on the order details page |
|
| `clickUpdateOrder` | `noticeText`, `waitForSave` | Helper method to click the Update button on the order details page |
|
||||||
| `completeOnboardingWizard` | | completes the onboarding wizard with some default settings |
|
|
||||||
| `createCoupon` | `couponAmount`, `couponType` | creates a basic coupon. Default amount is 5. Default coupon type is fixed discount. Returns the generated coupon code. |
|
| `createCoupon` | `couponAmount`, `couponType` | creates a basic coupon. Default amount is 5. Default coupon type is fixed discount. Returns the generated coupon code. |
|
||||||
| `createGroupedProduct` | | creates a grouped product for the grouped product tests. Returns the product id. |
|
| `createGroupedProduct` | | creates a grouped product for the grouped product tests. Returns the product id. |
|
||||||
| `createSimpleDownloadableProduct` | `name, downloadLimit, downloadName, price` | Create a simple downloadable product |
|
| `createSimpleDownloadableProduct` | `name, downloadLimit, downloadName, price` | Create a simple downloadable product |
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: dev
|
||||||
|
|
||||||
|
Remove Profile Wizard releated utils
|
|
@ -60,151 +60,6 @@ const waitAndClickPrimary = async ( waitForNetworkIdle = true ) => {
|
||||||
await page.waitForNavigation( { waitUntil: 'networkidle0' } );
|
await page.waitForNavigation( { waitUntil: 'networkidle0' } );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/**
|
|
||||||
* Complete onboarding wizard.
|
|
||||||
*/
|
|
||||||
const completeOnboardingWizard = async () => {
|
|
||||||
// Store Details section
|
|
||||||
await merchant.runSetupWizard();
|
|
||||||
|
|
||||||
// Fill store's address - first line
|
|
||||||
await expect( page ).toFill(
|
|
||||||
'#inspector-text-control-0',
|
|
||||||
config.get( 'addresses.admin.store.addressfirstline' )
|
|
||||||
);
|
|
||||||
|
|
||||||
// Fill store's address - second line
|
|
||||||
await expect( page ).toFill(
|
|
||||||
'#inspector-text-control-1',
|
|
||||||
config.get( 'addresses.admin.store.addresssecondline' )
|
|
||||||
);
|
|
||||||
|
|
||||||
// Fill country and state where the store is located
|
|
||||||
await expect( page ).toFill(
|
|
||||||
'.woocommerce-select-control__control-input',
|
|
||||||
config.get( 'addresses.admin.store.countryandstate' )
|
|
||||||
);
|
|
||||||
|
|
||||||
// Fill the city where the store is located
|
|
||||||
await expect( page ).toFill(
|
|
||||||
'#inspector-text-control-2',
|
|
||||||
config.get( 'addresses.admin.store.city' )
|
|
||||||
);
|
|
||||||
|
|
||||||
// Fill postcode of the store
|
|
||||||
await expect( page ).toFill(
|
|
||||||
'#inspector-text-control-3',
|
|
||||||
config.get( 'addresses.admin.store.postcode' )
|
|
||||||
);
|
|
||||||
|
|
||||||
// Verify that checkbox next to "I'm setting up a store for a client" is not selected
|
|
||||||
await verifyCheckboxIsUnset( '.components-checkbox-control__input' );
|
|
||||||
|
|
||||||
// Wait for "Continue" button to become active
|
|
||||||
await page.waitForSelector( 'button.is-primary:not(:disabled)' );
|
|
||||||
|
|
||||||
// Click on "Continue" button to move to the next step
|
|
||||||
await page.click( 'button.is-primary', { text: 'Continue' } );
|
|
||||||
|
|
||||||
// Wait for usage tracking pop-up window to appear on a new site
|
|
||||||
const usageTrackingHeader = await page.$(
|
|
||||||
'.components-modal__header-heading'
|
|
||||||
);
|
|
||||||
if ( usageTrackingHeader ) {
|
|
||||||
await expect( page ).toMatchElement(
|
|
||||||
'.components-modal__header-heading',
|
|
||||||
{
|
|
||||||
text: 'Build a better WooCommerce',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Query for "No Thanks" buttons
|
|
||||||
const continueButtons = await page.$$(
|
|
||||||
'.woocommerce-usage-modal__actions button.is-secondary'
|
|
||||||
);
|
|
||||||
expect( continueButtons ).toHaveLength( 1 );
|
|
||||||
|
|
||||||
await continueButtons[ 0 ].click();
|
|
||||||
await expect( page ).toMatchElement(
|
|
||||||
'.woocommerce-usage-modal__actions button.is-secondary.is-busy'
|
|
||||||
);
|
|
||||||
await expect( page ).not.toMatchElement(
|
|
||||||
'.woocommerce-usage-modal__actions button.is-primary:disabled'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
await page.waitForNavigation( { waitUntil: 'networkidle0' } );
|
|
||||||
|
|
||||||
// Industry section
|
|
||||||
|
|
||||||
// Query for the industries checkboxes
|
|
||||||
const industryCheckboxes = await page.$$(
|
|
||||||
'.components-checkbox-control__input'
|
|
||||||
);
|
|
||||||
expect( industryCheckboxes ).toHaveLength( 8 );
|
|
||||||
|
|
||||||
// Select all industries including "Other"
|
|
||||||
for ( let i = 0; i < 8; i++ ) {
|
|
||||||
await industryCheckboxes[ i ].click();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill "Other" industry
|
|
||||||
await expect( page ).toFill(
|
|
||||||
'.components-text-control__input',
|
|
||||||
config.get( 'onboardingwizard.industry' )
|
|
||||||
);
|
|
||||||
|
|
||||||
// Wait for "Continue" button to become active
|
|
||||||
await waitAndClickPrimary();
|
|
||||||
|
|
||||||
// Product types section
|
|
||||||
|
|
||||||
// Query for the product types checkboxes
|
|
||||||
const productTypesCheckboxes = await page.$$(
|
|
||||||
'.components-checkbox-control__input'
|
|
||||||
);
|
|
||||||
expect( productTypesCheckboxes ).toHaveLength( 7 );
|
|
||||||
|
|
||||||
// Select Physical and Downloadable products
|
|
||||||
for ( let i = 1; i < 2; i++ ) {
|
|
||||||
await productTypesCheckboxes[ i ].click();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for "Continue" button to become active
|
|
||||||
await waitAndClickPrimary();
|
|
||||||
|
|
||||||
// Business Details section
|
|
||||||
|
|
||||||
// Temporarily add delay to reduce test flakiness
|
|
||||||
await page.waitFor( 2000 );
|
|
||||||
|
|
||||||
// Query for the <SelectControl>s
|
|
||||||
const selectControls = await page.$$( '.woocommerce-select-control' );
|
|
||||||
expect( selectControls ).toHaveLength( 2 );
|
|
||||||
|
|
||||||
// Fill the number of products you plan to sell
|
|
||||||
await selectControls[ 0 ].click();
|
|
||||||
await page.waitForSelector( '.woocommerce-select-control__control' );
|
|
||||||
await expect( page ).toClick( '.woocommerce-select-control__option', {
|
|
||||||
text: config.get( 'onboardingwizard.numberofproducts' ),
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Fill currently selling elsewhere
|
|
||||||
await selectControls[ 1 ].click();
|
|
||||||
await page.waitForSelector( '.woocommerce-select-control__control' );
|
|
||||||
await expect( page ).toClick( '.woocommerce-select-control__option', {
|
|
||||||
text: config.get( 'onboardingwizard.sellingelsewhere' ),
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Wait for "Continue" button to become active
|
|
||||||
await waitAndClickPrimary( false );
|
|
||||||
|
|
||||||
// Skip installing extensions
|
|
||||||
await unsetCheckbox( '.components-checkbox-control__input' );
|
|
||||||
await verifyCheckboxIsUnset( '.components-checkbox-control__input' );
|
|
||||||
await waitAndClickPrimary();
|
|
||||||
|
|
||||||
// End of onboarding wizard
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create simple product.
|
* Create simple product.
|
||||||
|
@ -668,7 +523,6 @@ const deleteAllShippingZones = async () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
completeOnboardingWizard,
|
|
||||||
createSimpleProduct,
|
createSimpleProduct,
|
||||||
createVariableProduct,
|
createVariableProduct,
|
||||||
createGroupedProduct,
|
createGroupedProduct,
|
||||||
|
|
|
@ -31,8 +31,6 @@ const {
|
||||||
WP_ADMIN_NEW_PRODUCT,
|
WP_ADMIN_NEW_PRODUCT,
|
||||||
WP_ADMIN_PERMALINK_SETTINGS,
|
WP_ADMIN_PERMALINK_SETTINGS,
|
||||||
WP_ADMIN_PLUGINS,
|
WP_ADMIN_PLUGINS,
|
||||||
WP_ADMIN_SETUP_WIZARD,
|
|
||||||
WP_ADMIN_WC_HOME,
|
|
||||||
WP_ADMIN_WC_SETTINGS,
|
WP_ADMIN_WC_SETTINGS,
|
||||||
WP_ADMIN_WC_EXTENSIONS,
|
WP_ADMIN_WC_EXTENSIONS,
|
||||||
WP_ADMIN_WC_HELPER,
|
WP_ADMIN_WC_HELPER,
|
||||||
|
@ -42,7 +40,6 @@ const {
|
||||||
WP_ADMIN_IMPORT_PRODUCTS,
|
WP_ADMIN_IMPORT_PRODUCTS,
|
||||||
WP_ADMIN_PLUGIN_INSTALL,
|
WP_ADMIN_PLUGIN_INSTALL,
|
||||||
WP_ADMIN_WP_UPDATES,
|
WP_ADMIN_WP_UPDATES,
|
||||||
IS_RETEST_MODE,
|
|
||||||
} = require( './constants' );
|
} = require( './constants' );
|
||||||
|
|
||||||
const { getSlug, waitForTimeout } = require( './utils' );
|
const { getSlug, waitForTimeout } = require( './utils' );
|
||||||
|
@ -83,7 +80,6 @@ const merchant = {
|
||||||
await Promise.all( [
|
await Promise.all( [
|
||||||
page.click( 'input[type=submit]' ),
|
page.click( 'input[type=submit]' ),
|
||||||
page.waitForNavigation( { waitUntil: 'networkidle0' } ),
|
page.waitForNavigation( { waitUntil: 'networkidle0' } ),
|
||||||
merchant.dismissOnboardingWizard(),
|
|
||||||
] );
|
] );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -173,15 +169,6 @@ const merchant = {
|
||||||
} );
|
} );
|
||||||
},
|
},
|
||||||
|
|
||||||
runSetupWizard: async () => {
|
|
||||||
const setupWizard = IS_RETEST_MODE
|
|
||||||
? WP_ADMIN_SETUP_WIZARD
|
|
||||||
: WP_ADMIN_WC_HOME;
|
|
||||||
await page.goto( setupWizard, {
|
|
||||||
waitUntil: 'networkidle0',
|
|
||||||
} );
|
|
||||||
},
|
|
||||||
|
|
||||||
goToOrder: async ( orderId ) => {
|
goToOrder: async ( orderId ) => {
|
||||||
await page.goto( WP_ADMIN_SINGLE_CPT_VIEW( orderId ), {
|
await page.goto( WP_ADMIN_SINGLE_CPT_VIEW( orderId ), {
|
||||||
waitUntil: 'networkidle0',
|
waitUntil: 'networkidle0',
|
||||||
|
@ -290,9 +277,10 @@ const merchant = {
|
||||||
|
|
||||||
revokeDownloadableProductPermission: async ( productName ) => {
|
revokeDownloadableProductPermission: async ( productName ) => {
|
||||||
// Revoke downloadable product permission
|
// Revoke downloadable product permission
|
||||||
const permission = await expect(
|
const permission = await expect( page ).toMatchElement(
|
||||||
page
|
'div.wc-metabox > h3',
|
||||||
).toMatchElement( 'div.wc-metabox > h3', { text: productName } );
|
{ text: productName }
|
||||||
|
);
|
||||||
await expect( permission ).toClick( 'button.revoke_access' );
|
await expect( permission ).toClick( 'button.revoke_access' );
|
||||||
|
|
||||||
// Wait for auto save
|
// Wait for auto save
|
||||||
|
@ -625,10 +613,10 @@ const merchant = {
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Uploads and activates a plugin located at the provided file path. This will also deactivate and delete the plugin if it exists.
|
/* Uploads and activates a plugin located at the provided file path. This will also deactivate and delete the plugin if it exists.
|
||||||
*
|
*
|
||||||
* @param {string} pluginFilePath The location of the plugin zip file to upload.
|
* @param {string} pluginFilePath The location of the plugin zip file to upload.
|
||||||
* @param {string} pluginName The name of the plugin. For example, `WooCommerce`.
|
* @param {string} pluginName The name of the plugin. For example, `WooCommerce`.
|
||||||
*/
|
*/
|
||||||
uploadAndActivatePlugin: async ( pluginFilePath, pluginName ) => {
|
uploadAndActivatePlugin: async ( pluginFilePath, pluginName ) => {
|
||||||
await merchant.openPlugins();
|
await merchant.openPlugins();
|
||||||
|
|
||||||
|
@ -647,8 +635,7 @@ const merchant = {
|
||||||
await page.click( 'a.upload-view-toggle' );
|
await page.click( 'a.upload-view-toggle' );
|
||||||
|
|
||||||
await expect( page ).toMatchElement( 'p.install-help', {
|
await expect( page ).toMatchElement( 'p.install-help', {
|
||||||
text:
|
text: 'If you have a plugin in a .zip format, you may install or update it by uploading it here.',
|
||||||
'If you have a plugin in a .zip format, you may install or update it by uploading it here.',
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
const uploader = await page.$( 'input[type=file]' );
|
const uploader = await page.$( 'input[type=file]' );
|
||||||
|
@ -753,33 +740,6 @@ const merchant = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Dismiss the onboarding wizard if it is open.
|
|
||||||
*/
|
|
||||||
dismissOnboardingWizard: async () => {
|
|
||||||
let waitForNav = false;
|
|
||||||
const skipButton = await page.$(
|
|
||||||
'.woocommerce-profile-wizard__footer-link'
|
|
||||||
);
|
|
||||||
if ( skipButton ) {
|
|
||||||
await skipButton.click();
|
|
||||||
waitForNav = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dismiss usage tracking pop-up window if it appears on a new site
|
|
||||||
const usageTrackingHeader = await page.$(
|
|
||||||
'.woocommerce-usage-modal button.is-secondary'
|
|
||||||
);
|
|
||||||
if ( usageTrackingHeader ) {
|
|
||||||
await usageTrackingHeader.click();
|
|
||||||
waitForNav = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( waitForNav ) {
|
|
||||||
await page.waitForNavigation( { waitUntil: 'networkidle0' } );
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand or collapse the WP admin menu.
|
* Expand or collapse the WP admin menu.
|
||||||
*
|
*
|
||||||
|
|
|
@ -172,11 +172,6 @@ const StoreOwnerFlow = {
|
||||||
StoreOwnerFlowDeprecated();
|
StoreOwnerFlowDeprecated();
|
||||||
await merchant.openSettings( tab, section );
|
await merchant.openSettings( tab, section );
|
||||||
},
|
},
|
||||||
|
|
||||||
runSetupWizard: async () => {
|
|
||||||
StoreOwnerFlowDeprecated();
|
|
||||||
await merchant.runSetupWizard();
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { CustomerFlow, StoreOwnerFlow };
|
export { CustomerFlow, StoreOwnerFlow };
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Update storybook file format in support with Storybook 7 story indexer.
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Update storybook file format in support with Storybook 7 story indexer.
|
|
@ -71,7 +71,6 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.23.5",
|
"@babel/core": "^7.23.5",
|
||||||
"@storybook/addon-knobs": "^7.0.2",
|
|
||||||
"@testing-library/react": "12.1.3",
|
"@testing-library/react": "12.1.3",
|
||||||
"@types/jest": "^27.5.2",
|
"@types/jest": "^27.5.2",
|
||||||
"@types/react": "^17.0.71",
|
"@types/react": "^17.0.71",
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Increase specificity of product data views styles to avoid conflicts.
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Update storybook file format in support with Storybook 7 story indexer.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue