Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -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: '',
},
];
59 changes: 58 additions & 1 deletion e2e/api-mocking/mock-responses/polymarket/polymarket-mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions e2e/pages/Transactions/predictionsActivityDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ class PredictActivityDetails {
);
}

get amountDisplay(): DetoxElement {
return Matchers.getElementByID(
PredictActivityDetailsSelectorsIDs.AMOUNT_DISPLAY,
);
}

async tapBackButton(): Promise<void> {
await Gestures.waitAndTap(this.backButton);
}
Expand Down
54 changes: 40 additions & 14 deletions e2e/specs/predict/predict-claim-positions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand All @@ -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:
Expand All @@ -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');
}
},
);
});
Expand Down
Loading