diff --git a/e2e/api-mocking/mock-responses/polymarket/polymarket-activity-response.ts b/e2e/api-mocking/mock-responses/polymarket/polymarket-activity-response.ts index eff7b8fc4896..1a8ff9a52b89 100644 --- a/e2e/api-mocking/mock-responses/polymarket/polymarket-activity-response.ts +++ b/e2e/api-mocking/mock-responses/polymarket/polymarket-activity-response.ts @@ -345,3 +345,56 @@ export const POLYMARKET_ACTIVITY_RESPONSE = [ profileImageOptimized: '', }, ]; + +export const POLYMARKET_CLAIMED_POSITIONS_ACTIVITY_RESPONSE = [ + { + proxyWallet: PROXY_WALLET_ADDRESS, + timestamp: 1762189059, + conditionId: + '0xbf97a1420a810787dc6ffa2810f1d1d91977267e542b8685ecd21e622567a46c', + type: 'REDEEM', + size: 15, + usdcSize: 15, + transactionHash: + '0x205120808686f9164ca306404e6221cd0fda524002587a410bebdff3f7d3858c', + price: 0, + asset: '', + side: '', + outcomeIndex: 999, + title: 'Blue Jays vs. Mariners', + slug: 'mlb-tor-sea-2025-10-17', + icon: 'https://polymarket-upload.s3.us-east-2.amazonaws.com/Repetitive-markets/MLB.jpg', + eventSlug: 'mlb-tor-sea-2025-10-17', + outcome: '', + name: 'cropMaster', + pseudonym: 'Nonstop-Suitcase', + bio: '', + profileImage: '', + profileImageOptimized: '', + }, + { + proxyWallet: PROXY_WALLET_ADDRESS, + timestamp: 1762189060, + conditionId: + '0xa13312b2cc64532aed2a446b66e5a2d8d8b440b24d7213d33b6dae6a58c33223', + type: 'REDEEM', + size: 5, + usdcSize: 5, + transactionHash: + '0x205120808686f9164ca306404e6221cd0fda524002587a410bebdff3f7d3858d', + price: 0, + asset: '', + side: '', + outcomeIndex: 999, + title: 'Steelers vs. Bengals', + slug: 'nfl-pit-cin-2025-10-16', + icon: 'https://polymarket-upload.s3.us-east-2.amazonaws.com/nfl.png', + eventSlug: 'nfl-pit-cin-2025-10-16', + outcome: '', + name: 'cropMaster', + pseudonym: 'Nonstop-Suitcase', + bio: '', + profileImage: '', + profileImageOptimized: '', + }, +]; diff --git a/e2e/api-mocking/mock-responses/polymarket/polymarket-mocks.ts b/e2e/api-mocking/mock-responses/polymarket/polymarket-mocks.ts index e98f80bce90e..2d24fde30957 100644 --- a/e2e/api-mocking/mock-responses/polymarket/polymarket-mocks.ts +++ b/e2e/api-mocking/mock-responses/polymarket/polymarket-mocks.ts @@ -14,7 +14,10 @@ import { POLYMARKET_EVENT_DETAILS_SPURS_PELICANS_RESPONSE, } from './polymarket-event-details-response'; import { POLYMARKET_UPNL_RESPONSE } from './polymarket-upnl-response'; -import { POLYMARKET_ACTIVITY_RESPONSE } from './polymarket-activity-response'; +import { + POLYMARKET_ACTIVITY_RESPONSE, + POLYMARKET_CLAIMED_POSITIONS_ACTIVITY_RESPONSE, +} from './polymarket-activity-response'; import { POLYMARKET_ORDER_BOOK_RESPONSE, POLYMARKET_ZOHRAN_ORDER_BOOK_RESPONSE, @@ -985,6 +988,60 @@ export const POLYMARKET_REMOVE_CLAIMED_POSITIONS_MOCKS = async ( })); }; +/** + * Post-claim mock that adds REDEEM transactions to the activity endpoint + * After claiming, REDEEM type transactions should appear in the activity feed + * @param mockServer - The mockttp server instance + */ +export const POLYMARKET_ADD_CLAIMED_POSITIONS_TO_ACTIVITY_MOCKS = async ( + mockServer: Mockttp, +) => { + // Override the activity mock to include REDEEM transactions for claimed positions + await mockServer + .forGet('/proxy') + .matching((request) => { + const url = new URL(request.url).searchParams.get('url'); + return Boolean( + url && + /^https:\/\/data-api\.polymarket\.com\/activity\?user=0x[a-fA-F0-9]{40}$/.test( + url, + ), + ); + }) + .asPriority(PRIORITY.API_OVERRIDE) // Higher priority to override the original activity mock + .thenCallback((request) => { + const url = new URL(request.url).searchParams.get('url'); + const userMatch = url?.match(/user=(0x[a-fA-F0-9]{40})/); + const userAddress = userMatch ? userMatch[1] : USER_WALLET_ADDRESS; + + // Map claimed positions to use the actual user address + const claimedPositionsWithUserAddress = + POLYMARKET_CLAIMED_POSITIONS_ACTIVITY_RESPONSE.map((activity) => ({ + ...activity, + proxyWallet: userAddress, + })); + + // Map existing activity to use the actual user address + const existingActivityWithUserAddress = POLYMARKET_ACTIVITY_RESPONSE.map( + (activity) => ({ + ...activity, + proxyWallet: userAddress, + }), + ); + + // Add the REDEEM transactions at the beginning of the activity array (most recent first) + const activityWithClaims = [ + ...claimedPositionsWithUserAddress, + ...existingActivityWithUserAddress, + ]; + + return { + statusCode: 200, + json: activityWithClaims, + }; + }); +}; + /** * Post-cash-out mock that removes the cashed out position from positions endpoint * and adds a SELL transaction to the activity endpoint diff --git a/e2e/pages/Transactions/predictionsActivityDetails.ts b/e2e/pages/Transactions/predictionsActivityDetails.ts index 30751c980b31..77c0a745d349 100644 --- a/e2e/pages/Transactions/predictionsActivityDetails.ts +++ b/e2e/pages/Transactions/predictionsActivityDetails.ts @@ -15,6 +15,12 @@ class PredictActivityDetails { ); } + get amountDisplay(): DetoxElement { + return Matchers.getElementByID( + PredictActivityDetailsSelectorsIDs.AMOUNT_DISPLAY, + ); + } + async tapBackButton(): Promise { await Gestures.waitAndTap(this.backButton); } diff --git a/e2e/specs/predict/predict-claim-positions.spec.ts b/e2e/specs/predict/predict-claim-positions.spec.ts index 6c36737cbe80..7760c1176bc7 100644 --- a/e2e/specs/predict/predict-claim-positions.spec.ts +++ b/e2e/specs/predict/predict-claim-positions.spec.ts @@ -14,16 +14,20 @@ import { POLYMARKET_REMOVE_CLAIMED_POSITIONS_MOCKS, POLYMARKET_TRANSACTION_SENTINEL_MOCKS, POLYMARKET_UPDATE_USDC_BALANCE_MOCKS, + POLYMARKET_ADD_CLAIMED_POSITIONS_TO_ACTIVITY_MOCKS, } from '../../api-mocking/mock-responses/polymarket/polymarket-mocks'; import { Mockttp } from 'mockttp'; import { setupRemoteFeatureFlagsMock } from '../../api-mocking/helpers/remoteFeatureFlagsHelper'; import PredictClaimPage from '../../pages/Predict/PredictClaimPage'; - +import TabBarComponent from '../../pages/wallet/TabBarComponent'; +import ActivitiesView from '../../pages/Transactions/ActivitiesView'; +import PredictActivityDetails from '../../pages/Transactions/predictionsActivityDetails'; import { POLYMARKET_RESOLVED_LOST_POSITIONS_RESPONSE, POLYMARKET_WINNING_POSITIONS_RESPONSE, } from '../../api-mocking/mock-responses/polymarket/polymarket-positions-response'; import { PredictHelpers } from './helpers/predict-helpers'; +import { POLYMARKET_CLAIMED_POSITIONS_ACTIVITY_RESPONSE } from '../../api-mocking/mock-responses/polymarket/polymarket-activity-response'; /* Test Scenario: Claim positions @@ -56,7 +60,7 @@ describe(SmokePredictions('Predictions'), () => { await PredictHelpers.setPortugalLocation(); await loginToApp(); - // Claim button is animated - disabling sync to prevent test hang + // Claim button is animated - disabling sync on iOS to prevent test hang await device.disableSynchronization(); await WalletView.tapOnPredictionsTab(); @@ -68,15 +72,18 @@ describe(SmokePredictions('Predictions'), () => { await WalletView.tapClaimButton(); await Assertions.expectElementToBeVisible(PredictClaimPage.container); - // Set up mocks to remove claimed positions after tapping claim button - await POLYMARKET_REMOVE_CLAIMED_POSITIONS_MOCKS(mockServer); - await POLYMARKET_UPDATE_USDC_BALANCE_MOCKS(mockServer, 'claim'); - await PredictClaimPage.tapClaimConfirmButton(); - await device.enableSynchronization(); + + await POLYMARKET_UPDATE_USDC_BALANCE_MOCKS(mockServer, 'claim'); + await POLYMARKET_REMOVE_CLAIMED_POSITIONS_MOCKS(mockServer); + await POLYMARKET_ADD_CLAIMED_POSITIONS_TO_ACTIVITY_MOCKS(mockServer); await Assertions.expectElementToBeVisible(WalletView.container); + await device.enableSynchronization(); + await Assertions.expectElementToNotBeVisible(WalletView.claimButton, { + description: 'Claim button should not be visible', + }); /* Verify that all resolved positions (lost positions + winning positions) are removed after claiming Resolved positions include both: @@ -94,13 +101,32 @@ describe(SmokePredictions('Predictions'), () => { }); } - await Assertions.expectElementToNotBeVisible(WalletView.claimButton, { - description: 'Claim button should not be visible', - }); - /* there is a bug where balances are not updating quick enough. - Leaving this commented for now. Once the bug is fixed we shoudl uncomment. - */ - // await Assertions.expectTextDisplayed('$48.16'); + await TabBarComponent.tapActivity(); + + await ActivitiesView.tapOnPredictionsTab(); + + for (const position of POLYMARKET_CLAIMED_POSITIONS_ACTIVITY_RESPONSE) { + await ActivitiesView.tapPredictPosition(position.title); + await Assertions.expectElementToBeVisible( + PredictActivityDetails.container, + { + description: `Activity details should be visible for "${position.title}"`, + }, + ); + // Verify the balance is displayed correctly (formatted as $XX.XX) + const expectedBalance = `$${position.usdcSize.toFixed(2)}`; + await Assertions.expectTextDisplayed(expectedBalance, { + description: `Balance should be displayed as "${expectedBalance}" for "${position.title}"`, + }); + await PredictActivityDetails.tapBackButton(); + } + + await TabBarComponent.tapWallet(); + + // Verify balance on iOS only. Android balances take a while to refresh. + if (device.getPlatform() === 'ios') { + await Assertions.expectTextDisplayed('$48.16'); + } }, ); });