[e2e] Skipping 11 tests for the Pressable website (#51123)
* Skipping 11 tests for the Pressable website * Add changefile(s) from automation for the following project(s): woocommerce --------- Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: Jonathan Lane <lanej0@users.noreply.github.com>
This commit is contained in:
parent
881fd73847
commit
0d65648ed7
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: update
|
||||
|
||||
E2E tests - skipping 11 tests for the Pressable website
|
|
@ -512,121 +512,123 @@ test.describe( 'Assembler -> Color Pickers', { tag: '@gutenberg' }, () => {
|
|||
}
|
||||
);
|
||||
|
||||
test( 'Create "your own" pickers should be visible', async ( {
|
||||
assemblerPageObject,
|
||||
baseURL,
|
||||
}, testInfo ) => {
|
||||
testInfo.snapshotSuffix = '';
|
||||
const wordPressVersion = await getInstalledWordPressVersion();
|
||||
test(
|
||||
'Create "your own" pickers should be visible',
|
||||
{ tag: '@skip-on-default-pressable' },
|
||||
async ( { assemblerPageObject, baseURL }, testInfo ) => {
|
||||
testInfo.snapshotSuffix = '';
|
||||
const wordPressVersion = await getInstalledWordPressVersion();
|
||||
|
||||
const assembler = await assemblerPageObject.getAssembler();
|
||||
const colorPicker = assembler.getByText( 'Create your own' );
|
||||
const assembler = await assemblerPageObject.getAssembler();
|
||||
const colorPicker = assembler.getByText( 'Create your own' );
|
||||
|
||||
await colorPicker.click();
|
||||
await colorPicker.click();
|
||||
|
||||
// Check if Gutenberg is installed
|
||||
const apiContext = await request.newContext( {
|
||||
baseURL,
|
||||
extraHTTPHeaders: {
|
||||
Authorization: `Basic ${ encodeCredentials(
|
||||
admin.username,
|
||||
admin.password
|
||||
) }`,
|
||||
cookie: '',
|
||||
},
|
||||
} );
|
||||
const listPluginsResponse = await apiContext.get(
|
||||
`/wp-json/wp/v2/plugins`,
|
||||
{
|
||||
failOnStatusCode: true,
|
||||
}
|
||||
);
|
||||
const pluginsList = await listPluginsResponse.json();
|
||||
const gutenbergPlugin = pluginsList.find(
|
||||
( { textdomain } ) => textdomain === 'gutenberg'
|
||||
);
|
||||
|
||||
const mapTypeFeatures = {
|
||||
background: [ 'solid', 'gradient' ],
|
||||
text: [],
|
||||
heading: [ 'text', 'background', 'gradient' ],
|
||||
button: [ 'text', 'background', 'gradient' ],
|
||||
link: [ 'default', 'hover' ],
|
||||
captions: [],
|
||||
};
|
||||
const mapTypeFeaturesGutenberg = {
|
||||
background: [ 'color', 'gradient' ],
|
||||
text: [],
|
||||
heading: [ 'text', 'background', 'gradient' ],
|
||||
button: [ 'text', 'background', 'gradient' ],
|
||||
link: [ 'default', 'hover' ],
|
||||
captions: [],
|
||||
};
|
||||
|
||||
const customColorSelector =
|
||||
'.components-color-palette__custom-color-button';
|
||||
const gradientColorSelector =
|
||||
'.components-custom-gradient-picker__gradient-bar-background';
|
||||
|
||||
const mapFeatureSelectors = {
|
||||
solid: customColorSelector,
|
||||
text: customColorSelector,
|
||||
background: customColorSelector,
|
||||
default: customColorSelector,
|
||||
hover: customColorSelector,
|
||||
gradient: gradientColorSelector,
|
||||
};
|
||||
const mapFeatureSelectorsGutenberg = {
|
||||
color: customColorSelector,
|
||||
text: customColorSelector,
|
||||
background: customColorSelector,
|
||||
default: customColorSelector,
|
||||
hover: customColorSelector,
|
||||
gradient: gradientColorSelector,
|
||||
};
|
||||
|
||||
for ( const type of Object.keys( mapTypeFeatures ) ) {
|
||||
await assembler
|
||||
.locator(
|
||||
'.woocommerce-customize-store__color-panel-container'
|
||||
)
|
||||
.getByText( type )
|
||||
.click();
|
||||
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
if ( gutenbergPlugin || wordPressVersion >= 6.6 ) {
|
||||
for ( const feature of mapTypeFeaturesGutenberg[ type ] ) {
|
||||
const container = assembler.locator(
|
||||
'.block-editor-panel-color-gradient-settings__dropdown-content'
|
||||
);
|
||||
await container
|
||||
.getByRole( 'tab', {
|
||||
name: feature,
|
||||
} )
|
||||
.click();
|
||||
|
||||
const selector = mapFeatureSelectorsGutenberg[ feature ];
|
||||
const featureSelector = container.locator( selector );
|
||||
|
||||
await expect( featureSelector ).toBeVisible();
|
||||
// Check if Gutenberg is installed
|
||||
const apiContext = await request.newContext( {
|
||||
baseURL,
|
||||
extraHTTPHeaders: {
|
||||
Authorization: `Basic ${ encodeCredentials(
|
||||
admin.username,
|
||||
admin.password
|
||||
) }`,
|
||||
cookie: '',
|
||||
},
|
||||
} );
|
||||
const listPluginsResponse = await apiContext.get(
|
||||
`/wp-json/wp/v2/plugins`,
|
||||
{
|
||||
failOnStatusCode: true,
|
||||
}
|
||||
} else {
|
||||
for ( const feature of mapTypeFeatures[ type ] ) {
|
||||
const container = assembler.locator(
|
||||
'.block-editor-panel-color-gradient-settings__dropdown-content'
|
||||
);
|
||||
await container
|
||||
.getByRole( 'tab', {
|
||||
name: feature,
|
||||
} )
|
||||
.click();
|
||||
);
|
||||
const pluginsList = await listPluginsResponse.json();
|
||||
const gutenbergPlugin = pluginsList.find(
|
||||
( { textdomain } ) => textdomain === 'gutenberg'
|
||||
);
|
||||
|
||||
const selector = mapFeatureSelectors[ feature ];
|
||||
const featureSelector = container.locator( selector );
|
||||
const mapTypeFeatures = {
|
||||
background: [ 'solid', 'gradient' ],
|
||||
text: [],
|
||||
heading: [ 'text', 'background', 'gradient' ],
|
||||
button: [ 'text', 'background', 'gradient' ],
|
||||
link: [ 'default', 'hover' ],
|
||||
captions: [],
|
||||
};
|
||||
const mapTypeFeaturesGutenberg = {
|
||||
background: [ 'color', 'gradient' ],
|
||||
text: [],
|
||||
heading: [ 'text', 'background', 'gradient' ],
|
||||
button: [ 'text', 'background', 'gradient' ],
|
||||
link: [ 'default', 'hover' ],
|
||||
captions: [],
|
||||
};
|
||||
|
||||
await expect( featureSelector ).toBeVisible();
|
||||
const customColorSelector =
|
||||
'.components-color-palette__custom-color-button';
|
||||
const gradientColorSelector =
|
||||
'.components-custom-gradient-picker__gradient-bar-background';
|
||||
|
||||
const mapFeatureSelectors = {
|
||||
solid: customColorSelector,
|
||||
text: customColorSelector,
|
||||
background: customColorSelector,
|
||||
default: customColorSelector,
|
||||
hover: customColorSelector,
|
||||
gradient: gradientColorSelector,
|
||||
};
|
||||
const mapFeatureSelectorsGutenberg = {
|
||||
color: customColorSelector,
|
||||
text: customColorSelector,
|
||||
background: customColorSelector,
|
||||
default: customColorSelector,
|
||||
hover: customColorSelector,
|
||||
gradient: gradientColorSelector,
|
||||
};
|
||||
|
||||
for ( const type of Object.keys( mapTypeFeatures ) ) {
|
||||
await assembler
|
||||
.locator(
|
||||
'.woocommerce-customize-store__color-panel-container'
|
||||
)
|
||||
.getByText( type )
|
||||
.click();
|
||||
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
if ( gutenbergPlugin || wordPressVersion >= 6.6 ) {
|
||||
for ( const feature of mapTypeFeaturesGutenberg[ type ] ) {
|
||||
const container = assembler.locator(
|
||||
'.block-editor-panel-color-gradient-settings__dropdown-content'
|
||||
);
|
||||
await container
|
||||
.getByRole( 'tab', {
|
||||
name: feature,
|
||||
} )
|
||||
.click();
|
||||
|
||||
const selector =
|
||||
mapFeatureSelectorsGutenberg[ feature ];
|
||||
const featureSelector = container.locator( selector );
|
||||
|
||||
await expect( featureSelector ).toBeVisible();
|
||||
}
|
||||
} else {
|
||||
for ( const feature of mapTypeFeatures[ type ] ) {
|
||||
const container = assembler.locator(
|
||||
'.block-editor-panel-color-gradient-settings__dropdown-content'
|
||||
);
|
||||
await container
|
||||
.getByRole( 'tab', {
|
||||
name: feature,
|
||||
} )
|
||||
.click();
|
||||
|
||||
const selector = mapFeatureSelectors[ feature ];
|
||||
const featureSelector = container.locator( selector );
|
||||
|
||||
await expect( featureSelector ).toBeVisible();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
);
|
||||
} );
|
||||
|
|
|
@ -96,19 +96,20 @@ test.describe( 'Assembler -> Full composability', { tag: '@gutenberg' }, () => {
|
|||
}
|
||||
} );
|
||||
|
||||
test( 'The list of categories should be displayed', async ( {
|
||||
pageObject,
|
||||
baseURL,
|
||||
} ) => {
|
||||
await prepareAssembler( pageObject, baseURL );
|
||||
const assembler = await pageObject.getAssembler();
|
||||
test(
|
||||
'The list of categories should be displayed',
|
||||
{ tag: '@skip-on-default-pressable' },
|
||||
async ( { pageObject, baseURL } ) => {
|
||||
await prepareAssembler( pageObject, baseURL );
|
||||
const assembler = await pageObject.getAssembler();
|
||||
|
||||
const categories = assembler.locator(
|
||||
'.woocommerce-customize-store__sidebar-homepage-content .components-item-group'
|
||||
);
|
||||
const categories = assembler.locator(
|
||||
'.woocommerce-customize-store__sidebar-homepage-content .components-item-group'
|
||||
);
|
||||
|
||||
await expect( categories ).toHaveCount( 6 );
|
||||
} );
|
||||
await expect( categories ).toHaveCount( 6 );
|
||||
}
|
||||
);
|
||||
|
||||
test( 'Clicking on "Design your homepage" should open the Intro sidebar by default', async ( {
|
||||
pageObject,
|
||||
|
|
|
@ -70,20 +70,21 @@ test.describe( 'Assembler -> Homepage', { tag: '@gutenberg' }, () => {
|
|||
}
|
||||
} );
|
||||
|
||||
test( 'Available homepage should be displayed', async ( {
|
||||
pageObject,
|
||||
baseURL,
|
||||
} ) => {
|
||||
await prepareAssembler( pageObject, baseURL );
|
||||
test(
|
||||
'Available homepage should be displayed',
|
||||
{ tag: '@skip-on-default-pressable' },
|
||||
async ( { pageObject, baseURL } ) => {
|
||||
await prepareAssembler( pageObject, baseURL );
|
||||
|
||||
const assembler = await pageObject.getAssembler();
|
||||
const assembler = await pageObject.getAssembler();
|
||||
|
||||
const homepages = assembler.locator(
|
||||
'.block-editor-block-patterns-list__list-item'
|
||||
);
|
||||
const homepages = assembler.locator(
|
||||
'.block-editor-block-patterns-list__list-item'
|
||||
);
|
||||
|
||||
await expect( homepages ).toHaveCount( 3 );
|
||||
} );
|
||||
await expect( homepages ).toHaveCount( 3 );
|
||||
}
|
||||
);
|
||||
|
||||
test( 'The selected homepage should be focused when is clicked', async ( {
|
||||
pageObject,
|
||||
|
@ -247,31 +248,36 @@ test.describe( 'Homepage tracking banner', () => {
|
|||
}
|
||||
} );
|
||||
|
||||
test( 'Should show the "Want more patterns?" banner with the PTK API unavailable message', async ( {
|
||||
baseURL,
|
||||
pageObject,
|
||||
page,
|
||||
} ) => {
|
||||
await setOption( request, baseURL, 'woocommerce_allow_tracking', 'no' );
|
||||
test(
|
||||
'Should show the "Want more patterns?" banner with the PTK API unavailable message',
|
||||
{ tag: '@skip-on-default-pressable' },
|
||||
async ( { baseURL, pageObject, page } ) => {
|
||||
await setOption(
|
||||
request,
|
||||
baseURL,
|
||||
'woocommerce_allow_tracking',
|
||||
'no'
|
||||
);
|
||||
|
||||
await page.route( '**/wp-json/wc-admin/patterns*', ( route ) => {
|
||||
route.fulfill( {
|
||||
status: 500,
|
||||
await page.route( '**/wp-json/wc-admin/patterns*', ( route ) => {
|
||||
route.fulfill( {
|
||||
status: 500,
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
|
||||
await prepareAssembler( pageObject, baseURL );
|
||||
await prepareAssembler( pageObject, baseURL );
|
||||
|
||||
const assembler = await pageObject.getAssembler();
|
||||
await expect(
|
||||
assembler.getByText( 'Want more patterns?' )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
assembler.getByText(
|
||||
"Unfortunately, we're experiencing some technical issues — please come back later to access more patterns."
|
||||
)
|
||||
).toBeVisible();
|
||||
} );
|
||||
const assembler = await pageObject.getAssembler();
|
||||
await expect(
|
||||
assembler.getByText( 'Want more patterns?' )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
assembler.getByText(
|
||||
"Unfortunately, we're experiencing some technical issues — please come back later to access more patterns."
|
||||
)
|
||||
).toBeVisible();
|
||||
}
|
||||
);
|
||||
|
||||
test( 'Should show the "Want more patterns?" banner with the Opt-in message when tracking is not allowed', async ( {
|
||||
pageObject,
|
||||
|
|
|
@ -219,29 +219,29 @@ test.describe( 'Assembler -> Logo Picker', { tag: '@gutenberg' }, () => {
|
|||
await expect( emptyLogoLocator ).toBeHidden();
|
||||
} );
|
||||
|
||||
test( 'Enabling the "use as site icon" option should set the image as the site icon', async ( {
|
||||
page,
|
||||
assemblerPageObject,
|
||||
logoPickerPageObject,
|
||||
} ) => {
|
||||
const assembler = await assemblerPageObject.getAssembler();
|
||||
const emptyLogoPicker =
|
||||
logoPickerPageObject.getEmptyLogoPickerLocator( assembler );
|
||||
await emptyLogoPicker.click();
|
||||
await logoPickerPageObject.pickImage( assembler );
|
||||
await assembler.getByText( 'Use as site icon' ).click();
|
||||
await logoPickerPageObject.saveLogoSettings( assembler );
|
||||
test(
|
||||
'Enabling the "use as site icon" option should set the image as the site icon',
|
||||
{ tag: '@skip-on-default-pressable' },
|
||||
async ( { page, assemblerPageObject, logoPickerPageObject } ) => {
|
||||
const assembler = await assemblerPageObject.getAssembler();
|
||||
const emptyLogoPicker =
|
||||
logoPickerPageObject.getEmptyLogoPickerLocator( assembler );
|
||||
await emptyLogoPicker.click();
|
||||
await logoPickerPageObject.pickImage( assembler );
|
||||
await assembler.getByText( 'Use as site icon' ).click();
|
||||
await logoPickerPageObject.saveLogoSettings( assembler );
|
||||
|
||||
// alternative way to verify new site icon on the site
|
||||
// verifying site icon shown in the new tab is impossible in headless mode
|
||||
const date = new Date();
|
||||
const month = ( date.getMonth() + 1 ).toString().padStart( 2, '0' );
|
||||
await expect(
|
||||
page.goto(
|
||||
`/wp-content/uploads/${ date.getFullYear() }/${ month }/image-03-100x100.png`
|
||||
)
|
||||
).toBeTruthy();
|
||||
} );
|
||||
// alternative way to verify new site icon on the site
|
||||
// verifying site icon shown in the new tab is impossible in headless mode
|
||||
const date = new Date();
|
||||
const month = ( date.getMonth() + 1 ).toString().padStart( 2, '0' );
|
||||
await expect(
|
||||
page.goto(
|
||||
`/wp-content/uploads/${ date.getFullYear() }/${ month }/image-03-100x100.png`
|
||||
)
|
||||
).toBeTruthy();
|
||||
}
|
||||
);
|
||||
|
||||
test( 'The selected image should be visible on the frontend', async ( {
|
||||
page,
|
||||
|
|
|
@ -58,21 +58,24 @@ test.describe(
|
|||
);
|
||||
} );
|
||||
|
||||
test( 'it shows the "offline banner" when the network is offline', async ( {
|
||||
page,
|
||||
context,
|
||||
} ) => {
|
||||
await page.goto( CUSTOMIZE_STORE_URL );
|
||||
await expect(
|
||||
page.locator( 'text=Design your own' )
|
||||
).toBeVisible();
|
||||
await context.setOffline( true );
|
||||
test(
|
||||
'it shows the "offline banner" when the network is offline',
|
||||
{ tag: '@skip-on-default-pressable' },
|
||||
async ( { page, context } ) => {
|
||||
await page.goto( CUSTOMIZE_STORE_URL );
|
||||
await expect(
|
||||
page.locator( 'text=Design your own' )
|
||||
).toBeVisible();
|
||||
await context.setOffline( true );
|
||||
|
||||
await expect( page.locator( '.offline-banner' ) ).toBeVisible();
|
||||
await expect(
|
||||
page.locator( 'text=Looking to design your store using AI?' )
|
||||
).toBeVisible();
|
||||
} );
|
||||
await expect( page.locator( '.offline-banner' ) ).toBeVisible();
|
||||
await expect(
|
||||
page.locator(
|
||||
'text=Looking to design your store using AI?'
|
||||
)
|
||||
).toBeVisible();
|
||||
}
|
||||
);
|
||||
|
||||
test( 'it shows the "no AI" banner on Core when the task is not completed', async ( {
|
||||
page,
|
||||
|
|
|
@ -60,17 +60,20 @@ test.describe(
|
|||
);
|
||||
} );
|
||||
|
||||
test( 'Accessing the transitional page when the CYS flow is not completed should redirect to the Intro page', async ( {
|
||||
page,
|
||||
baseURL,
|
||||
} ) => {
|
||||
await page.goto( TRANSITIONAL_URL );
|
||||
test(
|
||||
'Accessing the transitional page when the CYS flow is not completed should redirect to the Intro page',
|
||||
{ tag: '@skip-on-default-pressable' },
|
||||
async ( { page, baseURL } ) => {
|
||||
await page.goto( TRANSITIONAL_URL );
|
||||
|
||||
const locator = page.locator( 'h1:visible' );
|
||||
await expect( locator ).not.toHaveText( 'Your store looks great!' );
|
||||
const locator = page.locator( 'h1:visible' );
|
||||
await expect( locator ).not.toHaveText(
|
||||
'Your store looks great!'
|
||||
);
|
||||
|
||||
await expect( page.url() ).toBe( `${ baseURL }${ INTRO_URL }` );
|
||||
} );
|
||||
await expect( page.url() ).toBe( `${ baseURL }${ INTRO_URL }` );
|
||||
}
|
||||
);
|
||||
|
||||
test( 'Clicking on "Finish customizing" in the assembler should go to the transitional page', async ( {
|
||||
pageObject,
|
||||
|
|
|
@ -16,7 +16,7 @@ const test = baseTest.extend( {
|
|||
|
||||
test.describe(
|
||||
'Transform Classic Cart To Cart Block',
|
||||
{ tag: [ '@gutenberg', '@services' ] },
|
||||
{ tag: [ '@gutenberg', '@services', '@skip-on-default-pressable' ] },
|
||||
() => {
|
||||
test( 'can transform classic cart to cart block', async ( {
|
||||
page,
|
||||
|
|
|
@ -68,105 +68,109 @@ test.describe(
|
|||
} );
|
||||
} );
|
||||
|
||||
test( 'can transform classic checkout to checkout block', async ( {
|
||||
page,
|
||||
api,
|
||||
testPage,
|
||||
} ) => {
|
||||
await goToPageEditor( { page } );
|
||||
test(
|
||||
'can transform classic checkout to checkout block',
|
||||
{ tag: '@skip-on-default-pressable' },
|
||||
async ( { page, api, testPage } ) => {
|
||||
await goToPageEditor( { page } );
|
||||
|
||||
await closeChoosePatternModal( { page } );
|
||||
await closeChoosePatternModal( { page } );
|
||||
|
||||
await fillPageTitle( page, testPage.title );
|
||||
const wordPressVersion = await getInstalledWordPressVersion();
|
||||
await insertBlock( page, 'Classic Checkout', wordPressVersion );
|
||||
await transformIntoBlocks( page );
|
||||
await fillPageTitle( page, testPage.title );
|
||||
const wordPressVersion = await getInstalledWordPressVersion();
|
||||
await insertBlock( page, 'Classic Checkout', wordPressVersion );
|
||||
await transformIntoBlocks( page );
|
||||
|
||||
// When Gutenberg is active, the canvas is in an iframe
|
||||
let canvas = await getCanvas( page );
|
||||
// When Gutenberg is active, the canvas is in an iframe
|
||||
let canvas = await getCanvas( page );
|
||||
|
||||
// Open Settings sidebar if closed
|
||||
await openEditorSettings( { page } );
|
||||
// Open Settings sidebar if closed
|
||||
await openEditorSettings( { page } );
|
||||
|
||||
// Activate the terms and conditions checkbox
|
||||
await canvas.getByLabel( 'Block: Terms and Conditions' ).click();
|
||||
await page.getByLabel( 'Require checkbox' ).check();
|
||||
// Activate the terms and conditions checkbox
|
||||
await canvas
|
||||
.getByLabel( 'Block: Terms and Conditions' )
|
||||
.click();
|
||||
await page.getByLabel( 'Require checkbox' ).check();
|
||||
|
||||
await publishPage( page, testPage.title );
|
||||
await publishPage( page, testPage.title );
|
||||
|
||||
// add additional payment option after page creation
|
||||
const r = await api.put( 'payment_gateways/bacs', {
|
||||
enabled: true,
|
||||
} );
|
||||
expect( r.data.enabled ).toBe( true );
|
||||
await page.reload();
|
||||
// add additional payment option after page creation
|
||||
const r = await api.put( 'payment_gateways/bacs', {
|
||||
enabled: true,
|
||||
} );
|
||||
expect( r.data.enabled ).toBe( true );
|
||||
await page.reload();
|
||||
|
||||
// Mandatory to wait for the editor content, to ensure the iframe is loaded (if Gutenberg is active)
|
||||
await expect( page.getByLabel( 'Editor content' ) ).toBeVisible();
|
||||
// Mandatory to wait for the editor content, to ensure the iframe is loaded (if Gutenberg is active)
|
||||
await expect(
|
||||
page.getByLabel( 'Editor content' )
|
||||
).toBeVisible();
|
||||
|
||||
// Get the canvas again after the page reload
|
||||
canvas = await getCanvas( page );
|
||||
// Get the canvas again after the page reload
|
||||
canvas = await getCanvas( page );
|
||||
|
||||
await expect(
|
||||
canvas.getByText( 'Direct bank transfer' )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
canvas.getByText( 'Cash on delivery' )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
canvas.getByText( 'Direct bank transfer' )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
canvas.getByText( 'Cash on delivery' )
|
||||
).toBeVisible();
|
||||
|
||||
// add additional shipping methods after page creation
|
||||
await api.post( `shipping/zones/${ shippingZoneId }/methods`, {
|
||||
method_id: 'flat_rate',
|
||||
settings: {
|
||||
cost: '5.00',
|
||||
},
|
||||
} );
|
||||
await api.post( `shipping/zones/${ shippingZoneId }/methods`, {
|
||||
method_id: 'local_pickup',
|
||||
} );
|
||||
await page.reload();
|
||||
// add additional shipping methods after page creation
|
||||
await api.post( `shipping/zones/${ shippingZoneId }/methods`, {
|
||||
method_id: 'flat_rate',
|
||||
settings: {
|
||||
cost: '5.00',
|
||||
},
|
||||
} );
|
||||
await api.post( `shipping/zones/${ shippingZoneId }/methods`, {
|
||||
method_id: 'local_pickup',
|
||||
} );
|
||||
await page.reload();
|
||||
|
||||
// verify that added shipping methods are present
|
||||
// there is issue in blocks: #45747 unable to verify the shipping methods
|
||||
// please uncomment below when the issue is resolved
|
||||
// await expect( page.getByLabel( 'Free shipping' ) ).toBeVisible();
|
||||
// await expect( page.getByLabel( 'Local pickup' ) ).toBeVisible();
|
||||
// await expect( page.getByLabel( 'Flat rate' ) ).toBeVisible();
|
||||
// verify that added shipping methods are present
|
||||
// there is issue in blocks: #45747 unable to verify the shipping methods
|
||||
// please uncomment below when the issue is resolved
|
||||
// await expect( page.getByLabel( 'Free shipping' ) ).toBeVisible();
|
||||
// await expect( page.getByLabel( 'Local pickup' ) ).toBeVisible();
|
||||
// await expect( page.getByLabel( 'Flat rate' ) ).toBeVisible();
|
||||
|
||||
// go to frontend to verify transformed checkout block
|
||||
// before that add product to cart to be able to visit checkout page
|
||||
await page.goto( `/cart/?add-to-cart=${ productId }` );
|
||||
await page.goto( testPage.slug );
|
||||
await expect(
|
||||
page.getByRole( 'heading', { name: testPage.title } )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page
|
||||
.getByRole( 'group', { name: 'Contact information' } )
|
||||
.locator( 'legend' )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator(
|
||||
'.wp-block-woocommerce-checkout-order-summary-block'
|
||||
)
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator( '.wc-block-components-address-form' ).first()
|
||||
).toBeVisible();
|
||||
// go to frontend to verify transformed checkout block
|
||||
// before that add product to cart to be able to visit checkout page
|
||||
await page.goto( `/cart/?add-to-cart=${ productId }` );
|
||||
await page.goto( testPage.slug );
|
||||
await expect(
|
||||
page.getByRole( 'heading', { name: testPage.title } )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page
|
||||
.getByRole( 'group', { name: 'Contact information' } )
|
||||
.locator( 'legend' )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator(
|
||||
'.wp-block-woocommerce-checkout-order-summary-block'
|
||||
)
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator( '.wc-block-components-address-form' ).first()
|
||||
).toBeVisible();
|
||||
|
||||
// verify existence of the terms & conditions and privacy policy checkbox
|
||||
await expect(
|
||||
page.getByText(
|
||||
'You must accept our Terms and Conditions and Privacy Policy to continue with your purchase.'
|
||||
)
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator( '#terms-and-conditions' )
|
||||
).toBeVisible();
|
||||
await page.locator( '#terms-and-conditions' ).check();
|
||||
await expect(
|
||||
page.locator( '#terms-and-conditions' )
|
||||
).toBeChecked();
|
||||
} );
|
||||
// verify existence of the terms & conditions and privacy policy checkbox
|
||||
await expect(
|
||||
page.getByText(
|
||||
'You must accept our Terms and Conditions and Privacy Policy to continue with your purchase.'
|
||||
)
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator( '#terms-and-conditions' )
|
||||
).toBeVisible();
|
||||
await page.locator( '#terms-and-conditions' ).check();
|
||||
await expect(
|
||||
page.locator( '#terms-and-conditions' )
|
||||
).toBeChecked();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -59,365 +59,378 @@ test.describe( 'General tab', { tag: '@gutenberg' }, () => {
|
|||
'The block product editor is not being tested'
|
||||
);
|
||||
|
||||
test( 'can create a simple product', async ( { page } ) => {
|
||||
await test.step( 'add new product', async () => {
|
||||
await page.goto( NEW_EDITOR_ADD_PRODUCT_URL );
|
||||
} );
|
||||
test(
|
||||
'can create a simple product',
|
||||
{ tag: '@skip-on-default-pressable' },
|
||||
async ( { page } ) => {
|
||||
await test.step( 'add new product', async () => {
|
||||
await page.goto( NEW_EDITOR_ADD_PRODUCT_URL );
|
||||
} );
|
||||
|
||||
await test.step( 'add product name', async () => {
|
||||
await clickOnTab( 'General', page );
|
||||
await page
|
||||
.getByPlaceholder( 'e.g. 12 oz Coffee Mug' )
|
||||
// Have to use pressSequentially in order for the SKU to be auto-updated
|
||||
// before we move to the SKU field and attempt to fill it in; otherwise,
|
||||
// the SKU field can sometimes end up getting auto-updated after we have filled it in,
|
||||
// wiping out the value we entered.
|
||||
.pressSequentially( productData.name );
|
||||
} );
|
||||
await test.step( 'add product name', async () => {
|
||||
await clickOnTab( 'General', page );
|
||||
await page
|
||||
.getByPlaceholder( 'e.g. 12 oz Coffee Mug' )
|
||||
// Have to use pressSequentially in order for the SKU to be auto-updated
|
||||
// before we move to the SKU field and attempt to fill it in; otherwise,
|
||||
// the SKU field can sometimes end up getting auto-updated after we have filled it in,
|
||||
// wiping out the value we entered.
|
||||
.pressSequentially( productData.name );
|
||||
} );
|
||||
|
||||
await test.step( 'add simple product description', async () => {
|
||||
const descriptionSimpleParagraph = page.locator(
|
||||
'[data-template-block-id="product-description__content"] > p'
|
||||
);
|
||||
await test.step( 'add simple product description', async () => {
|
||||
const descriptionSimpleParagraph = page.locator(
|
||||
'[data-template-block-id="product-description__content"] > p'
|
||||
);
|
||||
|
||||
await descriptionSimpleParagraph.fill(
|
||||
productData.descriptionSimple
|
||||
);
|
||||
} );
|
||||
await descriptionSimpleParagraph.fill(
|
||||
productData.descriptionSimple
|
||||
);
|
||||
} );
|
||||
|
||||
await test.step( 'add full product description', async () => {
|
||||
// Helps to ensure that block toolbar appears, by letting the editor
|
||||
// know that the user is done typing.
|
||||
await page.keyboard.press( 'Escape' );
|
||||
await test.step( 'add full product description', async () => {
|
||||
// Helps to ensure that block toolbar appears, by letting the editor
|
||||
// know that the user is done typing.
|
||||
await page.keyboard.press( 'Escape' );
|
||||
|
||||
await page.getByText( 'Full editor' ).click();
|
||||
await page.getByText( 'Full editor' ).click();
|
||||
|
||||
const wordPressVersion = await getInstalledWordPressVersion();
|
||||
await insertBlock( page, 'Heading', wordPressVersion );
|
||||
const wordPressVersion =
|
||||
await getInstalledWordPressVersion();
|
||||
await insertBlock( page, 'Heading', wordPressVersion );
|
||||
|
||||
const editorCanvasLocator = page.frameLocator(
|
||||
'iframe[name="editor-canvas"]'
|
||||
);
|
||||
const editorCanvasLocator = page.frameLocator(
|
||||
'iframe[name="editor-canvas"]'
|
||||
);
|
||||
|
||||
await editorCanvasLocator
|
||||
.locator( '[data-title="Heading"]' )
|
||||
.fill( productData.descriptionTitle );
|
||||
await editorCanvasLocator
|
||||
.locator( '[data-title="Heading"]' )
|
||||
.fill( productData.descriptionTitle );
|
||||
|
||||
await editorCanvasLocator
|
||||
.locator( '[data-title="Heading"]' )
|
||||
.blur();
|
||||
await editorCanvasLocator
|
||||
.locator( '[data-title="Heading"]' )
|
||||
.blur();
|
||||
|
||||
await insertBlock( page, 'Paragraph', wordPressVersion );
|
||||
await insertBlock( page, 'Paragraph', wordPressVersion );
|
||||
|
||||
await editorCanvasLocator
|
||||
.locator( '[data-title="Paragraph"]' )
|
||||
.last()
|
||||
.fill( productData.descriptionParagraph );
|
||||
await editorCanvasLocator
|
||||
.locator( '[data-title="Paragraph"]' )
|
||||
.last()
|
||||
.fill( productData.descriptionParagraph );
|
||||
|
||||
await page.getByRole( 'button', { name: 'Done' } ).click();
|
||||
} );
|
||||
await page.getByRole( 'button', { name: 'Done' } ).click();
|
||||
} );
|
||||
|
||||
await test.step( 'verify full product description', async () => {
|
||||
const previewContainerIframe = page
|
||||
.locator( '.block-editor-block-preview__container' )
|
||||
.frameLocator( 'iframe[title="Editor canvas"]' );
|
||||
await test.step( 'verify full product description', async () => {
|
||||
const previewContainerIframe = page
|
||||
.locator( '.block-editor-block-preview__container' )
|
||||
.frameLocator( 'iframe[title="Editor canvas"]' );
|
||||
|
||||
const descriptionTitle = previewContainerIframe.locator(
|
||||
'[data-title="Heading"]'
|
||||
);
|
||||
const descriptionInitialParagraph = previewContainerIframe
|
||||
.locator( '[data-title="Paragraph"]' )
|
||||
.first();
|
||||
const descriptionSecondParagraph = previewContainerIframe
|
||||
.locator( '[data-title="Paragraph"]' )
|
||||
.last();
|
||||
const descriptionTitle = previewContainerIframe.locator(
|
||||
'[data-title="Heading"]'
|
||||
);
|
||||
const descriptionInitialParagraph = previewContainerIframe
|
||||
.locator( '[data-title="Paragraph"]' )
|
||||
.first();
|
||||
const descriptionSecondParagraph = previewContainerIframe
|
||||
.locator( '[data-title="Paragraph"]' )
|
||||
.last();
|
||||
|
||||
await expect( descriptionTitle ).toHaveText(
|
||||
productData.descriptionTitle
|
||||
);
|
||||
await expect( descriptionInitialParagraph ).toHaveText(
|
||||
productData.descriptionSimple
|
||||
);
|
||||
await expect( descriptionSecondParagraph ).toHaveText(
|
||||
productData.descriptionParagraph
|
||||
);
|
||||
await expect( descriptionTitle ).toHaveText(
|
||||
productData.descriptionTitle
|
||||
);
|
||||
await expect( descriptionInitialParagraph ).toHaveText(
|
||||
productData.descriptionSimple
|
||||
);
|
||||
await expect( descriptionSecondParagraph ).toHaveText(
|
||||
productData.descriptionParagraph
|
||||
);
|
||||
|
||||
await descriptionTitle.click();
|
||||
await descriptionTitle.click();
|
||||
|
||||
await expect(
|
||||
page.getByText( 'Edit in full editor' )
|
||||
).toBeVisible();
|
||||
} );
|
||||
await expect(
|
||||
page.getByText( 'Edit in full editor' )
|
||||
).toBeVisible();
|
||||
} );
|
||||
|
||||
await test.step( 'add product summary', async () => {
|
||||
await page
|
||||
.locator(
|
||||
'[data-template-block-id="basic-details"] .components-summary-control'
|
||||
)
|
||||
.last()
|
||||
.fill( productData.summary );
|
||||
await test.step( 'add product summary', async () => {
|
||||
await page
|
||||
.locator(
|
||||
'[data-template-block-id="basic-details"] .components-summary-control'
|
||||
)
|
||||
.last()
|
||||
.fill( productData.summary );
|
||||
|
||||
// Blur the summary field to hide the toolbar before clicking on the regular price field.
|
||||
await page
|
||||
.locator(
|
||||
'[data-template-block-id="basic-details"] .components-summary-control'
|
||||
)
|
||||
.last()
|
||||
.blur();
|
||||
} );
|
||||
// Blur the summary field to hide the toolbar before clicking on the regular price field.
|
||||
await page
|
||||
.locator(
|
||||
'[data-template-block-id="basic-details"] .components-summary-control'
|
||||
)
|
||||
.last()
|
||||
.blur();
|
||||
} );
|
||||
|
||||
await test.step( 'add product price', async () => {
|
||||
const regularPrice = page
|
||||
.locator( 'input[name="regular_price"]' )
|
||||
.first();
|
||||
await regularPrice.waitFor( { state: 'visible' } );
|
||||
await regularPrice.click();
|
||||
await regularPrice.fill( productData.productPrice );
|
||||
await test.step( 'add product price', async () => {
|
||||
const regularPrice = page
|
||||
.locator( 'input[name="regular_price"]' )
|
||||
.first();
|
||||
await regularPrice.waitFor( { state: 'visible' } );
|
||||
await regularPrice.click();
|
||||
await regularPrice.fill( productData.productPrice );
|
||||
|
||||
const salePrice = page
|
||||
.locator( 'input[name="sale_price"]' )
|
||||
.first();
|
||||
await salePrice.waitFor( { state: 'visible' } );
|
||||
await salePrice.click();
|
||||
await salePrice.fill( productData.salePrice );
|
||||
} );
|
||||
const salePrice = page
|
||||
.locator( 'input[name="sale_price"]' )
|
||||
.first();
|
||||
await salePrice.waitFor( { state: 'visible' } );
|
||||
await salePrice.click();
|
||||
await salePrice.fill( productData.salePrice );
|
||||
} );
|
||||
|
||||
await test.step( 'add custom fields', async () => {
|
||||
await clickOnTab( 'Organization', page );
|
||||
await test.step( 'add custom fields', async () => {
|
||||
await clickOnTab( 'Organization', page );
|
||||
|
||||
const customFieldsAddNewButton = page
|
||||
.getByLabel( 'Block: Product custom fields toggle control' )
|
||||
.getByRole( 'button', { name: 'Add new' } );
|
||||
const customFieldsAddNewButton = page
|
||||
.getByLabel(
|
||||
'Block: Product custom fields toggle control'
|
||||
)
|
||||
.getByRole( 'button', { name: 'Add new' } );
|
||||
|
||||
// When re-running the test without resetting the env,
|
||||
// the custom fields toggle might be already checked,
|
||||
// so we need to check if the "Add new" button is already visible.
|
||||
//
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
if ( ! ( await customFieldsAddNewButton.isVisible() ) ) {
|
||||
// Toggle the "Show custom fields" so that the "Add new" button is visible
|
||||
|
||||
const customFieldsToggle = page.getByRole( 'checkbox', {
|
||||
name: 'Show custom fields',
|
||||
} );
|
||||
|
||||
await customFieldsToggle.scrollIntoViewIfNeeded();
|
||||
|
||||
// click() is used instead of check() because
|
||||
// Playwright sometimes has issues with custom checkboxes:
|
||||
// - https://github.com/microsoft/playwright/issues/13470
|
||||
// - https://github.com/microsoft/playwright/issues/20893
|
||||
// - https://github.com/microsoft/playwright/issues/27016
|
||||
// When re-running the test without resetting the env,
|
||||
// the custom fields toggle might be already checked,
|
||||
// so we need to check if the "Add new" button is already visible.
|
||||
//
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
if ( ! ( await customFieldsToggle.isChecked() ) ) {
|
||||
await customFieldsToggle.click();
|
||||
if ( ! ( await customFieldsAddNewButton.isVisible() ) ) {
|
||||
// Toggle the "Show custom fields" so that the "Add new" button is visible
|
||||
|
||||
const customFieldsToggle = page.getByRole( 'checkbox', {
|
||||
name: 'Show custom fields',
|
||||
} );
|
||||
|
||||
await customFieldsToggle.scrollIntoViewIfNeeded();
|
||||
|
||||
// click() is used instead of check() because
|
||||
// Playwright sometimes has issues with custom checkboxes:
|
||||
// - https://github.com/microsoft/playwright/issues/13470
|
||||
// - https://github.com/microsoft/playwright/issues/20893
|
||||
// - https://github.com/microsoft/playwright/issues/27016
|
||||
//
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
if ( ! ( await customFieldsToggle.isChecked() ) ) {
|
||||
await customFieldsToggle.click();
|
||||
}
|
||||
|
||||
await customFieldsToggle.isEnabled();
|
||||
}
|
||||
|
||||
await customFieldsToggle.isEnabled();
|
||||
}
|
||||
await expect( customFieldsAddNewButton ).toBeVisible();
|
||||
|
||||
await expect( customFieldsAddNewButton ).toBeVisible();
|
||||
await customFieldsAddNewButton.click();
|
||||
|
||||
await customFieldsAddNewButton.click();
|
||||
// Add custom fields modal
|
||||
const modal = page.locator(
|
||||
'.woocommerce-product-custom-fields__create-modal'
|
||||
);
|
||||
|
||||
// Add custom fields modal
|
||||
const modal = page.locator(
|
||||
'.woocommerce-product-custom-fields__create-modal'
|
||||
);
|
||||
await expect(
|
||||
modal.getByText( 'Add custom fields' )
|
||||
).toBeVisible();
|
||||
|
||||
await expect(
|
||||
modal.getByText( 'Add custom fields' )
|
||||
).toBeVisible();
|
||||
|
||||
const nameInput = modal.getByLabel( 'Name' );
|
||||
// Have to use pressSequentially in order to get the dropdown to show up and be able to select the option
|
||||
await nameInput.pressSequentially(
|
||||
productData.customFields[ 0 ].name
|
||||
);
|
||||
|
||||
await expect(
|
||||
modal.getByRole(
|
||||
'option',
|
||||
const nameInput = modal.getByLabel( 'Name' );
|
||||
// Have to use pressSequentially in order to get the dropdown to show up and be able to select the option
|
||||
await nameInput.pressSequentially(
|
||||
productData.customFields[ 0 ].name
|
||||
)
|
||||
).toBeVisible();
|
||||
);
|
||||
|
||||
await nameInput.press( 'Enter' );
|
||||
await expect(
|
||||
modal.getByRole(
|
||||
'option',
|
||||
productData.customFields[ 0 ].name
|
||||
)
|
||||
).toBeVisible();
|
||||
|
||||
const valueInput = modal.getByLabel( 'Value' );
|
||||
await valueInput.fill( productData.customFields[ 0 ].value );
|
||||
await nameInput.press( 'Enter' );
|
||||
|
||||
await modal
|
||||
.getByRole( 'button', { name: 'Add', exact: true } )
|
||||
.click();
|
||||
const valueInput = modal.getByLabel( 'Value' );
|
||||
await valueInput.fill(
|
||||
productData.customFields[ 0 ].value
|
||||
);
|
||||
|
||||
await expect(
|
||||
modal.getByText( 'Add custom fields' )
|
||||
).toBeHidden();
|
||||
await modal
|
||||
.getByRole( 'button', { name: 'Add', exact: true } )
|
||||
.click();
|
||||
|
||||
await expect(
|
||||
page.getByText( productData.customFields[ 0 ].name )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText( productData.customFields[ 0 ].value )
|
||||
).toBeVisible();
|
||||
} );
|
||||
await expect(
|
||||
modal.getByText( 'Add custom fields' )
|
||||
).toBeHidden();
|
||||
|
||||
await test.step( 'add inventory details', async () => {
|
||||
await clickOnTab( 'Inventory', page );
|
||||
await expect(
|
||||
page.getByText( productData.customFields[ 0 ].name )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText( productData.customFields[ 0 ].value )
|
||||
).toBeVisible();
|
||||
} );
|
||||
|
||||
await page
|
||||
.getByLabel( 'SKU (Stock Keeping Unit)' )
|
||||
.fill( productData.sku );
|
||||
await page
|
||||
.getByLabel( 'GTIN, UPC, EAN, or ISBN' )
|
||||
.fill( productData.gtin );
|
||||
} );
|
||||
await test.step( 'add inventory details', async () => {
|
||||
await clickOnTab( 'Inventory', page );
|
||||
|
||||
await test.step( 'add shipping details', async () => {
|
||||
await clickOnTab( 'Shipping', page );
|
||||
await page
|
||||
.getByLabel( 'SKU (Stock Keeping Unit)' )
|
||||
.fill( productData.sku );
|
||||
await page
|
||||
.getByLabel( 'GTIN, UPC, EAN, or ISBN' )
|
||||
.fill( productData.gtin );
|
||||
} );
|
||||
|
||||
// Shipping class
|
||||
await page
|
||||
.getByLabel( 'Shipping class', { exact: true } )
|
||||
//.locator( 'select[name="shipping_class"]' )
|
||||
.selectOption( 'Add new shipping class' );
|
||||
await test.step( 'add shipping details', async () => {
|
||||
await clickOnTab( 'Shipping', page );
|
||||
|
||||
// New shipping class modal
|
||||
const modal = page.locator(
|
||||
'.woocommerce-add-new-shipping-class-modal'
|
||||
);
|
||||
// Shipping class
|
||||
await page
|
||||
.getByLabel( 'Shipping class', { exact: true } )
|
||||
//.locator( 'select[name="shipping_class"]' )
|
||||
.selectOption( 'Add new shipping class' );
|
||||
|
||||
await expect(
|
||||
modal.getByText( 'New shipping class' )
|
||||
).toBeVisible();
|
||||
// New shipping class modal
|
||||
const modal = page.locator(
|
||||
'.woocommerce-add-new-shipping-class-modal'
|
||||
);
|
||||
|
||||
await modal
|
||||
.getByLabel( 'Name (Required)' )
|
||||
.fill( productData.shipping.shippingClassName );
|
||||
await expect(
|
||||
modal.getByText( 'New shipping class' )
|
||||
).toBeVisible();
|
||||
|
||||
await modal.getByText( 'Add' ).click();
|
||||
await modal
|
||||
.getByLabel( 'Name (Required)' )
|
||||
.fill( productData.shipping.shippingClassName );
|
||||
|
||||
await expect(
|
||||
modal.getByText( 'New shipping class' )
|
||||
).toBeHidden();
|
||||
await modal.getByText( 'Add' ).click();
|
||||
|
||||
await expect(
|
||||
page.getByLabel( 'Shipping class', { exact: true } )
|
||||
).toHaveValue( productData.shipping.shippingClassName );
|
||||
await expect(
|
||||
modal.getByText( 'New shipping class' )
|
||||
).toBeHidden();
|
||||
|
||||
// Shipping dimensions
|
||||
await page
|
||||
.getByLabel( 'Width A' )
|
||||
.fill( productData.shipping.width );
|
||||
await page
|
||||
.getByLabel( 'Length B' )
|
||||
.fill( productData.shipping.length );
|
||||
await page
|
||||
.getByLabel( 'Height C' )
|
||||
.fill( productData.shipping.height );
|
||||
await page
|
||||
.getByLabel( 'Weight' )
|
||||
.fill( productData.shipping.weight );
|
||||
} );
|
||||
await expect(
|
||||
page.getByLabel( 'Shipping class', { exact: true } )
|
||||
).toHaveValue( productData.shipping.shippingClassName );
|
||||
|
||||
await test.step( 'publish the product', async () => {
|
||||
await page
|
||||
.locator( '.woocommerce-product-header__actions' )
|
||||
.getByRole( 'button', {
|
||||
name: 'Publish',
|
||||
} )
|
||||
.click();
|
||||
// Shipping dimensions
|
||||
await page
|
||||
.getByLabel( 'Width A' )
|
||||
.fill( productData.shipping.width );
|
||||
await page
|
||||
.getByLabel( 'Length B' )
|
||||
.fill( productData.shipping.length );
|
||||
await page
|
||||
.getByLabel( 'Height C' )
|
||||
.fill( productData.shipping.height );
|
||||
await page
|
||||
.getByLabel( 'Weight' )
|
||||
.fill( productData.shipping.weight );
|
||||
} );
|
||||
|
||||
await expect(
|
||||
page.getByLabel( 'Dismiss this notice' )
|
||||
).toContainText( 'Product published' );
|
||||
await test.step( 'publish the product', async () => {
|
||||
await page
|
||||
.locator( '.woocommerce-product-header__actions' )
|
||||
.getByRole( 'button', {
|
||||
name: 'Publish',
|
||||
} )
|
||||
.click();
|
||||
|
||||
const title = page.locator(
|
||||
'.woocommerce-product-header__title'
|
||||
);
|
||||
await expect(
|
||||
page.getByLabel( 'Dismiss this notice' )
|
||||
).toContainText( 'Product published' );
|
||||
|
||||
// Save product ID
|
||||
const productIdRegex = /product%2F(\d+)/;
|
||||
const url = page.url();
|
||||
const productIdMatch = productIdRegex.exec( url );
|
||||
// This isn't really a conditional branch in the test;
|
||||
// just making sure we don't blow up if the regex doesn't match
|
||||
// (it will be caught in the expect below).
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
productId = productIdMatch ? productIdMatch[ 1 ] : null;
|
||||
const title = page.locator(
|
||||
'.woocommerce-product-header__title'
|
||||
);
|
||||
|
||||
expect( productId ).toBeDefined();
|
||||
await expect( title ).toHaveText( productData.name );
|
||||
} );
|
||||
// Save product ID
|
||||
const productIdRegex = /product%2F(\d+)/;
|
||||
const url = page.url();
|
||||
const productIdMatch = productIdRegex.exec( url );
|
||||
// This isn't really a conditional branch in the test;
|
||||
// just making sure we don't blow up if the regex doesn't match
|
||||
// (it will be caught in the expect below).
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
productId = productIdMatch ? productIdMatch[ 1 ] : null;
|
||||
|
||||
// Note for future refactoring: It would be good to reuse the verification step
|
||||
// from product-create-simple.spec.js, as both tests are just verifying that the
|
||||
// product was created correctly by looking at the front end.
|
||||
await test.step( 'verify the saved product in frontend', async () => {
|
||||
const permalink = await page
|
||||
.locator( '.product-details-section__product-link a' )
|
||||
.getAttribute( 'href' );
|
||||
expect( productId ).toBeDefined();
|
||||
await expect( title ).toHaveText( productData.name );
|
||||
} );
|
||||
|
||||
await page.goto( permalink );
|
||||
// Note for future refactoring: It would be good to reuse the verification step
|
||||
// from product-create-simple.spec.js, as both tests are just verifying that the
|
||||
// product was created correctly by looking at the front end.
|
||||
await test.step( 'verify the saved product in frontend', async () => {
|
||||
const permalink = await page
|
||||
.locator( '.product-details-section__product-link a' )
|
||||
.getAttribute( 'href' );
|
||||
|
||||
// Verify product name
|
||||
await expect(
|
||||
page.getByRole( 'heading', {
|
||||
name: productData.name,
|
||||
} )
|
||||
).toBeVisible();
|
||||
await page.goto( permalink );
|
||||
|
||||
// Verify price
|
||||
await expect(
|
||||
page.getByText( productData.productPrice ).first()
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText( productData.salePrice ).first()
|
||||
).toBeVisible();
|
||||
// Verify product name
|
||||
await expect(
|
||||
page.getByRole( 'heading', {
|
||||
name: productData.name,
|
||||
} )
|
||||
).toBeVisible();
|
||||
|
||||
// Verify summary
|
||||
await expect(
|
||||
page.getByText( productData.summary )
|
||||
).toBeVisible();
|
||||
// Verify price
|
||||
await expect(
|
||||
page.getByText( productData.productPrice ).first()
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText( productData.salePrice ).first()
|
||||
).toBeVisible();
|
||||
|
||||
// Verify description
|
||||
await page.getByRole( 'tab', { name: 'Description' } ).click();
|
||||
// Verify summary
|
||||
await expect(
|
||||
page.getByText( productData.summary )
|
||||
).toBeVisible();
|
||||
|
||||
await expect(
|
||||
page.getByText( productData.descriptionTitle )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText( productData.descriptionSimple )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText( productData.descriptionParagraph )
|
||||
).toBeVisible();
|
||||
// Verify description
|
||||
await page
|
||||
.getByRole( 'tab', { name: 'Description' } )
|
||||
.click();
|
||||
|
||||
// Verify inventory details
|
||||
await expect(
|
||||
page.getByText( `SKU: ${ productData.sku }` )
|
||||
).toBeVisible();
|
||||
// Note: GTIN is not displayed in the front end in the theme used in the test
|
||||
await expect(
|
||||
page.getByText( productData.descriptionTitle )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText( productData.descriptionSimple )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText( productData.descriptionParagraph )
|
||||
).toBeVisible();
|
||||
|
||||
// Note: Shipping class is not displayed in the front end in the theme used in the test
|
||||
// Verify inventory details
|
||||
await expect(
|
||||
page.getByText( `SKU: ${ productData.sku }` )
|
||||
).toBeVisible();
|
||||
// Note: GTIN is not displayed in the front end in the theme used in the test
|
||||
|
||||
// Verify shipping dimensions
|
||||
await page
|
||||
.getByRole( 'tab', { name: 'Additional information' } )
|
||||
.click();
|
||||
// Note: Shipping class is not displayed in the front end in the theme used in the test
|
||||
|
||||
await expect(
|
||||
page.getByText( `Weight ${ productData.shipping.weight }` )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText(
|
||||
`Dimensions ${ productData.shipping.length } × ${ productData.shipping.width } × ${ productData.shipping.height }`
|
||||
)
|
||||
).toBeVisible();
|
||||
} );
|
||||
} );
|
||||
// Verify shipping dimensions
|
||||
await page
|
||||
.getByRole( 'tab', { name: 'Additional information' } )
|
||||
.click();
|
||||
|
||||
await expect(
|
||||
page.getByText(
|
||||
`Weight ${ productData.shipping.weight }`
|
||||
)
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText(
|
||||
`Dimensions ${ productData.shipping.length } × ${ productData.shipping.width } × ${ productData.shipping.height }`
|
||||
)
|
||||
).toBeVisible();
|
||||
} );
|
||||
}
|
||||
);
|
||||
|
||||
test( 'can not create a product with duplicated SKU', async ( {
|
||||
page,
|
||||
|
|
|
@ -68,130 +68,139 @@ test.describe( 'General tab', { tag: '@gutenberg' }, () => {
|
|||
'The block product editor is not being tested'
|
||||
);
|
||||
|
||||
test( 'can create a product with linked products', async ( {
|
||||
page,
|
||||
} ) => {
|
||||
await page.goto( NEW_EDITOR_ADD_PRODUCT_URL );
|
||||
await clickOnTab( 'General', page );
|
||||
await page
|
||||
.getByPlaceholder( 'e.g. 12 oz Coffee Mug' )
|
||||
.fill( productData.name );
|
||||
await page
|
||||
.locator(
|
||||
'[data-template-block-id="basic-details"] .components-summary-control'
|
||||
)
|
||||
.last()
|
||||
.fill( productData.summary );
|
||||
test(
|
||||
'can create a product with linked products',
|
||||
{ tag: '@skip-on-default-pressable' },
|
||||
async ( { page } ) => {
|
||||
await page.goto( NEW_EDITOR_ADD_PRODUCT_URL );
|
||||
await clickOnTab( 'General', page );
|
||||
await page
|
||||
.getByPlaceholder( 'e.g. 12 oz Coffee Mug' )
|
||||
.fill( productData.name );
|
||||
await page
|
||||
.locator(
|
||||
'[data-template-block-id="basic-details"] .components-summary-control'
|
||||
)
|
||||
.last()
|
||||
.fill( productData.summary );
|
||||
|
||||
// Include in category
|
||||
await clickOnTab( 'Organization', page );
|
||||
const waitForCategoriesResponse = page.waitForResponse(
|
||||
( response ) =>
|
||||
response.url().includes( '/wp-json/wp/v2/product_cat' ) &&
|
||||
response.status() === 200
|
||||
);
|
||||
await page.getByLabel( 'Categories' ).click();
|
||||
await waitForCategoriesResponse;
|
||||
await page.getByLabel( categoryName ).check();
|
||||
await page.getByLabel( `Remove Uncategorized` ).click();
|
||||
await expect(
|
||||
page.getByLabel( `Remove ${ categoryName }` )
|
||||
).toBeVisible();
|
||||
// Include in category
|
||||
await clickOnTab( 'Organization', page );
|
||||
const waitForCategoriesResponse = page.waitForResponse(
|
||||
( response ) =>
|
||||
response
|
||||
.url()
|
||||
.includes( '/wp-json/wp/v2/product_cat' ) &&
|
||||
response.status() === 200
|
||||
);
|
||||
await page.getByLabel( 'Categories' ).click();
|
||||
await waitForCategoriesResponse;
|
||||
await page.getByLabel( categoryName ).check();
|
||||
await page.getByLabel( `Remove Uncategorized` ).click();
|
||||
await expect(
|
||||
page.getByLabel( `Remove ${ categoryName }` )
|
||||
).toBeVisible();
|
||||
|
||||
const waitForProductsSearchResponse = page.waitForResponse(
|
||||
( response ) =>
|
||||
response
|
||||
.url()
|
||||
.includes( '/wp-json/wc/v3/products?search' ) &&
|
||||
response.status() === 200
|
||||
);
|
||||
await clickOnTab( 'Linked products', page );
|
||||
await waitForProductsSearchResponse;
|
||||
const waitForProductsSearchResponse = page.waitForResponse(
|
||||
( response ) =>
|
||||
response
|
||||
.url()
|
||||
.includes( '/wp-json/wc/v3/products?search' ) &&
|
||||
response.status() === 200
|
||||
);
|
||||
await clickOnTab( 'Linked products', page );
|
||||
await waitForProductsSearchResponse;
|
||||
|
||||
await expect(
|
||||
page.getByRole( 'heading', {
|
||||
name: 'Cross-sells',
|
||||
} )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole( 'heading', {
|
||||
name: 'Cross-sells',
|
||||
} )
|
||||
).toBeVisible();
|
||||
|
||||
await page
|
||||
.locator(
|
||||
'.wp-block-woocommerce-product-linked-list-field__form-group-content'
|
||||
)
|
||||
.first()
|
||||
.getByRole( 'combobox' )
|
||||
.fill( productName );
|
||||
await page
|
||||
.locator(
|
||||
'.wp-block-woocommerce-product-linked-list-field__form-group-content'
|
||||
)
|
||||
.first()
|
||||
.getByRole( 'combobox' )
|
||||
.fill( productName );
|
||||
|
||||
await page.getByText( linkedProductsData[ 0 ].name ).click();
|
||||
await page.getByText( linkedProductsData[ 0 ].name ).click();
|
||||
|
||||
const chooseProductsResponsePromise = page.waitForResponse(
|
||||
( response ) =>
|
||||
response
|
||||
.url()
|
||||
.includes(
|
||||
'/wp-json/wc/v3/products/suggested-products'
|
||||
) && response.status() === 200
|
||||
);
|
||||
const chooseProductsResponsePromise = page.waitForResponse(
|
||||
( response ) =>
|
||||
response
|
||||
.url()
|
||||
.includes(
|
||||
'/wp-json/wc/v3/products/suggested-products'
|
||||
) && response.status() === 200
|
||||
);
|
||||
|
||||
await page.getByText( 'Choose products for me' ).first().click();
|
||||
await chooseProductsResponsePromise;
|
||||
await page
|
||||
.getByText( 'Choose products for me' )
|
||||
.first()
|
||||
.click();
|
||||
await chooseProductsResponsePromise;
|
||||
|
||||
await expect(
|
||||
page.getByRole( 'row', { name: productName } )
|
||||
).toHaveCount( 4 );
|
||||
await expect(
|
||||
page.getByRole( 'row', { name: productName } )
|
||||
).toHaveCount( 4 );
|
||||
|
||||
const upsellsRows = page.locator(
|
||||
'div.woocommerce-product-list div[role="table"] div[role="rowgroup"] div[role="row"]'
|
||||
);
|
||||
const upsellsRows = page.locator(
|
||||
'div.woocommerce-product-list div[role="table"] div[role="rowgroup"] div[role="row"]'
|
||||
);
|
||||
|
||||
await expect( upsellsRows ).toHaveCount( 4 );
|
||||
await expect( upsellsRows ).toHaveCount( 4 );
|
||||
|
||||
await page
|
||||
.locator(
|
||||
'.wp-block-woocommerce-product-linked-list-field__form-group-content'
|
||||
)
|
||||
.last()
|
||||
.getByRole( 'combobox' )
|
||||
.fill( linkedProductsData[ 1 ].name );
|
||||
await page
|
||||
.locator(
|
||||
'.wp-block-woocommerce-product-linked-list-field__form-group-content'
|
||||
)
|
||||
.last()
|
||||
.getByRole( 'combobox' )
|
||||
.fill( linkedProductsData[ 1 ].name );
|
||||
|
||||
await page
|
||||
.getByText( linkedProductsData[ 1 ].name )
|
||||
.first()
|
||||
.click();
|
||||
await page
|
||||
.getByText( linkedProductsData[ 1 ].name )
|
||||
.first()
|
||||
.click();
|
||||
|
||||
await page
|
||||
.locator( '.woocommerce-product-header__actions' )
|
||||
.getByRole( 'button', {
|
||||
name: 'Publish',
|
||||
} )
|
||||
.click();
|
||||
await page
|
||||
.locator( '.woocommerce-product-header__actions' )
|
||||
.getByRole( 'button', {
|
||||
name: 'Publish',
|
||||
} )
|
||||
.click();
|
||||
|
||||
await expect(
|
||||
page.getByLabel( 'Dismiss this notice' )
|
||||
).toContainText( 'Product published' );
|
||||
await expect(
|
||||
page.getByLabel( 'Dismiss this notice' )
|
||||
).toContainText( 'Product published' );
|
||||
|
||||
const title = page.locator( '.woocommerce-product-header__title' );
|
||||
const title = page.locator(
|
||||
'.woocommerce-product-header__title'
|
||||
);
|
||||
|
||||
// Save product ID
|
||||
const productIdRegex = /product%2F(\d+)/;
|
||||
const url = page.url();
|
||||
const productIdMatch = productIdRegex.exec( url );
|
||||
productId = productIdMatch ? productIdMatch[ 1 ] : null;
|
||||
// Save product ID
|
||||
const productIdRegex = /product%2F(\d+)/;
|
||||
const url = page.url();
|
||||
const productIdMatch = productIdRegex.exec( url );
|
||||
productId = productIdMatch ? productIdMatch[ 1 ] : null;
|
||||
|
||||
await expect( productId ).toBeDefined();
|
||||
await expect( title ).toHaveText( productData.name );
|
||||
await expect( productId ).toBeDefined();
|
||||
await expect( title ).toHaveText( productData.name );
|
||||
|
||||
await page.goto( `/?post_type=product&p=${ productId }` );
|
||||
await page.goto( `/?post_type=product&p=${ productId }` );
|
||||
|
||||
await expect(
|
||||
page.getByRole( 'heading', { name: productData.name } )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole( 'heading', { name: productData.name } )
|
||||
).toBeVisible();
|
||||
|
||||
const productsList = page.locator(
|
||||
'section.upsells.products ul > li'
|
||||
);
|
||||
const productsList = page.locator(
|
||||
'section.upsells.products ul > li'
|
||||
);
|
||||
|
||||
await expect( productsList ).toHaveCount( 4 );
|
||||
} );
|
||||
await expect( productsList ).toHaveCount( 4 );
|
||||
}
|
||||
);
|
||||
} );
|
||||
} );
|
||||
|
|
Loading…
Reference in New Issue