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

E2E Playwright Migration: convert Order Partial Refund spec #10194

Merged
merged 20 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions changelog/dev-9963-e2e-convert-order-partial-refund-spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: dev

Convert merchant-orders-partial-refund spec from Puppeteer to Playwright.
219 changes: 219 additions & 0 deletions tests/e2e-pw/specs/merchant/merchant-orders-partial-refund.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/**
* External dependencies
*/
import { test, expect, Page } from '@playwright/test';

/**
* Internal dependencies
*/
import { config } from '../../config/default';
import { getMerchant, getShopper } from '../../utils/helpers';
import {
fillCardDetails,
placeOrder,
setupProductCheckout,
} from '../../utils/shopper';
import { goToShop } from '../../utils/shopper-navigation';
import { goToOrder } from '../../utils/merchant-navigation';
import {
activateMulticurrency,
deactivateMulticurrency,
restoreCurrencies,
} from '../../utils/merchant';

// Needs to be finished.
test.describe( 'Order > Partial refund', () => {
const product1 = config.products.simple.name;
const product2 = 'Belt';
const product3 = 'Hoodie with Logo';

/**
* Elements:
* - test title
* - object containing the items to be ordered, and the quantities and amounts to be refunded
*/
const dataTable: Array< [
string,
{
lineItems: Array< [ string, number ] >;
refundInputs: { refundQty: number; refundAmount: number }[];
}
] > = [
[
'Partially refund one product of two product order',
{
lineItems: [
[ product1, 1 ],
[ product2, 1 ],
],
refundInputs: [ { refundQty: 0, refundAmount: 5 } ],
},
],
[
'Refund two products of three product order',
{
lineItems: [
[ product1, 1 ],
[ product2, 2 ],
[ product3, 1 ],
],
refundInputs: [
{ refundQty: 1, refundAmount: 18 },
{ refundQty: 1, refundAmount: 55 },
],
},
],
];

let orderIds: string[];
let orderTotal: string;
let wasMulticurrencyEnabled = false;
let merchantPage: Page, shopperPage: Page;

const orderProducts = async ( dataTableIndex: number ) => {
const lineItems = dataTable[ dataTableIndex ][ 1 ].lineItems;
await goToShop( shopperPage );
await setupProductCheckout( shopperPage, lineItems );
await fillCardDetails( shopperPage );
await placeOrder( shopperPage );
await expect(
shopperPage.getByRole( 'heading', { name: 'Order received' } )
).toBeVisible();

const orderIdField = shopperPage.locator(
'.woocommerce-order-overview__order.order > strong'
);
const orderId = await orderIdField.innerText();

return orderId;
};

test.beforeAll( async ( { browser } ) => {
merchantPage = ( await getMerchant( browser ) ).merchantPage;
wasMulticurrencyEnabled = await activateMulticurrency( merchantPage );
await restoreCurrencies( merchantPage );
shopperPage = ( await getShopper( browser ) ).shopperPage;
const firstOrderId = await orderProducts( 0 );
const secondOrderId = await orderProducts( 1 );
orderIds = [ firstOrderId, secondOrderId ];
} );

test.afterAll( async () => {
if ( ! wasMulticurrencyEnabled ) {
await deactivateMulticurrency( merchantPage );
}
} );

dataTable.forEach( ( [ title, { refundInputs } ], i ) => {
test( title, async ( { browser } ) => {
merchantPage = ( await getMerchant( browser ) ).merchantPage;
tpaksu marked this conversation as resolved.
Show resolved Hide resolved
await goToOrder( merchantPage, orderIds[ i ] );

const orderTotalField = merchantPage
.getByRole( 'row', { name: 'Order Total: $' } )
.locator( 'bdi' );

// Calculate order total, refund total, and net payment.
orderTotal = await orderTotalField.innerText();
const orderTotalNumber = parseFloat( orderTotal.substring( 1 ) );
const refundTotal = refundInputs
.map( ( { refundAmount } ) => refundAmount )
.reduce( ( acc, cur ) => acc + cur );
const refundTotalString = refundTotal.toFixed( 2 );
const netPayment = ( orderTotalNumber - refundTotal ).toFixed( 2 );

await merchantPage
.getByRole( 'button', { name: 'Refund' } )
.click();

// Fill in the refund inputs.
for ( let j = 0; j < refundInputs.length; j++ ) {
const { refundQty, refundAmount } = refundInputs[ j ];
await merchantPage
.locator( '.refund_order_item_qty' )
.nth( j )
.fill( refundQty.toString() );

await merchantPage
.locator( '.refund_line_total' )
.nth( j )
.clear();

await merchantPage
.locator( '.refund_line_total' )
.nth( j )
.fill( refundAmount.toString() );

await merchantPage.keyboard.press( 'Tab' );
tpaksu marked this conversation as resolved.
Show resolved Hide resolved
}

// Check that the refund amount is correct.
await expect(
merchantPage.getByLabel( 'Refund amount:' )
).toHaveValue( `${ refundTotalString }` );

await merchantPage
.getByLabel( 'Reason for refund (optional):' )
.fill( title );

// Check that the reason for refund is correct.
await expect(
merchantPage.getByLabel( 'Reason for refund (optional):' )
).toHaveValue( title );

merchantPage.on( 'dialog', ( dialog ) => dialog.accept() );

await merchantPage
.getByRole( 'button', {
name: `Refund $${ refundTotalString } via WooPayments`,
} )
.click();

// Verify that the refunded amounts are correct.
for ( let k = 0; k < refundInputs.length; k++ ) {
const { refundQty, refundAmount } = refundInputs[ k ];

if ( refundQty ) {
await expect(
merchantPage.getByText( '-1' ).nth( k )
).toHaveText( `-${ refundQty.toString() }` );

await expect(
merchantPage
.locator( '#order_line_items' )
.getByText( '-$' )
.nth( k )
).toHaveText( `-$${ refundAmount.toFixed( 2 ) }` );
} else {
await expect(
merchantPage
.locator( '#order_line_items' )
.getByText( '-$' )
).toHaveText( `-$${ refundAmount.toFixed( 2 ) }` );
}
}

// Check that the refund order note includes the refund amount and reason.
const refundNote = await merchantPage
.getByText( 'A refund of' )
.innerText();

expect( refundNote ).toContain( title );
expect( refundNote ).toContain( refundTotalString );

// Check that the refunded amount line item is correct.
await expect(
merchantPage
.getByRole( 'row', { name: 'Refunded' } )
.locator( 'bdi' )
).toHaveText( `$${ refundTotalString } USD` );

// Check that the net payment line item is correct.
await expect(
merchantPage
.getByRole( 'row', { name: 'Net Payment' } )
.locator( 'bdi' )
).toHaveText( `$${ netPayment } USD` );
} );
} );
} );
Loading
Loading