Add conditional copy/content and CTA to expanded task items (https://github.com/woocommerce/woocommerce-admin/pull/6956)
* Add action button to TaskItem. * Pass through click event. * Add separate action and label to onClick. * Add initial copy for task expansion. * Expand one task at a time. * Add descriptive text to the payments step. * Set the first incomplete task current by default. * Revert expansion behavior. * Fix margins. * Curate purchase products task content based on selections. * Fix appearance task copy. * Fix payment task copy. * Add conditional tax step title. * Indicated if task is expanded to click handlers. * Automatically enable WC Tax from the expanded CTA. * Restore additional text property. * Fix task title xpath selector in E2E test. * Fix automatic tax setup query param logic. * Add changelog entries.
This commit is contained in:
parent
9fbebae1a6
commit
c23d02bcc0
|
@ -43,6 +43,14 @@ const taskDashboardSelect = ( select ) => {
|
|||
const countryCode = getCountryCode(
|
||||
generalSettings.woocommerce_default_country
|
||||
);
|
||||
const {
|
||||
woocommerce_store_address: storeAddress,
|
||||
woocommerce_default_country: defaultCountry,
|
||||
woocommerce_store_postcode: storePostCode,
|
||||
} = generalSettings;
|
||||
const hasCompleteAddress = Boolean(
|
||||
storeAddress && defaultCountry && storePostCode
|
||||
);
|
||||
|
||||
const activePlugins = getActivePlugins();
|
||||
const installedPlugins = getInstalledPlugins();
|
||||
|
@ -65,6 +73,7 @@ const taskDashboardSelect = ( select ) => {
|
|||
onboardingStatus,
|
||||
profileItems,
|
||||
trackedCompletedTasks,
|
||||
hasCompleteAddress,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -85,6 +94,7 @@ const TaskDashboard = ( { userPreferences, query } ) => {
|
|||
isTaskListComplete,
|
||||
isExtendedTaskListHidden,
|
||||
isExtendedTaskListComplete,
|
||||
hasCompleteAddress,
|
||||
} = useSelect( taskDashboardSelect );
|
||||
|
||||
const [ isCartModalOpen, setIsCartModalOpen ] = useState( false );
|
||||
|
@ -173,6 +183,7 @@ const TaskDashboard = ( { userPreferences, query } ) => {
|
|||
query,
|
||||
toggleCartModal,
|
||||
onTaskSelect,
|
||||
hasCompleteAddress,
|
||||
} );
|
||||
|
||||
const { extension, setup: setupTasks } = allTasks;
|
||||
|
|
|
@ -32,6 +32,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
.woocommerce-task__additional-info,
|
||||
.woocommerce-task__estimated-time,
|
||||
.woocommerce-task-list__item-content {
|
||||
color: $gray-700;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.woocommerce-task-list__item-content {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
#wpbody-content {
|
||||
position: relative;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,21 @@ export const TaskList = ( {
|
|||
possiblyTrackCompletedTasks();
|
||||
}, [ query ] );
|
||||
|
||||
const visibleTasks = tasks.filter(
|
||||
( task ) => task.visible && ! dismissedTasks.includes( task.key )
|
||||
);
|
||||
|
||||
const completedTaskKeys = visibleTasks
|
||||
.filter( ( task ) => task.completed )
|
||||
.map( ( task ) => task.key );
|
||||
|
||||
const incompleteTasks = tasks.filter(
|
||||
( task ) =>
|
||||
task.visible &&
|
||||
! task.completed &&
|
||||
! dismissedTasks.includes( task.key )
|
||||
);
|
||||
|
||||
const possiblyCompleteTaskList = () => {
|
||||
const taskListVariableName = `woocommerce_${ name }_complete`;
|
||||
const taskListToComplete = isComplete
|
||||
|
@ -64,8 +79,8 @@ export const TaskList = ( {
|
|||
}
|
||||
|
||||
if (
|
||||
( ! getIncompleteTasks().length && ! isComplete ) ||
|
||||
( getIncompleteTasks().length && isComplete )
|
||||
( ! incompleteTasks.length && ! isComplete ) ||
|
||||
( incompleteTasks.length && isComplete )
|
||||
) {
|
||||
updateOptions( {
|
||||
...taskListToComplete,
|
||||
|
@ -73,26 +88,11 @@ export const TaskList = ( {
|
|||
}
|
||||
};
|
||||
|
||||
const getCompletedTaskKeys = () => {
|
||||
return getVisibleTasks()
|
||||
.filter( ( task ) => task.completed )
|
||||
.map( ( task ) => task.key );
|
||||
};
|
||||
|
||||
const getIncompleteTasks = () => {
|
||||
return tasks.filter(
|
||||
( task ) =>
|
||||
task.visible &&
|
||||
! task.completed &&
|
||||
! dismissedTasks.includes( task.key )
|
||||
);
|
||||
};
|
||||
|
||||
const getTrackedIncompletedTasks = (
|
||||
partialCompletedTasks,
|
||||
allTrackedTask
|
||||
) => {
|
||||
return getVisibleTasks()
|
||||
return visibleTasks
|
||||
.filter(
|
||||
( task ) =>
|
||||
allTrackedTask.includes( task.key ) &&
|
||||
|
@ -102,7 +102,6 @@ export const TaskList = ( {
|
|||
};
|
||||
|
||||
const possiblyTrackCompletedTasks = () => {
|
||||
const completedTaskKeys = getCompletedTaskKeys();
|
||||
const trackedCompletedTasks = getTrackedCompletedTasks(
|
||||
completedTaskKeys,
|
||||
totalTrackedCompletedTasks
|
||||
|
@ -160,12 +159,6 @@ export const TaskList = ( {
|
|||
} );
|
||||
};
|
||||
|
||||
const getVisibleTasks = () => {
|
||||
return tasks.filter(
|
||||
( task ) => task.visible && ! dismissedTasks.includes( task.key )
|
||||
);
|
||||
};
|
||||
|
||||
const recordTaskListView = () => {
|
||||
if ( query.task ) {
|
||||
return;
|
||||
|
@ -174,8 +167,6 @@ export const TaskList = ( {
|
|||
const isCoreTaskList = name === 'task_list';
|
||||
const taskListName = isCoreTaskList ? 'tasklist' : 'extended_tasklist';
|
||||
|
||||
const visibleTasks = getVisibleTasks();
|
||||
|
||||
recordEvent( `${ taskListName }_view`, {
|
||||
number_tasks: visibleTasks.length,
|
||||
store_connected: profileItems.wccom_connected,
|
||||
|
@ -196,8 +187,8 @@ export const TaskList = ( {
|
|||
|
||||
recordEvent( `${ taskListName }_completed`, {
|
||||
action,
|
||||
completed_task_count: getCompletedTaskKeys().length,
|
||||
incomplete_task_count: getIncompleteTasks().length,
|
||||
completed_task_count: completedTaskKeys.length,
|
||||
incomplete_task_count: incompleteTasks.length,
|
||||
} );
|
||||
updateOptions( {
|
||||
...updateOptionsParams,
|
||||
|
@ -223,7 +214,7 @@ export const TaskList = ( {
|
|||
);
|
||||
};
|
||||
|
||||
const listTasks = getVisibleTasks().map( ( task ) => {
|
||||
const listTasks = visibleTasks.map( ( task ) => {
|
||||
if ( ! task.onClick ) {
|
||||
task.onClick = ( e ) => {
|
||||
if ( e.target.nodeName === 'A' ) {
|
||||
|
@ -277,7 +268,7 @@ export const TaskList = ( {
|
|||
<CardHeader size="medium">
|
||||
<div className="wooocommerce-task-card__header">
|
||||
<Text variant="title.small">{ listTitle }</Text>
|
||||
<Badge count={ getIncompleteTasks().length } />
|
||||
<Badge count={ incompleteTasks.length } />
|
||||
</div>
|
||||
{ renderMenu() }
|
||||
</CardHeader>
|
||||
|
@ -294,6 +285,9 @@ export const TaskList = ( {
|
|||
onDismiss={ () => dismissTask( task ) }
|
||||
time={ task.time }
|
||||
level={ task.level }
|
||||
action={ task.onClick }
|
||||
actionLabel={ task.action }
|
||||
additionalInfo={ task.additionalInfo }
|
||||
/>
|
||||
) ) }
|
||||
</ListComp>
|
||||
|
|
|
@ -56,6 +56,7 @@ export function getAllTasks( {
|
|||
query,
|
||||
toggleCartModal,
|
||||
onTaskSelect,
|
||||
hasCompleteAddress,
|
||||
} ) {
|
||||
const {
|
||||
hasPaymentGateway,
|
||||
|
@ -84,6 +85,8 @@ export function getAllTasks( {
|
|||
|
||||
const woocommercePaymentsInstalled =
|
||||
installedPlugins.indexOf( 'woocommerce-payments' ) !== -1;
|
||||
const woocommerceServicesActive =
|
||||
activePlugins.indexOf( 'woocommerce-services' ) !== -1;
|
||||
const {
|
||||
completed: profilerCompleted,
|
||||
product_types: productTypes,
|
||||
|
@ -94,10 +97,11 @@ export function getAllTasks( {
|
|||
businessExtensions || []
|
||||
).includes( 'woocommerce-payments' );
|
||||
|
||||
let purchaseAndInstallText = __(
|
||||
let purchaseAndInstallTitle = __(
|
||||
'Add paid extensions to my store',
|
||||
'woocommerce-admin'
|
||||
);
|
||||
let purchaseAndInstallContent;
|
||||
|
||||
if ( uniqueItemsList.length === 1 ) {
|
||||
const { name: itemName } = uniqueItemsList[ 0 ];
|
||||
|
@ -105,14 +109,64 @@ export function getAllTasks( {
|
|||
'Add %s to my store',
|
||||
'woocommerce-admin'
|
||||
);
|
||||
purchaseAndInstallText = sprintf( purchaseAndInstallFormat, itemName );
|
||||
purchaseAndInstallTitle = sprintf( purchaseAndInstallFormat, itemName );
|
||||
purchaseAndInstallContent = products.find(
|
||||
( { label } ) => label === itemName
|
||||
)?.description;
|
||||
} else {
|
||||
const uniqueProductNames = uniqueItemsList.map( ( { name } ) => name );
|
||||
const lastProduct = uniqueProductNames.pop();
|
||||
let firstProducts = uniqueProductNames.join( ', ' );
|
||||
if ( uniqueProductNames.length > 1 ) {
|
||||
firstProducts += ',';
|
||||
}
|
||||
/* translators: %1$s: list of product names comma separated, %2%s the last product name */
|
||||
purchaseAndInstallContent = sprintf(
|
||||
__(
|
||||
'Good choice! You chose to add %1$s and %2$s to your store.',
|
||||
'woocommerce-admin'
|
||||
),
|
||||
firstProducts,
|
||||
lastProduct
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
automatedTaxSupportedCountries = [],
|
||||
taxJarActivated,
|
||||
} = onboardingStatus;
|
||||
|
||||
const isTaxJarSupported =
|
||||
! taxJarActivated && // WCS integration doesn't work with the official TaxJar plugin.
|
||||
automatedTaxSupportedCountries.includes( countryCode );
|
||||
|
||||
const canUseAutomatedTaxes =
|
||||
hasCompleteAddress && woocommerceServicesActive && isTaxJarSupported;
|
||||
|
||||
let taxAction = __( "Let's go", 'woocommerce-admin' );
|
||||
let taxContent = __(
|
||||
'Set your store location and configure tax rate settings.',
|
||||
'woocommerce-admin'
|
||||
);
|
||||
|
||||
if ( canUseAutomatedTaxes ) {
|
||||
taxAction = __( 'Yes please', 'woocommerce-admin' );
|
||||
taxContent = __(
|
||||
'Good news! WooCommerce Services and Jetpack can automate your sales tax calculations for you.',
|
||||
'woocommerce-admin'
|
||||
);
|
||||
}
|
||||
|
||||
const tasks = [
|
||||
{
|
||||
key: 'store_details',
|
||||
title: __( 'Store details', 'woocommerce-admin' ),
|
||||
content: __(
|
||||
'Your store address is required to set the origin country for shipping, currencies, and payment options.',
|
||||
'woocommerce-admin'
|
||||
),
|
||||
container: null,
|
||||
action: __( "Let's go", 'woocommerce-admin' ),
|
||||
onClick: () => {
|
||||
onTaskSelect( 'store_details' );
|
||||
getHistory().push( getNewPath( {}, '/setup-wizard', {} ) );
|
||||
|
@ -124,8 +178,10 @@ export function getAllTasks( {
|
|||
},
|
||||
{
|
||||
key: 'purchase',
|
||||
title: purchaseAndInstallText,
|
||||
title: purchaseAndInstallTitle,
|
||||
content: purchaseAndInstallContent,
|
||||
container: null,
|
||||
action: __( 'Purchase & install now', 'woocommerce-admin' ),
|
||||
onClick: () => {
|
||||
onTaskSelect( 'purchase' );
|
||||
return remainingProducts.length ? toggleCartModal() : null;
|
||||
|
@ -139,6 +195,10 @@ export function getAllTasks( {
|
|||
{
|
||||
key: 'products',
|
||||
title: __( 'Add my products', 'woocommerce-admin' ),
|
||||
content: __(
|
||||
'Start by adding the first product to your store. You can add your products manually, via CSV, or import them from another service.',
|
||||
'woocommerce-admin'
|
||||
),
|
||||
container: <Products />,
|
||||
onClick: () => {
|
||||
onTaskSelect( 'products' );
|
||||
|
@ -155,6 +215,12 @@ export function getAllTasks( {
|
|||
'Get paid with WooCommerce Payments',
|
||||
'woocommerce-admin'
|
||||
),
|
||||
content: __(
|
||||
"You're only one step away from getting paid. Verify your business details to start managing transactions with WooCommerce Payments.",
|
||||
'woocommerce-admin'
|
||||
),
|
||||
action: __( 'Finish setup', 'woocommmerce-admin' ),
|
||||
expanded: true,
|
||||
container: <Fragment />,
|
||||
completed: wcPayIsConnected,
|
||||
onClick: async ( e ) => {
|
||||
|
@ -196,6 +262,10 @@ export function getAllTasks( {
|
|||
{
|
||||
key: 'payments',
|
||||
title: __( 'Set up payments', 'woocommerce-admin' ),
|
||||
content: __(
|
||||
'Choose payment providers and enable payment methods at checkout.',
|
||||
'woocommerce-admin'
|
||||
),
|
||||
container: <Payments />,
|
||||
completed: hasPaymentGateway,
|
||||
onClick: () => {
|
||||
|
@ -212,10 +282,19 @@ export function getAllTasks( {
|
|||
{
|
||||
key: 'tax',
|
||||
title: __( 'Set up tax', 'woocommerce-admin' ),
|
||||
content: taxContent,
|
||||
container: <Tax />,
|
||||
onClick: () => {
|
||||
action: taxAction,
|
||||
onClick: ( e, args = {} ) => {
|
||||
// The expanded item CTA allows us to enable
|
||||
// automated taxes for eligible stores.
|
||||
// Note: this will be initially part of an A/B test.
|
||||
const { isExpanded } = args;
|
||||
onTaskSelect( 'tax' );
|
||||
updateQueryString( { task: 'tax' } );
|
||||
updateQueryString( {
|
||||
task: 'tax',
|
||||
auto: canUseAutomatedTaxes && isExpanded,
|
||||
} );
|
||||
},
|
||||
completed: isTaxComplete,
|
||||
visible: true,
|
||||
|
@ -225,7 +304,12 @@ export function getAllTasks( {
|
|||
{
|
||||
key: 'shipping',
|
||||
title: __( 'Set up shipping', 'woocommerce-admin' ),
|
||||
content: __(
|
||||
"Set your store location and where you'll ship to.",
|
||||
'woocommerce-admin'
|
||||
),
|
||||
container: <Shipping />,
|
||||
action: __( "Let's go", 'woocommerce-admin' ),
|
||||
onClick: () => {
|
||||
if ( shippingZonesCount > 0 ) {
|
||||
window.location = getLinkTypeAndHref( {
|
||||
|
@ -247,7 +331,12 @@ export function getAllTasks( {
|
|||
{
|
||||
key: 'appearance',
|
||||
title: __( 'Personalize my store', 'woocommerce-admin' ),
|
||||
content: __(
|
||||
'Add your logo, create a homepage, and start designing your store.',
|
||||
'woocommerce-admin'
|
||||
),
|
||||
container: <Appearance />,
|
||||
action: __( "Let's go", 'woocommerce-admin' ),
|
||||
onClick: () => {
|
||||
onTaskSelect( 'appearance' );
|
||||
updateQueryString( { task: 'appearance' } );
|
||||
|
|
|
@ -46,7 +46,13 @@ class Tax extends Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { query } = this.props;
|
||||
const { auto } = query;
|
||||
this.reset();
|
||||
|
||||
if ( auto === 'true' ) {
|
||||
this.enableAutomatedTax();
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
|
@ -396,6 +402,13 @@ class Tax extends Component {
|
|||
return filter( steps, ( step ) => step.visible );
|
||||
}
|
||||
|
||||
enableAutomatedTax() {
|
||||
recordEvent( 'tasklist_tax_setup_automated_proceed', {
|
||||
setup_automatically: true,
|
||||
} );
|
||||
this.updateAutomatedTax( true );
|
||||
}
|
||||
|
||||
renderSuccessScreen() {
|
||||
const { isPending } = this.props;
|
||||
|
||||
|
@ -427,12 +440,7 @@ class Tax extends Component {
|
|||
disabled={ isPending }
|
||||
isPrimary
|
||||
isBusy={ isPending }
|
||||
onClick={ () => {
|
||||
recordEvent( 'tasklist_tax_setup_automated_proceed', {
|
||||
setup_automatically: true,
|
||||
} );
|
||||
this.updateAutomatedTax( true );
|
||||
} }
|
||||
onClick={ this.enableAutomatedTax }
|
||||
>
|
||||
{ __( 'Yes please', 'woocommerce-admin' ) }
|
||||
</Button>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Unreleased
|
||||
|
||||
- Remove the use of Dashicons and replace with @wordpress/icons or gridicons #7020
|
||||
- Add expanded item text and CTA button. #6956
|
||||
|
||||
# 1.2.0
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ $task-alert-yellow: #f0b849;
|
|||
|
||||
.woocommerce-task-list__item {
|
||||
position: relative;
|
||||
padding-right: $gap-large;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
|
@ -56,6 +57,16 @@ $task-alert-yellow: #f0b849;
|
|||
}
|
||||
}
|
||||
|
||||
.woocommerce-task-list__item-content {
|
||||
margin-top: $gap-smallest;
|
||||
margin-bottom: $gap-smallest;
|
||||
}
|
||||
|
||||
.woocommerce-task-list__item-action {
|
||||
margin-top: $gap-smallest;
|
||||
margin-bottom: $gap-smaller;
|
||||
}
|
||||
|
||||
.woocommerce-task-list__item-after {
|
||||
margin-left: $gap;
|
||||
margin-right: $gap-large;
|
||||
|
@ -87,7 +98,8 @@ $task-alert-yellow: #f0b849;
|
|||
color: $gray-700;
|
||||
}
|
||||
|
||||
.woocommerce-task-list__item-content {
|
||||
.woocommerce-task-list__item-content,
|
||||
.woocommerce-task__estimated-time {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,17 +24,26 @@ const sanitizeHTML = ( html: string ) => {
|
|||
|
||||
type TaskLevel = 1 | 2 | 3;
|
||||
|
||||
type ActionArgs = {
|
||||
isExpanded?: boolean;
|
||||
};
|
||||
|
||||
type TaskItemProps = {
|
||||
title: string;
|
||||
completed: boolean;
|
||||
onClick: () => void;
|
||||
onClick?: () => void;
|
||||
isDismissable?: boolean;
|
||||
onDismiss?: () => void;
|
||||
additionalInfo?: string;
|
||||
time?: string;
|
||||
content?: string;
|
||||
content: string;
|
||||
expanded?: boolean;
|
||||
level?: TaskLevel;
|
||||
action: (
|
||||
event?: React.MouseEvent | React.KeyboardEvent,
|
||||
args?: ActionArgs
|
||||
) => void;
|
||||
actionLabel?: string;
|
||||
};
|
||||
|
||||
const OptionalTaskTooltip: React.FC< {
|
||||
|
@ -71,6 +80,8 @@ export const TaskItem: React.FC< TaskItemProps > = ( {
|
|||
content,
|
||||
expanded = false,
|
||||
level = 3,
|
||||
action,
|
||||
actionLabel,
|
||||
} ) => {
|
||||
const className = classnames( 'woocommerce-task-list__item', {
|
||||
complete: completed,
|
||||
|
@ -97,32 +108,43 @@ export const TaskItem: React.FC< TaskItemProps > = ( {
|
|||
</div>
|
||||
</OptionalTaskTooltip>
|
||||
<div className="woocommerce-task-list__item-text">
|
||||
<span className="woocommerce-task-list__item-title">
|
||||
<Text
|
||||
as="div"
|
||||
variant={ completed ? 'body.small' : 'button' }
|
||||
>
|
||||
<Text as="div" variant={ completed ? 'body.small' : 'button' }>
|
||||
<span className="woocommerce-task-list__item-title">
|
||||
{ title }
|
||||
{ additionalInfo && (
|
||||
<div
|
||||
className="woocommerce-task__additional-info"
|
||||
dangerouslySetInnerHTML={ sanitizeHTML(
|
||||
additionalInfo
|
||||
) }
|
||||
></div>
|
||||
) }
|
||||
{ expanded && content && (
|
||||
<div className="woocommerce-task-list__item-content">
|
||||
{ content }
|
||||
</div>
|
||||
) }
|
||||
{ time && ! completed && (
|
||||
<div className="woocommerce-task__estimated-time">
|
||||
{ time }
|
||||
</div>
|
||||
) }
|
||||
</Text>
|
||||
</span>
|
||||
</span>
|
||||
{ expanded && (
|
||||
<div className="woocommerce-task-list__item-content">
|
||||
{ content }
|
||||
</div>
|
||||
) }
|
||||
{ additionalInfo && (
|
||||
<div
|
||||
className="woocommerce-task__additional-info"
|
||||
dangerouslySetInnerHTML={ sanitizeHTML(
|
||||
additionalInfo
|
||||
) }
|
||||
></div>
|
||||
) }
|
||||
{ expanded && ! completed && (
|
||||
<Button
|
||||
className="woocommerce-task-list__item-action"
|
||||
isPrimary
|
||||
onClick={ (
|
||||
event: React.MouseEvent | React.KeyboardEvent
|
||||
) => {
|
||||
event.stopPropagation();
|
||||
action( event, { isExpanded: true } );
|
||||
} }
|
||||
>
|
||||
{ actionLabel || title }
|
||||
</Button>
|
||||
) }
|
||||
{ time && (
|
||||
<div className="woocommerce-task__estimated-time">
|
||||
{ time }
|
||||
</div>
|
||||
) }
|
||||
</Text>
|
||||
</div>
|
||||
{ onDismiss && isDismissable && ! completed && (
|
||||
<div className="woocommerce-task-list__item-after">
|
||||
|
|
|
@ -93,6 +93,7 @@ Release and roadmap notes are available on the [WooCommerce Developers Blog](htt
|
|||
- Add: Free extension list powered by remote config #6952
|
||||
- Add: Add PayPal to fallback payment gateways #7001
|
||||
- Add: Add a data store for WC Payments REST APIs #6918
|
||||
- Add: Progressive setup checklist copy and call to action buttons. #6956
|
||||
- Add: Add Paystack as fallback gateway #7025
|
||||
- Add: Add COD method to default payment gateway recommendations #7057
|
||||
- Dev: Update package-lock to fix versioning of local packages. #6843
|
||||
|
|
|
@ -42,7 +42,7 @@ export class WcHomescreen extends BasePage {
|
|||
}
|
||||
|
||||
async clickOnTaskList( taskTitle: string ) {
|
||||
const item = await waitForElementByText( 'div', taskTitle );
|
||||
const item = await waitForElementByText( 'span', taskTitle );
|
||||
|
||||
if ( ! item ) {
|
||||
throw new Error(
|
||||
|
|
Loading…
Reference in New Issue