Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert Shopper Blocks Checkout Failures spec to Playwright #10232

Merged
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8ac2993
Convert shopper checkout purchase with UPE tests to Playwright
tpaksu Jan 21, 2025
3873b13
Create a new account with selling something
tpaksu Jan 21, 2025
da2ddef
Move `restoreCurrencies` before deactivating multicurrency
tpaksu Jan 21, 2025
4918761
Combine other saved card test with the current one
tpaksu Jan 22, 2025
76a2a36
Delete another duplicate test
tpaksu Jan 22, 2025
af2e7c8
Merge branch 'develop' into dev/10064-playwright-migration-shopper-ch…
tpaksu Jan 22, 2025
6d746fd
Convert shopper-wc-blocks-saved-card-checkout-and-usage spec to Playw…
tpaksu Jan 23, 2025
d4a01c6
Fix checking for new payment method option existence
tpaksu Jan 23, 2025
1a32c19
Merge branch 'develop' into dev/10075-playwright-migration-shopper-wc…
tpaksu Jan 23, 2025
acdb0dc
Add missing awaits
tpaksu Jan 23, 2025
dccfc04
Rewrite Checkout WCB page creation, fix COT deprecated notice
tpaksu Jan 23, 2025
dc2895c
Revert rewrite.
tpaksu Jan 23, 2025
33e5483
Temporarily use test.only to focus only on this test on PR
tpaksu Jan 23, 2025
e0b72c7
Temporarily enable testOnly
tpaksu Jan 23, 2025
6479afa
Only run a single test
tpaksu Jan 23, 2025
d76d034
Remove single test running
tpaksu Jan 23, 2025
aa4f275
Merge branch 'develop' into dev/10075-playwright-migration-shopper-wc…
tpaksu Jan 24, 2025
5f254cc
Wait for the title input to get actionable
tpaksu Jan 24, 2025
5d45c0b
Implement Playwright spec
ismaeldcom Jan 24, 2025
97a369d
Delete Puppeteer spec
ismaeldcom Jan 24, 2025
98c445e
Add changelog entry
ismaeldcom Jan 24, 2025
da618ba
Merge branch 'develop' into dev/10075-playwright-migration-shopper-wc…
tpaksu Jan 24, 2025
1f712a0
Handle editor iframe
ismaeldcom Jan 24, 2025
1e1e9d5
Merge branch 'develop' into dev/10075-playwright-migration-shopper-wc…
jessepearson Jan 27, 2025
c3e8ede
Merge branch 'develop' into dev/10075-playwright-migration-shopper-wc…
tpaksu Jan 28, 2025
6c1390c
Try removing waitForUrl to solve flakiness
tpaksu Jan 28, 2025
fa7e672
Merge branch 'dev/10075-playwright-migration-shopper-wc-blocks-saved-…
eduardoumpierre Jan 28, 2025
5271c82
Merge branch 'develop' into dev/10073-convert-shopper-wc-blocks-check…
allie500 Jan 28, 2025
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
@@ -0,0 +1,5 @@
Significance: patch
Type: dev
Comment: Convert shopper-wc-blocks-checkout-failures spec from Puppeteer to Playwright


Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: dev

Convert Shopper WC Blocks saved card checkout and usage test to Playwright
107 changes: 107 additions & 0 deletions tests/e2e-pw/specs/shopper/shopper-wc-blocks-checkout-failures.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**
* External dependencies
*/
import test, { Page, expect } from '@playwright/test';

/**
* Internal dependencies
*/
import {
checkPageExists,
describeif,
getMerchant,
getShopper,
} from '../../utils/helpers';
import * as navigation from '../../utils/shopper-navigation';
import * as shopper from '../../utils/shopper';
import { addWCBCheckoutPage } from '../../utils/merchant';
import { shouldRunWCBlocksTests } from '../../utils/constants';
import { config } from '../../config/default';

const failures = [
{
card: config.cards.declined,
error: 'Your card was declined.',
},
{
card: config.cards[ 'invalid-exp-date' ],
error: 'Your card’s expiration year is in the past.',
},
{
card: config.cards[ 'invalid-cvv-number' ],
error: 'Your card’s security code is incomplete.',
},
{
card: config.cards[ 'declined-funds' ],
error: 'Your card has insufficient funds.',
},
{
card: config.cards[ 'declined-expired' ],
error: 'Your card has expired.',
},
{
card: config.cards[ 'declined-cvc' ],
error: "Your card's security code is incorrect.",
},
{
card: config.cards[ 'declined-processing' ],
error:
'An error occurred while processing your card. Try again in a little bit.',
},
{
card: config.cards[ 'declined-incorrect' ],
error: 'Your card number is invalid.',
},
{
card: config.cards[ 'declined-3ds' ],
error: 'Your card has been declined.',
auth: true,
},
];

describeif( shouldRunWCBlocksTests )(
'WooCommerce Blocks > Checkout failures',
() => {
let shopperPage: Page;

test.beforeAll( async ( { browser }, { project } ) => {
shopperPage = ( await getShopper( browser ) ).shopperPage;

if (
! ( await checkPageExists(
shopperPage,
project.use.baseURL + '/checkout-wcb'
) )
) {
const { merchantPage } = await getMerchant( browser );
await addWCBCheckoutPage( merchantPage );
}

await shopper.addCartProduct( shopperPage );
await navigation.goToCheckoutWCB( shopperPage );
await shopper.fillBillingAddressWCB(
shopperPage,
config.addresses.customer.billing
);
} );

test.afterAll( async () => {
await shopper.emptyCart( shopperPage );
} );

for ( const { card, error, auth } of failures ) {
test( `Should show error – ${ error }`, async () => {
await shopper.fillCardDetailsWCB( shopperPage, card );
await shopperPage
.getByRole( 'button', { name: 'Place Order' } )
.click();
if ( auth ) {
await shopper.confirmCardAuthentication( shopperPage );
}
await expect(
shopperPage.getByLabel( 'Checkout' ).getByText( error )
).toBeVisible();
} );
}
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* External dependencies
*/
import test, { Page, expect } from '@playwright/test';

/**
* Internal dependencies
*/
import {
checkPageExists,
describeif,
getMerchant,
getShopper,
} from '../../utils/helpers';
import { shouldRunWCBlocksTests } from '../../utils/constants';
import {
goToMyAccount,
goToShop,
goToCheckoutWCB,
} from '../../utils/shopper-navigation';
import {
addCartProduct,
deleteSavedCard,
emptyCart,
fillBillingAddressWCB,
fillCardDetailsWCB,
selectSavedCardOnCheckout,
} from '../../utils/shopper';
import { addWCBCheckoutPage } from '../../utils/merchant';
import { config } from '../../config/default';

describeif( shouldRunWCBlocksTests )(
'WooCommerce Blocks > Saved cards',
() => {
let shopperPage: Page;
const card = config.cards.basic;

test.beforeAll( async ( { browser }, { project } ) => {
shopperPage = ( await getShopper( browser ) ).shopperPage;
if (
! ( await checkPageExists(
shopperPage,
project.use.baseURL + '/checkout-wcb'
) )
) {
const { merchantPage } = await getMerchant( browser );
await addWCBCheckoutPage( merchantPage );
}
} );

test( 'should be able to save basic card on Blocks checkout', async () => {
await emptyCart( shopperPage );
await goToShop( shopperPage );
await addCartProduct( shopperPage );
await goToCheckoutWCB( shopperPage );
await fillBillingAddressWCB(
shopperPage,
config.addresses.customer.billing
);
await fillCardDetailsWCB( shopperPage, config.cards.basic );
await shopperPage
.getByLabel(
'Save payment information to my account for future purchases.'
)
.click();
await shopperPage
.getByRole( 'button', { name: 'Place Order' } )
.click();
await expect(
shopperPage.getByRole( 'heading', {
name: 'Order received',
} )
).toBeVisible();
await goToMyAccount( shopperPage, 'payment-methods' );
await expect(
shopperPage.getByText( card.label ).first()
).toBeVisible();
await expect(
shopperPage
.getByText(
`${ card.expires.month }/${ card.expires.year }`
)
.first()
).toBeVisible();
} );

test( 'should process a payment with the saved card from Blocks checkout', async () => {
await goToShop( shopperPage );
await addCartProduct( shopperPage );
await goToCheckoutWCB( shopperPage );
await fillBillingAddressWCB(
shopperPage,
config.addresses.customer.billing
);
await selectSavedCardOnCheckout( shopperPage, card );
await shopperPage
.getByRole( 'button', { name: 'Place Order' } )
.click();
await expect(
shopperPage.getByRole( 'heading', {
name: 'Order received',
} )
).toBeVisible();
} );
test( 'should delete the card ', async () => {
await goToMyAccount( shopperPage, 'payment-methods' );
await deleteSavedCard( shopperPage, card );
await expect(
shopperPage.getByText( 'Payment method deleted.' )
).toBeVisible();
} );
}
);
2 changes: 2 additions & 0 deletions tests/e2e-pw/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export const shouldRunSubscriptionsTests =
export const shouldRunActionSchedulerTests =
process.env.SKIP_WC_ACTION_SCHEDULER_TESTS !== '1';

export const shouldRunWCBlocksTests = process.env.SKIP_WC_BLOCKS_TESTS !== '1';

export const products = {
SUBSCRIPTION_SIGNUP_FEE: 70,
SUBSCRIPTION_NO_SIGNUP_FEE: 88,
Expand Down
20 changes: 20 additions & 0 deletions tests/e2e-pw/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,23 @@ export const getAnonymousShopper = async (
*/
export const describeif = ( condition: boolean ) =>
condition ? test.describe : test.describe.skip;

export const checkPageExists = async (
page: Page,
pageUrl: string
): Promise< boolean > => {
// Check whether specified page exists
return page
.goto( pageUrl, {
waitUntil: 'load',
} )
.then( ( response ) => {
if ( response.status() === 404 ) {
return false;
}
return true;
} )
.catch( () => {
return false;
} );
};
36 changes: 36 additions & 0 deletions tests/e2e-pw/utils/merchant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,42 @@ export const deactivateWooPay = async ( page: Page ) => {
await saveWooPaymentsSettings( page );
};

export const addWCBCheckoutPage = async ( page: Page ) => {
await page.goto( '/wp-admin/edit.php?post_type=page', {
waitUntil: 'load',
} );

await page
.locator( '#wpbody-content' )
.getByRole( 'link', { name: 'Add New Page' } )
.click();
await page.waitForLoadState( 'load' );

const welcomeGuide = page.locator( '.components-guide' );
if ( await welcomeGuide.isVisible() ) {
await page.getByLabel( 'Close', { exact: true } ).click();
await page.waitForTimeout( 1500 );
}

// Handle whether the editor uses iframe or not.
const editor = page.frame( 'editor-canvas' ) || page;
await editor.getByLabel( 'Add title' ).fill( 'Checkout WCB' );
await editor.getByLabel( 'Add block' ).click();

await page.getByPlaceholder( 'Search' ).fill( 'Checkout' );
await page.getByRole( 'option', { name: 'Checkout', exact: true } ).click();

// Dismiss dialog about potentially compatibility issues
await page.waitForTimeout( 500 );
await page.keyboard.press( 'Escape' ); // to dismiss a dialog if present

// Publish the page
await page.locator( 'button.editor-post-publish-panel__toggle' ).click();
await page.waitForTimeout( 500 );
await page.locator( 'button.editor-post-publish-button' ).click();
await expect( page.getByText( 'Checkout WCB is now live.' ) ).toBeVisible();
};

export const isCaptureLaterEnabled = async ( page: Page ) => {
await navigation.goToWooPaymentsSettings( page );

Expand Down
6 changes: 6 additions & 0 deletions tests/e2e-pw/utils/shopper-navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ export const goToCheckout = async ( page: Page ) => {
await isUIUnblocked( page );
};

export const goToCheckoutWCB = async ( page: Page ) => {
await page.goto( '/checkout-wcb', {
waitUntil: 'load',
} );
};

export const goToOrders = async ( page: Page ) => {
await page.goto( '/my-account/orders/', {
waitUntil: 'load',
Expand Down
Loading
Loading