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