-
Notifications
You must be signed in to change notification settings - Fork 69
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
Update dispute challenge/accept e2e tests to match changes to transaction details and order edit screens #7448
Changes from 12 commits
3981b96
f3fef3b
250e77e
3efa7ee
5f57879
bec6683
448b8a0
f855197
0090cf2
e209cff
9f3bb59
d04810d
c878253
104b482
3e9f30f
876468e
72c7467
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Significance: patch | ||
Type: dev | ||
Comment: Not user-facing: update e2e tests for dispute challenge/accept flows to match new Transaction Dispute Details UI | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,18 +3,17 @@ | |
* External dependencies | ||
*/ | ||
import config from 'config'; | ||
const { merchant, shopper, evalAndClick } = require( '@woocommerce/e2e-utils' ); | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { fillCardDetails, setupProductCheckout } from '../../../utils/payments'; | ||
|
||
import { merchantWCP } from '../../../utils'; | ||
|
||
const { merchant, shopper } = require( '@woocommerce/e2e-utils' ); | ||
import { uiLoaded } from '../../../utils'; | ||
|
||
let orderId; | ||
|
||
describe.skip( 'Disputes > Save dispute for editing', () => { | ||
describe( 'Disputes > Save dispute for editing', () => { | ||
beforeAll( async () => { | ||
await page.goto( config.get( 'url' ), { waitUntil: 'networkidle0' } ); | ||
|
||
|
@@ -42,23 +41,25 @@ describe.skip( 'Disputes > Save dispute for editing', () => { | |
} ); | ||
|
||
it( 'should show a dispute in payment details', async () => { | ||
// Pull out and follow the link to avoid working in multiple tabs | ||
const paymentDetailsLink = await page.$eval( | ||
'p.order_number > a', | ||
( anchor ) => anchor.getAttribute( 'href' ) | ||
); | ||
|
||
await merchantWCP.openPaymentDetails( paymentDetailsLink ); | ||
// Click the order dispute notice. | ||
await expect( page ).toClick( '[type="button"]', { | ||
text: 'Respond now', | ||
} ); | ||
await page.waitForNavigation( { | ||
waitUntil: 'networkidle0', | ||
} ); | ||
|
||
// Verify we have a dispute for this purchase | ||
await expect( page ).toMatchElement( 'li.woocommerce-timeline-item', { | ||
text: 'Payment disputed as Product not received.', | ||
// Verify we see the dispute details on the transaction details page. | ||
await expect( page ).toMatchElement( '.dispute-notice', { | ||
text: 'The cardholder claims the product was not received', | ||
} ); | ||
} ); | ||
|
||
it( 'should be able to save dispute for editing', async () => { | ||
// Click to challenge the dispute | ||
await merchantWCP.openChallengeDispute(); | ||
// Click the challenge dispute button. | ||
await evalAndClick( '[data-testid="challenge-dispute-button"]' ); | ||
await page.waitForNavigation( { waitUntil: 'networkidle0' } ); | ||
await uiLoaded(); | ||
|
||
await page.waitForSelector( | ||
'div.wcpay-dispute-evidence .components-flex.components-card__header', | ||
|
@@ -105,6 +106,8 @@ describe.skip( 'Disputes > Save dispute for editing', () => { | |
// Reload the page | ||
await page.reload(); | ||
|
||
await uiLoaded(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test was flaky in my local environment: adding this seemed to make the test more robust. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds important and impactful 😁 … if the UI isn't loaded and we start |
||
|
||
// Verify the previously selected Product type was saved | ||
await expect( page ).toMatchElement( | ||
'[data-testid="dispute-challenge-product-type-selector"]', | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,17 +2,17 @@ | |
* External dependencies | ||
*/ | ||
import config from 'config'; | ||
const { merchant, shopper, evalAndClick } = require( '@woocommerce/e2e-utils' ); | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { merchantWCP } from '../../../utils'; | ||
import { uiLoaded } from '../../../utils'; | ||
import { fillCardDetails, setupProductCheckout } from '../../../utils/payments'; | ||
|
||
const { merchant, shopper } = require( '@woocommerce/e2e-utils' ); | ||
|
||
let orderId; | ||
|
||
describe.skip( 'Disputes > Submit losing dispute', () => { | ||
describe( 'Disputes > Submit losing dispute', () => { | ||
beforeAll( async () => { | ||
await page.goto( config.get( 'url' ), { waitUntil: 'networkidle0' } ); | ||
|
||
|
@@ -40,46 +40,44 @@ describe.skip( 'Disputes > Submit losing dispute', () => { | |
} ); | ||
|
||
it( 'should process and confirm a losing dispute', async () => { | ||
// Pull out and follow the link to avoid working in multiple tabs | ||
const paymentDetailsLink = await page.$eval( | ||
'p.order_number > a', | ||
( anchor ) => anchor.getAttribute( 'href' ) | ||
); | ||
|
||
await merchantWCP.openPaymentDetails( paymentDetailsLink ); | ||
// Click the order dispute notice. | ||
await expect( page ).toClick( '[type="button"]', { | ||
text: 'Respond now', | ||
} ); | ||
await page.waitForNavigation( { | ||
waitUntil: 'networkidle0', | ||
} ); | ||
|
||
// Verify we have a dispute for this purchase | ||
await expect( page ).toMatchElement( 'li.woocommerce-timeline-item', { | ||
text: 'Payment disputed as Product not received.', | ||
// Verify we see the dispute details on the transaction details page. | ||
await expect( page ).toMatchElement( '.dispute-notice', { | ||
text: 'The cardholder claims the product was not received', | ||
} ); | ||
|
||
// Accept the dispute | ||
await merchantWCP.openAcceptDispute(); | ||
// Open the accept dispute modal. | ||
await evalAndClick( '[data-testid="open-accept-dispute-modal-button"' ); | ||
await uiLoaded(); | ||
// Click the accept dispute button. | ||
await evalAndClick( '[data-testid="accept-dispute-button"]' ); | ||
// Wait for the accept POST request to resolve and the status chip to update with the new status. | ||
await expect( page ).toMatchElement( '.chip', { | ||
text: 'Disputed: Lost', | ||
timeout: 10000, | ||
} ); | ||
|
||
// If webhooks are not received, the dispute status won't be updated in the dispute list page resulting in test failure. | ||
// Workaround - Open payment details page again and check dispute's status. | ||
await merchantWCP.openPaymentDetails( paymentDetailsLink ); | ||
// Check the dispute details footer | ||
await expect( page ).toMatchElement( | ||
'.transaction-details-dispute-footer *', | ||
{ | ||
text: 'This dispute was accepted and lost', | ||
} | ||
); | ||
|
||
// Confirm buttons are not present anymore since a dispute has been accepted. | ||
await expect( page ).not.toMatchElement( | ||
// eslint-disable-next-line max-len | ||
'div.transaction-details-dispute-details-body div.transaction-details-dispute-details-body__actions button.components-button.is-primary', | ||
{ | ||
text: 'Challenge dispute', | ||
} | ||
'[data-testid="challenge-dispute-button"]' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚀 These There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The WooCommerce guide Best Practices for Writing and Running End-to-End Tests recommends a similar approach:
|
||
); | ||
await expect( page ).not.toMatchElement( | ||
// eslint-disable-next-line max-len | ||
'div.transaction-details-dispute-details-body div.transaction-details-dispute-details-body__actions button.components-button.is-tertiary', | ||
{ | ||
text: 'Accept dispute', | ||
} | ||
'[data-testid="open-accept-dispute-modal-button"]' | ||
); | ||
|
||
// Confirm dispute status is Lost. | ||
await page.waitForSelector( 'li.woocommerce-timeline-item' ); | ||
await expect( page ).toMatchElement( 'li.woocommerce-timeline-item', { | ||
text: 'Dispute lost. The bank ruled in favor of your customer.', | ||
} ); | ||
} ); | ||
} ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,7 @@ const { | |
|
||
let orderId; | ||
|
||
describe.skip( 'Disputes > Submit winning dispute', () => { | ||
describe( 'Disputes > Submit winning dispute', () => { | ||
beforeAll( async () => { | ||
await page.goto( config.get( 'url' ), { waitUntil: 'networkidle0' } ); | ||
|
||
|
@@ -50,15 +50,24 @@ describe.skip( 'Disputes > Submit winning dispute', () => { | |
'p.order_number > a', | ||
( anchor ) => anchor.getAttribute( 'href' ) | ||
); | ||
await merchantWCP.openPaymentDetails( paymentDetailsLink ); | ||
|
||
// Verify we have a dispute for this purchase | ||
await expect( page ).toMatchElement( 'li.woocommerce-timeline-item', { | ||
text: 'Payment disputed as Transaction unauthorized.', | ||
// Click the order dispute notice. | ||
await expect( page ).toClick( '[type="button"]', { | ||
text: 'Respond now', | ||
} ); | ||
await page.waitForNavigation( { | ||
waitUntil: 'networkidle0', | ||
} ); | ||
|
||
// Verify we see the dispute details on the transaction details page. | ||
await expect( page ).toMatchElement( '.dispute-notice', { | ||
text: 'The cardholder claims this is an unauthorized transaction', | ||
} ); | ||
|
||
// Challenge the dispute | ||
await merchantWCP.openChallengeDispute(); | ||
// Click the challenge dispute button. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clear names and comments in these e2e tests might help make them stable and easier to maintain (as we iterate on the software and flows). For this example, I think this is a setup step (not a test expectation), and it does quite a few things. Would this comment accurately reflect the intention? // Simulate merchant challenging the dispute.
// Wait for the dispute challenge page to load and render. This also explicitly states the outcome (expected state). I think that's useful because the actual test expectations apply to that page. |
||
await evalAndClick( '[data-testid="challenge-dispute-button"]' ); | ||
await page.waitForNavigation( { waitUntil: 'networkidle0' } ); | ||
await uiLoaded(); | ||
|
||
// Select product type | ||
await expect( page ).toSelect( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,6 @@ | |
const { | ||
merchant, | ||
shopper, | ||
evalAndClick, | ||
uiUnblocked, | ||
clearAndFillInput, | ||
setCheckbox, | ||
|
@@ -26,7 +25,6 @@ import { uiLoaded } from './helpers'; | |
|
||
const SHOP_MY_ACCOUNT_PAGE = baseUrl + 'my-account/'; | ||
const MY_ACCOUNT_PAYMENT_METHODS = baseUrl + 'my-account/payment-methods'; | ||
const WC_ADMIN_BASE_URL = baseUrl + 'wp-admin/'; | ||
const MY_ACCOUNT_SUBSCRIPTIONS = baseUrl + 'my-account/subscriptions'; | ||
const MY_ACCOUNT_EDIT = baseUrl + 'my-account/edit-account'; | ||
const MY_ACCOUNT_ORDERS = SHOP_MY_ACCOUNT_PAGE + 'orders/'; | ||
|
@@ -589,43 +587,6 @@ export const merchantWCP = { | |
} ); | ||
}, | ||
|
||
openDisputeDetails: async ( disputeDetailsLink ) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This helper function is no longer relevant. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. … because the dispute details screen is goneburgers? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice. I mentioned it part of the #7363 tasks. |
||
await Promise.all( [ | ||
page.goto( WC_ADMIN_BASE_URL + disputeDetailsLink, { | ||
waitUntil: 'networkidle0', | ||
} ), | ||
uiLoaded(), | ||
] ); | ||
await uiLoaded(); | ||
}, | ||
|
||
openChallengeDispute: async () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've removed this helper function and moved the logic inline to simplify the code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like this – it's not just simplification. You are removing a problematic abstraction and making each test more self-contained (decoupled). |
||
await Promise.all( [ | ||
evalAndClick( | ||
// eslint-disable-next-line max-len | ||
'div.transaction-details-dispute-details-body div.transaction-details-dispute-details-body__actions button.components-button.is-primary' | ||
), | ||
page.waitForNavigation( { waitUntil: 'networkidle0' } ), | ||
uiLoaded(), | ||
] ); | ||
}, | ||
|
||
openAcceptDispute: async () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've removed this helper function and moved the logic inline to simplify the code – this was only used in one test. |
||
await Promise.all( [ | ||
This comment was marked as outdated.
Sorry, something went wrong. |
||
page.removeAllListeners( 'dialog' ), | ||
evalAndClick( | ||
// eslint-disable-next-line max-len | ||
'div.transaction-details-dispute-details-body div.transaction-details-dispute-details-body__actions button.components-button.is-tertiary' | ||
), | ||
evalAndClick( | ||
// eslint-disable-next-line max-len | ||
'.transaction-details-dispute-accept-modal__actions button.components-button.is-primary' | ||
), | ||
page.waitForNavigation( { waitUntil: 'networkidle0' } ), | ||
uiLoaded(), | ||
] ); | ||
}, | ||
|
||
openPaymentDetails: async ( paymentDetailsLink ) => { | ||
await Promise.all( [ | ||
page.goto( paymentDetailsLink, { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming of the suites, and the tests is a good place to take care and be really clear.
I think this test is focused on verifying that merchants can save and resume their response to dispute. Is that correct?
If so, something like this might be clearer:
Disputes > Merchant can save and resume draft dispute challenge
These suite names, and the individual tests, are likely to align very closely to flows. So we might already have a list of names we can use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
I've updated the filename from
merchant-disputes-save-for-editing.spec.js
→merchant-disputes-save-draft-challenge.spec.js
in 3e9f30f.I've also updated the test names within this file in 876468e.