From 341a7429166e74cead297a3269849ffd9bef0144 Mon Sep 17 00:00:00 2001 From: Lucio Giannotta Date: Mon, 21 Feb 2022 13:26:22 +0100 Subject: [PATCH] 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 --- .../tests/e2e/config/setup.js | 9 +- .../tests/e2e/config/teardown.js | 6 ++ .../tests/e2e/fixtures/fixture-data.js | 14 +++ .../tests/e2e/fixtures/fixture-loaders.js | 38 +++++++ .../site-editing-templates.test.js.snap | 10 ++ .../backend/site-editing-templates.test.js | 98 +++++++++++++++++++ .../frontend/legacy-template-blocks.test.js | 35 +++++++ 7 files changed, 208 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce-blocks/tests/e2e/config/setup.js b/plugins/woocommerce-blocks/tests/e2e/config/setup.js index aa5b00b8b45..a4a6e1eb166 100644 --- a/plugins/woocommerce-blocks/tests/e2e/config/setup.js +++ b/plugins/woocommerce-blocks/tests/e2e/config/setup.js @@ -14,6 +14,7 @@ import { createProducts, createReviews, createCategories, + createTags, createShippingZones, createBlockPages, enablePaymentGateways, @@ -39,21 +40,23 @@ module.exports = async ( globalConfig ) => { createTaxes(), createCoupons(), createCategories(), + createTags(), createShippingZones(), createProductAttributes(), enablePaymentGateways(), setupPageSettings(), - ] ); + ] ).catch( console.log ); const [ taxes, coupons, categories, + tags, shippingZones, attributes, ] = results; // Create products after categories. - const products = await createProducts( categories, attributes ); + const products = await createProducts( categories, tags, attributes ); /** * Create fixture reviews data for each product. */ @@ -68,6 +71,8 @@ module.exports = async ( globalConfig ) => { shippingZones, pages, attributes, + categories, + tags, }; } catch ( e ) { console.log( e ); diff --git a/plugins/woocommerce-blocks/tests/e2e/config/teardown.js b/plugins/woocommerce-blocks/tests/e2e/config/teardown.js index e86953257e4..eab0dc24720 100644 --- a/plugins/woocommerce-blocks/tests/e2e/config/teardown.js +++ b/plugins/woocommerce-blocks/tests/e2e/config/teardown.js @@ -9,6 +9,8 @@ import { teardown as teardownPuppeteer } from 'jest-environment-puppeteer'; */ import { deleteTaxes, + deleteCategories, + deleteTags, deleteCoupons, deleteProducts, deleteShippingZones, @@ -20,6 +22,8 @@ module.exports = async ( globalConfig ) => { await teardownPuppeteer( globalConfig ); const { taxes, + tags, + categories, coupons, products, shippingZones, @@ -27,6 +31,8 @@ module.exports = async ( globalConfig ) => { attributes, } = global.fixtureData; return Promise.allSettled( [ + deleteCategories( categories ), + deleteTags( tags ), deleteTaxes( taxes ), deleteCoupons( coupons ), deleteProducts( products ), diff --git a/plugins/woocommerce-blocks/tests/e2e/fixtures/fixture-data.js b/plugins/woocommerce-blocks/tests/e2e/fixtures/fixture-data.js index 0cf7b075220..c4109dd7532 100644 --- a/plugins/woocommerce-blocks/tests/e2e/fixtures/fixture-data.js +++ b/plugins/woocommerce-blocks/tests/e2e/fixtures/fixture-data.js @@ -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 * @@ -173,6 +184,7 @@ const Products = () => [ options: [ '128gb' ], }, ], + tags: [ 'Newest' ], }, { name: '32GB USB Stick', @@ -215,6 +227,7 @@ const Products = () => [ }, ], categories: [ 'Music' ], + tags: [ 'Newest' ], }, ]; @@ -370,5 +383,6 @@ module.exports = { Settings, PageSettings, Shipping, + Tags, Taxes, }; diff --git a/plugins/woocommerce-blocks/tests/e2e/fixtures/fixture-loaders.js b/plugins/woocommerce-blocks/tests/e2e/fixtures/fixture-loaders.js index 71e410fb92c..c4953896fd8 100644 --- a/plugins/woocommerce-blocks/tests/e2e/fixtures/fixture-loaders.js +++ b/plugins/woocommerce-blocks/tests/e2e/fixtures/fixture-loaders.js @@ -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. * @@ -149,6 +178,7 @@ const deleteCategories = ( categories ) => { * @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} 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 {Object[]} fixture An array of objects describing our data, defaults * to our fixture. @@ -157,6 +187,7 @@ const deleteCategories = ( categories ) => { */ const createProducts = ( categories, + tags, attributes, 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 ) { product.attributes = product.attributes.map( ( productAttribute ) => { @@ -415,6 +451,8 @@ module.exports = { deleteCoupons, createCategories, deleteCategories, + createTags, + deleteTags, createProducts, deleteProducts, createReviews, diff --git a/plugins/woocommerce-blocks/tests/e2e/specs/backend/__snapshots__/site-editing-templates.test.js.snap b/plugins/woocommerce-blocks/tests/e2e/specs/backend/__snapshots__/site-editing-templates.test.js.snap index 612c8dc674b..c0a841aebbc 100644 --- a/plugins/woocommerce-blocks/tests/e2e/specs/backend/__snapshots__/site-editing-templates.test.js.snap +++ b/plugins/woocommerce-blocks/tests/e2e/specs/backend/__snapshots__/site-editing-templates.test.js.snap @@ -20,6 +20,16 @@ exports[`Store Editing Templates Product Category block template should contain " `; +exports[`Store Editing Templates Product Tag block template should contain the "WooCommerce Product Taxonomy Block" legacy template 1`] = ` +" + + +
+ + +" +`; + exports[`Store Editing Templates Single Product block template should contain the "WooCommerce Single Product Block" legacy template 1`] = ` " diff --git a/plugins/woocommerce-blocks/tests/e2e/specs/backend/site-editing-templates.test.js b/plugins/woocommerce-blocks/tests/e2e/specs/backend/site-editing-templates.test.js index 2983eee4714..d179a2524b2 100644 --- a/plugins/woocommerce-blocks/tests/e2e/specs/backend/site-editing-templates.test.js +++ b/plugins/woocommerce-blocks/tests/e2e/specs/backend/site-editing-templates.test.js @@ -81,6 +81,14 @@ const BLOCK_DATA = { }, 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 = { @@ -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, + } ); + } ); + } ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/specs/frontend/legacy-template-blocks.test.js b/plugins/woocommerce-blocks/tests/e2e/specs/frontend/legacy-template-blocks.test.js index 5ca6372260b..712ad1cd1ad 100644 --- a/plugins/woocommerce-blocks/tests/e2e/specs/frontend/legacy-template-blocks.test.js +++ b/plugins/woocommerce-blocks/tests/e2e/specs/frontend/legacy-template-blocks.test.js @@ -111,4 +111,39 @@ describe( 'Legacy Template blocks', () => { 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 ); + } ); + } ); } );