E2E tests for Product Tag Template and Legacy Block (https://github.com/woocommerce/woocommerce-blocks/pull/5888)

Also: 

* Add fixtures for tags
* Teardown both categories and tags when tests are done
This commit is contained in:
Lucio Giannotta 2022-02-21 13:26:22 +01:00 committed by GitHub
parent d64ebc72dc
commit 341a742916
7 changed files with 208 additions and 2 deletions

View File

@ -14,6 +14,7 @@ import {
createProducts, createProducts,
createReviews, createReviews,
createCategories, createCategories,
createTags,
createShippingZones, createShippingZones,
createBlockPages, createBlockPages,
enablePaymentGateways, enablePaymentGateways,
@ -39,21 +40,23 @@ module.exports = async ( globalConfig ) => {
createTaxes(), createTaxes(),
createCoupons(), createCoupons(),
createCategories(), createCategories(),
createTags(),
createShippingZones(), createShippingZones(),
createProductAttributes(), createProductAttributes(),
enablePaymentGateways(), enablePaymentGateways(),
setupPageSettings(), setupPageSettings(),
] ); ] ).catch( console.log );
const [ const [
taxes, taxes,
coupons, coupons,
categories, categories,
tags,
shippingZones, shippingZones,
attributes, attributes,
] = results; ] = results;
// Create products after categories. // Create products after categories.
const products = await createProducts( categories, attributes ); const products = await createProducts( categories, tags, attributes );
/** /**
* Create fixture reviews data for each product. * Create fixture reviews data for each product.
*/ */
@ -68,6 +71,8 @@ module.exports = async ( globalConfig ) => {
shippingZones, shippingZones,
pages, pages,
attributes, attributes,
categories,
tags,
}; };
} catch ( e ) { } catch ( e ) {
console.log( e ); console.log( e );

View File

@ -9,6 +9,8 @@ import { teardown as teardownPuppeteer } from 'jest-environment-puppeteer';
*/ */
import { import {
deleteTaxes, deleteTaxes,
deleteCategories,
deleteTags,
deleteCoupons, deleteCoupons,
deleteProducts, deleteProducts,
deleteShippingZones, deleteShippingZones,
@ -20,6 +22,8 @@ module.exports = async ( globalConfig ) => {
await teardownPuppeteer( globalConfig ); await teardownPuppeteer( globalConfig );
const { const {
taxes, taxes,
tags,
categories,
coupons, coupons,
products, products,
shippingZones, shippingZones,
@ -27,6 +31,8 @@ module.exports = async ( globalConfig ) => {
attributes, attributes,
} = global.fixtureData; } = global.fixtureData;
return Promise.allSettled( [ return Promise.allSettled( [
deleteCategories( categories ),
deleteTags( tags ),
deleteTaxes( taxes ), deleteTaxes( taxes ),
deleteCoupons( coupons ), deleteCoupons( coupons ),
deleteProducts( products ), deleteProducts( products ),

View File

@ -126,6 +126,17 @@ const Categories = () => [
}, },
]; ];
/**
* Product tags fixture data, using the create batch endpoint
*
* @see {@link https://woocommerce.github.io/woocommerce-rest-api-docs/#batch-update-product-tags|Batch update product tags}
*/
const Tags = () => [
{
name: 'Newest',
},
];
/** /**
* Product fixture data, using the create batch endpoint * Product fixture data, using the create batch endpoint
* *
@ -173,6 +184,7 @@ const Products = () => [
options: [ '128gb' ], options: [ '128gb' ],
}, },
], ],
tags: [ 'Newest' ],
}, },
{ {
name: '32GB USB Stick', name: '32GB USB Stick',
@ -215,6 +227,7 @@ const Products = () => [
}, },
], ],
categories: [ 'Music' ], categories: [ 'Music' ],
tags: [ 'Newest' ],
}, },
]; ];
@ -370,5 +383,6 @@ module.exports = {
Settings, Settings,
PageSettings, PageSettings,
Shipping, Shipping,
Tags,
Taxes, Taxes,
}; };

View File

@ -141,6 +141,35 @@ const deleteCategories = ( categories ) => {
} ); } );
}; };
/**
* Create Product Tags.
*
* @param {Object[]} fixture An array of objects describing our data, defaults
* to our fixture.
* @return {Promise} a promise that resolves to an array of newly created tags,
* or rejects if the request failed.
*/
const createTags = ( fixture = fixtures.Tags() ) =>
WooCommerce.post( 'products/tags/batch', {
create: fixture,
} ).then( ( response ) => response.data.create );
/**
* Delete Product Tags.
*
* @param {Object[]} tags an array of tags to delete.
*
* @return {Promise} return a promise that resolves to the deleted data or
* reject if the request failed.
*/
const deleteTags = ( tags ) => {
const ids = tags.map( ( tag ) => tag.id );
return WooCommerce.post( 'products/tags/batch', {
delete: ids,
} );
};
/** /**
* Create Products. * Create Products.
* *
@ -149,6 +178,7 @@ const deleteCategories = ( categories ) => {
* @todo add more products to e2e fixtures data. * @todo add more products to e2e fixtures data.
* *
* @param {Array} categories Array of category objects so we can replace names with ids in the request. * @param {Array} categories Array of category objects so we can replace names with ids in the request.
* @param {Array} tags Array of category objects so we can replace names with ids in the request.
* @param {Array} attributes Array of attribute objects so we can replace names with ids in the request. * @param {Array} attributes Array of attribute objects so we can replace names with ids in the request.
* @param {Object[]} fixture An array of objects describing our data, defaults * @param {Object[]} fixture An array of objects describing our data, defaults
* to our fixture. * to our fixture.
@ -157,6 +187,7 @@ const deleteCategories = ( categories ) => {
*/ */
const createProducts = ( const createProducts = (
categories, categories,
tags,
attributes, attributes,
fixture = fixtures.Products() fixture = fixtures.Products()
) => { ) => {
@ -168,6 +199,11 @@ const createProducts = (
) )
); );
} }
if ( tags && product.tags ) {
product.tags = product.tags.map( ( tagName ) =>
tags.find( ( tag ) => tag.name === tagName )
);
}
if ( attributes && product.attributes ) { if ( attributes && product.attributes ) {
product.attributes = product.attributes.map( product.attributes = product.attributes.map(
( productAttribute ) => { ( productAttribute ) => {
@ -415,6 +451,8 @@ module.exports = {
deleteCoupons, deleteCoupons,
createCategories, createCategories,
deleteCategories, deleteCategories,
createTags,
deleteTags,
createProducts, createProducts,
deleteProducts, deleteProducts,
createReviews, createReviews,

View File

@ -20,6 +20,16 @@ exports[`Store Editing Templates Product Category block template should contain
<!-- wp:template-part {\\"slug\\":\\"footer\\",\\"theme\\":\\"emptytheme\\"} /-->" <!-- wp:template-part {\\"slug\\":\\"footer\\",\\"theme\\":\\"emptytheme\\"} /-->"
`; `;
exports[`Store Editing Templates Product Tag block template should contain the "WooCommerce Product Taxonomy Block" legacy template 1`] = `
"<!-- wp:template-part {\\"slug\\":\\"header\\",\\"theme\\":\\"emptytheme\\"} /-->
<!-- wp:group {\\"layout\\":{\\"inherit\\":true}} -->
<div class=\\"wp-block-group\\"><!-- wp:woocommerce/legacy-template {\\"template\\":\\"taxonomy-product_tag\\"} /--></div>
<!-- /wp:group -->
<!-- wp:template-part {\\"slug\\":\\"footer\\",\\"theme\\":\\"emptytheme\\"} /-->"
`;
exports[`Store Editing Templates Single Product block template should contain the "WooCommerce Single Product Block" legacy template 1`] = ` exports[`Store Editing Templates Single Product block template should contain the "WooCommerce Single Product Block" legacy template 1`] = `
"<!-- wp:template-part {\\"slug\\":\\"header\\",\\"theme\\":\\"emptytheme\\"} /--> "<!-- wp:template-part {\\"slug\\":\\"header\\",\\"theme\\":\\"emptytheme\\"} /-->

View File

@ -81,6 +81,14 @@ const BLOCK_DATA = {
}, },
name: 'woocommerce/legacy-template', name: 'woocommerce/legacy-template',
}, },
'taxonomy-product_tag': {
attributes: {
placeholder: 'archive-product',
template: 'taxonomy-product_tag',
title: 'WooCommerce Product Tag Block',
},
name: 'woocommerce/legacy-template',
},
}; };
const SELECTORS = { const SELECTORS = {
@ -393,4 +401,94 @@ describe( 'Store Editing Templates', () => {
} ); } );
} ); } );
} ); } );
describe( 'Product Tag block template', () => {
it( 'default template from WooCommerce Blocks is available on an FSE theme', async () => {
const EXPECTED_TEMPLATE = defaultTemplateProps( 'Product Tag' );
await goToSiteEditor( '?postType=wp_template' );
const templates = await getAllTemplates();
try {
expect( templates ).toContainEqual( EXPECTED_TEMPLATE );
} catch ( ok ) {
// Depending on the speed of the execution and whether Chrome is headless or not
// the id might be parsed or not
expect( templates ).toContainEqual( {
...EXPECTED_TEMPLATE,
addedBy: WOOCOMMERCE_PARSED_ID,
} );
}
} );
it( 'should contain the "WooCommerce Product Taxonomy Block" legacy template', async () => {
const templateQuery = addQueryArgs( '', {
postId: 'woocommerce/woocommerce//taxonomy-product_tag',
postType: 'wp_template',
} );
await goToSiteEditor( templateQuery );
await waitForCanvas();
const [ legacyBlock ] = await filterCurrentBlocks(
( block ) =>
block.name === BLOCK_DATA[ 'taxonomy-product_tag' ].name
);
expect( legacyBlock.attributes.template ).toBe(
BLOCK_DATA[ 'taxonomy-product_tag' ].attributes.template
);
expect( await getCurrentSiteEditorContent() ).toMatchSnapshot();
} );
it( 'should show the action menu if the template has been customized by the user', async () => {
const EXPECTED_TEMPLATE = {
...defaultTemplateProps( 'Product Tag' ),
hasActions: true,
};
await visitTemplateAndAddCustomParagraph( 'taxonomy-product_tag' );
await goToSiteEditor( '?postType=wp_template' );
const templates = await getAllTemplates();
try {
expect( templates ).toContainEqual( EXPECTED_TEMPLATE );
} catch ( ok ) {
// Depending on the speed of the execution and whether Chrome is headless or not
// the id might be parsed or not
expect( templates ).toContainEqual( {
...EXPECTED_TEMPLATE,
addedBy: WOOCOMMERCE_PARSED_ID,
} );
}
} );
it( 'should preserve and correctly show the user customization on the back-end', async () => {
const templateQuery = addQueryArgs( '', {
postId: 'woocommerce/woocommerce//taxonomy-product_tag',
postType: 'wp_template',
} );
await goToSiteEditor( templateQuery );
await waitForCanvas();
await expect( canvas() ).toMatchElement(
SELECTORS.blocks.paragraph,
{ text: CUSTOMIZED_STRING, timeout: DEFAULT_TIMEOUT }
);
} );
it( 'should show the user customization on the front-end', async () => {
await page.goto( new URL( '/product-tag/newest', BASE_URL ) );
await expect( page ).toMatchElement( 'p', {
text: CUSTOMIZED_STRING,
timeout: DEFAULT_TIMEOUT,
} );
} );
} );
} ); } );

View File

@ -111,4 +111,39 @@ describe( 'Legacy Template blocks', () => {
expect( $productElements ).toHaveLength( Number( displayedCount ) ); expect( $productElements ).toHaveLength( Number( displayedCount ) );
} ); } );
} ); } );
describe( 'Product Tag block', () => {
it( 'renders a list of products with their count, pagination and the tag title', async () => {
const TAG_NAME = 'Newest';
const { productArchivePage } = SELECTORS;
await page.goto(
new URL( `/product-tag/${ TAG_NAME.toLowerCase() }`, BASE_URL )
);
await expect( page ).toMatchElement( productArchivePage.title, {
text: TAG_NAME,
} );
await page.waitForSelector( productArchivePage.productsList );
await page.waitForSelector( productArchivePage.resultsCount );
const {
displayedCount,
shouldHavePaginationUI,
} = await extractPaginationData();
if ( shouldHavePaginationUI ) {
await expect( page ).toMatchElement(
productArchivePage.paginationUI
);
}
const $productElements = await page.$$(
productArchivePage.productContainers
);
expect( $productElements ).toHaveLength( displayedCount );
} );
} );
} ); } );