diff --git a/changelog/dev-10061-e2e-create-playwright-shopper-checkout-failures-spec b/changelog/dev-10061-e2e-create-playwright-shopper-checkout-failures-spec new file mode 100644 index 00000000000..de6f342b4a8 --- /dev/null +++ b/changelog/dev-10061-e2e-create-playwright-shopper-checkout-failures-spec @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +E2E Playwright Migration: convert shopper-checkout-failures spec to Playwright and remove Puppeteer spec. diff --git a/tests/e2e-pw/specs/shopper/shopper-checkout-failures.spec.ts b/tests/e2e-pw/specs/shopper/shopper-checkout-failures.spec.ts new file mode 100644 index 00000000000..77c87952d4b --- /dev/null +++ b/tests/e2e-pw/specs/shopper/shopper-checkout-failures.spec.ts @@ -0,0 +1,147 @@ +/** + * External dependencies + */ +import { test, expect, Page } from '@playwright/test'; + +/** + * Internal dependencies + */ + +import { config } from '../../config/default'; +import * as shopper from '../../utils/shopper'; + +test.describe( 'Shopper > Checkout > Failures with various cards', () => { + const waitForBanner = async ( page: Page, errorText: string ) => { + await expect( page.getByText( errorText ) ).toBeVisible(); + }; + + test.beforeEach( async ( { page } ) => { + await shopper.addCartProduct( page ); + await shopper.setupCheckout( page, config.addresses.customer.billing ); + } ); + + test( 'should throw an error that the card was simply declined', async ( { + page, + } ) => { + await shopper.fillCardDetails( page, config.cards.declined ); + await shopper.placeOrder( page ); + + await waitForBanner( page, 'Error: Your card was declined.' ); + } ); + + test( 'should throw an error that the card expiration date is in the past', async ( { + page, + } ) => { + await shopper.fillCardDetails( + page, + config.cards[ 'declined-expired' ] + ); + await shopper.placeOrder( page ); + + await waitForBanner( page, 'Error: Your card has expired.' ); + } ); + + test( 'should throw an error that the card CVV number is invalid', async ( { + page, + } ) => { + await shopper.fillCardDetails( + page, + config.cards[ 'invalid-cvv-number' ] + ); + + await page.keyboard.press( 'Tab' ); + + const frameHandle = await page.waitForSelector( + '#payment .payment_method_woocommerce_payments .wcpay-upe-element iframe' + ); + + const stripeFrame = await frameHandle.contentFrame(); + const cvcErrorText = await stripeFrame.locator( 'p#Field-cvcError' ); + + await expect( cvcErrorText ).toHaveText( + 'Your card’s security code is incomplete.' + ); + } ); + + test( 'should throw an error that the card was declined due to insufficient funds', async ( { + page, + } ) => { + await shopper.fillCardDetails( page, config.cards[ 'declined-funds' ] ); + await shopper.placeOrder( page ); + + await waitForBanner( page, 'Error: Your card has insufficient funds.' ); + } ); + + test( 'should throw an error that the card was declined due to expired card', async ( { + page, + } ) => { + await shopper.fillCardDetails( + page, + config.cards[ 'declined-expired' ] + ); + await shopper.placeOrder( page ); + + await waitForBanner( page, 'Error: Your card has expired.' ); + } ); + + test( 'should throw an error that the card was declined due to incorrect CVC number', async ( { + page, + } ) => { + await shopper.fillCardDetails( page, config.cards[ 'declined-cvc' ] ); + await shopper.placeOrder( page ); + + await waitForBanner( + page, + "Error: Your card's security code is incorrect." + ); + } ); + + test( 'should throw an error that the card was declined due to processing error', async ( { + page, + } ) => { + await shopper.fillCardDetails( + page, + config.cards[ 'declined-processing' ] + ); + await shopper.placeOrder( page ); + + await waitForBanner( + page, + 'Error: An error occurred while processing your card. Try again in a little bit.' + ); + } ); + + test( 'should throw an error that the card was declined due to incorrect card number', async ( { + page, + } ) => { + await shopper.fillCardDetails( + page, + config.cards[ 'declined-incorrect' ] + ); + + const frameHandle = await page.waitForSelector( + '#payment .payment_method_woocommerce_payments .wcpay-upe-element iframe' + ); + + const stripeFrame = await frameHandle.contentFrame(); + const numberErrorText = await stripeFrame.locator( + 'p#Field-numberError' + ); + + expect( numberErrorText ).toHaveText( 'Your card number is invalid.' ); + } ); + + test( 'should throw an error that the card was declined due to invalid 3DS card', async ( { + page, + } ) => { + await shopper.fillCardDetails( page, config.cards[ 'declined-3ds' ] ); + await shopper.placeOrder( page ); + + await shopper.confirmCardAuthentication( page, false ); + + await waitForBanner( + page, + 'We are unable to authenticate your payment method. Please choose a different payment method and try again.' + ); + } ); +} ); diff --git a/tests/e2e/specs/wcpay/shopper/shopper-checkout-failures.spec.js b/tests/e2e/specs/wcpay/shopper/shopper-checkout-failures.spec.js deleted file mode 100644 index 0d8391454d6..00000000000 --- a/tests/e2e/specs/wcpay/shopper/shopper-checkout-failures.spec.js +++ /dev/null @@ -1,132 +0,0 @@ -/** - * External dependencies - */ -import config from 'config'; - -import { - clearCardDetails, - fillCardDetails, - setupProductCheckout, -} from '../../../utils/payments'; -import { shopperWCP } from '../../../utils'; - -const { uiUnblocked } = require( '@woocommerce/e2e-utils' ); -const notice = 'div.wc-block-components-notice-banner'; -const oldNotice = 'div.woocommerce-NoticeGroup ul.woocommerce-error > li'; - -const waitForBanner = async ( errorText ) => { - return shopperWCP.waitForErrorBanner( errorText, notice, oldNotice ); -}; - -describe( 'Shopper > Checkout > Failures with various cards', () => { - beforeAll( async () => { - await setupProductCheckout( - config.get( 'addresses.customer.billing' ) - ); - } ); - - afterEach( async () => { - await clearCardDetails(); - } ); - - afterAll( async () => { - // Clear the cart at the end so it's ready for another test - await shopperWCP.emptyCart(); - } ); - - it( 'should throw an error that the card was simply declined', async () => { - const declinedCard = config.get( 'cards.declined' ); - await fillCardDetails( page, declinedCard ); - await expect( page ).toClick( '#place_order' ); - await uiUnblocked(); - await waitForBanner( 'Error: Your card was declined.' ); - } ); - - it( 'should throw an error that the card expiration date is in the past', async () => { - const cardInvalidExpDate = config.get( 'cards.invalid-exp-date' ); - await fillCardDetails( page, cardInvalidExpDate ); - await expect( page ).toClick( '#place_order' ); - await uiUnblocked(); - await expect( - page - ).toMatchElement( - 'div.woocommerce-NoticeGroup > ul.woocommerce-error', - { text: 'Your card’s expiration year is in the past.' } - ); - } ); - - it( 'should throw an error that the card CVV number is invalid', async () => { - const cardInvalidCVV = config.get( 'cards.invalid-cvv-number' ); - await fillCardDetails( page, cardInvalidCVV ); - await expect( page ).toClick( '#place_order' ); - await uiUnblocked(); - await expect( - page - ).toMatchElement( - 'div.woocommerce-NoticeGroup > ul.woocommerce-error', - { text: 'Your card’s security code is incomplete.' } - ); - } ); - - it( 'should throw an error that the card was declined due to insufficient funds', async () => { - const cardInsufficientFunds = config.get( 'cards.declined-funds' ); - await fillCardDetails( page, cardInsufficientFunds ); - await expect( page ).toClick( '#place_order' ); - await uiUnblocked(); - await waitForBanner( 'Error: Your card has insufficient funds.' ); - } ); - - it( 'should throw an error that the card was declined due to expired card', async () => { - const cardExpired = config.get( 'cards.declined-expired' ); - await fillCardDetails( page, cardExpired ); - await expect( page ).toClick( '#place_order' ); - await uiUnblocked(); - await waitForBanner( 'Error: Your card has expired.' ); - } ); - - it( 'should throw an error that the card was declined due to incorrect CVC number', async () => { - const cardIncorrectCVC = config.get( 'cards.declined-cvc' ); - await fillCardDetails( page, cardIncorrectCVC ); - await expect( page ).toClick( '#place_order' ); - await uiUnblocked(); - await waitForBanner( "Error: Your card's security code is incorrect." ); - } ); - - it( 'should throw an error that the card was declined due to processing error', async () => { - const cardProcessingError = config.get( 'cards.declined-processing' ); - await fillCardDetails( page, cardProcessingError ); - await expect( page ).toClick( '#place_order' ); - await uiUnblocked(); - await waitForBanner( - 'Error: An error occurred while processing your card. Try again in a little bit.' - ); - } ); - - it( 'should throw an error that the card was declined due to incorrect card number', async () => { - const cardIncorrectNumber = config.get( 'cards.declined-incorrect' ); - await fillCardDetails( page, cardIncorrectNumber ); - await expect( page ).toClick( '#place_order' ); - await uiUnblocked(); - await expect( - page - ).toMatchElement( - 'div.woocommerce-NoticeGroup > ul.woocommerce-error', - { text: 'Your card number is invalid.' } - ); - } ); - - it( 'should throw an error that the card was declined due to invalid 3DS card', async () => { - const declinedCard = config.get( 'cards.declined-3ds' ); - await fillCardDetails( page, declinedCard ); - await expect( page ).toClick( '#place_order' ); - await page.waitForSelector( 'ul.woocommerce-error' ); - const declined3dsCardError = await page.$eval( - 'div.woocommerce-NoticeGroup > ul.woocommerce-error', - ( el ) => el.innerText - ); - await expect( page ).toMatchTextContent( - declined3dsCardError, - 'Your card has been declined.' - ); - } ); -} );