Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

e2e tests for cart and checkout templates #9939

Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ae73afe
Merge branch 'trunk' into poc/cart_and_checkout_fse_templates
wavvves Mar 7, 2023
047a42b
Merge branch 'trunk' into add/9288_cart-checkout-order-received_fse_t…
wavvves Jun 6, 2023
f79b42b
Resolve merge conflicts
mikejolley Jun 20, 2023
f001917
Add e2e for permalink settings
mikejolley Jun 21, 2023
8186549
Test that templates exist
mikejolley Jun 21, 2023
f88c03b
Add test to check that templates can be edited
mikejolley Jun 22, 2023
e861c1c
Add tests to confirm templates can be edited
mikejolley Jun 22, 2023
dbc2171
Ensure cart has contents before running tests on frontend views
mikejolley Jun 26, 2023
efb2b52
Commend out problem test
mikejolley Jun 26, 2023
89ac75c
Make sure search has multiple results
mikejolley Jun 26, 2023
97ef316
Remove useThrottle - bad rebase
mikejolley Jun 27, 2023
e37bbd4
Revert changes to docs after rebase
mikejolley Jun 27, 2023
0f9893c
Revert function call for noReviewsPlaceholder
mikejolley Jun 27, 2023
12c7119
Bad rebase
mikejolley Jun 27, 2023
314b844
Reverts
mikejolley Jun 27, 2023
1ae9926
Remove revertTemplate
mikejolley Jun 27, 2023
790b53f
Spacing
mikejolley Jun 27, 2023
87f9259
Wait for networkidle after navigation
mikejolley Jun 27, 2023
98d88cd
Always wait for network
mikejolley Jun 27, 2023
df350d1
Use button roles in site editor
mikejolley Jun 27, 2023
2cdad1e
More specific button locator
mikejolley Jun 27, 2023
7de932e
Update option comparison
mikejolley Jun 27, 2023
4fbdbbe
Fix template content
mikejolley Jun 27, 2023
6623b3c
Disable failing tests
mikejolley Jun 27, 2023
9587ed4
Disable failing classic template tests
mikejolley Jun 27, 2023
45b2949
Use enterEditMode
mikejolley Jun 27, 2023
d51966e
More enterEditMode usage
mikejolley Jun 27, 2023
8e8856a
enterEditMode
mikejolley Jun 27, 2023
0ae69cd
Use test.skip
mikejolley Jun 28, 2023
1b02c07
More robust selectors
mikejolley Jun 28, 2023
41f1f8c
Alt iframe selector
mikejolley Jun 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ const templates = {
slug: 'single-product',
frontendPage: '/product/single/',
},
'taxonomy-product_attribute': {
templateTitle: 'Product Attribute',
slug: 'taxonomy-product_attribute',
frontendPage: '/product-attribute/color/',
},

// This test is disabled because archives are disabled for attributes by default. This can be uncommented when this is toggled on.
//'taxonomy-product_attribute': {
// templateTitle: 'Product Attribute',
// slug: 'taxonomy-product_attribute',
// frontendPage: '/product-attribute/color/',
//},
'taxonomy-product_cat': {
templateTitle: 'Product Category',
slug: 'taxonomy-product_cat',
Expand All @@ -49,7 +49,7 @@ const templates = {
'product-search-results': {
templateTitle: 'Product Search Results',
slug: 'product-search-results',
frontendPage: '/?s=single&post_type=product',
frontendPage: '/?s=s&post_type=product',
},
};

Expand Down Expand Up @@ -100,9 +100,9 @@ for ( const { templateTitle, slug, frontendPage } of Object.values(

await page.goto( frontendPage );

const helloWorldText = await page.getByText( 'Hello World' );

expect( helloWorldText ).not.toBeNull();
Copy link
Member Author

@mikejolley mikejolley Jun 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a bug! getByText returns arrays

await expect(
page.getByText( 'Hello World' ).first()
).toBeVisible();
} );

test.afterAll( async ( { requestUtils } ) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* External dependencies
*/
import { test, expect } from '@woocommerce/e2e-playwright-utils';
import { cli } from '@woocommerce/e2e-utils';

/**
* Internal dependencies
*/
import { goToShop, addToCart } from '../../utils';

test.describe(
'Tests permalink settings for the cart and checkout templates',
async () => {
test.afterAll( async () => {
await cli(
'npm run wp-env run tests-cli "wp option update woocommerce_cart_page_endpoint cart"'
);
await cli(
'npm run wp-env run tests-cli "wp option update woocommerce_checkout_page_endpoint checkout"'
);
} );

test.describe( 'Settings page', () => {
test( 'Load advanced settings', async ( { page } ) => {
await page.goto(
'/wp-admin/admin.php?page=wc-settings&tab=advanced'
);
const title = page
.locator( 'div.wrap.woocommerce > form > h2' )
.first();
await expect( title ).toHaveText( 'Page setup' );
} );
test( 'Permlink settings exist', async ( { page } ) => {
await page.goto(
'/wp-admin/admin.php?page=wc-settings&tab=advanced'
);
const cartInput = page.locator(
'tr:has-text("Cart page "):has-text("cart template") input'
);
const checkoutInput = page.locator(
'tr:has-text("Checkout page "):has-text("checkout template") input'
);

await expect( cartInput ).toBeVisible();
await expect( checkoutInput ).toBeVisible();
} );
} );

test.describe( 'Frontend templates are updated', () => {
test.beforeEach( async ( { page } ) => {
await goToShop( page );
await addToCart( page );
} );

test( 'Changing cart permalink works', async ( { page } ) => {
await page.goto(
'/wp-admin/admin.php?page=wc-settings&tab=advanced'
);
const cartInput = page.locator(
'tr:has-text("Cart page "):has-text("cart template") input'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that I would love to revisit this and use the provided locators in future. For now this is OK to get tests working.

);
cartInput.fill( 'updated-cart-permalink' );
await page.click( 'button[name="save"]' );
await page.waitForLoadState( 'networkidle' );

// Visit the updated page.
await page.goto( '/updated-cart-permalink' );
const cartText = await page.getByText( 'Proceed to checkout' );
expect( cartText ).toBeVisible();
} );

test( 'Changing checkout permalink works', async ( { page } ) => {
await page.goto(
'/wp-admin/admin.php?page=wc-settings&tab=advanced'
);
const checkoutInput = page.locator(
'tr:has-text("Checkout page "):has-text("checkout template") input'
);
checkoutInput.fill( 'updated-checkout-permalink' );
await page.click( 'button[name="save"]' );
await page.waitForLoadState( 'networkidle' );

// Visit the updated page.
await page.goto( '/updated-checkout-permalink' );
const cartText = await page.getByText( 'Place Order' );
expect( cartText ).toBeVisible();
} );
} );
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ const blockData: BlockData = {
};

const templates = {
'taxonomy-product_attribute': {
templateTitle: 'Product Attribute',
slug: 'taxonomy-product_attribute',
frontendPage: '/product-attribute/color/',
},
// This test is disabled because archives are disabled for attributes by default. This can be uncommented when this is toggled on.
//'taxonomy-product_attribute': {
// templateTitle: 'Product Attribute',
// slug: 'taxonomy-product_attribute',
// frontendPage: '/product-attribute/color/',
//},
'taxonomy-product_cat': {
templateTitle: 'Product Category',
slug: 'taxonomy-product_cat',
Expand Down
46 changes: 46 additions & 0 deletions tests/e2e-pw/tests/templates/cart-template.block_theme.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* External dependencies
*/
import { test, expect } from '@woocommerce/e2e-playwright-utils';

const permalink = '/cart';
const templatePath = 'woocommerce/woocommerce//cart';
const templateType = 'wp_template';

test.describe( 'Test the cart template', async () => {
test.afterAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
} );

test( 'Template can be opened in the site editor', async ( { page } ) => {
await page.goto( '/wp-admin/site-editor.php' );
await page.click( 'text=Templates' );
await page.click( 'text=Cart' );
await page.getByRole( 'button', { name: /Edit/i } ).click();

await expect(
page
.frameLocator( 'iFrame' )
.locator( 'button:has-text("Proceed to checkout")' )
.first()
).toBeVisible();
} );

test( 'Template can be modified', async ( { page, admin, editor } ) => {
await admin.visitSiteEditor( {
postId: templatePath,
postType: templateType,
} );
await editor.canvas.click( 'body' );
await editor.canvas.waitForLoadState( 'networkidle' );
await editor.insertBlock( {
name: 'core/paragraph',
attributes: { content: 'Hello World' },
} );
await editor.saveSiteEditorEntities();
await page.goto( permalink );

await expect( page.getByText( 'Hello World' ).first() ).toBeVisible();
} );
} );
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* External dependencies
*/
import { test, expect } from '@woocommerce/e2e-playwright-utils';

const permalink = '/checkout';
const templatePath = 'woocommerce/woocommerce//checkout-header';
const templateType = 'wp_template_part';

test.afterAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
} );

test.describe( 'Test the checkout header template part', async () => {
test( 'Template can be opened in the site editor', async ( { page } ) => {
await page.goto( '/wp-admin/site-editor.php' );
await page.click( 'text=Template Parts' );
await page.click( 'text=Checkout Header' );

const editButton = page.getByRole( 'button', { name: /Edit/i } );
await expect( editButton ).toBeVisible();
} );

test( 'Template can be modified', async ( { page, admin, editor } ) => {
await admin.visitSiteEditor( {
postId: templatePath,
postType: templateType,
} );
await editor.canvas.click( 'body' );
await editor.canvas.waitForLoadState( 'networkidle' );
await editor.insertBlock( {
name: 'core/paragraph',
attributes: { content: 'Hello World' },
} );
await editor.saveSiteEditorEntities();

await page.goto( permalink );

await expect( page.getByText( 'Hello World' ).first() ).toBeVisible();
} );
} );
46 changes: 46 additions & 0 deletions tests/e2e-pw/tests/templates/checkout-template.block_theme.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* External dependencies
*/
import { test, expect } from '@woocommerce/e2e-playwright-utils';

const permalink = '/checkout';
const templatePath = 'woocommerce/woocommerce//checkout';
const templateType = 'wp_template';

test.describe( 'Test the checkout template', async () => {
test.afterAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
} );

test( 'Template can be opened in the site editor', async ( { page } ) => {
await page.goto( '/wp-admin/site-editor.php' );
await page.click( 'text=Templates' );
await page.click( 'text=Checkout' );
await page.getByRole( 'button', { name: /Edit/i } ).click();

await expect(
page
.frameLocator( 'iFrame' )
.locator( 'button:has-text("Place order")' )
.first()
).toBeVisible();
} );

test( 'Template can be modified', async ( { page, admin, editor } ) => {
await admin.visitSiteEditor( {
postId: templatePath,
postType: templateType,
} );
await editor.canvas.click( 'body' );
await editor.canvas.waitForLoadState( 'networkidle' );
await editor.insertBlock( {
name: 'core/paragraph',
attributes: { content: 'Hello World' },
} );
await editor.saveSiteEditorEntities();
await page.goto( permalink );

await expect( page.getByText( 'Hello World' ).first() ).toBeVisible();
} );
} );
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* External dependencies
*/
import { test, expect } from '@woocommerce/e2e-playwright-utils';

const permalink = '/checkout/order-received';
const templatePath = 'woocommerce/woocommerce//order-confirmation';
const templateType = 'wp_template';

test.describe( 'Test the order confirmation template', async () => {
test( 'Template can be opened in the site editor', async ( { page } ) => {
await page.goto( '/wp-admin/site-editor.php' );
await page.click( 'text=Templates' );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

page.click is deprecated the documentation mentions clicking a locator is better.

We could do await page.getByText( 'Templates' ).click() instead. (But it might not work if there are multiple instances of the Templates text on the page, so might need to qualify this locator further).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It says "discouraged"—is that the same thing? I've copied usage from other tests and the global-setup file. I'd rather leave it as I'm just trying to get new tests added rather than update our playwright implementation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah you're right, sorry I misread it as deprecated, I'm so used to seeing that in yellow boxes in documentation 🙈

I am ok with it being left like this for now if updating it is going to delay this PR being merged. I would like to revisit at some point though.

await page.click( 'text=Order confirmation' );
await page.getByRole( 'button', { name: /Edit/i } ).click();

await expect(
page
.frameLocator( 'iFrame' )
.locator(
'p:has-text("Thank you. Your order has been received.")'
)
.first()
).toBeVisible();
} );

test( 'Template can be modified', async ( { page, admin, editor } ) => {
await admin.visitSiteEditor( {
postId: templatePath,
postType: templateType,
} );
await editor.canvas.click( 'body' );
await editor.canvas.waitForLoadState( 'networkidle' );
await editor.insertBlock( {
name: 'core/paragraph',
attributes: { content: 'Hello World' },
} );
await editor.saveSiteEditorEntities();
await page.goto( permalink );

await expect( page.getByText( 'Hello World' ).first() ).toBeVisible();
} );
} );
3 changes: 0 additions & 3 deletions tests/e2e-pw/utils/editor/EditorUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
* External dependencies
*/
import { Editor } from '@wordpress/e2e-test-utils-playwright';
/**
* Internal dependencies
*/

export class EditorUtils {
editor: Editor;
Expand Down
9 changes: 9 additions & 0 deletions tests/e2e-pw/utils/frontend/add-to-cart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* External dependencies
*/
import { Page } from '@playwright/test';

export const addToCart = async ( page: Page ) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing actionable here, but I just pointing out that we could probably add product name as an arg here too. Thinking about when we're on the shop page and we call this, it would fail because of multiple add to cart buttons, so if we add a product name we could call by the button's label:

Add “Beanie” to your basket

await page.click( 'text=Add to cart' );
await page.waitForLoadState( 'networkidle' );
};
11 changes: 11 additions & 0 deletions tests/e2e-pw/utils/frontend/go-to-shop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* External dependencies
*/
import { Page } from '@playwright/test';

// Navigate to the shop page.
export const goToShop = ( page: Page ) => {
page.goto( '/shop', {
waitUntil: 'networkidle',
} );
};
2 changes: 2 additions & 0 deletions tests/e2e-pw/utils/frontend/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from './get-block-by-name';
export * from './go-to-shop';
export * from './add-to-cart';
5 changes: 0 additions & 5 deletions tests/e2e-pw/utils/go-to-shop.ts

This file was deleted.