diff --git a/changelog/dev-10071-convert-shopper-pay-for-order-e2e-spec b/changelog/dev-10071-convert-shopper-pay-for-order-e2e-spec new file mode 100644 index 00000000000..b6a0d24707a --- /dev/null +++ b/changelog/dev-10071-convert-shopper-pay-for-order-e2e-spec @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +Add the Playwright Pay for Order spec and remove the equivalent Puppeteer spec. diff --git a/changelog/dev-10113-bump-e2e-dockerfile-php-xdebug-versions b/changelog/dev-10113-bump-e2e-dockerfile-php-xdebug-versions new file mode 100644 index 00000000000..08d6ae0059d --- /dev/null +++ b/changelog/dev-10113-bump-e2e-dockerfile-php-xdebug-versions @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +Update the PHP version and the Xdebug version used in the E2E testing environment. diff --git a/tests/e2e-pw/specs/shopper/shopper-pay-for-order.spec.ts b/tests/e2e-pw/specs/shopper/shopper-pay-for-order.spec.ts new file mode 100644 index 00000000000..843fad52478 --- /dev/null +++ b/tests/e2e-pw/specs/shopper/shopper-pay-for-order.spec.ts @@ -0,0 +1,91 @@ +/** + * External dependencies + */ +import { test, expect } from '@playwright/test'; + +/** + * Internal dependencies + */ +import { config } from '../../config/default'; +import * as shopper from '../../utils/shopper'; +import * as shopperNavigation from '../../utils/shopper-navigation'; +import * as devtools from '../../utils/devtools'; +import { getMerchant, getShopper } from '../../utils/helpers'; + +const cardTestingPreventionStates = [ + { cardTestingPreventionEnabled: false }, + { cardTestingPreventionEnabled: true }, +]; + +test.describe( 'Shopper > Pay for Order', () => { + cardTestingPreventionStates.forEach( + ( { cardTestingPreventionEnabled } ) => { + test( `should be able to pay for a failed order with card testing protection ${ cardTestingPreventionEnabled }`, async ( { + browser, + } ) => { + const { merchantPage } = await getMerchant( browser ); + const { shopperPage } = await getShopper( browser ); + + // Enable or disable card testing protection. + if ( ! cardTestingPreventionEnabled ) { + await devtools.disableCardTestingProtection( merchantPage ); + } else { + await devtools.enableCardTestingProtection( merchantPage ); + } + + // Attempt to pay with a declined card. + await shopper.addCartProduct( shopperPage ); + await shopper.setupCheckout( + shopperPage, + config.addresses.customer.billing + ); + await shopper.fillCardDetails( + shopperPage, + config.cards.declined + ); + await shopper.placeOrder( shopperPage ); + + await expect( + shopperPage.getByText( 'Your card was declined' ).first() + ).toBeVisible(); + + // Go to the orders page and pay with a basic card. + await shopperNavigation.goToOrders( shopperPage ); + + const payForOrderButton = shopperPage + .locator( '.woocommerce-button.button.pay', { + hasText: 'Pay', + } ) + .first(); + await payForOrderButton.click(); + await shopper.fillCardDetails( + shopperPage, + config.cards.basic + ); + + // Check for the fraud prevenction token presence. + const token = await shopperPage.evaluate( () => { + return ( window as any ).wcpayFraudPreventionToken; + } ); + + if ( cardTestingPreventionEnabled ) { + expect( token ).not.toBeUndefined(); + } else { + expect( token ).toBeUndefined(); + } + + // Click the pay for order button. + await shopper.placeOrder( shopperPage ); + + await expect( + shopperPage.getByText( 'Order received' ).first() + ).toBeVisible(); + + // Disable card testing protection if necessary. + if ( cardTestingPreventionEnabled ) { + await devtools.disableCardTestingProtection( merchantPage ); + } + } ); + } + ); +} ); diff --git a/tests/e2e-pw/utils/devtools.ts b/tests/e2e-pw/utils/devtools.ts new file mode 100644 index 00000000000..0ad37df9b3e --- /dev/null +++ b/tests/e2e-pw/utils/devtools.ts @@ -0,0 +1,40 @@ +/** + * External dependencies + */ +import { Page, expect } from '@playwright/test'; + +const goToDevToolsSettings = ( page: Page ) => + page.goto( 'wp-admin/admin.php?page=wcpaydev', { + waitUntil: 'load', + } ); + +const saveDevToolsSettings = async ( page: Page ) => { + await page.getByRole( 'button', { name: 'Save Changes' } ).click(); + expect( page.getByText( /Settings saved/ ) ).toBeVisible(); +}; + +const getIsCardTestingProtectionEnabled = ( page: Page ) => + page.getByLabel( 'Card testing mitigations enabled' ).isChecked(); + +const toggleCardTestingProtection = ( page: Page ) => + page + .locator( 'label[for="wcpaydev_force_card_testing_protection_on"]' ) + .click(); + +export const enableCardTestingProtection = async ( page: Page ) => { + await goToDevToolsSettings( page ); + + if ( ! ( await getIsCardTestingProtectionEnabled( page ) ) ) { + await toggleCardTestingProtection( page ); + await saveDevToolsSettings( page ); + } +}; + +export const disableCardTestingProtection = async ( page: Page ) => { + await goToDevToolsSettings( page ); + + if ( await getIsCardTestingProtectionEnabled( page ) ) { + await toggleCardTestingProtection( page ); + await saveDevToolsSettings( page ); + } +}; diff --git a/tests/e2e/env/wordpress-xdebug/Dockerfile b/tests/e2e/env/wordpress-xdebug/Dockerfile index c6dd80eb07d..4019dad8194 100644 --- a/tests/e2e/env/wordpress-xdebug/Dockerfile +++ b/tests/e2e/env/wordpress-xdebug/Dockerfile @@ -1,5 +1,5 @@ -FROM wordpress:6.0.2-php7.4 -RUN pecl install xdebug-2.9.8 \ +FROM wordpress:php8.1 +RUN pecl install xdebug \ && echo 'xdebug.remote_enable=1' >> $PHP_INI_DIR/php.ini \ && echo 'xdebug.remote_port=9000' >> $PHP_INI_DIR/php.ini \ && echo 'xdebug.remote_host=host.docker.internal' >> $PHP_INI_DIR/php.ini \ diff --git a/tests/e2e/specs/wcpay/shopper/shopper-pay-for-order.spec.js b/tests/e2e/specs/wcpay/shopper/shopper-pay-for-order.spec.js deleted file mode 100644 index b0ebc0b8696..00000000000 --- a/tests/e2e/specs/wcpay/shopper/shopper-pay-for-order.spec.js +++ /dev/null @@ -1,84 +0,0 @@ -const { uiUnblocked, shopper, merchant } = require( '@woocommerce/e2e-utils' ); -const { - setupProductCheckout, - fillCardDetails, - fillCardDetailsPayForOrder, -} = require( '../../../utils/payments' ); -const config = require( 'config' ); -const { shopperWCP, merchantWCP } = require( '../../../utils' ); - -const cardTestingPreventionStates = [ - { cardTestingPreventionEnabled: false }, - { cardTestingPreventionEnabled: true }, -]; - -describe.each( cardTestingPreventionStates )( - 'Shopper > Pay for Order', - ( { cardTestingPreventionEnabled } ) => { - beforeAll( async () => { - if ( cardTestingPreventionEnabled ) { - await merchant.login(); - await merchantWCP.enableCardTestingProtection(); - await merchant.logout(); - } - await shopper.login(); - await setupProductCheckout( - config.get( 'addresses.customer.billing' ) - ); - } ); - - afterAll( async () => { - await shopper.logout(); - if ( cardTestingPreventionEnabled ) { - await merchant.login(); - await merchantWCP.disableCardTestingProtection(); - await merchant.logout(); - } - } ); - - it( `should be able to pay for a failed order, carding protection ${ cardTestingPreventionEnabled }`, async () => { - // try to pay with a declined card - const declinedCard = config.get( 'cards.declined' ); - await shopperWCP.selectNewPaymentMethod(); - await fillCardDetails( page, declinedCard ); - await expect( page ).toClick( '#place_order' ); - await uiUnblocked(); - await shopperWCP.waitForErrorBanner( - 'Error: Your card was declined.', - 'div.wc-block-components-notice-banner', - 'div.woocommerce-NoticeGroup > ul.woocommerce-error > li' - ); - - // after the card has been declined, go to the order page and pay with a basic card - await shopperWCP.goToOrders(); - - const payButtons = await page.$$( - '.woocommerce-button.button.pay' - ); - const payButton = payButtons.find( - async ( button ) => - ( await page.evaluate( - ( elem ) => elem.innerText, - button - ) ) === 'Pay' - ); - await payButton.click(); - const card = config.get( 'cards.basic' ); - await fillCardDetailsPayForOrder( page, card ); - - // Check the token presence when card testing prevention is enabled. - if ( cardTestingPreventionEnabled ) { - const token = await page.evaluate( () => { - return window.wcpayFraudPreventionToken; - } ); - expect( token ).not.toBeUndefined(); - } - - await expect( page ).toClick( 'button', { text: 'Pay for order' } ); - await page.waitForNavigation( { - waitUntil: 'networkidle0', - } ); - await expect( page ).toMatchTextContent( 'Order received' ); - } ); - } -);