feat: swap quote event (#7174)
* wip: more metrics * wip: SWAP_INPUT_FIRST_USED * feat: track elapsed times * feat: add e2e test * fix: order of logging * feat: swap quote request logging * feat: e2e test * feat: another property * test: test events separately * fix: dont log for price quotes
This commit is contained in:
parent
3f05a88409
commit
877e000da6
@ -3,8 +3,8 @@ import { SwapEventName } from '@uniswap/analytics-events'
|
||||
import { USDC_MAINNET } from '../../../src/constants/tokens'
|
||||
import { getTestSelector } from '../../utils'
|
||||
|
||||
describe('time-to-swap logging', () => {
|
||||
it('completes two swaps and verifies the TTS logging for the first', () => {
|
||||
describe('swap flow logging', () => {
|
||||
it('completes two swaps and verifies the TTS logging for the first, plus all intermediate steps along the way', () => {
|
||||
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`)
|
||||
cy.hardhat()
|
||||
|
||||
@ -13,6 +13,24 @@ describe('time-to-swap logging', () => {
|
||||
cy.get('#swap-currency-output .token-amount-input').type('1').should('have.value', '1')
|
||||
cy.get('#swap-currency-input .token-amount-input').should('not.have.value', '')
|
||||
|
||||
// Verify first swap action
|
||||
cy.waitForAmplitudeEvent(SwapEventName.SWAP_FIRST_ACTION).then((event: any) => {
|
||||
cy.wrap(event.event_properties).should('have.property', 'time_to_first_swap_action')
|
||||
cy.wrap(event.event_properties.time_to_first_swap_action).should('be.a', 'number')
|
||||
cy.wrap(event.event_properties.time_to_first_swap_action).should('be.gte', 0)
|
||||
})
|
||||
|
||||
// Verify Swap Quote
|
||||
cy.waitForAmplitudeEvent(SwapEventName.SWAP_QUOTE_FETCH).then((event: any) => {
|
||||
// Price quotes don't include these values, so we only verify the types if they exist
|
||||
if (event.event_properties.time_to_first_quote_request) {
|
||||
cy.wrap(event.event_properties.time_to_first_quote_request).should('be.a', 'number')
|
||||
cy.wrap(event.event_properties.time_to_first_quote_request).should('be.gte', 0)
|
||||
cy.wrap(event.event_properties.time_to_first_quote_request_since_first_input).should('be.a', 'number')
|
||||
cy.wrap(event.event_properties.time_to_first_quote_request_since_first_input).should('be.gte', 0)
|
||||
}
|
||||
})
|
||||
|
||||
// Submit transaction
|
||||
cy.get('#swap-button').click()
|
||||
cy.contains('Confirm swap').click()
|
||||
@ -31,10 +49,19 @@ describe('time-to-swap logging', () => {
|
||||
})
|
||||
|
||||
// Second swap in the session:
|
||||
// Enter amount to swap
|
||||
cy.get('#swap-currency-output .token-amount-input').clear().type('1').should('have.value', '1')
|
||||
// Enter amount to swap (different from first trade, to trigger a new quote request)
|
||||
cy.get('#swap-currency-output .token-amount-input').clear().type('10').should('have.value', '10')
|
||||
cy.get('#swap-currency-input .token-amount-input').should('not.have.value', '')
|
||||
|
||||
// Verify second Swap Quote
|
||||
cy.waitForAmplitudeEvent(SwapEventName.SWAP_QUOTE_FETCH).then((event: any) => {
|
||||
// Price quotes don't include these values, so we only verify the types if they exist
|
||||
if (event.event_properties.time_to_first_quote_request) {
|
||||
cy.wrap(event.event_properties.time_to_first_quote_request).should('be.undefined')
|
||||
cy.wrap(event.event_properties.time_to_first_quote_request_since_first_input).should('be.undefined')
|
||||
}
|
||||
})
|
||||
|
||||
// Submit transaction
|
||||
cy.get('#swap-button').click()
|
||||
cy.contains('Confirm swap').click()
|
@ -4,6 +4,7 @@ import { TradeType } from '@uniswap/sdk-core'
|
||||
import { isUniswapXSupportedChain } from 'constants/chains'
|
||||
import { getClientSideQuote } from 'lib/hooks/routing/clientSideSmartOrderRouter'
|
||||
import ms from 'ms'
|
||||
import { logSwapQuoteRequest } from 'tracing/swapFlowLoggers'
|
||||
import { trace } from 'tracing/trace'
|
||||
|
||||
import {
|
||||
@ -119,6 +120,7 @@ export const routingApi = createApi({
|
||||
},
|
||||
async queryFn(args, _api, _extraOptions, fetch) {
|
||||
let fellBack = false
|
||||
logSwapQuoteRequest(args.tokenInChainId, args.routerPreference)
|
||||
const quoteStartMark = performance.mark(`quote-fetch-start-${Date.now()}`)
|
||||
if (shouldUseAPIRouter(args)) {
|
||||
fellBack = true
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { calculateElapsedTimeWithPerformanceMark } from './utils'
|
||||
|
||||
// These events should happen in this order.
|
||||
export enum SwapEventType {
|
||||
/**
|
||||
* Full list of actions that can trigger the FIRST_SWAP_ACTION moment:
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { SwapEventName } from '@uniswap/analytics-events'
|
||||
import { ITraceContext } from 'analytics'
|
||||
import { sendAnalyticsEvent } from 'analytics'
|
||||
import { INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference } from 'state/routing/types'
|
||||
|
||||
import { SwapEventTimestampTracker, SwapEventType } from './SwapEventTimestampTracker'
|
||||
|
||||
@ -32,3 +33,25 @@ export function maybeLogFirstSwapAction(analyticsContext: ITraceContext) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function logSwapQuoteRequest(
|
||||
chainId: number,
|
||||
routerPreference: RouterPreference | typeof INTERNAL_ROUTER_PREFERENCE_PRICE
|
||||
) {
|
||||
let performanceMetrics = {}
|
||||
if (routerPreference !== INTERNAL_ROUTER_PREFERENCE_PRICE) {
|
||||
const hasSetSwapQuote = tracker.hasTimestamp(SwapEventType.FIRST_QUOTE_FETCH_STARTED)
|
||||
const elapsedTime = tracker.setElapsedTime(SwapEventType.FIRST_QUOTE_FETCH_STARTED)
|
||||
performanceMetrics = {
|
||||
// We only log the time_to_first_quote_request metric for the first quote request of a session.
|
||||
time_to_first_quote_request: hasSetSwapQuote ? undefined : elapsedTime,
|
||||
time_to_first_quote_request_since_first_input: hasSetSwapQuote
|
||||
? undefined
|
||||
: tracker.getElapsedTime(SwapEventType.FIRST_QUOTE_FETCH_STARTED, SwapEventType.FIRST_SWAP_ACTION),
|
||||
}
|
||||
}
|
||||
sendAnalyticsEvent(SwapEventName.SWAP_QUOTE_FETCH, {
|
||||
chainId,
|
||||
...performanceMetrics,
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user