Update eslint parser to @babel/eslint-parser (#43859)

This commit is contained in:
Adrian Moldovan 2024-01-24 13:06:51 +02:00 committed by GitHub
parent a6210ba312
commit 0aebb139c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 2328 additions and 1622 deletions

View File

@ -17,7 +17,7 @@ module.exports = {
indent: 0,
'no-console': 1,
},
parser: 'babel-eslint',
parser: '@babel/eslint-parser',
parserOptions: {
ecmaVersion: 8,
ecmaFeatures: {
@ -28,13 +28,13 @@ module.exports = {
},
overrides: [
{
files: ["tests/e2e-pw/**/*.spec.js", "tests/e2e/**/*.spec.js"],
files: [ 'tests/e2e/**/*.spec.js' ],
rules: {
"jest/no-test-callback": "off",
"@wordpress/no-unsafe-wp-apis": "off",
"import/no-extraneous-dependencies": "off",
"import/no-unresolved": "off"
}
'jest/no-test-callback': 'off',
'@wordpress/no-unsafe-wp-apis': 'off',
'import/no-extraneous-dependencies': 'off',
'import/no-unresolved': 'off',
},
},
]
],
};

View File

@ -0,0 +1,4 @@
Significance: patch
Type: dev
Fix eslint parser

View File

@ -215,6 +215,7 @@
"eslint": "^8.55.0",
"eslint-config-wpcalypso": "5.0.0",
"eslint-plugin-jest": "23.20.0",
"eslint-plugin-playwright": "0.22.1",
"istanbul": "1.0.0-alpha.2",
"jest": "~27.5.1",
"mocha": "7.2.0",

View File

@ -0,0 +1,9 @@
module.exports = {
extends: [ 'plugin:playwright/recommended' ],
rules: {
'playwright/no-skipped-test': 'off',
'no-console': 'off',
'jest/no-test-callback': 'off',
'jest/no-disabled-tests': 'off',
},
};

View File

@ -61,7 +61,7 @@ module.exports = async ( config ) => {
for ( let i = 0; i < adminRetries; i++ ) {
try {
console.log( 'Trying to log-in as admin...' );
await adminPage.goto( `/wp-admin`, { waitUntil: 'networkidle' } );
await adminPage.goto( `/wp-admin` );
await adminPage
.locator( 'input[name="log"]' )
.fill( admin.username );
@ -69,6 +69,7 @@ module.exports = async ( config ) => {
.locator( 'input[name="pwd"]' )
.fill( admin.password );
await adminPage.locator( 'text=Log In' ).click();
// eslint-disable-next-line playwright/no-networkidle
await adminPage.waitForLoadState( 'networkidle' );
await adminPage.goto( `/wp-admin` );
await adminPage.waitForLoadState( 'domcontentloaded' );
@ -142,9 +143,7 @@ module.exports = async ( config ) => {
for ( let i = 0; i < customerRetries; i++ ) {
try {
console.log( 'Trying to log-in as customer...' );
await customerPage.goto( `/wp-admin`, {
waitUntil: 'networkidle',
} );
await customerPage.goto( `/wp-admin` );
await customerPage
.locator( 'input[name="log"]' )
.fill( customer.username );
@ -190,7 +189,7 @@ module.exports = async ( config ) => {
// (if a value for ENABLE_HPOS was set)
// This was always being set to 'yes' after login in wp-env so this step ensures the
// correct value is set before we begin our tests
if (ENABLE_HPOS) {
if ( ENABLE_HPOS ) {
const hposSettingRetries = 5;
const api = new wcApi( {
url: baseURL,
@ -201,18 +200,31 @@ module.exports = async ( config ) => {
const value = ENABLE_HPOS === '0' ? 'no' : 'yes';
for (let i = 0; i < hposSettingRetries; i++) {
for ( let i = 0; i < hposSettingRetries; i++ ) {
try {
console.log( `Trying to switch ${ value === 'yes' ? 'on' : 'off' } HPOS...` );
const response = await api.post( 'settings/advanced/woocommerce_custom_orders_table_enabled', { value } );
console.log(
`Trying to switch ${
value === 'yes' ? 'on' : 'off'
} HPOS...`
);
const response = await api.post(
'settings/advanced/woocommerce_custom_orders_table_enabled',
{ value }
);
if ( response.data.value === value ) {
console.log( `HPOS Switched ${ value === 'yes' ? 'on' : 'off' } successfully` );
console.log(
`HPOS Switched ${
value === 'yes' ? 'on' : 'off'
} successfully`
);
hposConfigured = true;
break;
}
} catch (e) {
console.log( `HPOS setup failed. Retrying... ${ i }/${ hposSettingRetries }` );
console.log(e);
} catch ( e ) {
console.log(
`HPOS setup failed. Retrying... ${ i }/${ hposSettingRetries }`
);
console.log( e );
}
}

View File

@ -19,7 +19,7 @@ module.exports = async ( config ) => {
for ( let i = 0; i < keysRetries; i++ ) {
try {
console.log( 'Trying to clear consumer token... Try:' + i );
await adminPage.goto( `/wp-admin`, { waitUntil: 'networkidle' } );
await adminPage.goto( `/wp-admin` );
await adminPage
.locator( 'input[name="log"]' )
.fill( admin.username );
@ -27,6 +27,7 @@ module.exports = async ( config ) => {
.locator( 'input[name="pwd"]' )
.fill( admin.password );
await adminPage.locator( 'text=Log In' ).click();
// eslint-disable-next-line playwright/no-networkidle
await adminPage.waitForLoadState( 'networkidle' );
await adminPage.goto(
`/wp-admin/admin.php?page=wc-settings&tab=advanced&section=keys`
@ -40,35 +41,51 @@ module.exports = async ( config ) => {
console.log( 'Clearing pages...' );
// clear pages created
await adminPage.goto( '/wp-admin/edit.php?s=page-&post_status=all&post_type=page', { waitForLoadState: 'networkidle' } );
if ( !adminPage.getByText( 'No pages found.') ) {
await adminPage.goto(
'/wp-admin/edit.php?s=page-&post_status=all&post_type=page'
);
if ( ! adminPage.getByText( 'No pages found.' ) ) {
await adminPage.locator( '#cb-select-all-1' ).check();
await adminPage.locator( '#bulk-action-selector-top' ).selectOption( 'Move to Trash' );
await adminPage
.locator( '#bulk-action-selector-top' )
.selectOption( 'Move to Trash' );
await adminPage.locator( '#doaction' ).click();
}
// clear mini cart pages
await adminPage.goto( '/wp-admin/edit.php?s=Mini+Cart&post_status=all&post_type=page', { waitForLoadState: 'networkidle' } );
if ( !adminPage.getByText( 'No pages found.') ) {
await adminPage.goto(
'/wp-admin/edit.php?s=Mini+Cart&post_status=all&post_type=page'
);
if ( ! adminPage.getByText( 'No pages found.' ) ) {
await adminPage.locator( '#cb-select-all-1' ).check();
await adminPage.locator( '#bulk-action-selector-top' ).selectOption( 'Move to Trash' );
await adminPage
.locator( '#bulk-action-selector-top' )
.selectOption( 'Move to Trash' );
await adminPage.locator( '#doaction' ).click();
}
// clear product showcase pages
await adminPage.goto( '/wp-admin/edit.php?s=Product+Showcase&post_status=all&post_type=page', { waitForLoadState: 'networkidle' } );
if ( !adminPage.getByText( 'No pages found.') ) {
await adminPage.goto(
'/wp-admin/edit.php?s=Product+Showcase&post_status=all&post_type=page'
);
if ( ! adminPage.getByText( 'No pages found.' ) ) {
await adminPage.locator( '#cb-select-all-1' ).check();
await adminPage.locator( '#bulk-action-selector-top' ).selectOption( 'Move to Trash' );
await adminPage
.locator( '#bulk-action-selector-top' )
.selectOption( 'Move to Trash' );
await adminPage.locator( '#doaction' ).click();
}
console.log( 'Clearing posts...' );
// clear posts
await adminPage.goto( '/wp-admin/edit.php?s=Post-&post_status=all&post_type=post', { waitForLoadState: 'networkidle' } );
if ( !adminPage.getByText( 'No posts found.') ) {
await adminPage.goto(
'/wp-admin/edit.php?s=Post-&post_status=all&post_type=post'
);
if ( ! adminPage.getByText( 'No posts found.' ) ) {
await adminPage.locator( '#cb-select-all-1' ).check();
await adminPage.locator( '#bulk-action-selector-top' ).selectOption( 'Move to Trash' );
await adminPage
.locator( '#bulk-action-selector-top' )
.selectOption( 'Move to Trash' );
await adminPage.locator( '#doaction' ).click();
}

View File

@ -25,7 +25,14 @@ const config = {
workers: CI ? 1 : 4,
reporter: [
[ 'list' ],
[ 'blob', { outputFolder: ALLURE_RESULTS_DIR ?? './tests/e2e-pw/test-results/allure-results' } ],
[
'blob',
{
outputFolder:
ALLURE_RESULTS_DIR ??
'./tests/e2e-pw/test-results/allure-results',
},
],
[
'html',
{

View File

@ -1,20 +1,17 @@
const { test, expect } = require( '@playwright/test' );
test.describe(
'Store owner can login and make sure WooCommerce is activated',
() => {
test.use( { storageState: process.env.ADMINSTATE } );
test.describe( 'Store owner can login and make sure WooCommerce is activated', () => {
test.use( { storageState: process.env.ADMINSTATE } );
test( 'can make sure WooCommerce is activated.', async ( { page } ) => {
await page.goto( '/wp-admin/plugins.php' );
// Expect the woo plugin to be displayed -- if there's an update available, it has the same data-slug attribute
await expect(
page.locator( "//tr[@data-slug='woocommerce'][1]" )
).toBeVisible();
// Expect it to have an active class
await expect(
page.locator( "//tr[@data-slug='woocommerce'][1]" )
).toHaveClass( /active/ );
} );
}
);
test( 'can make sure WooCommerce is activated.', async ( { page } ) => {
await page.goto( '/wp-admin/plugins.php' );
// Expect the woo plugin to be displayed -- if there's an update available, it has the same data-slug attribute
await expect(
page.locator( "//tr[@data-slug='woocommerce'][1]" )
).toBeVisible();
// Expect it to have an active class
await expect(
page.locator( "//tr[@data-slug='woocommerce'][1]" )
).toHaveClass( /active/ );
} );
} );

View File

@ -6,7 +6,7 @@ test.describe( 'Analytics-related tests', () => {
test.use( { storageState: process.env.ADMINSTATE } );
test.beforeAll( async( { baseURL, browser } ) => {
test.beforeAll( async ( { baseURL, browser } ) => {
const api = new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,
@ -14,25 +14,26 @@ test.describe( 'Analytics-related tests', () => {
version: 'wc/v3',
} );
// create a couple of product categories
await api.post( 'products/categories/batch', {
create: [
{ name: 'Easy' },
{ name: 'Complicated' },
]
} ).then( ( response ) => {
categoryIds = response.data.create.map(category => category.id);
} );
await api
.post( 'products/categories/batch', {
create: [ { name: 'Easy' }, { name: 'Complicated' } ],
} )
.then( ( response ) => {
categoryIds = response.data.create.map(
( category ) => category.id
);
} );
// create a number of products to be used in orders
const productsArray = [];
const ordersArray = [];
let variationIds = [];
const variationIds = [];
// 3 simple products
for ( let i = 1; i < 4; i++ ) {
productsArray.push( {
name: `Product ${ i }`,
type: "simple",
type: 'simple',
regular_price: `${ i }0.99`,
categories: [ { id: categoryIds[ 0 ] } ],
} );
@ -41,14 +42,14 @@ test.describe( 'Analytics-related tests', () => {
productsArray.push( {
name: 'Variable Product',
type: 'variable',
categories: [ { id: categoryIds[1] } ],
categories: [ { id: categoryIds[ 1 ] } ],
attributes: [
{
name: 'Colour',
options: [ 'Red', 'Blue', 'Orange', 'Green' ],
visible: true,
variation: true,
}
},
],
} );
const variations = [
@ -89,19 +90,25 @@ test.describe( 'Analytics-related tests', () => {
],
},
];
await api.post( 'products/batch', {
create: productsArray
} ).then( ( response ) => {
productIds = response.data.create.map( item => item.id );
} );
await api
.post( 'products/batch', {
create: productsArray,
} )
.then( ( response ) => {
productIds = response.data.create.map( ( item ) => item.id );
} );
// set up the variations on the variable product
for ( const key in variations ) {
await api.post(
`products/${ productIds[productIds.length - 1 ]}/variations`,
variations[ key ]
).then( ( response ) => {
variationIds.push( response.data.id );
} );
await api
.post(
`products/${
productIds[ productIds.length - 1 ]
}/variations`,
variations[ key ]
)
.then( ( response ) => {
variationIds.push( response.data.id );
} );
}
// set up 10 orders
@ -110,32 +117,34 @@ test.describe( 'Analytics-related tests', () => {
status: 'completed',
line_items: [
{
product_id: productIds[0],
quantity: 5
product_id: productIds[ 0 ],
quantity: 5,
},
{
product_id: productIds[1],
quantity: 2
product_id: productIds[ 1 ],
quantity: 2,
},
{
product_id: productIds[3],
variation_id: variationIds[1],
quantity: 3
product_id: productIds[ 3 ],
variation_id: variationIds[ 1 ],
quantity: 3,
},
{
product_id: productIds[3],
variation_id: variationIds[3],
quantity: 1
}
]
product_id: productIds[ 3 ],
variation_id: variationIds[ 3 ],
quantity: 1,
},
],
} );
}
// create the orders
await api.post( 'orders/batch', {
create: ordersArray
} ).then( ( response ) => {
orderIds = response.data.create.map( order => order.id );
} );
await api
.post( 'orders/batch', {
create: ordersArray,
} )
.then( ( response ) => {
orderIds = response.data.create.map( ( order ) => order.id );
} );
// process the Action Scheduler tasks
setupPage = await browser.newPage();
@ -143,7 +152,7 @@ test.describe( 'Analytics-related tests', () => {
await setupPage.goto( '?process-waiting-actions' );
} );
test.afterAll( async( { baseURL } ) => {
test.afterAll( async ( { baseURL } ) => {
const api = new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,
@ -158,193 +167,468 @@ test.describe( 'Analytics-related tests', () => {
await api.post( 'orders/batch', { delete: orderIds } );
} );
test( 'confirms correct summary numbers on overview page', async( { page } ) => {
await page.goto( '/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Foverview' );
test( 'confirms correct summary numbers on overview page', async ( {
page,
} ) => {
await page.goto(
'/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Foverview'
);
await expect( page.getByRole( 'menuitem', { name: 'Total sales $1,229.30 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Net sales $1,229.30 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Orders 10 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Products sold 110 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Variations Sold 40 No change from Previous year:' } ) ).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Total sales $1,229.30 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Net sales $1,229.30 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Orders 10 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Products sold 110 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Variations Sold 40 No change from Previous year:',
} )
).toBeVisible();
} );
test( 'downloads revenue report as CSV', async( { page } ) => {
await page.goto( '/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Frevenue' );
test( 'downloads revenue report as CSV', async ( { page } ) => {
await page.goto(
'/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Frevenue'
);
// FTUX tour on first run through
try {
await page.getByLabel('Close Tour').click( { timeout: 5000 } );
} catch (e) {
await page.getByLabel( 'Close Tour' ).click( { timeout: 5000 } );
} catch ( e ) {
console.log( 'Tour was not visible, skipping.' );
}
// the revenue report can either download immediately, or get mailed.
try {
await page.getByRole( 'button', { name: 'Download' } ).click();
await expect( page.locator( '.components-snackbar' ) ).toBeVisible( { timeout: 10000 } ); // fail fast if the snackbar doesn't display
await expect( page.locator( '.components-snackbar' ) ).toHaveText( 'Your Revenue Report will be emailed to you.' );
} catch (e) {
await expect( page.locator( '.components-snackbar' ) ).toBeVisible(
{ timeout: 10000 }
); // fail fast if the snackbar doesn't display
await expect( page.locator( '.components-snackbar' ) ).toHaveText(
'Your Revenue Report will be emailed to you.'
);
} catch ( e ) {
const downloadPromise = page.waitForEvent( 'download' );
await page.getByRole( 'button', { name: 'Download' } ).click();
const download = await downloadPromise;
await expect( download.suggestedFilename() ).toContain( 'revenue.csv' );
// eslint-disable-next-line jest/no-try-expect
await expect( download.suggestedFilename() ).toContain(
'revenue.csv'
);
}
} );
test( 'use date filter on overview page', async( { page } ) => {
await page.goto( '/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Foverview' );
test( 'use date filter on overview page', async ( { page } ) => {
await page.goto(
'/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Foverview'
);
// assert that current month is shown and that values are for that
await expect( page.getByText( 'Month to date' ).first() ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Total sales $1,229.30 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Net sales $1,229.30 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Orders 10 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Products sold 110 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Variations Sold 40 No change from Previous year:' } ) ).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Total sales $1,229.30 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Net sales $1,229.30 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Orders 10 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Products sold 110 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Variations Sold 40 No change from Previous year:',
} )
).toBeVisible();
// click the date filter and change to Last month (should be no sales/orders)
await page.getByRole( 'button', { name: 'Month to date' } ).click();
await page.getByText( 'Last month' ).click();
await page.getByRole( 'button', { name: 'Update' } ).click();
await expect( page.getByRole( 'menuitem', { name: 'Total sales $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Net sales $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Orders 0 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Products sold 0 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Variations Sold 0 No change from Previous year:' } ) ).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Total sales $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Net sales $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Orders 0 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Products sold 0 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Variations Sold 0 No change from Previous year:',
} )
).toBeVisible();
} );
test( 'use date filter on revenue report', async( { page } ) => {
await page.goto( '/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Frevenue' );
test( 'use date filter on revenue report', async ( { page } ) => {
await page.goto(
'/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Frevenue'
);
// FTUX tour on first run through
try {
await page.getByLabel('Close Tour').click( { timeout: 5000 } );
} catch (e) {
await page.getByLabel( 'Close Tour' ).click( { timeout: 5000 } );
} catch ( e ) {
console.log( 'Tour was not visible, skipping.' );
}
// assert that current month is shown and that values are for that
await expect( page.getByText( 'Month to date' ).first() ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Gross sales $1,229.30 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Returns $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Coupons $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Net sales $1,229.30 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Taxes $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Shipping $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Total sales $1,229.30 No change from Previous year:' } ) ).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Gross sales $1,229.30 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Returns $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Coupons $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Net sales $1,229.30 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Taxes $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Shipping $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Total sales $1,229.30 No change from Previous year:',
} )
).toBeVisible();
// click the date filter and change to Last month (should be no sales/orders)
await page.getByRole( 'button', { name: 'Month to date' } ).click();
await page.getByText( 'Last month' ).click();
await page.getByRole( 'button', { name: 'Update' } ).click();
await expect( page.getByRole( 'menuitem', { name: 'Gross sales $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Returns $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Coupons $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Net sales $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Taxes $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Shipping $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Total sales $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Gross sales $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Returns $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Coupons $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Net sales $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Taxes $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Shipping $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Total sales $0.00 No change from Previous year:',
} )
).toBeVisible();
} );
test( 'set custom date range on revenue report', async( { page } ) => {
await page.goto( '/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Frevenue' );
test( 'set custom date range on revenue report', async ( { page } ) => {
await page.goto(
'/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Frevenue'
);
// FTUX tour on first run through
try {
await page.getByLabel('Close Tour').click( { timeout: 5000 } );
} catch (e) {
await page.getByLabel( 'Close Tour' ).click( { timeout: 5000 } );
} catch ( e ) {
console.log( 'Tour was not visible, skipping.' );
}
// assert that current month is shown and that values are for that
await expect( page.getByText( 'Month to date' ).first() ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Gross sales $1,229.30 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Returns $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Coupons $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Net sales $1,229.30 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Taxes $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Shipping $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Total sales $1,229.30 No change from Previous year:' } ) ).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Gross sales $1,229.30 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Returns $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Coupons $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Net sales $1,229.30 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Taxes $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Shipping $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Total sales $1,229.30 No change from Previous year:',
} )
).toBeVisible();
// click the date filter and change to custom date range (should be no sales/orders)
await page.getByRole( 'button', { name: 'Month to date' } ).click();
await page.getByText( 'Custom', { exact: true } ).click();
await page.getByPlaceholder( 'mm/dd/yyyy' ).first().fill( '01/01/2022' );
await page
.getByPlaceholder( 'mm/dd/yyyy' )
.first()
.fill( '01/01/2022' );
await page.getByPlaceholder( 'mm/dd/yyyy' ).last().fill( '01/30/2022' );
await page.getByRole( 'button', { name: 'Update' } ).click();
// assert values updated
await expect( page.getByRole( 'button', { name: 'Custom (Jan 1 - 30, 2022) vs. Previous year (Jan 1 - 30, 2021)'} ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Gross sales $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Returns $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Coupons $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Net sales $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Taxes $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Shipping $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Total sales $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect(
page.getByRole( 'button', {
name: 'Custom (Jan 1 - 30, 2022) vs. Previous year (Jan 1 - 30, 2021)',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Gross sales $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Returns $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Coupons $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Net sales $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Taxes $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Shipping $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Total sales $0.00 No change from Previous year:',
} )
).toBeVisible();
} );
test( 'use advanced filters on orders report', async( { page } ) => {
await page.goto( '/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Forders' );
test( 'use advanced filters on orders report', async ( { page } ) => {
await page.goto(
'/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Forders'
);
// FTUX tour on first run through
try {
await page.getByLabel('Close Tour').click( { timeout: 5000 } );
} catch (e) {
await page.getByLabel( 'Close Tour' ).click( { timeout: 5000 } );
} catch ( e ) {
console.log( 'Tour was not visible, skipping.' );
}
// no filters applied
await expect( page.getByRole( 'menuitem', { name: 'Orders 10 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Net sales $1,229.30 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Average order value $122.93 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Average items per order 11 No change from Previous year:' } ) ).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Orders 10 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Net sales $1,229.30 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Average order value $122.93 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Average items per order 11 No change from Previous year:',
} )
).toBeVisible();
// apply some filters
await page.getByRole('button', { name: 'All orders' }).click();
await page.getByRole( 'button', { name: 'All orders' } ).click();
await page.getByText( 'Advanced filters' ).click();
await page.getByRole( 'button', { name: 'Add a Filter' } ).click();
await page.getByRole( 'button', { name: 'Order Status' } ).click();
await page.getByLabel( 'Select an order status filter match' ).selectOption( 'Is' );
await page.getByLabel( 'Select an order status', { exact: true } ).selectOption( 'Failed' );
await page
.getByLabel( 'Select an order status filter match' )
.selectOption( 'Is' );
await page
.getByLabel( 'Select an order status', { exact: true } )
.selectOption( 'Failed' );
await page.getByRole( 'link', { name: 'Filter', exact: true } ).click();
await expect( page.getByRole( 'menuitem', { name: 'Orders 0 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Net sales $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Average order value $0.00 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Average items per order 0 No change from Previous year:' } ) ).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Orders 0 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Net sales $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Average order value $0.00 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Average items per order 0 No change from Previous year:',
} )
).toBeVisible();
await page.getByLabel( 'Select an order status', { exact: true } ).selectOption( 'Completed' );
await page
.getByLabel( 'Select an order status', { exact: true } )
.selectOption( 'Completed' );
await page.getByRole( 'link', { name: 'Filter', exact: true } ).click();
await expect( page.getByRole( 'menuitem', { name: 'Orders 10 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Net sales $1,229.30 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Average order value $122.93 No change from Previous year:' } ) ).toBeVisible();
await expect( page.getByRole( 'menuitem', { name: 'Average items per order 11 No change from Previous year:' } ) ).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Orders 10 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Net sales $1,229.30 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Average order value $122.93 No change from Previous year:',
} )
).toBeVisible();
await expect(
page.getByRole( 'menuitem', {
name: 'Average items per order 11 No change from Previous year:',
} )
).toBeVisible();
} );
test( 'analytics settings' , async( { page } ) => {
await page.goto( '/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Fsettings' );
page.on('dialog', dialog => dialog.accept());
test( 'analytics settings', async ( { page } ) => {
await page.goto(
'/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Fsettings'
);
page.on( 'dialog', ( dialog ) => dialog.accept() );
// change some settings
await page.getByRole( 'checkbox', { name: 'On hold' } ).first().click();
await page.getByRole( 'checkbox', { name: 'Pending payment' } ).last().click();
await page
.getByRole( 'checkbox', { name: 'Pending payment' } )
.last()
.click();
await page.getByRole( 'checkbox', { name: 'Failed' } ).last().click();
await page.getByRole( 'button', { name: 'Month to date' } ).click();
await page.getByText( 'Week to date' ).click();
await page.getByRole( 'button', { name: 'Update' } ).click();
await page.getByRole( 'button', { name: 'Save settings' } ).click();
await expect( page.getByText( 'Your settings have been successfully saved.' ).first() ).toBeVisible();
await expect(
page
.getByText( 'Your settings have been successfully saved.' )
.first()
).toBeVisible();
await page.reload();
await expect( page.getByRole( 'checkbox', { name: 'On hold' } ).first() ).toBeChecked();
await expect( page.getByRole( 'checkbox', { name: 'Pending payment' } ).last() ).toBeChecked();
await expect( page.getByRole( 'checkbox', { name: 'Failed' } ).last() ).toBeChecked();
await expect( await page.getByRole( 'button', { name: 'Week to date' } ) ).toBeVisible();
await expect(
page.getByRole( 'checkbox', { name: 'On hold' } ).first()
).toBeChecked();
await expect(
page.getByRole( 'checkbox', { name: 'Pending payment' } ).last()
).toBeChecked();
await expect(
page.getByRole( 'checkbox', { name: 'Failed' } ).last()
).toBeChecked();
await expect(
page.getByRole( 'button', { name: 'Week to date' } )
).toBeVisible();
// reset to default settings
await page.getByRole( 'button', { name: 'Reset defaults' } ).click();
await expect( page.getByText( 'Your settings have been successfully saved.' ).first() ).toBeVisible();
await expect(
page
.getByText( 'Your settings have been successfully saved.' )
.first()
).toBeVisible();
} );
} );

View File

@ -3,32 +3,34 @@ const { admin } = require( '../../test-data/data' );
const EXPECTED_SECTION_HEADERS = [ 'Performance', 'Charts', 'Leaderboards' ];
let /**
* @type {number}
*/
userId,
/**
* @type {Locator}
*/
headings_sections,
/**
* @type {Locator}
*/
heading_performance,
/**
* @type {Locator}
*/
buttons_ellipsis,
/**
* @type {Locator}
*/ menuitem_moveUp,
/**
* @type {Locator}
*/ menuitem_moveDown,
/**
* @type {Page}
*/
page;
/**
* @type {number}
*/
let userId;
/**
* @type {Locator}
*/
let headings_sections;
/**
* @type {Locator}
*/
let heading_performance;
/**
* @type {Locator}
*/
let buttons_ellipsis;
/**
* @type {Locator}
*/
let menuitem_moveUp;
/**
* @type {Locator}
*/
let menuitem_moveDown;
/**
* @type {Page}
*/
let page;
const base64String = Buffer.from(
`${ admin.username }:${ admin.password }`
@ -55,13 +57,11 @@ const hidePerformanceSection = async () => {
},
};
const response = await request.post( url, {
return await request.post( url, {
data,
params,
headers,
} );
return response;
} );
await test.step( `Assert response status is OK`, async () => {
@ -92,13 +92,11 @@ const resetSections = async () => {
},
};
const response = await request.post( url, {
return await request.post( url, {
data,
params,
headers,
} );
return response;
} );
await test.step( `Assert response status is OK`, async () => {
@ -190,14 +188,14 @@ test.describe( 'Analytics pages', () => {
test( 'should not display move up for the top, or move down for the bottom section', async () => {
await test.step( `Check the top section`, async () => {
await buttons_ellipsis.first().click();
await expect( menuitem_moveUp ).not.toBeVisible();
await expect( menuitem_moveUp ).toBeHidden();
await expect( menuitem_moveDown ).toBeVisible();
await page.keyboard.press( 'Escape' );
} );
await test.step( `Check the bottom section`, async () => {
await buttons_ellipsis.last().click();
await expect( menuitem_moveDown ).not.toBeVisible();
await expect( menuitem_moveDown ).toBeHidden();
await expect( menuitem_moveUp ).toBeVisible();
await page.keyboard.press( 'Escape' );
} );
@ -261,7 +259,7 @@ test.describe( 'Analytics pages', () => {
await test.step( `Expect the Performance section to be hidden`, async () => {
await expect( headings_sections ).toHaveCount( 2 );
await expect( heading_performance ).not.toBeVisible();
await expect( heading_performance ).toBeHidden();
} );
} );

View File

@ -4,7 +4,7 @@ const wcApi = require( '@woocommerce/woocommerce-rest-api' ).default;
test.describe( 'Payment setup task', () => {
test.use( { storageState: process.env.ADMINSTATE } );
test.beforeEach( async ( { page, baseURL } ) => {
test.beforeEach( async ( { baseURL } ) => {
await new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,

View File

@ -12,7 +12,7 @@ test.describe( 'Manage webhooks', () => {
version: 'wc/v3',
} );
await api.get( 'webhooks' ).then( ( response ) => {
let ids = response.data.map( webhook => webhook.id );
const ids = response.data.map( ( webhook ) => webhook.id );
api.post( 'webhooks/batch', {
delete: ids,
@ -20,11 +20,12 @@ test.describe( 'Manage webhooks', () => {
} );
} );
const WEBHOOKS_SCREEN_URI = 'wp-admin/admin.php?page=wc-settings&tab=advanced&section=webhooks';
const WEBHOOKS_SCREEN_URI =
'wp-admin/admin.php?page=wc-settings&tab=advanced&section=webhooks';
test( 'Webhook cannot be bulk deleted without nonce', async ( {
page,
} ) => {
page,
} ) => {
await page.goto( WEBHOOKS_SCREEN_URI, { waitUntil: 'networkidle' } );
await page.getByRole( 'link', { name: 'Add webhook' } ).click();
@ -37,25 +38,35 @@ test.describe( 'Manage webhooks', () => {
await page.waitForLoadState( 'networkidle' );
await expect( page.getByText( 'Webhook updated successfully.' ) ).toBeVisible( { timeout: 1 } );
await expect(
page.getByText( 'Webhook updated successfully.' )
).toBeVisible( { timeout: 1 } );
await page.goto( WEBHOOKS_SCREEN_URI, { waitUntil: 'networkidle' } );
await expect( page.getByRole( 'row', { name: 'Webhook 1' } ) ).toBeVisible( { timeout: 1 } );
await expect(
page.getByRole( 'row', { name: 'Webhook 1' } )
).toBeVisible( { timeout: 1 } );
let editURL = await page.getByRole( 'link', { name: 'Webhook 1', exact: true } ).getAttribute( 'href' );
let editURL = await page
.getByRole( 'link', { name: 'Webhook 1', exact: true } )
.getAttribute( 'href' );
editURL = new URL( editURL );
const origin = editURL.origin;
const webhookID = editURL.searchParams.get( 'edit-webhook' );
let actionURI = new URL( origin + '/' + WEBHOOKS_SCREEN_URI );
const actionURI = new URL( origin + '/' + WEBHOOKS_SCREEN_URI );
actionURI.searchParams.set( 'action', 'delete' );
actionURI.searchParams.set( 'webhook[]', webhookID );
await page.goto( actionURI.toString(), { waitUntil: 'networkidle' } );
await expect( page.getByText( 'webhook permanently deleted' ) ).not.toBeVisible( { timeout: 1 } );
await expect(
page.getByText( 'webhook permanently deleted' )
).toBeHidden( { timeout: 1 } );
await expect( page.getByText( 'The link you followed has expired.' ) ).toBeVisible( { timeout: 1 } );
await expect(
page.getByText( 'The link you followed has expired.' )
).toBeVisible( { timeout: 1 } );
} );
} );

View File

@ -1,36 +1,31 @@
const { test, expect } = require( '@playwright/test' );
test.describe(
'A basic set of tests to ensure WP, wp-admin and my-account load',
() => {
test( 'Load the home page', async ( { page } ) => {
await page.goto( '/' );
const title = page.locator( 'h1.site-title' );
await expect( title ).toHaveText(
'WooCommerce Core E2E Test Suite'
);
} );
test.describe( 'A basic set of tests to ensure WP, wp-admin and my-account load', () => {
test( 'Load the home page', async ( { page } ) => {
await page.goto( '/' );
const title = page.locator( 'h1.site-title' );
await expect( title ).toHaveText( 'WooCommerce Core E2E Test Suite' );
} );
test.describe( 'Sign in as admin', () => {
test.use( {
storageState: process.env.ADMINSTATE,
} );
test( 'Load wp-admin', async ( { page } ) => {
await page.goto( '/wp-admin' );
const title = page.locator( 'div.wrap > h1' );
await expect( title ).toHaveText( 'Dashboard' );
} );
test.describe( 'Sign in as admin', () => {
test.use( {
storageState: process.env.ADMINSTATE,
} );
test( 'Load wp-admin', async ( { page } ) => {
await page.goto( '/wp-admin' );
const title = page.locator( 'div.wrap > h1' );
await expect( title ).toHaveText( 'Dashboard' );
} );
} );
test.describe( 'Sign in as customer', () => {
test.use( {
storageState: process.env.CUSTOMERSTATE,
} );
test( 'Load customer my account page', async ( { page } ) => {
await page.goto( '/my-account' );
const title = page.locator( 'h1.entry-title' );
await expect( title ).toHaveText( 'My account' );
} );
test.describe( 'Sign in as customer', () => {
test.use( {
storageState: process.env.CUSTOMERSTATE,
} );
}
);
test( 'Load customer my account page', async ( { page } ) => {
await page.goto( '/my-account' );
const title = page.locator( 'h1.entry-title' );
await expect( title ).toHaveText( 'My account' );
} );
} );
} );

View File

@ -13,7 +13,7 @@ const skipTestIfUndefined = () => {
const skipMessage = `Skipping this test on daily run. Environment not compatible.`;
test.skip( () => {
const shouldSkip = BASE_URL != undefined;
const shouldSkip = BASE_URL !== undefined;
if ( shouldSkip ) {
console.log( skipMessage );

View File

@ -42,7 +42,6 @@ test.describe( 'Add New Coupon Page', () => {
await page.locator( '#coupon_amount' ).fill( '100' );
await page.locator( '#publish:not(.disabled)' ).click();
await page.waitForLoadState( 'networkidle' );
await expect(
page

View File

@ -43,8 +43,7 @@ test.describe( 'Can create a new page', () => {
await page
.getByRole( 'document', {
name:
'Empty block; start writing or type forward slash to choose a block',
name: 'Empty block; start writing or type forward slash to choose a block',
} )
.fill( 'Test Page' );

View File

@ -28,7 +28,7 @@ test.describe( 'Can create a new post', () => {
force: true,
},
} );
// expect( response.ok() ).toBeTruthy();
// expect( response.ok() ).toBeTruthy();
}
} );
} );
@ -44,8 +44,7 @@ test.describe( 'Can create a new post', () => {
await page
.getByRole( 'document', {
name:
'Empty block; start writing or type forward slash to choose a block',
name: 'Empty block; start writing or type forward slash to choose a block',
} )
.fill( 'Test Post' );

View File

@ -33,7 +33,9 @@ test.describe( 'Merchant can add shipping classes', () => {
// Add shipping classes
for ( const { name, slug, description } of shippingClasses ) {
await page.getByRole('link', { name: 'Add shipping class' }).click();
await page
.getByRole( 'link', { name: 'Add shipping class' } )
.click();
await page
.getByPlaceholder( 'e.g. Heavy', { exact: true } )
.fill( name );
@ -41,7 +43,10 @@ test.describe( 'Merchant can add shipping classes', () => {
.getByPlaceholder( 'e.g. heavy-packages', { exact: true } )
.fill( slug );
await page
.getByPlaceholder( 'e.g. For heavy items requiring higher postage', { exact: true } )
.getByPlaceholder(
'e.g. For heavy items requiring higher postage',
{ exact: true }
)
.fill( description );
await page.getByRole( 'button', { name: 'Create' } ).click();

View File

@ -274,7 +274,7 @@ test.describe( 'WooCommerce Shipping Settings - Add new shipping zone', () => {
);
await page.locator( '#zone_name' ).fill( shippingZoneNameUSRegion );
const input = await page.getByPlaceholder(
const input = page.getByPlaceholder(
'Start typing to filter zones'
);
input.click();
@ -340,7 +340,7 @@ test.describe( 'WooCommerce Shipping Settings - Add new shipping zone', () => {
);
await page.locator( '#zone_name' ).fill( shippingZoneNameFlatRate );
const input = await page.getByPlaceholder(
const input = page.getByPlaceholder(
'Start typing to filter zones'
);
input.click();
@ -508,7 +508,7 @@ test.describe( 'Verifies shipping options from customer perspective', () => {
await page.locator( 'button[name=calc_shipping]' ).click();
await expect(
page.locator( 'button[name=calc_shipping]' )
).not.toBeVisible();
).toBeHidden();
await expect(
page.locator( '.shipping ul#shipping_method > li > label' )
@ -529,7 +529,7 @@ test.describe( 'Verifies shipping options from customer perspective', () => {
await page.locator( 'button[name=calc_shipping]' ).click();
await expect(
page.locator( 'button[name=calc_shipping]' )
).not.toBeVisible();
).toBeHidden();
await expect(
page.locator( '.shipping ul#shipping_method > li > label' )
@ -551,7 +551,7 @@ test.describe( 'Verifies shipping options from customer perspective', () => {
await page.locator( 'button[name=calc_shipping]' ).click();
await expect(
page.locator( 'button[name=calc_shipping]' )
).not.toBeVisible();
).toBeHidden();
await expect(
page.locator( '.shipping ul#shipping_method > li > label' )

View File

@ -5,7 +5,7 @@ const virtualProductName = 'Virtual Product Name';
const nonVirtualProductName = 'Non Virtual Product Name';
const productPrice = '9.99';
const productTag = 'nonVirtualTag';
const productCategory = 'nonVirtualCategory'
const productCategory = 'nonVirtualCategory';
const productDescription = 'Description of a non-virtual product.';
const productDescriptionShort = 'Short description';
let shippingZoneId, virtualProductId, nonVirtualProductId;
@ -52,30 +52,32 @@ test.describe.serial( 'Add New Simple Product Page', () => {
} );
// clean up tag after run
await api
.get( 'products/tags' )
.then( async ( response ) => {
for (let i = 0; i < response.data.length; i++) {
if (response.data[i].name === productTag) {
await api.delete(`products/tags/${response.data[i].id}`, {
await api.get( 'products/tags' ).then( async ( response ) => {
for ( let i = 0; i < response.data.length; i++ ) {
if ( response.data[ i ].name === productTag ) {
await api.delete(
`products/tags/${ response.data[ i ].id }`,
{
force: true,
} );
}
}
);
}
} );
}
} );
// clean up category after run
await api
.get( 'products/categories' )
.then( async ( response ) => {
for (let i = 0; i < response.data.length; i++) {
if (response.data[i].name === productCategory) {
await api.delete(`products/categories/${response.data[i].id}`, {
await api.get( 'products/categories' ).then( async ( response ) => {
for ( let i = 0; i < response.data.length; i++ ) {
if ( response.data[ i ].name === productCategory ) {
await api.delete(
`products/categories/${ response.data[ i ].id }`,
{
force: true,
} );
}
}
);
}
} );
}
} );
// delete the shipping zone
await api.delete( `shipping/zones/${ shippingZoneId }`, {
@ -120,7 +122,9 @@ test.describe.serial( 'Add New Simple Product Page', () => {
await page.goto( `/?post_type=product&p=${ virtualProductId }`, {
waitUntil: 'networkidle',
} );
await expect( page.getByRole( 'heading', { name: virtualProductName } ) ).toBeVisible();
await expect(
page.getByRole( 'heading', { name: virtualProductName } )
).toBeVisible();
await expect( page.getByText( productPrice ).first() ).toBeVisible();
await page.getByRole( 'button', { name: 'Add to cart' } ).click();
await page.getByRole( 'link', { name: 'View cart' } ).click();
@ -129,14 +133,14 @@ test.describe.serial( 'Add New Simple Product Page', () => {
);
await expect(
page.locator( 'a.shipping-calculator-button' )
).not.toBeVisible();
).toBeHidden();
await page
.locator( `a.remove[data-product_id='${ virtualProductId }']` )
.click();
await page.waitForLoadState( 'networkidle' );
await expect(
page.locator( `a.remove[data-product_id='${ virtualProductId }']` )
).not.toBeVisible();
).toBeHidden();
} );
test( 'can create simple non-virtual product', async ( { page } ) => {
@ -150,9 +154,11 @@ test.describe.serial( 'Add New Simple Product Page', () => {
.locator( '.wp-editor' )
.fill( productDescription );
await page.getByRole( 'textbox', { name: 'Regular price ($)', exact: true} ).fill( productPrice )
await page
.getByRole( 'textbox', { name: 'Regular price ($)', exact: true } )
.fill( productPrice );
await page.getByText('Inventory').click();
await page.getByText( 'Inventory' ).click();
await page.getByLabel( 'SKU', { exact: true } ).fill( '11' );
const productDimensions = {
@ -162,11 +168,15 @@ test.describe.serial( 'Add New Simple Product Page', () => {
height: '30',
};
await page.getByRole( 'link' , { name: 'Shipping' } ).click();
await page.getByRole( 'link', { name: 'Shipping' } ).click();
await page.getByPlaceholder( '0' ).fill( productDimensions.weight );
await page.getByPlaceholder( 'Length' ).fill( productDimensions.length );
await page
.getByPlaceholder( 'Length' )
.fill( productDimensions.length );
await page.getByPlaceholder( 'Width' ).fill( productDimensions.width );
await page.getByPlaceholder( 'Height' ).fill( productDimensions.height );
await page
.getByPlaceholder( 'Height' )
.fill( productDimensions.height );
await page
.frameLocator( '#excerpt_ifr' )
@ -174,13 +184,25 @@ test.describe.serial( 'Add New Simple Product Page', () => {
.fill( productDescriptionShort );
await page.getByText( '+ Add new category' ).click();
await page.getByLabel( 'Add new category', { exact: true } ).fill( productCategory );
await page.getByRole( 'button', { name: 'Add new category', exact: true} ).click();
await page
.getByLabel( 'Add new category', { exact: true } )
.fill( productCategory );
await page
.getByRole( 'button', { name: 'Add new category', exact: true } )
.click();
await page.getByRole( 'combobox', { name: 'Add new tag'} ).fill( productTag );
await page.getByRole( 'button', { name: 'Add', exact: true} ).click();
await page
.getByRole( 'combobox', { name: 'Add new tag' } )
.fill( productTag );
await page.getByRole( 'button', { name: 'Add', exact: true } ).click();
await page.getByRole( 'button', { name: 'Publish', exact: true, disabled: false } ).click();
await page
.getByRole( 'button', {
name: 'Publish',
exact: true,
disabled: false,
} )
.click();
await page.waitForLoadState( 'networkidle' );
// When running in parallel, clicking the publish button sometimes saves products as a draft
@ -189,7 +211,13 @@ test.describe.serial( 'Add New Simple Product Page', () => {
await page.locator( '#post-status-display' ).innerText()
).includes( 'Draft' )
) {
await page.getByRole( 'button', { name: 'Publish', exact: true, disabled: false } ).click();
await page
.getByRole( 'button', {
name: 'Publish',
exact: true,
disabled: false,
} )
.click();
await page.waitForLoadState( 'networkidle' );
}
@ -210,7 +238,9 @@ test.describe.serial( 'Add New Simple Product Page', () => {
await page.goto( `/?post_type=product&p=${ nonVirtualProductId }`, {
waitUntil: 'networkidle',
} );
await expect( page.getByRole( 'heading', { name: nonVirtualProductName } ) ).toBeVisible();
await expect(
page.getByRole( 'heading', { name: nonVirtualProductName } )
).toBeVisible();
await expect( page.getByText( productPrice ).first() ).toBeVisible();
await page.getByRole( 'button', { name: 'Add to cart' } ).click();
await page.getByRole( 'link', { name: 'View cart' } ).click();
@ -228,6 +258,6 @@ test.describe.serial( 'Add New Simple Product Page', () => {
page.locator(
`a.remove[data-product_id='${ nonVirtualProductId }']`
)
).not.toBeVisible();
).toBeHidden();
} );
} );

View File

@ -5,119 +5,110 @@ let productId, orderId;
const productName = 'Simple Product Name';
const productPrice = '15.99';
test.describe(
'WooCommerce Merchant Flow: Orders > Customer Payment Page',
() => {
test.use( { storageState: process.env.ADMINSTATE } );
test.describe( 'WooCommerce Merchant Flow: Orders > Customer Payment Page', () => {
test.use( { storageState: process.env.ADMINSTATE } );
test.beforeAll( async ( { baseURL } ) => {
const api = new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,
consumerSecret: process.env.CONSUMER_SECRET,
version: 'wc/v3',
test.beforeAll( async ( { baseURL } ) => {
const api = new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,
consumerSecret: process.env.CONSUMER_SECRET,
version: 'wc/v3',
} );
// create a simple product
await api
.post( 'products', {
name: productName,
type: 'simple',
regular_price: productPrice,
} )
.then( ( response ) => {
productId = response.data.id;
} );
// create a simple product
await api
.post( 'products', {
name: productName,
type: 'simple',
regular_price: productPrice,
} )
.then( ( response ) => {
productId = response.data.id;
} );
// create an order
await api
.post( 'orders', {
line_items: [
{
product_id: productId,
quantity: 1,
},
],
} )
.then( ( response ) => {
orderId = response.data.id;
} );
// enable bank transfer as a payment option
await api.put( 'payment_gateways/bacs', {
enabled: 'true',
// create an order
await api
.post( 'orders', {
line_items: [
{
product_id: productId,
quantity: 1,
},
],
} )
.then( ( response ) => {
orderId = response.data.id;
} );
// enable bank transfer as a payment option
await api.put( 'payment_gateways/bacs', {
enabled: 'true',
} );
} );
test.afterAll( async ( { baseURL } ) => {
const api = new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,
consumerSecret: process.env.CONSUMER_SECRET,
version: 'wc/v3',
} );
await api.delete( `products/${ productId }`, { force: true } );
await api.delete( `orders/${ orderId }`, { force: true } );
await api.put( 'payment_gateways/bacs', { enabled: 'false' } );
test.afterAll( async ( { baseURL } ) => {
const api = new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,
consumerSecret: process.env.CONSUMER_SECRET,
version: 'wc/v3',
} );
await api.delete( `products/${ productId }`, { force: true } );
await api.delete( `orders/${ orderId }`, { force: true } );
await api.put( 'payment_gateways/bacs', { enabled: 'false' } );
} );
test( 'should show the customer payment page link on a pending order', async ( {
page,
} ) => {
await page.goto(
`wp-admin/post.php?post=${ orderId }&action=edit`
);
test( 'should show the customer payment page link on a pending order', async ( {
page,
} ) => {
await page.goto( `wp-admin/post.php?post=${ orderId }&action=edit` );
// verify that the order is pending payment
await expect(
page.locator( '#select2-order_status-container' )
).toContainText( 'Pending payment' );
// verify that the order is pending payment
await expect(
page.locator( '#select2-order_status-container' )
).toContainText( 'Pending payment' );
//verify that the customer payment page link is displayed
await expect(
page.locator( 'label[for=order_status] > a' )
).toContainText( 'Customer payment page →' );
} );
//verify that the customer payment page link is displayed
await expect(
page.locator( 'label[for=order_status] > a' )
).toContainText( 'Customer payment page →' );
} );
test( 'should load the customer payment page', async ( { page } ) => {
await page.goto(
`wp-admin/post.php?post=${ orderId }&action=edit`
);
test( 'should load the customer payment page', async ( { page } ) => {
await page.goto( `wp-admin/post.php?post=${ orderId }&action=edit` );
// visit the page
await page.locator( 'label[for=order_status] > a' ).click();
// visit the page
await page.locator( 'label[for=order_status] > a' ).click();
// verify we landed on the customer payment page
await expect( page.locator( 'h1.entry-title' ) ).toContainText(
'Pay for order'
);
await expect( page.locator( 'td.product-name' ) ).toContainText(
productName
);
await expect(
page.locator( 'span.woocommerce-Price-amount.amount >> nth=0' )
).toContainText( productPrice );
} );
// verify we landed on the customer payment page
await expect( page.locator( 'h1.entry-title' ) ).toContainText(
'Pay for order'
);
await expect( page.locator( 'td.product-name' ) ).toContainText(
productName
);
await expect(
page.locator( 'span.woocommerce-Price-amount.amount >> nth=0' )
).toContainText( productPrice );
} );
test( 'can pay for the order through the customer payment page', async ( {
page,
} ) => {
// key required, so can't go directly to the customer payment page
await page.goto(
`wp-admin/post.php?post=${ orderId }&action=edit`
);
await page.locator( 'label[for=order_status] > a' ).click();
test( 'can pay for the order through the customer payment page', async ( {
page,
} ) => {
// key required, so can't go directly to the customer payment page
await page.goto( `wp-admin/post.php?post=${ orderId }&action=edit` );
await page.locator( 'label[for=order_status] > a' ).click();
// pay for the order
await page.locator( 'button#place_order' ).click();
// pay for the order
await page.locator( 'button#place_order' ).click();
// Verify we landed on the order received page
await expect( page.locator( 'h1.entry-title' ) ).toContainText(
'Order received'
);
await expect(
page.locator( 'li.woocommerce-order-overview__order.order' )
).toContainText( orderId.toString() );
await expect(
page.locator( 'span.woocommerce-Price-amount.amount >> nth=0' )
).toContainText( productPrice );
} );
}
);
// Verify we landed on the order received page
await expect( page.locator( 'h1.entry-title' ) ).toContainText(
'Order received'
);
await expect(
page.locator( 'li.woocommerce-order-overview__order.order' )
).toContainText( orderId.toString() );
await expect(
page.locator( 'span.woocommerce-Price-amount.amount >> nth=0' )
).toContainText( productPrice );
} );
} );

View File

@ -66,24 +66,65 @@ test.describe( 'Bulk edit orders', () => {
test( 'can bulk update order status', async ( { page } ) => {
await page.goto( 'wp-admin/admin.php?page=wc-orders' );
// expect order status 'processing' to show
await expect( page.locator( `:is(#order-${ orderId1 }, #post-${ orderId1 })` ).getByText( 'Processing' ) ).toBeVisible();
await expect( page.locator( `:is(#order-${ orderId2 }, #post-${ orderId2 })` ).getByText( 'Processing' ) ).toBeVisible();
await expect( page.locator( `:is(#order-${ orderId3 }, #post-${ orderId3 })` ).getByText( 'Processing' ) ).toBeVisible();
await expect( page.locator( `:is(#order-${ orderId4 }, #post-${ orderId4 })` ).getByText( 'Processing' ) ).toBeVisible();
await expect( page.locator( `:is(#order-${ orderId5 }, #post-${ orderId5 })` ).getByText( 'Processing' ) ).toBeVisible();
await expect(
page
.locator( `:is(#order-${ orderId1 }, #post-${ orderId1 })` )
.getByText( 'Processing' )
).toBeVisible();
await expect(
page
.locator( `:is(#order-${ orderId2 }, #post-${ orderId2 })` )
.getByText( 'Processing' )
).toBeVisible();
await expect(
page
.locator( `:is(#order-${ orderId3 }, #post-${ orderId3 })` )
.getByText( 'Processing' )
).toBeVisible();
await expect(
page
.locator( `:is(#order-${ orderId4 }, #post-${ orderId4 })` )
.getByText( 'Processing' )
).toBeVisible();
await expect(
page
.locator( `:is(#order-${ orderId5 }, #post-${ orderId5 })` )
.getByText( 'Processing' )
).toBeVisible();
await page.locator( '#cb-select-all-1' ).click();
await page.locator( '#bulk-action-selector-top' ).selectOption( 'Change status to completed' );
await page.locator('#doaction').click();
await page
.locator( '#bulk-action-selector-top' )
.selectOption( 'Change status to completed' );
await page.locator( '#doaction' ).click();
// expect order status 'completed' to show
await expect( page.locator( `:is(#order-${ orderId1 }, #post-${ orderId1 })`).getByText( 'Completed' ) ).toBeVisible();
await expect( page.locator( `:is(#order-${ orderId2 }, #post-${ orderId2 })`).getByText( 'Completed' ) ).toBeVisible();
await expect( page.locator( `:is(#order-${ orderId3 }, #post-${ orderId3 })`).getByText( 'Completed' ) ).toBeVisible();
await expect( page.locator( `:is(#order-${ orderId4 }, #post-${ orderId4 })`).getByText( 'Completed' ) ).toBeVisible();
await expect( page.locator( `:is(#order-${ orderId5 }, #post-${ orderId5 })`).getByText( 'Completed' ) ).toBeVisible();
await expect(
page
.locator( `:is(#order-${ orderId1 }, #post-${ orderId1 })` )
.getByText( 'Completed' )
).toBeVisible();
await expect(
page
.locator( `:is(#order-${ orderId2 }, #post-${ orderId2 })` )
.getByText( 'Completed' )
).toBeVisible();
await expect(
page
.locator( `:is(#order-${ orderId3 }, #post-${ orderId3 })` )
.getByText( 'Completed' )
).toBeVisible();
await expect(
page
.locator( `:is(#order-${ orderId4 }, #post-${ orderId4 })` )
.getByText( 'Completed' )
).toBeVisible();
await expect(
page
.locator( `:is(#order-${ orderId5 }, #post-${ orderId5 })` )
.getByText( 'Completed' )
).toBeVisible();
} );
} );

View File

@ -98,7 +98,9 @@ test.describe( 'WooCommerce Orders > Apply Coupon', () => {
await page.locator( 'button.add-coupon' ).click();
await expect(
page.locator('#woocommerce-order-items li').filter({ hasText: couponCode })
page
.locator( '#woocommerce-order-items li' )
.filter( { hasText: couponCode } )
).toBeVisible();
await expect(
page.getByRole( 'cell', { name: 'Coupon(s)' } )
@ -107,7 +109,10 @@ test.describe( 'WooCommerce Orders > Apply Coupon', () => {
page.getByRole( 'cell', { name: `- $${ couponAmount }.00` } )
).toBeVisible();
await expect(
page.getByRole('cell', { name: `$${ discountedPrice }`, exact: true })
page.getByRole( 'cell', {
name: `$${ discountedPrice }`,
exact: true,
} )
).toBeVisible();
} );
@ -115,7 +120,9 @@ test.describe( 'WooCommerce Orders > Apply Coupon', () => {
await page.goto( `/wp-admin/post.php?post=${ orderId }&action=edit` );
// assert that there is a coupon on the order
await expect(
page.locator('#woocommerce-order-items li').filter({ hasText: couponCode })
page
.locator( '#woocommerce-order-items li' )
.filter( { hasText: couponCode } )
).toBeVisible();
await expect(
page.getByRole( 'cell', { name: 'Coupon(s)' } )
@ -124,7 +131,10 @@ test.describe( 'WooCommerce Orders > Apply Coupon', () => {
page.getByRole( 'cell', { name: `- $${ couponAmount }.00` } )
).toBeVisible();
await expect(
page.getByRole('cell', { name: `$${ discountedPrice }`, exact: true })
page.getByRole( 'cell', {
name: `$${ discountedPrice }`,
exact: true,
} )
).toBeVisible();
// remove the coupon
await page.locator( 'a.remove-coupon' ).dispatchEvent( 'click' ); // have to use dispatchEvent because nothing visible to click on
@ -132,9 +142,9 @@ test.describe( 'WooCommerce Orders > Apply Coupon', () => {
// make sure the coupon was removed
await expect(
page.locator( '.wc_coupon_list li', { hasText: couponCode } )
).not.toBeVisible();
).toBeHidden();
await expect(
page.getByRole('cell', { name: `$${ productPrice }` }).nth(1)
page.getByRole( 'cell', { name: `$${ productPrice }` } ).nth( 1 )
).toBeVisible();
} );
} );

View File

@ -78,12 +78,18 @@ test.describe( 'Edit order', () => {
// load the orders listing and confirm order is completed
await page.goto( 'wp-admin/admin.php?page=wc-orders' );
await expect( page.locator( `:is(#order-${orderId}, #post-${orderId})` ).getByRole( 'cell', { name: 'Completed' }) ).toBeVisible();
await expect(
page
.locator( `:is(#order-${ orderId }, #post-${ orderId })` )
.getByRole( 'cell', { name: 'Completed' } )
).toBeVisible();
} );
test( 'can update order status to cancelled', async ( { page } ) => {
// open order we created
await page.goto( `wp-admin/post.php?post=${ orderToCancel }&action=edit` );
await page.goto(
`wp-admin/post.php?post=${ orderToCancel }&action=edit`
);
// update order status to Completed
await page.locator( '#order_status' ).selectOption( 'Cancelled' );
@ -93,12 +99,22 @@ test.describe( 'Edit order', () => {
await expect( page.locator( '#order_status' ) ).toHaveValue(
'wc-cancelled'
);
await expect( page.getByText( 'Order status changed from Processing to Cancelled.' ) ).toBeVisible();
await expect(
page.getByText(
'Order status changed from Processing to Cancelled.'
)
).toBeVisible();
// load the orders listing and confirm order is cancelled
await page.goto( 'wp-admin/admin.php?page=wc-orders' );
await expect( page.locator( `:is(#order-${orderToCancel}, #post-${orderToCancel})` ).getByRole( 'cell', { name: 'Cancelled' }) ).toBeVisible();
await expect(
page
.locator(
`:is(#order-${ orderToCancel }, #post-${ orderToCancel })`
)
.getByRole( 'cell', { name: 'Cancelled' } )
).toBeVisible();
} );
test( 'can update order details', async ( { page } ) => {
@ -123,35 +139,65 @@ test.describe( 'Edit order', () => {
test( 'can add and delete order notes', async ( { page } ) => {
// open order we created
await page.goto( `wp-admin/post.php?post=${ orderId }&action=edit` );
await page.on( 'dialog', dialog => dialog.accept() );
page.on( 'dialog', ( dialog ) => dialog.accept() );
// add an order note
await page.getByLabel( 'Add note' ).fill( 'This order is a test order. It is only a test. This note is a private note.' );
await page
.getByLabel( 'Add note' )
.fill(
'This order is a test order. It is only a test. This note is a private note.'
);
await page.getByRole( 'button', { name: 'Add', exact: true } ).click();
// verify the note saved
await expect( page.getByText( 'This order is a test order. It is only a test. This note is a private note.' ) ).toBeVisible();
await expect(
page.getByText(
'This order is a test order. It is only a test. This note is a private note.'
)
).toBeVisible();
// delete the note
await page.getByRole( 'button', { name: 'Delete note' } ).first().click();
await page
.getByRole( 'button', { name: 'Delete note' } )
.first()
.click();
// verify the note is gone
await expect( page.getByText( 'This order is a test order. It is only a test. This note is a private note.' ) ).not.toBeVisible();
await expect(
page.getByText(
'This order is a test order. It is only a test. This note is a private note.'
)
).toBeHidden();
// add note to customer
// add an order note
await page.getByLabel( 'Add note' ).fill( 'This order is a test order. It is only a test. This note is a note to the customer.' );
await page.getByLabel('Note type').selectOption( 'Note to customer' );
await page
.getByLabel( 'Add note' )
.fill(
'This order is a test order. It is only a test. This note is a note to the customer.'
);
await page.getByLabel( 'Note type' ).selectOption( 'Note to customer' );
await page.getByRole( 'button', { name: 'Add', exact: true } ).click();
// verify the note saved
await expect( page.getByText( 'This order is a test order. It is only a test. This note is a note to the customer.' ) ).toBeVisible();
await expect(
page.getByText(
'This order is a test order. It is only a test. This note is a note to the customer.'
)
).toBeVisible();
// delete the note
await page.getByRole( 'button', { name: 'Delete note' } ).first().click();
await page
.getByRole( 'button', { name: 'Delete note' } )
.first()
.click();
// verify the note is gone
await expect( page.getByText( 'This order is a test order. It is only a test. This note is a private note.' ) ).not.toBeVisible();
await expect(
page.getByText(
'This order is a test order. It is only a test. This note is a private note.'
)
).toBeHidden();
} );
test( 'can load billing details', async ( { page, baseURL } ) => {
@ -182,37 +228,35 @@ test.describe( 'Edit order', () => {
postcode: '94107',
phone: '123456789',
email: 'archie123@email.addr',
}
},
} )
.then( ( response ) => {
customerId = response.data.id;
} );
// Open our test order and select the customer we just created.
await page.goto( `wp-admin/post.php?post=${orderId}&action=edit` );
await page.goto( `wp-admin/post.php?post=${ orderId }&action=edit` );
// Simulate the ajax `woocommerce_get_customer_details` call normally done inside meta-boxes-order.js.
const response = await page.evaluate(
async ( customerId ) => {
const simulateCustomerDetailsCall = new Promise( ( resolve ) => {
jQuery.ajax( {
url: woocommerce_admin_meta_boxes.ajax_url,
data: {
user_id : customerId,
action : 'woocommerce_get_customer_details',
security: woocommerce_admin_meta_boxes.get_customer_details_nonce
},
type: 'POST',
success: function( response ) {
resolve( response );
}
} );
const response = await page.evaluate( async ( customerId ) => {
const simulateCustomerDetailsCall = new Promise( ( resolve ) => {
jQuery.ajax( {
url: woocommerce_admin_meta_boxes.ajax_url,
data: {
user_id: customerId,
action: 'woocommerce_get_customer_details',
security:
woocommerce_admin_meta_boxes.get_customer_details_nonce,
},
type: 'POST',
success( response ) {
resolve( response );
},
} );
} );
return await simulateCustomerDetailsCall;
},
customerId
);
return await simulateCustomerDetailsCall;
}, customerId );
// Response should contain billing address info, but should not contain user meta data.
expect( 'billing' in response ).toBeTruthy();
@ -283,8 +327,7 @@ test.describe( 'Edit order > Downloadable product permissions', () => {
{
id: uuid.v4(),
name: 'Single',
file:
'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg',
file: 'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg',
},
],
} )
@ -303,8 +346,7 @@ test.describe( 'Edit order > Downloadable product permissions', () => {
{
id: uuid.v4(),
name: 'Single',
file:
'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg',
file: 'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg',
},
],
} )

View File

@ -1,7 +1,7 @@
const { test, expect } = require( '@playwright/test' );
const wcApi = require( '@woocommerce/woocommerce-rest-api' ).default;
const orderBatchId = new Array();
const orderBatchId = [];
const statusColumnTextSelector = 'mark.order-status > span';
// Define order statuses to filter against

View File

@ -1,5 +1,4 @@
const { test, expect } = require( '@playwright/test' );
const { features } = require( '../../utils' );
const wcApi = require( '@woocommerce/woocommerce-rest-api' ).default;
// a representation of the menu structure for WC
@ -210,8 +209,7 @@ for ( const currentPage of wcPages ) {
).toContainText( currentPage.subpages[ i ].heading );
await expect(
page.locator( currentPage.subpages[ i ].element )
.first()
page.locator( currentPage.subpages[ i ].element ).first()
).toBeVisible();
await expect(

View File

@ -1,135 +1,172 @@
const {test: baseTest, expect} = require('@playwright/test');
const wcApi = require('@woocommerce/woocommerce-rest-api').default;
const { test: baseTest, expect } = require( '@playwright/test' );
const wcApi = require( '@woocommerce/woocommerce-rest-api' ).default;
baseTest.describe('Products > Delete Product', () => {
baseTest.use({storageState: process.env.ADMINSTATE});
baseTest.describe( 'Products > Delete Product', () => {
baseTest.use( { storageState: process.env.ADMINSTATE } );
const test = baseTest.extend({
api: async ({baseURL}, use) => {
const api = new wcApi({
const apiFixture = baseTest.extend( {
api: async ( { baseURL }, use ) => {
const api = new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,
consumerSecret: process.env.CONSUMER_SECRET,
version: 'wc/v3',
axiosConfig: {
// allow 404s, so we can check if the product was deleted without try/catch
validateStatus: function (status) {
return status >= 200 && status < 300 || status === 404;
validateStatus( status ) {
return (
( status >= 200 && status < 300 ) || status === 404
);
},
},
});
} );
await use(api);
await use( api );
},
} );
product: async ({api}, use) => {
const test = apiFixture.extend( {
product: async ( { api }, use ) => {
const product = {
id: 0,
name: `Product ${Date.now()}`,
name: `Product ${ Date.now() }`,
type: 'simple',
regular_price: '12.99'
}
regular_price: '12.99',
};
await api
.post('products', product)
.then((response) => {
product.id = response.data.id;
});
await api.post( 'products', product ).then( ( response ) => {
product.id = response.data.id;
} );
await use(product);
await use( product );
// permanently delete the product if it still exists
const r = await api.get(`products/${product.id}`);
if (r.status !== 404) {
await api.delete(`products/${product.id}`, {
const r = await api.get( `products/${ product.id }` );
if ( r.status !== 404 ) {
await api.delete( `products/${ product.id }`, {
force: true,
});
} );
}
},
});
} );
test('can delete a product from edit view', async ({page, product}) => {
const editUrl = `wp-admin/post.php?post=${product.id}&action=edit`;
test( 'can delete a product from edit view', async ( {
page,
product,
} ) => {
const editUrl = `wp-admin/post.php?post=${ product.id }&action=edit`;
await test.step('Navigate to product edit page', async () => {
await page.goto(editUrl);
});
await test.step( 'Navigate to product edit page', async () => {
await page.goto( editUrl );
} );
await test.step('Move product to trash', async () => {
await page.getByRole('link', {name: 'Move to Trash'}).click();
});
await test.step( 'Move product to trash', async () => {
await page.getByRole( 'link', { name: 'Move to Trash' } ).click();
} );
await test.step('Verify product was trashed', async () => {
await test.step( 'Verify product was trashed', async () => {
// Verify displayed message
await expect(
page.locator('#message').last()
).toContainText('1 product moved to the Trash.');
await expect( page.locator( '#message' ).last() ).toContainText(
'1 product moved to the Trash.'
);
// Verify the product is now in the trash
await page.goto(`wp-admin/edit.php?post_status=trash&post_type=product`);
await expect(page.locator(`#post-${product.id}`)).toBeVisible();
await page.goto(
`wp-admin/edit.php?post_status=trash&post_type=product`
);
await expect(
page.locator( `#post-${ product.id }` )
).toBeVisible();
// Verify the product cannot be edited via direct URL
await page.goto(editUrl);
await expect(page.getByText('You cannot edit this item because it is in the Trash. Please restore it and try again.')).toBeVisible();
await page.goto( editUrl );
await expect(
page.getByText(
'You cannot edit this item because it is in the Trash. Please restore it and try again.'
)
).toBeVisible();
} );
} );
});
});
test( 'can quick delete a product from product list', async ( {
page,
product,
} ) => {
await test.step( 'Navigate to products list page', async () => {
await page.goto( `wp-admin/edit.php?post_type=product` );
} );
test('can quick delete a product from product list', async ({page, product}) => {
await test.step('Navigate to products list page', async () => {
await page.goto(`wp-admin/edit.php?post_type=product`);
});
await test.step('Move product to trash', async () => {
await test.step( 'Move product to trash', async () => {
// mouse over the product row to display the quick actions
await page.locator(`#post-${product.id}`).hover();
await page.locator( `#post-${ product.id }` ).hover();
// move product to trash
await page.locator(`#post-${product.id} .submitdelete`).click();
});
await page.locator( `#post-${ product.id } .submitdelete` ).click();
} );
await test.step('Verify product was trashed', async () => {
await test.step( 'Verify product was trashed', async () => {
// Verify displayed message
await expect(
page.locator('#message').last()
).toContainText('1 product moved to the Trash.');
await expect( page.locator( '#message' ).last() ).toContainText(
'1 product moved to the Trash.'
);
// Verify the product is now in the trash
await page.goto(`wp-admin/edit.php?post_status=trash&post_type=product`);
await expect(page.locator(`#post-${product.id}`)).toBeVisible();
await page.goto(
`wp-admin/edit.php?post_status=trash&post_type=product`
);
await expect(
page.locator( `#post-${ product.id }` )
).toBeVisible();
// Verify the product cannot be edited via direct URL
await page.goto(`wp-admin/post.php?post=${product.id}&action=edit`);
await expect(page.getByText('You cannot edit this item because it is in the Trash. Please restore it and try again.')).toBeVisible();
});
});
await page.goto(
`wp-admin/post.php?post=${ product.id }&action=edit`
);
await expect(
page.getByText(
'You cannot edit this item because it is in the Trash. Please restore it and try again.'
)
).toBeVisible();
} );
} );
test('can permanently delete a product from trash list', async ({page, product, api}) => {
test( 'can permanently delete a product from trash list', async ( {
page,
product,
api,
} ) => {
// trash the product
await api.delete(`products/${product.id}`, {
await api.delete( `products/${ product.id }`, {
force: false,
});
} );
await test.step('Navigate to products trash list page', async () => {
await page.goto(`wp-admin/edit.php?post_status=trash&post_type=product`);
});
await test.step( 'Navigate to products trash list page', async () => {
await page.goto(
`wp-admin/edit.php?post_status=trash&post_type=product`
);
} );
await test.step('Permanently delete the product', async () => {
await test.step( 'Permanently delete the product', async () => {
// mouse over the product row to display the quick actions
await page.locator(`#post-${product.id}`).hover();
await page.locator( `#post-${ product.id }` ).hover();
// delete the product
await page.locator(`#post-${product.id} .submitdelete`).click();
});
await page.locator( `#post-${ product.id } .submitdelete` ).click();
} );
await test.step('Verify product was permanently deleted', async () => {
await test.step( 'Verify product was permanently deleted', async () => {
await expect( page.locator( '#message' ).last() ).toContainText(
'1 product permanently deleted.'
);
await page.goto(
`wp-admin/post.php?post=${ product.id }&action=edit`
);
await expect(
page.locator('#message').last()
).toContainText('1 product permanently deleted.');
await page.goto(`wp-admin/post.php?post=${product.id}&action=edit`);
await expect(page.getByText('You attempted to edit an item that does not exist. Perhaps it was deleted?')).toBeVisible();
});
});
});
page.getByText(
'You attempted to edit an item that does not exist. Perhaps it was deleted?'
)
).toBeVisible();
} );
} );
} );

View File

@ -71,9 +71,11 @@ test.describe( 'Add product attributes', () => {
.click();
await expect(
page.getByRole( 'heading', {
name: 'New attribute',
} ).first()
page
.getByRole( 'heading', {
name: 'New attribute',
} )
.first()
).toBeVisible();
} );
}
@ -116,7 +118,7 @@ test.describe( 'Add product attributes', () => {
await test.step( `Wait for the loading overlay to disappear.`, async () => {
await expect(
page.locator( '.blockOverlay' )
).not.toBeVisible();
).toBeHidden();
} );
} );
}
@ -145,9 +147,11 @@ test.describe( 'Add product attributes', () => {
const attributeValues = attribute.options.join( ' | ' );
await test.step( `Expect "${ attributeName }" to appear on the list of saved attributes, and expand it.`, async () => {
const heading_attributeName = page.getByRole( 'heading', {
name: attributeName,
} ).last();
const heading_attributeName = page
.getByRole( 'heading', {
name: attributeName,
} )
.last();
await expect( heading_attributeName ).toBeVisible();
await heading_attributeName.click();

View File

@ -23,49 +23,36 @@ test.describe( 'Add variable product', () => {
await page.goto( productPageURL );
} );
await test.step(
`Type "${ variableProductName }" into the "Product name" input field.`,
async () => {
const productNameTextbox = page.getByLabel( 'Product name' );
const permalink = page.locator( '#sample-permalink' );
await test.step( `Type "${ variableProductName }" into the "Product name" input field.`, async () => {
const productNameTextbox = page.getByLabel( 'Product name' );
const permalink = page.locator( '#sample-permalink' );
await productNameTextbox.fill( variableProductName );
await productNameTextbox.blur();
await expect( permalink ).toBeVisible();
}
);
await productNameTextbox.fill( variableProductName );
await productNameTextbox.blur();
await expect( permalink ).toBeVisible();
} );
await test.step(
'Select the "Variable product" product type.',
async () => {
await page
.locator( '#product-type' )
.selectOption( 'variable' );
}
);
await test.step( 'Select the "Variable product" product type.', async () => {
await page.locator( '#product-type' ).selectOption( 'variable' );
} );
await test.step(
'Scroll into the "Attributes" tab and click it.',
async () => {
const attributesTab = page
.locator( '.attribute_tab' )
.getByRole( 'link', { name: 'Attributes' } );
await test.step( 'Scroll into the "Attributes" tab and click it.', async () => {
const attributesTab = page
.locator( '.attribute_tab' )
.getByRole( 'link', { name: 'Attributes' } );
await attributesTab.scrollIntoViewIfNeeded();
await attributesTab.scrollIntoViewIfNeeded();
await attributesTab.click();
}
);
await attributesTab.click();
} );
// the tour only seems to display when not running headless, so just make sure
const tourWasDisplayed = await test.step(
'See if the tour was displayed.',
async () => {
const tourWasDisplayed =
await test.step( 'See if the tour was displayed.', async () => {
return await page
.locator( '.woocommerce-tour-kit-step__heading' )
.isVisible();
}
);
} );
if ( tourWasDisplayed ) {
await test.step( 'Tour was displayed, so dismiss it.', async () => {
@ -74,16 +61,13 @@ test.describe( 'Add variable product', () => {
.click();
} );
await test.step(
"Wait for the tour's dismissal to be saved",
async () => {
await page.waitForResponse(
( response ) =>
response.url().includes( '/users/' ) &&
response.status() === 200
);
}
);
await test.step( "Wait for the tour's dismissal to be saved", async () => {
await page.waitForResponse(
( response ) =>
response.url().includes( '/users/' ) &&
response.status() === 200
);
} );
}
await test.step( `Expect the "Variations" tab to appear`, async () => {
@ -96,27 +80,21 @@ test.describe( 'Add variable product', () => {
await page.locator( '#save-post' ).click();
} );
await test.step(
'Expect the "Product draft updated." notice to appear.',
async () => {
await expect(
page.getByText( 'Product draft updated.' )
).toBeVisible();
}
);
await test.step( 'Expect the "Product draft updated." notice to appear.', async () => {
await expect(
page.getByText( 'Product draft updated.' )
).toBeVisible();
} );
await test.step(
'Expect the product type to be "Variable product"',
async () => {
const selectedProductType = page.locator(
'select#product-type [selected]'
);
await test.step( 'Expect the product type to be "Variable product"', async () => {
const selectedProductType = page.locator(
'select#product-type [selected]'
);
await expect( selectedProductType ).toHaveText(
'Variable product'
);
}
);
await expect( selectedProductType ).toHaveText(
'Variable product'
);
} );
await test.step( 'Save product ID for clean up.', async () => {
productId = page.url().match( /(?<=post=)\d+/ );

View File

@ -25,9 +25,8 @@ test.describe( 'Add variations', () => {
productAttributes
);
expectedGeneratedVariations = generateVariationsFromAttributes(
productAttributes
);
expectedGeneratedVariations =
generateVariationsFromAttributes( productAttributes );
variationsToManuallyCreate = expectedGeneratedVariations.slice( 0, 3 );
@ -41,177 +40,149 @@ test.describe( 'Add variations', () => {
test( 'can generate variations from product attributes', async ( {
page,
} ) => {
await test.step(
`Open "Edit product" page of product id ${ productId_generateVariations }`,
async () => {
await page.goto(
`/wp-admin/post.php?post=${ productId_generateVariations }&action=edit`
);
}
);
await test.step( `Open "Edit product" page of product id ${ productId_generateVariations }`, async () => {
await page.goto(
`/wp-admin/post.php?post=${ productId_generateVariations }&action=edit`
);
} );
await test.step( 'Click on the "Variations" tab.', async () => {
await page.locator( '.variations_tab' ).click();
} );
await test.step(
'Click on the "Generate variations" button.',
async () => {
// event listener for handling the link_all_variations confirmation dialog
page.on( 'dialog', ( dialog ) => dialog.accept() );
await test.step( 'Click on the "Generate variations" button.', async () => {
// event listener for handling the link_all_variations confirmation dialog
page.on( 'dialog', ( dialog ) => dialog.accept() );
await page.locator( 'button.generate_variations' ).click();
}
);
await page.locator( 'button.generate_variations' ).click();
} );
await test.step(
`Expect the number of variations to be ${ expectedGeneratedVariations.length }`,
async () => {
const variations = page.locator( '.woocommerce_variation' );
await test.step( `Expect the number of variations to be ${ expectedGeneratedVariations.length }`, async () => {
const variations = page.locator( '.woocommerce_variation' );
await expect( variations ).toHaveCount(
expectedGeneratedVariations.length
);
}
);
await expect( variations ).toHaveCount(
expectedGeneratedVariations.length
);
} );
for ( const variation of expectedGeneratedVariations ) {
await test.step(
`Expect the variation "${ variation.join(
', '
) }" to be generated.`,
async () => {
let variationRow = page.locator(
'.woocommerce_variation h3'
await test.step( `Expect the variation "${ variation.join(
', '
) }" to be generated.`, async () => {
let variationRow = page.locator( '.woocommerce_variation h3' );
for ( const attributeValue of variation ) {
variationRow = variationRow.filter( {
has: page.locator( 'option[selected]', {
hasText: attributeValue,
} ),
} );
}
await expect( variationRow ).toBeVisible();
} );
}
} );
test( 'can manually add a variation', async ( { page } ) => {
await test.step( `Open "Edit product" page of product id ${ productId_addManually }`, async () => {
await page.goto(
`/wp-admin/post.php?post=${ productId_addManually }&action=edit`
);
} );
// hook up the woocommerce_variations_added jQuery trigger so we can check if it's fired
await test.step( 'Hook up the woocommerce_variations_added jQuery trigger', async () => {
await page.evaluate( () => {
window.woocommerceVariationsAddedFunctionCalls = [];
window
.jQuery( '#variable_product_options' )
.on( 'woocommerce_variations_added', ( event, data ) => {
window.woocommerceVariationsAddedFunctionCalls.push( [
event,
data,
] );
} );
} );
} );
await test.step( 'Click on the "Variations" tab.', async () => {
await page.locator( '.variations_tab' ).click();
} );
await test.step( `Manually add ${ variationsToManuallyCreate.length } variations`, async () => {
const variationRows = page.locator( '.woocommerce_variation h3' );
let variationRowsCount = await variationRows.count();
const originalVariationRowsCount = variationRowsCount;
for ( const variationToCreate of variationsToManuallyCreate ) {
await test.step( 'Click "Add manually"', async () => {
const addManuallyButton = page.getByRole( 'button', {
name: 'Add manually',
} );
await addManuallyButton.click();
await expect( variationRows ).toHaveCount(
++variationRowsCount
);
for ( const attributeValue of variation ) {
variationRow = variationRow.filter( {
// verify that the woocommerce_variations_added jQuery trigger was fired
const woocommerceVariationsAddedFunctionCalls =
await page.evaluate(
() => window.woocommerceVariationsAddedFunctionCalls
);
expect(
woocommerceVariationsAddedFunctionCalls.length
).toEqual(
variationRowsCount - originalVariationRowsCount
);
} );
for ( const attributeValue of variationToCreate ) {
const attributeName = productAttributes.find(
( { options } ) => options.includes( attributeValue )
).name;
const addAttributeMenu = variationRows
.nth( 0 )
.locator( 'select', {
has: page.locator( 'option', {
hasText: attributeValue,
} ),
} );
await test.step( `Select "${ attributeValue }" from the "${ attributeName }" attribute menu`, async () => {
await addAttributeMenu.selectOption( attributeValue );
} );
}
await test.step( 'Click "Save changes"', async () => {
await page
.getByRole( 'button', {
name: 'Save changes',
} )
.click();
} );
await test.step( `Expect the variation ${ variationToCreate.join(
', '
) } to be successfully saved.`, async () => {
let newlyAddedVariationRow;
for ( const attributeValue of variationToCreate ) {
newlyAddedVariationRow = (
newlyAddedVariationRow || variationRows
).filter( {
has: page.locator( 'option[selected]', {
hasText: attributeValue,
} ),
} );
}
await expect( variationRow ).toBeVisible();
}
);
}
} );
test( 'can manually add a variation', async ( { page } ) => {
await test.step(
`Open "Edit product" page of product id ${ productId_addManually }`,
async () => {
await page.goto(
`/wp-admin/post.php?post=${ productId_addManually }&action=edit`
);
}
);
// hook up the woocommerce_variations_added jQuery trigger so we can check if it's fired
await test.step(
'Hook up the woocommerce_variations_added jQuery trigger',
async () => {
await page.evaluate( () => {
window.woocommerceVariationsAddedFunctionCalls = [];
window.jQuery( '#variable_product_options' ).on(
'woocommerce_variations_added',
( event, data ) => {
window.woocommerceVariationsAddedFunctionCalls.push(
[event, data ]
);
} );
await expect( newlyAddedVariationRow ).toBeVisible();
} );
}
);
await test.step( 'Click on the "Variations" tab.', async () => {
await page.locator( '.variations_tab' ).click();
} );
await test.step(
`Manually add ${ variationsToManuallyCreate.length } variations`,
async () => {
const variationRows = page.locator(
'.woocommerce_variation h3'
);
let variationRowsCount = await variationRows.count();
const originalVariationRowsCount = variationRowsCount;
for ( const variationToCreate of variationsToManuallyCreate ) {
await test.step( 'Click "Add manually"', async () => {
const addManuallyButton = page.getByRole( 'button', {
name: 'Add manually',
} );
await addManuallyButton.click();
await expect( variationRows ).toHaveCount(
++variationRowsCount
);
// verify that the woocommerce_variations_added jQuery trigger was fired
const woocommerceVariationsAddedFunctionCalls = await page.evaluate( () => window.woocommerceVariationsAddedFunctionCalls );
expect( woocommerceVariationsAddedFunctionCalls.length ).toEqual( variationRowsCount - originalVariationRowsCount );
} );
for ( const attributeValue of variationToCreate ) {
const attributeName = productAttributes.find(
( { options } ) =>
options.includes( attributeValue )
).name;
const addAttributeMenu = variationRows
.nth( 0 )
.locator( 'select', {
has: page.locator( 'option', {
hasText: attributeValue,
} ),
} );
await test.step(
`Select "${ attributeValue }" from the "${ attributeName }" attribute menu`,
async () => {
await addAttributeMenu.selectOption(
attributeValue
);
}
);
}
await test.step( 'Click "Save changes"', async () => {
await page
.getByRole( 'button', {
name: 'Save changes',
} )
.click();
} );
await test.step(
`Expect the variation ${ variationToCreate.join(
', '
) } to be successfully saved.`,
async () => {
let newlyAddedVariationRow;
for ( const attributeValue of variationToCreate ) {
newlyAddedVariationRow = (
newlyAddedVariationRow || variationRows
).filter( {
has: page.locator( 'option[selected]', {
hasText: attributeValue,
} ),
} );
}
await expect(
newlyAddedVariationRow
).toBeVisible();
}
);
}
}
);
} );
} );

View File

@ -31,84 +31,66 @@ test.describe( 'Update variations', () => {
test.use( { storageState: process.env.ADMINSTATE } );
test.beforeAll( async ( { browser } ) => {
await test.step(
'Create variable product for individual edit test',
async () => {
productId_indivEdit = await createVariableProduct(
productAttributes
);
await test.step( 'Create variable product for individual edit test', async () => {
productId_indivEdit = await createVariableProduct(
productAttributes
);
variationIds_indivEdit = await createVariations(
productId_indivEdit,
sampleVariations
);
}
);
variationIds_indivEdit = await createVariations(
productId_indivEdit,
sampleVariations
);
} );
await test.step(
'Create variable product for bulk edit test',
async () => {
productId_bulkEdit = await createVariableProduct(
productAttributes
);
await test.step( 'Create variable product for bulk edit test', async () => {
productId_bulkEdit = await createVariableProduct(
productAttributes
);
await createVariations( productId_bulkEdit, sampleVariations );
}
);
await createVariations( productId_bulkEdit, sampleVariations );
} );
await test.step(
'Create variable product for "delete all" test',
async () => {
productId_deleteAll = await createVariableProduct(
productAttributes
);
await test.step( 'Create variable product for "delete all" test', async () => {
productId_deleteAll = await createVariableProduct(
productAttributes
);
await createVariations( productId_deleteAll, sampleVariations );
}
);
await createVariations( productId_deleteAll, sampleVariations );
} );
await test.step(
'Create variable product for "manage stock" test',
async () => {
productId_manageStock = await createVariableProduct(
productAttributes
);
await test.step( 'Create variable product for "manage stock" test', async () => {
productId_manageStock = await createVariableProduct(
productAttributes
);
const variation = sampleVariations.slice( -1 );
const variation = sampleVariations.slice( -1 );
await createVariations( productId_manageStock, variation );
}
);
await createVariations( productId_manageStock, variation );
} );
await test.step(
'Create variable product for "variation defaults" test',
async () => {
productId_variationDefaults = await createVariableProduct(
productAttributes
);
await test.step( 'Create variable product for "variation defaults" test', async () => {
productId_variationDefaults = await createVariableProduct(
productAttributes
);
await createVariations(
productId_variationDefaults,
sampleVariations
);
await createVariations(
productId_variationDefaults,
sampleVariations
);
defaultVariation = sampleVariations[ 1 ].attributes;
}
);
defaultVariation = sampleVariations[ 1 ].attributes;
} );
await test.step(
'Create variable product with 1 variation for "remove variation" test',
async () => {
productId_removeVariation = await createVariableProduct(
productAttributes
);
await test.step( 'Create variable product with 1 variation for "remove variation" test', async () => {
productId_removeVariation = await createVariableProduct(
productAttributes
);
await createVariations(
productId_removeVariation,
sampleVariations.slice( -1 )
);
}
);
await createVariations(
productId_removeVariation,
sampleVariations.slice( -1 )
);
} );
await test.step( 'Hide variable product tour', async () => {
await showVariableProductTour( browser, false );
@ -138,13 +120,14 @@ test.describe( 'Update variations', () => {
} );
await test.step( 'Click on the "Variations" tab.', async () => {
await page.getByRole('link', { name: 'Variations' }).last().click();
await page
.getByRole( 'link', { name: 'Variations' } )
.last()
.click();
} );
await test.step( 'Expand all variations.', async () => {
await page
.getByRole('link', { name: 'Expand' }).first()
.click();
await page.getByRole( 'link', { name: 'Expand' } ).first().click();
} );
await test.step( 'Edit the first variation.', async () => {
@ -156,14 +139,11 @@ test.describe( 'Update variations', () => {
.check();
} );
await test.step(
`Set regular price to "${ variationOnePrice }".`,
async () => {
await firstVariation
.getByRole( 'textbox', { name: 'Regular price' } )
.fill( variationOnePrice );
}
);
await test.step( `Set regular price to "${ variationOnePrice }".`, async () => {
await firstVariation
.getByRole( 'textbox', { name: 'Regular price' } )
.fill( variationOnePrice );
} );
} );
await test.step( 'Edit the second variation.', async () => {
@ -175,14 +155,11 @@ test.describe( 'Update variations', () => {
.check();
} );
await test.step(
`Set regular price to "${ variationTwoPrice }".`,
async () => {
await secondVariation
.getByRole( 'textbox', { name: 'Regular price' } )
.fill( variationTwoPrice );
}
);
await test.step( `Set regular price to "${ variationTwoPrice }".`, async () => {
await secondVariation
.getByRole( 'textbox', { name: 'Regular price' } )
.fill( variationTwoPrice );
} );
} );
await test.step( 'Edit the third variation.', async () => {
@ -192,14 +169,11 @@ test.describe( 'Update variations', () => {
.check();
} );
await test.step(
`Set regular price to "${ variationThreePrice }".`,
async () => {
await thirdVariation
.getByRole( 'textbox', { name: 'Regular price' } )
.fill( variationThreePrice );
}
);
await test.step( `Set regular price to "${ variationThreePrice }".`, async () => {
await thirdVariation
.getByRole( 'textbox', { name: 'Regular price' } )
.fill( variationThreePrice );
} );
await test.step( 'Set the weight and dimensions.', async () => {
await thirdVariation
@ -229,107 +203,87 @@ test.describe( 'Update variations', () => {
} );
await test.step( 'Click on the "Variations" tab.', async () => {
await page.getByRole('link', { name: 'Variations' }).last().click();
} );
await test.step( 'Expand all variations.', async () => {
await page
.getByRole('link', { name: 'Expand' }).first()
.getByRole( 'link', { name: 'Variations' } )
.last()
.click();
} );
await test.step(
'Expect the first variation to be virtual.',
async () => {
await expect(
firstVariation.getByRole( 'checkbox', {
name: 'Virtual',
} )
).toBeChecked();
}
);
await test.step( 'Expand all variations.', async () => {
await page.getByRole( 'link', { name: 'Expand' } ).first().click();
} );
await test.step(
`Expect the regular price of the first variation to be "${ variationOnePrice }".`,
async () => {
await expect(
firstVariation.getByRole( 'textbox', {
name: 'Regular price',
} )
).toHaveValue( variationOnePrice );
}
);
await test.step( 'Expect the first variation to be virtual.', async () => {
await expect(
firstVariation.getByRole( 'checkbox', {
name: 'Virtual',
} )
).toBeChecked();
} );
await test.step(
'Expect the second variation to be virtual.',
async () => {
await expect(
secondVariation.getByRole( 'checkbox', {
name: 'Virtual',
} )
).toBeChecked();
}
);
await test.step( `Expect the regular price of the first variation to be "${ variationOnePrice }".`, async () => {
await expect(
firstVariation.getByRole( 'textbox', {
name: 'Regular price',
} )
).toHaveValue( variationOnePrice );
} );
await test.step(
`Expect the regular price of the second variation to be "${ variationTwoPrice }".`,
async () => {
await expect(
secondVariation.getByRole( 'textbox', {
name: 'Regular price',
} )
).toHaveValue( variationTwoPrice );
}
);
await test.step( 'Expect the second variation to be virtual.', async () => {
await expect(
secondVariation.getByRole( 'checkbox', {
name: 'Virtual',
} )
).toBeChecked();
} );
await test.step(
'Expect the "Manage stock?" checkbox of the third variation to be checked.',
async () => {
await expect(
thirdVariation.getByRole( 'checkbox', {
name: 'Manage stock?',
} )
).toBeChecked();
}
);
await test.step( `Expect the regular price of the second variation to be "${ variationTwoPrice }".`, async () => {
await expect(
secondVariation.getByRole( 'textbox', {
name: 'Regular price',
} )
).toHaveValue( variationTwoPrice );
} );
await test.step(
`Expect the regular price of the third variation to be "${ variationThreePrice }".`,
async () => {
await expect(
thirdVariation.getByRole( 'textbox', {
name: 'Regular price',
} )
).toHaveValue( variationThreePrice );
}
);
await test.step( 'Expect the "Manage stock?" checkbox of the third variation to be checked.', async () => {
await expect(
thirdVariation.getByRole( 'checkbox', {
name: 'Manage stock?',
} )
).toBeChecked();
} );
await test.step(
'Expect the weight and dimensions of the third variation to be correct.',
async () => {
await expect(
thirdVariation.getByRole( 'textbox', {
name: 'Weight',
} )
).toHaveValue( productWeight );
await test.step( `Expect the regular price of the third variation to be "${ variationThreePrice }".`, async () => {
await expect(
thirdVariation.getByRole( 'textbox', {
name: 'Regular price',
} )
).toHaveValue( variationThreePrice );
} );
await expect(
thirdVariation.getByRole( 'textbox', {
name: 'Length',
} )
).toHaveValue( productLength );
await test.step( 'Expect the weight and dimensions of the third variation to be correct.', async () => {
await expect(
thirdVariation.getByRole( 'textbox', {
name: 'Weight',
} )
).toHaveValue( productWeight );
await expect(
thirdVariation.getByRole( 'textbox', { name: 'Width' } )
).toHaveValue( productWidth );
await expect(
thirdVariation.getByRole( 'textbox', {
name: 'Length',
} )
).toHaveValue( productLength );
await expect(
thirdVariation.getByRole( 'textbox', {
name: 'Height',
} )
).toHaveValue( productHeight );
}
);
await expect(
thirdVariation.getByRole( 'textbox', { name: 'Width' } )
).toHaveValue( productWidth );
await expect(
thirdVariation.getByRole( 'textbox', {
name: 'Height',
} )
).toHaveValue( productHeight );
} );
} );
test( 'can bulk edit variations', async ( { page } ) => {
@ -340,37 +294,32 @@ test.describe( 'Update variations', () => {
} );
await test.step( 'Click on the "Variations" tab.', async () => {
await page.getByRole('link', { name: 'Variations' }).last().click();
} );
await test.step(
'Select the \'Toggle "Downloadable"\' bulk action.',
async () => {
await page
.locator( '#field_to_edit' )
.selectOption( 'toggle_downloadable' );
}
);
await test.step( 'Expand all variations.', async () => {
await page
.getByRole('link', { name: 'Expand' }).first()
.getByRole( 'link', { name: 'Variations' } )
.last()
.click();
} );
await test.step(
'Expect all "Downloadable" checkboxes to be checked.',
async () => {
const checkBoxes = page.locator(
'input[name^="variable_is_downloadable"]'
);
const count = await checkBoxes.count();
await test.step( 'Select the \'Toggle "Downloadable"\' bulk action.', async () => {
await page
.locator( '#field_to_edit' )
.selectOption( 'toggle_downloadable' );
} );
for ( let i = 0; i < count; i++ ) {
await expect( checkBoxes.nth( i ) ).toBeChecked();
}
await test.step( 'Expand all variations.', async () => {
await page.getByRole( 'link', { name: 'Expand' } ).first().click();
} );
await test.step( 'Expect all "Downloadable" checkboxes to be checked.', async () => {
const checkBoxes = page.locator(
'input[name^="variable_is_downloadable"]'
);
const count = await checkBoxes.count();
for ( let i = 0; i < count; i++ ) {
await expect( checkBoxes.nth( i ) ).toBeChecked();
}
);
} );
} );
test( 'can delete all variations', async ( { page } ) => {
@ -381,27 +330,22 @@ test.describe( 'Update variations', () => {
} );
await test.step( 'Click on the "Variations" tab.', async () => {
await page.getByRole('link', { name: 'Variations' }).last().click();
await page
.getByRole( 'link', { name: 'Variations' } )
.last()
.click();
} );
await test.step(
'Select the bulk action "Delete all variations".',
async () => {
page.on( 'dialog', ( dialog ) => dialog.accept() );
await page
.locator( '#field_to_edit' )
.selectOption( 'delete_all' );
}
);
await test.step( 'Select the bulk action "Delete all variations".', async () => {
page.on( 'dialog', ( dialog ) => dialog.accept() );
await page.locator( '#field_to_edit' ).selectOption( 'delete_all' );
} );
await test.step(
'Expect that there are no more variations.',
async () => {
await expect(
page.locator( '.woocommerce_variation' )
).toHaveCount( 0 );
}
);
await test.step( 'Expect that there are no more variations.', async () => {
await expect(
page.locator( '.woocommerce_variation' )
).toHaveCount( 0 );
} );
} );
test( 'can manage stock levels', async ( { page } ) => {
@ -416,9 +360,7 @@ test.describe( 'Update variations', () => {
} );
await test.step( 'Expand all variations', async () => {
await page
.getByRole('link', { name: 'Expand' }).first()
.click();
await page.getByRole( 'link', { name: 'Expand' } ).first().click();
} );
const variationContainer = page.locator(
@ -431,93 +373,63 @@ test.describe( 'Update variations', () => {
.check();
} );
await test.step(
`Expect the "Stock status" text box to disappear`,
async () => {
await expect(
variationContainer.locator( 'p.variable_stock_status' )
).not.toBeVisible();
}
);
await test.step( `Expect the "Stock status" text box to disappear`, async () => {
await expect(
variationContainer.locator( 'p.variable_stock_status' )
).toBeHidden();
} );
await test.step(
`Enter "${ variationOnePrice }" as the regular price`,
async () => {
await variationContainer
.getByPlaceholder( 'Variation price (required)' )
.fill( variationOnePrice );
}
);
await test.step( `Enter "${ variationOnePrice }" as the regular price`, async () => {
await variationContainer
.getByPlaceholder( 'Variation price (required)' )
.fill( variationOnePrice );
} );
await test.step(
`Enter "${ stockAmount }" as the stock quantity`,
async () => {
await variationContainer
.locator( 'input[name^="variable_stock"]' )
.fill( stockAmount );
}
);
await test.step( `Enter "${ stockAmount }" as the stock quantity`, async () => {
await variationContainer
.locator( 'input[name^="variable_stock"]' )
.fill( stockAmount );
} );
await test.step(
'Select "Allow, but notify customer" from the "Allow backorders?" menu',
async () => {
await variationContainer
.locator( 'select[name^="variable_backorders"]' )
.selectOption( 'notify' );
}
);
await test.step( 'Select "Allow, but notify customer" from the "Allow backorders?" menu', async () => {
await variationContainer
.locator( 'select[name^="variable_backorders"]' )
.selectOption( 'notify' );
} );
await test.step(
`Enter "${ lowStockAmount }" in the "Low stock threshold" input field.`,
async () => {
await variationContainer
.getByPlaceholder( 'Store-wide threshold' )
.fill( lowStockAmount );
}
);
await test.step( `Enter "${ lowStockAmount }" in the "Low stock threshold" input field.`, async () => {
await variationContainer
.getByPlaceholder( 'Store-wide threshold' )
.fill( lowStockAmount );
} );
await test.step( 'Click "Save changes"', async () => {
await page.getByRole('button', { name: 'Save changes' }).click();
await page.getByRole( 'button', { name: 'Save changes' } ).click();
} );
await test.step( 'Expand all variations', async () => {
await page
.getByRole('link', { name: 'Expand' }).first()
.click();
await page.getByRole( 'link', { name: 'Expand' } ).first().click();
} );
await test.step(
'Expect the stock quantity to be saved correctly',
async () => {
await expect(
variationContainer.locator(
'input[name^="variable_stock"]'
)
).toHaveValue( stockAmount );
}
);
await test.step( 'Expect the stock quantity to be saved correctly', async () => {
await expect(
variationContainer.locator( 'input[name^="variable_stock"]' )
).toHaveValue( stockAmount );
} );
await test.step(
'Expect the "Low stock threshold" value to be saved correctly',
async () => {
await expect(
variationContainer.getByPlaceholder(
'Store-wide threshold'
)
).toHaveValue( lowStockAmount );
}
);
await test.step( 'Expect the "Low stock threshold" value to be saved correctly', async () => {
await expect(
variationContainer.getByPlaceholder( 'Store-wide threshold' )
).toHaveValue( lowStockAmount );
} );
await test.step(
'Expect the "Allow backorders?" value to be saved correctly',
async () => {
await expect(
variationContainer.locator(
'select[name^="variable_backorders"] > option[selected]'
)
).toHaveText( 'Allow, but notify customer' );
}
);
await test.step( 'Expect the "Allow backorders?" value to be saved correctly', async () => {
await expect(
variationContainer.locator(
'select[name^="variable_backorders"] > option[selected]'
)
).toHaveText( 'Allow, but notify customer' );
} );
} );
test( 'can set variation defaults', async ( { page } ) => {
@ -528,11 +440,14 @@ test.describe( 'Update variations', () => {
} );
await test.step( 'Click on the "Variations" tab.', async () => {
await page.getByRole('link', { name: 'Variations' }).last().click();
await page
.getByRole( 'link', { name: 'Variations' } )
.last()
.click();
} );
await test.step( 'Wait for block overlay to disappear.', async () => {
await expect( page.locator( '.blockOverlay' ) ).not.toBeVisible();
await expect( page.locator( '.blockOverlay' ) ).toBeHidden();
} );
await test.step( 'Select variation defaults', async () => {
@ -561,27 +476,21 @@ test.describe( 'Update variations', () => {
await page.goto( permalink );
} );
await test.step(
'Expect the default attributes to be pre-selected',
async () => {
for ( const attribute of defaultVariation ) {
await test.step(
`Expect "${ attribute.option }" is selected as the default "${ attribute.name }"`,
async () => {
const defaultSelectedAttribute = page
.getByRole( 'row', {
name: attribute.name,
} )
.locator( 'option[selected]' );
await test.step( 'Expect the default attributes to be pre-selected', async () => {
for ( const attribute of defaultVariation ) {
await test.step( `Expect "${ attribute.option }" is selected as the default "${ attribute.name }"`, async () => {
const defaultSelectedAttribute = page
.getByRole( 'row', {
name: attribute.name,
} )
.locator( 'option[selected]' );
await expect( defaultSelectedAttribute ).toHaveText(
attribute.option
);
}
await expect( defaultSelectedAttribute ).toHaveText(
attribute.option
);
}
} );
}
);
} );
} );
test( 'can remove a variation', async ( { page } ) => {
@ -592,7 +501,10 @@ test.describe( 'Update variations', () => {
} );
await test.step( 'Click on the "Variations" tab.', async () => {
await page.getByRole('link', { name: 'Variations' }).last().click();
await page
.getByRole( 'link', { name: 'Variations' } )
.last()
.click();
} );
await test.step( 'Click "Remove" on a variation', async () => {

View File

@ -53,7 +53,9 @@ test.describe( 'General tab', () => {
await clickOnTab( 'General', page );
await page.getByPlaceholder( 'e.g. 12 oz Coffee Mug' ).isVisible();
expect( page.locator( '.block-editor-warning' ) ).toHaveCount( 0 );
await expect( page.locator( '.block-editor-warning' ) ).toHaveCount(
0
);
} );
} );
@ -88,56 +90,54 @@ test.describe( 'General tab', () => {
}
} );
test( 'can create a simple product', 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 );
await page
.locator(
'[id^="wp-block-woocommerce-product-regular-price-field"]'
)
.first()
.fill( productData.productPrice );
await page
.locator(
'[id^="wp-block-woocommerce-product-sale-price-field"]'
)
.first()
.fill( productData.salePrice );
test( 'can create a simple product', 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 );
await page
.locator(
'[id^="wp-block-woocommerce-product-regular-price-field"]'
)
.first()
.fill( productData.productPrice );
await page
.locator(
'[id^="wp-block-woocommerce-product-sale-price-field"]'
)
.first()
.fill( productData.salePrice );
await page
.locator( '.woocommerce-product-header__actions' )
.getByRole( 'button', {
name: 'Add',
} )
.click();
await page
.locator( '.woocommerce-product-header__actions' )
.getByRole( 'button', {
name: 'Add',
} )
.click();
const element = await page.locator(
'div.components-snackbar__content'
);
const textContent = await element.innerText();
const element = page.locator( 'div.components-snackbar__content' );
const textContent = await element.innerText();
await expect( textContent ).toMatch( /Product added/ );
await expect( textContent ).toMatch( /Product added/ );
const title = await page.locator(
'.woocommerce-product-header__title'
);
const title = page.locator( '.woocommerce-product-header__title' );
// Save product ID
const productIdRegex = /product%2F(\d+)/;
const url = await 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 );
} );
test( 'can not create a product with duplicated SKU', async ( {
page,
} ) => {
@ -147,7 +147,9 @@ test( 'can create a simple product', async ( { page } ) => {
.locator( '//input[@placeholder="e.g. 12 oz Coffee Mug"]' )
.fill( productData.name );
await page
.locator( '[data-template-block-id="basic-details"] .components-summary-control' )
.locator(
'[data-template-block-id="basic-details"] .components-summary-control'
)
.fill( productData.summary );
await page
.locator(
@ -162,9 +164,7 @@ test( 'can create a simple product', async ( { page } ) => {
} )
.click();
const element = await page.locator(
'div.components-snackbar__content'
);
const element = page.locator( 'div.components-snackbar__content' );
const textContent = await element.innerText();
await expect( textContent ).toMatch( /Invalid or duplicated SKU./ );
@ -175,7 +175,9 @@ test( 'can create a simple product', async ( { page } ) => {
await page.goto( `/?post_type=product&p=${ productId }`, {
waitUntil: 'networkidle',
} );
await expect( page.getByRole( 'heading', { name: productData.name } ) ).toBeVisible();
await expect(
page.getByRole( 'heading', { name: productData.name } )
).toBeVisible();
const productPriceElements = await page
.locator( '.summary .woocommerce-Price-amount' )
.all();
@ -204,7 +206,7 @@ test( 'can create a simple product', async ( { page } ) => {
await page.waitForLoadState( 'networkidle' );
await expect(
page.locator( `a.remove[data-product_id='${ productId }']` )
).not.toBeVisible();
).toBeHidden();
} );
} );
} );

View File

@ -53,12 +53,16 @@ test.describe.serial( 'Disable block product editor', () => {
} );
test( 'can be disabled from the header', async ( { page } ) => {
await page.goto( '/wp-admin/admin.php?page=wc-admin&path=%2Fadd-product' );
await page.goto(
'/wp-admin/admin.php?page=wc-admin&path=%2Fadd-product'
);
try {
// dismiss feature highlight if shown
await page.getByRole( 'button', { name: 'Close Tour' } ).click( { timeout: 5000 } );
} catch (e) {}
await page
.getByRole( 'button', { name: 'Close Tour' } )
.click( { timeout: 5000 } );
} catch ( e ) {}
// turn off block product editor from the header
await page

View File

@ -193,7 +193,7 @@ test.describe.serial( 'WooCommerce Tax Settings', () => {
// Save changes
await page.locator( 'text=Save changes' ).click();
await expect( page.locator( '.blockOverlay' ) ).not.toBeVisible();
await expect( page.locator( '.blockOverlay' ) ).toBeHidden();
// Verity that there are 2 rates
await expect( page.locator( '#rates tr' ) ).toHaveCount( 2 );
@ -206,7 +206,7 @@ test.describe.serial( 'WooCommerce Tax Settings', () => {
// Save changes
await page.locator( 'text=Save changes' ).click();
await expect( page.locator( '.blockOverlay' ) ).not.toBeVisible();
await expect( page.locator( '.blockOverlay' ) ).toBeHidden();
// Verify that there is 1 tax rate left
await expect( page.locator( '#rates tr' ) ).toHaveCount( 1 );
@ -220,7 +220,7 @@ test.describe.serial( 'WooCommerce Tax Settings', () => {
await page.locator( '[value="CA State Tax"]' ).click();
await page.locator( '.wc_tax_rates a.remove_tax_rates' ).click();
await page.locator( 'text=Save changes' ).click();
await expect( page.locator( '.blockOverlay' ) ).not.toBeVisible();
await expect( page.locator( '.blockOverlay' ) ).toBeHidden();
} );
test( 'can remove tax classes', async ( { page } ) => {
@ -232,7 +232,7 @@ test.describe.serial( 'WooCommerce Tax Settings', () => {
// Remove "Fancy" tax class
await page.locator( '#woocommerce_tax_classes' ).fill( '' );
await page.locator( 'text=Save changes' ).click();
await expect( page.locator( '.blockOverlay' ) ).not.toBeVisible();
await expect( page.locator( '.blockOverlay' ) ).toBeHidden();
// Verify that settings have been saved
await expect( page.locator( 'div.updated.inline' ) ).toContainText(

View File

@ -10,7 +10,9 @@ test.describe( 'Customer-role users are blocked from accessing the WP Dashboard.
};
for ( const [ description, path ] of Object.entries( dashboardScreens ) ) {
test( `Customer is redirected from ${description} back to the My Account page.`, async ( { page } ) => {
test( `Customer is redirected from ${ description } back to the My Account page.`, async ( {
page,
} ) => {
await page.goto( path );
expect( page.url() ).toContain( '/my-account/' );
} );

View File

@ -13,166 +13,163 @@ const categoryC = 'Fish';
let categoryAId, categoryBId, categoryCId, product1Id, product2Id, product3Id;
test.describe(
'Search, browse by categories and sort items in the shop',
() => {
test.beforeAll( async ( { baseURL } ) => {
const api = new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,
consumerSecret: process.env.CONSUMER_SECRET,
version: 'wc/v3',
test.describe( 'Search, browse by categories and sort items in the shop', () => {
test.beforeAll( async ( { baseURL } ) => {
const api = new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,
consumerSecret: process.env.CONSUMER_SECRET,
version: 'wc/v3',
} );
// add product categories
await api
.post( 'products/categories', {
name: categoryA,
} )
.then( ( response ) => {
categoryAId = response.data.id;
} );
// add product categories
await api
.post( 'products/categories', {
name: categoryA,
} )
.then( ( response ) => {
categoryAId = response.data.id;
} );
await api
.post( 'products/categories', {
name: categoryB,
} )
.then( ( response ) => {
categoryBId = response.data.id;
} );
await api
.post( 'products/categories', {
name: categoryC,
} )
.then( ( response ) => {
categoryCId = response.data.id;
} );
// add products
await api
.post( 'products', {
name: simpleProductName + ' 1',
type: 'simple',
regular_price: singleProductPrice1,
categories: [ { id: categoryAId } ],
} )
.then( ( response ) => {
product1Id = response.data.id;
} );
await api
.post( 'products', {
name: simpleProductName + ' 2',
type: 'simple',
regular_price: singleProductPrice2,
categories: [ { id: categoryBId } ],
} )
.then( ( response ) => {
product2Id = response.data.id;
} );
await api
.post( 'products', {
name: simpleProductName + ' 3',
type: 'simple',
regular_price: singleProductPrice3,
categories: [ { id: categoryCId } ],
} )
.then( ( response ) => {
product3Id = response.data.id;
} );
} );
test.afterAll( async ( { baseURL } ) => {
const api = new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,
consumerSecret: process.env.CONSUMER_SECRET,
version: 'wc/v3',
await api
.post( 'products/categories', {
name: categoryB,
} )
.then( ( response ) => {
categoryBId = response.data.id;
} );
await api.post( 'products/batch', {
delete: [ product1Id, product2Id, product3Id ],
await api
.post( 'products/categories', {
name: categoryC,
} )
.then( ( response ) => {
categoryCId = response.data.id;
} );
await api.post( 'products/categories/batch', {
delete: [ categoryAId, categoryBId, categoryCId ],
// add products
await api
.post( 'products', {
name: simpleProductName + ' 1',
type: 'simple',
regular_price: singleProductPrice1,
categories: [ { id: categoryAId } ],
} )
.then( ( response ) => {
product1Id = response.data.id;
} );
await api
.post( 'products', {
name: simpleProductName + ' 2',
type: 'simple',
regular_price: singleProductPrice2,
categories: [ { id: categoryBId } ],
} )
.then( ( response ) => {
product2Id = response.data.id;
} );
await api
.post( 'products', {
name: simpleProductName + ' 3',
type: 'simple',
regular_price: singleProductPrice3,
categories: [ { id: categoryCId } ],
} )
.then( ( response ) => {
product3Id = response.data.id;
} );
} );
test.afterAll( async ( { baseURL } ) => {
const api = new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,
consumerSecret: process.env.CONSUMER_SECRET,
version: 'wc/v3',
} );
test( 'should let user search the store', async ( { page } ) => {
await page.goto( 'shop/' );
await page
.locator( '#wp-block-search__input-1' )
.fill( simpleProductName + ' 1' );
await page.locator( 'button.wp-block-search__button' ).click();
await expect( page.locator( 'h1.page-title' ) ).toContainText(
`${ simpleProductName } 1`
);
await expect( page.locator( 'h2.entry-title' ) ).toContainText(
simpleProductName + ' 1'
);
await api.post( 'products/batch', {
delete: [ product1Id, product2Id, product3Id ],
} );
test( 'should let user browse products by categories', async ( {
page,
} ) => {
// browse the Audio category
await page.goto( 'shop/' );
await page.locator( `text=${ simpleProductName } 2` ).click();
await page
.locator( 'span.posted_in > a', { hasText: categoryB } )
.click();
// verify the Audio category page
await expect( page.locator( 'h1.page-title' ) ).toContainText(
categoryB
);
await expect(
page.locator( 'h2.woocommerce-loop-product__title' )
).toContainText( simpleProductName + ' 2' );
await page.locator( `text=${ simpleProductName } 2` ).click();
await expect( page.locator( 'h1.entry-title' ) ).toContainText(
simpleProductName + ' 2'
);
await api.post( 'products/categories/batch', {
delete: [ categoryAId, categoryBId, categoryCId ],
} );
} );
test( 'should let user sort the products in the shop', async ( {
page,
} ) => {
await page.goto( 'shop/' );
test( 'should let user search the store', async ( { page } ) => {
await page.goto( 'shop/' );
// sort by price high to low
await page.locator( '.orderby' ).selectOption( 'price-desc' );
await page
.locator( '#wp-block-search__input-1' )
.fill( simpleProductName + ' 1' );
await page.locator( 'button.wp-block-search__button' ).click();
// Check that the priciest appears before the cheapest in the list
const highToLowList = await page
.getByRole( 'listitem' )
.getByRole( 'heading' )
.allInnerTexts();
const highToLow_index_priciest = highToLowList.indexOf(
`${ simpleProductName } 3`
);
const highToLow_index_cheapest = highToLowList.indexOf(
`${ simpleProductName } 1`
);
expect( highToLow_index_priciest ).toBeLessThan(
highToLow_index_cheapest
);
await expect( page.locator( 'h1.page-title' ) ).toContainText(
`${ simpleProductName } 1`
);
await expect( page.locator( 'h2.entry-title' ) ).toContainText(
simpleProductName + ' 1'
);
} );
// sort by price low to high
await page.locator( '.orderby' ).selectOption( 'price' );
test( 'should let user browse products by categories', async ( {
page,
} ) => {
// browse the Audio category
await page.goto( 'shop/' );
await page.locator( `text=${ simpleProductName } 2` ).click();
await page
.locator( 'span.posted_in > a', { hasText: categoryB } )
.click();
// Check that the cheapest appears before the priciest in the list
const lowToHighList = await page
.getByRole( 'listitem' )
.getByRole( 'heading' )
.allInnerTexts();
const lowToHigh_index_priciest = lowToHighList.indexOf(
`${ simpleProductName } 3`
);
const lowToHigh_index_cheapest = lowToHighList.indexOf(
`${ simpleProductName } 1`
);
expect( lowToHigh_index_cheapest ).toBeLessThan(
lowToHigh_index_priciest
);
} );
}
);
// verify the Audio category page
await expect( page.locator( 'h1.page-title' ) ).toContainText(
categoryB
);
await expect(
page.locator( 'h2.woocommerce-loop-product__title' )
).toContainText( simpleProductName + ' 2' );
await page.locator( `text=${ simpleProductName } 2` ).click();
await expect( page.locator( 'h1.entry-title' ) ).toContainText(
simpleProductName + ' 2'
);
} );
test( 'should let user sort the products in the shop', async ( {
page,
} ) => {
await page.goto( 'shop/' );
// sort by price high to low
await page.locator( '.orderby' ).selectOption( 'price-desc' );
// Check that the priciest appears before the cheapest in the list
const highToLowList = await page
.getByRole( 'listitem' )
.getByRole( 'heading' )
.allInnerTexts();
const highToLow_index_priciest = highToLowList.indexOf(
`${ simpleProductName } 3`
);
const highToLow_index_cheapest = highToLowList.indexOf(
`${ simpleProductName } 1`
);
expect( highToLow_index_priciest ).toBeLessThan(
highToLow_index_cheapest
);
// sort by price low to high
await page.locator( '.orderby' ).selectOption( 'price' );
// Check that the cheapest appears before the priciest in the list
const lowToHighList = await page
.getByRole( 'listitem' )
.getByRole( 'heading' )
.allInnerTexts();
const lowToHigh_index_priciest = lowToHighList.indexOf(
`${ simpleProductName } 3`
);
const lowToHigh_index_cheapest = lowToHighList.indexOf(
`${ simpleProductName } 1`
);
expect( lowToHigh_index_cheapest ).toBeLessThan(
lowToHigh_index_priciest
);
} );
} );

View File

@ -1,19 +1,19 @@
const {test, expect} = require('@playwright/test');
const { test, expect } = require( '@playwright/test' );
test.describe('WordPress', async () => {
test.use({storageState: process.env.CUSTOMERSTATE});
test.beforeEach(async ({page}) => {
await page.goto('hello-world/');
await expect(page.getByRole('heading', { name: 'Hello world!' })).toBeVisible();
});
test('logged-in customer can comment on a post', async ({page}) => {
let comment = `This is a test comment ${Date.now()}`;
await page.getByRole('textbox', {name: 'comment'}).fill(comment);
await page.getByRole('button', {name: 'Post Comment'}).click();
await expect(page.getByText(comment)).toBeVisible();
});
});
test.describe( 'WordPress', async () => {
test.use( { storageState: process.env.CUSTOMERSTATE } );
test.beforeEach( async ( { page } ) => {
await page.goto( 'hello-world/' );
await expect(
page.getByRole( 'heading', { name: 'Hello world!' } )
).toBeVisible();
} );
test( 'logged-in customer can comment on a post', async ( { page } ) => {
const comment = `This is a test comment ${ Date.now() }`;
await page.getByRole( 'textbox', { name: 'comment' } ).fill( comment );
await page.getByRole( 'button', { name: 'Post Comment' } ).click();
await expect( page.getByText( comment ) ).toBeVisible();
} );
} );

View File

@ -26,7 +26,7 @@ const skipTestIfUndefined = () => {
*
* If `GITHUB_TOKEN` is defined, use it as `Authorization` header.
*
* @returns Download URL of the WooCommerce ZIP. This URL depends on whether `GITHUB_TOKEN` was specified or not.
* @return Download URL of the WooCommerce ZIP. This URL depends on whether `GITHUB_TOKEN` was specified or not.
*
* If `GITHUB_TOKEN` was defined, this function assumes that you're trying to access all releases, including drafts (as draft releases don't show up in the response of an unauthenticated GET `List releases` request ).
* In this case, the returned value will be the `asset.url`.

View File

@ -3099,6 +3099,9 @@ importers:
eslint-plugin-jest:
specifier: 23.20.0
version: 23.20.0(eslint@8.55.0)(typescript@5.3.3)
eslint-plugin-playwright:
specifier: 0.22.1
version: 0.22.1(eslint-plugin-jest@23.20.0)(eslint@8.55.0)
istanbul:
specifier: 1.0.0-alpha.2
version: 1.0.0-alpha.2
@ -31856,6 +31859,20 @@ packages:
eslint: 8.55.0
dev: true
/eslint-plugin-playwright@0.22.1(eslint-plugin-jest@23.20.0)(eslint@8.55.0):
resolution: {integrity: sha512-xUQ9mJH+CjifLG6vMowl3r49G/8JvW4G10IqHjc1WO44fffdhLZF/i4Def+U3y6LqUEBp0JAMnWUhEck7ksqrw==}
peerDependencies:
eslint: '>=7'
eslint-plugin-jest: '>=25'
peerDependenciesMeta:
eslint-plugin-jest:
optional: true
dependencies:
eslint: 8.55.0
eslint-plugin-jest: 23.20.0(eslint@8.55.0)(typescript@5.3.3)
globals: 13.24.0
dev: true
/eslint-plugin-prettier@3.4.1(eslint-config-prettier@6.15.0)(eslint@7.32.0)(wp-prettier@2.2.1-beta-1):
resolution: {integrity: sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==}
engines: {node: '>=6.0.0'}