E2E tests for Product Archive Template and Legacy Block (https://github.com/woocommerce/woocommerce-blocks/pull/5748)
Also: * Refactors the function to add a custom paragraph * Add front-end test for archive template * Use WordPress data to guarantee block presence * Use WordPress data instead of selectors to match blocks
This commit is contained in:
parent
497820dcb9
commit
5de9fec527
|
@ -1,5 +1,15 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Store Editing Templates Product Archive block template should contain the "WooCommerce Product Archive 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\\":\\"archive-product\\"} /--></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\\"} /-->
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { URL } from 'url';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
activateTheme,
|
activateTheme,
|
||||||
canvas,
|
canvas,
|
||||||
|
@ -11,6 +13,7 @@ import {
|
||||||
visitPostOfType,
|
visitPostOfType,
|
||||||
} from '@woocommerce/blocks-test-utils';
|
} from '@woocommerce/blocks-test-utils';
|
||||||
import {
|
import {
|
||||||
|
BASE_URL,
|
||||||
DEFAULT_TIMEOUT,
|
DEFAULT_TIMEOUT,
|
||||||
filterCurrentBlocks,
|
filterCurrentBlocks,
|
||||||
getAllTemplates,
|
getAllTemplates,
|
||||||
|
@ -19,6 +22,22 @@ import {
|
||||||
waitForCanvas,
|
waitForCanvas,
|
||||||
} from '../../utils';
|
} from '../../utils';
|
||||||
|
|
||||||
|
async function visitTemplateAndAddCustomParagraph(
|
||||||
|
templateSlug,
|
||||||
|
customText = CUSTOMIZED_STRING
|
||||||
|
) {
|
||||||
|
const templateQuery = addQueryArgs( '', {
|
||||||
|
postId: `woocommerce/woocommerce//${ templateSlug }`,
|
||||||
|
postType: 'wp_template',
|
||||||
|
} );
|
||||||
|
|
||||||
|
await goToSiteEditor( templateQuery );
|
||||||
|
await waitForCanvas();
|
||||||
|
await insertBlock( 'Paragraph' );
|
||||||
|
await page.keyboard.type( customText );
|
||||||
|
await saveTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
function blockSelector( id ) {
|
function blockSelector( id ) {
|
||||||
return `[data-type="${ id }"]`;
|
return `[data-type="${ id }"]`;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +57,14 @@ function legacyBlockSelector( title ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const BLOCK_DATA = {
|
const BLOCK_DATA = {
|
||||||
|
'archive-product': {
|
||||||
|
attributes: {
|
||||||
|
placeholder: 'archive-product',
|
||||||
|
template: 'archive-product',
|
||||||
|
title: 'WooCommerce Product Grid Block',
|
||||||
|
},
|
||||||
|
name: 'woocommerce/legacy-template',
|
||||||
|
},
|
||||||
'single-product': {
|
'single-product': {
|
||||||
attributes: {
|
attributes: {
|
||||||
placeholder: 'single-product',
|
placeholder: 'single-product',
|
||||||
|
@ -51,6 +78,7 @@ const BLOCK_DATA = {
|
||||||
const SELECTORS = {
|
const SELECTORS = {
|
||||||
blocks: {
|
blocks: {
|
||||||
paragraph: blockSelector( 'core/paragraph' ),
|
paragraph: blockSelector( 'core/paragraph' ),
|
||||||
|
productArchive: legacyBlockSelector( 'WooCommerce Product Grid Block' ),
|
||||||
singleProduct: legacyBlockSelector(
|
singleProduct: legacyBlockSelector(
|
||||||
'WooCommerce Single Product Block'
|
'WooCommerce Single Product Block'
|
||||||
),
|
),
|
||||||
|
@ -121,18 +149,9 @@ describe( 'Store Editing Templates', () => {
|
||||||
hasActions: true,
|
hasActions: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const templateQuery = addQueryArgs( '', {
|
await visitTemplateAndAddCustomParagraph( 'single-product' );
|
||||||
postId: 'woocommerce/woocommerce//single-product',
|
|
||||||
postType: 'wp_template',
|
|
||||||
} );
|
|
||||||
|
|
||||||
await goToSiteEditor( templateQuery );
|
await goToSiteEditor( 'postType=wp_template' );
|
||||||
await waitForCanvas();
|
|
||||||
await insertBlock( 'Paragraph' );
|
|
||||||
await page.keyboard.type( CUSTOMIZED_STRING );
|
|
||||||
await saveTemplate();
|
|
||||||
|
|
||||||
await goToSiteEditor( '?postType=wp_template' );
|
|
||||||
const templates = await getAllTemplates();
|
const templates = await getAllTemplates();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -177,4 +196,99 @@ describe( 'Store Editing Templates', () => {
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
describe( 'Product Archive block template', () => {
|
||||||
|
it( 'default template from WooCommerce Blocks is available on an FSE theme', async () => {
|
||||||
|
const EXPECTED_TEMPLATE = defaultTemplateProps( 'Product Archive' );
|
||||||
|
|
||||||
|
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 Archive Block" legacy template', async () => {
|
||||||
|
const templateQuery = addQueryArgs( '', {
|
||||||
|
postId: 'woocommerce/woocommerce//archive-product',
|
||||||
|
postType: 'wp_template',
|
||||||
|
} );
|
||||||
|
|
||||||
|
await goToSiteEditor( templateQuery );
|
||||||
|
await waitForCanvas();
|
||||||
|
|
||||||
|
const [ legacyBlock ] = await filterCurrentBlocks(
|
||||||
|
( block ) => block.name === BLOCK_DATA[ 'archive-product' ].name
|
||||||
|
);
|
||||||
|
|
||||||
|
expect( legacyBlock.attributes.template ).toBe(
|
||||||
|
BLOCK_DATA[ 'archive-product' ].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 Archive' ),
|
||||||
|
hasActions: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
await visitTemplateAndAddCustomParagraph( 'archive-product' );
|
||||||
|
|
||||||
|
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//archive-product',
|
||||||
|
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( '/?post_type=product', BASE_URL ) );
|
||||||
|
const exampleProductName = 'Woo Single #1';
|
||||||
|
|
||||||
|
await visitPostOfType( exampleProductName, 'product' );
|
||||||
|
const permalink = await getNormalPagePermalink();
|
||||||
|
|
||||||
|
await page.goto( permalink );
|
||||||
|
|
||||||
|
await expect( page ).toMatchElement( 'p', {
|
||||||
|
text: CUSTOMIZED_STRING,
|
||||||
|
timeout: DEFAULT_TIMEOUT,
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { URL } from 'url';
|
||||||
|
import { activateTheme } from '@wordpress/e2e-test-utils';
|
||||||
|
|
||||||
|
import { BASE_URL } from '../../utils';
|
||||||
|
|
||||||
|
const SELECTORS = {
|
||||||
|
productArchivePage: {
|
||||||
|
paginationUI: '.woocommerce-pagination',
|
||||||
|
productContainers: '.products .product',
|
||||||
|
productsList: '.products',
|
||||||
|
resultsCount: '.woocommerce-result-count',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
describe( 'Legacy Template blocks', () => {
|
||||||
|
beforeAll( async () => {
|
||||||
|
await activateTheme( 'emptytheme' );
|
||||||
|
} );
|
||||||
|
|
||||||
|
afterAll( async () => {
|
||||||
|
await activateTheme( 'twentytwentyone' );
|
||||||
|
} );
|
||||||
|
|
||||||
|
describe( 'Product Archive block', () => {
|
||||||
|
it( 'renders a list of products with their count and pagination', async () => {
|
||||||
|
const { productArchivePage } = SELECTORS;
|
||||||
|
|
||||||
|
await page.goto( new URL( '/?post_type=product', BASE_URL ) );
|
||||||
|
|
||||||
|
await page.waitForSelector( productArchivePage.productsList );
|
||||||
|
await page.waitForSelector( productArchivePage.resultsCount );
|
||||||
|
|
||||||
|
const { displayedCount, shouldHavePaginationUI } = await page.$eval(
|
||||||
|
productArchivePage.resultsCount,
|
||||||
|
( $el ) => {
|
||||||
|
const resultsCountRegEx = /1–(\d+)|\d+/;
|
||||||
|
const matches = $el.textContent.match( resultsCountRegEx );
|
||||||
|
|
||||||
|
// Depending on pagination, string can be either:
|
||||||
|
// a) 'Showing x–y of z results'
|
||||||
|
// b) 'Showing all x results'
|
||||||
|
return {
|
||||||
|
displayedCount: matches[ 1 ] || matches[ 0 ],
|
||||||
|
shouldHavePaginationUI: !! matches[ 1 ],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( shouldHavePaginationUI ) {
|
||||||
|
await expect( page ).toMatchElement(
|
||||||
|
productArchivePage.paginationUI
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const $productElements = await page.$$(
|
||||||
|
productArchivePage.productContainers
|
||||||
|
);
|
||||||
|
|
||||||
|
expect( $productElements ).toHaveLength( Number( displayedCount ) );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
} );
|
|
@ -1,6 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
|
import config from 'config';
|
||||||
import {
|
import {
|
||||||
disableSiteEditorWelcomeGuide,
|
disableSiteEditorWelcomeGuide,
|
||||||
openGlobalBlockInserter,
|
openGlobalBlockInserter,
|
||||||
|
@ -25,6 +26,7 @@ import { elementExists, getTextContent } from './page-utils';
|
||||||
* @typedef {{ addedBy: string, hasActions: boolean, templateTitle: string }} TemplateTableItem
|
* @typedef {{ addedBy: string, hasActions: boolean, templateTitle: string }} TemplateTableItem
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
export const BASE_URL = config.get( 'url' );
|
||||||
export const DEFAULT_TIMEOUT = 30000;
|
export const DEFAULT_TIMEOUT = 30000;
|
||||||
|
|
||||||
const SELECTORS = {
|
const SELECTORS = {
|
||||||
|
|
Loading…
Reference in New Issue