Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
83723cb1
Commit
83723cb1
authored
May 31, 2023
by
isstuev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixes&tests
parent
76eb57f2
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
436 additions
and
28 deletions
+436
-28
tx.ts
mocks/txs/tx.ts
+23
-0
socketServer.ts
playwright/fixtures/socketServer.ts
+5
-0
AddressTokenTransfers.pw.tsx
ui/address/AddressTokenTransfers.pw.tsx
+176
-8
AddressTokenTransfers.tsx
ui/address/AddressTokenTransfers.tsx
+14
-3
AddressTxs.pw.tsx
ui/address/AddressTxs.pw.tsx
+180
-5
AddressTxs.tsx
ui/address/AddressTxs.tsx
+38
-12
No files found.
mocks/txs/tx.ts
View file @
83723cb1
...
@@ -251,3 +251,26 @@ export const l2tx: Transaction = {
...
@@ -251,3 +251,26 @@ export const l2tx: Transaction = {
l1_gas_used
:
'
17060
'
,
l1_gas_used
:
'
17060
'
,
l1_fee
:
'
1584574188135760
'
,
l1_fee
:
'
1584574188135760
'
,
};
};
export
const
base2
=
{
...
base
,
hash
:
'
0x02d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3193
'
,
from
:
{
...
base
.
from
,
hash
:
'
0xd789a607CEac2f0E14867de4EB15b15C9FFB5859
'
,
},
};
export
const
base3
=
{
...
base
,
hash
:
'
0x12d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3193
'
,
from
:
{
...
base
.
from
,
hash
:
'
0xd789a607CEac2f0E14867de4EB15b15C9FFB5859
'
,
},
};
export
const
base4
=
{
...
base
,
hash
:
'
0x22d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3193
'
,
};
playwright/fixtures/socketServer.ts
View file @
83723cb1
...
@@ -5,6 +5,8 @@ import { WebSocketServer } from 'ws';
...
@@ -5,6 +5,8 @@ import { WebSocketServer } from 'ws';
import
type
{
AddressCoinBalanceHistoryItem
}
from
'
types/api/address
'
;
import
type
{
AddressCoinBalanceHistoryItem
}
from
'
types/api/address
'
;
import
type
{
NewBlockSocketResponse
}
from
'
types/api/block
'
;
import
type
{
NewBlockSocketResponse
}
from
'
types/api/block
'
;
import
type
{
SmartContractVerificationResponse
}
from
'
types/api/contract
'
;
import
type
{
SmartContractVerificationResponse
}
from
'
types/api/contract
'
;
import
type
{
TokenTransfer
}
from
'
types/api/tokenTransfer
'
;
import
type
{
Transaction
}
from
'
types/api/transaction
'
;
type
ReturnType
=
()
=>
Promise
<
WebSocket
>
;
type
ReturnType
=
()
=>
Promise
<
WebSocket
>
;
...
@@ -58,11 +60,14 @@ export const joinChannel = async(socket: WebSocket, channelName: string) => {
...
@@ -58,11 +60,14 @@ export const joinChannel = async(socket: WebSocket, channelName: string) => {
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
coin_balance
'
,
payload
:
{
coin_balance
:
AddressCoinBalanceHistoryItem
}):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
coin_balance
'
,
payload
:
{
coin_balance
:
AddressCoinBalanceHistoryItem
}):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
token_balance
'
,
payload
:
{
block_number
:
number
}):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
token_balance
'
,
payload
:
{
block_number
:
number
}):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
transaction
'
,
payload
:
{
transaction
:
number
}):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
transaction
'
,
payload
:
{
transaction
:
number
}):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
transaction
'
,
payload
:
{
transactions
:
Array
<
Transaction
>
}):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
pending_transaction
'
,
payload
:
{
pending_transaction
:
number
}):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
pending_transaction
'
,
payload
:
{
pending_transaction
:
number
}):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
pending_transaction
'
,
payload
:
{
pending_transactions
:
Array
<
Transaction
>
}):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
new_block
'
,
payload
:
NewBlockSocketResponse
):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
new_block
'
,
payload
:
NewBlockSocketResponse
):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
verification_result
'
,
payload
:
SmartContractVerificationResponse
):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
verification_result
'
,
payload
:
SmartContractVerificationResponse
):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
total_supply
'
,
payload
:
{
total_supply
:
number
}):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
total_supply
'
,
payload
:
{
total_supply
:
number
}):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
changed_bytecode
'
,
payload
:
Record
<
string
,
never
>
):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
changed_bytecode
'
,
payload
:
Record
<
string
,
never
>
):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
'
token_transfer
'
,
payload
:
{
token_transfers
:
Array
<
TokenTransfer
>
}):
void
;
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
string
,
payload
:
unknown
):
void
{
export
function
sendMessage
(
socket
:
WebSocket
,
channel
:
Channel
,
msg
:
string
,
payload
:
unknown
):
void
{
socket
.
send
(
JSON
.
stringify
([
socket
.
send
(
JSON
.
stringify
([
...
channel
,
...
channel
,
...
...
ui/address/AddressTokenTransfers.pw.tsx
View file @
83723cb1
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
{
test
,
expect
,
devices
}
from
'
@playwright/experimental-ct-react
'
;
import
{
test
as
base
,
expect
,
devices
}
from
'
@playwright/experimental-ct-react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
erc1155A
}
from
'
mocks/tokens/tokenTransfer
'
;
import
*
as
tokenTransferMock
from
'
mocks/tokens/tokenTransfer
'
;
import
*
as
socketServer
from
'
playwright/fixtures/socketServer
'
;
import
TestApp
from
'
playwright/TestApp
'
;
import
TestApp
from
'
playwright/TestApp
'
;
import
buildApiUrl
from
'
playwright/utils/buildApiUrl
'
;
import
buildApiUrl
from
'
playwright/utils/buildApiUrl
'
;
import
AddressTokenTransfers
from
'
./AddressTokenTransfers
'
;
import
AddressTokenTransfers
from
'
./AddressTokenTransfers
'
;
const
API_URL
=
buildApiUrl
(
'
address_token_transfers
'
,
{
hash
:
'
0xd789a607CEac2f0E14867de4EB15b15C9FFB5859
'
})
+
const
CURRENT_ADDRESS
=
'
0xd789a607CEac2f0E14867de4EB15b15C9FFB5859
'
;
const
API_URL
=
buildApiUrl
(
'
address_token_transfers
'
,
{
hash
:
CURRENT_ADDRESS
})
+
'
?token=0x1189a607CEac2f0E14867de4EB15b15C9FFB5859
'
;
'
?token=0x1189a607CEac2f0E14867de4EB15b15C9FFB5859
'
;
const
hooksConfig
=
{
const
hooksConfig
=
{
router
:
{
router
:
{
query
:
{
hash
:
'
0xd789a607CEac2f0E14867de4EB15b15C9FFB5859
'
,
token
:
'
0x1189a607CEac2f0E14867de4EB15b15C9FFB5859
'
},
query
:
{
hash
:
CURRENT_ADDRESS
,
token
:
'
0x1189a607CEac2f0E14867de4EB15b15C9FFB5859
'
},
},
},
};
};
const
test
=
base
.
extend
<
socketServer
.
SocketServerFixture
>
({
createSocket
:
socketServer
.
createSocket
,
});
// FIXME
// test cases which use socket cannot run in parallel since the socket server always run on the same port
test
.
describe
.
configure
({
mode
:
'
serial
'
});
test
(
'
with token filter and pagination
'
,
async
({
mount
,
page
})
=>
{
test
(
'
with token filter and pagination
'
,
async
({
mount
,
page
})
=>
{
await
page
.
route
(
API_URL
,
(
route
)
=>
route
.
fulfill
({
await
page
.
route
(
API_URL
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
erc1155A
],
next_page_params
:
{
block_number
:
1
}
}),
body
:
JSON
.
stringify
({
items
:
[
tokenTransferMock
.
erc1155A
],
next_page_params
:
{
block_number
:
1
}
}),
}));
}));
const
component
=
await
mount
(
const
component
=
await
mount
(
...
@@ -37,7 +48,7 @@ test('with token filter and pagination', async({ mount, page }) => {
...
@@ -37,7 +48,7 @@ test('with token filter and pagination', async({ mount, page }) => {
test
(
'
with token filter and no pagination
'
,
async
({
mount
,
page
})
=>
{
test
(
'
with token filter and no pagination
'
,
async
({
mount
,
page
})
=>
{
await
page
.
route
(
API_URL
,
(
route
)
=>
route
.
fulfill
({
await
page
.
route
(
API_URL
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
erc1155A
]
}),
body
:
JSON
.
stringify
({
items
:
[
tokenTransferMock
.
erc1155A
]
}),
}));
}));
const
component
=
await
mount
(
const
component
=
await
mount
(
...
@@ -57,7 +68,7 @@ test.describe('mobile', () => {
...
@@ -57,7 +68,7 @@ test.describe('mobile', () => {
test
(
'
with token filter and pagination
'
,
async
({
mount
,
page
})
=>
{
test
(
'
with token filter and pagination
'
,
async
({
mount
,
page
})
=>
{
await
page
.
route
(
API_URL
,
(
route
)
=>
route
.
fulfill
({
await
page
.
route
(
API_URL
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
erc1155A
],
next_page_params
:
{
block_number
:
1
}
}),
body
:
JSON
.
stringify
({
items
:
[
tokenTransferMock
.
erc1155A
],
next_page_params
:
{
block_number
:
1
}
}),
}));
}));
const
component
=
await
mount
(
const
component
=
await
mount
(
...
@@ -74,7 +85,7 @@ test.describe('mobile', () => {
...
@@ -74,7 +85,7 @@ test.describe('mobile', () => {
test
(
'
with token filter and no pagination
'
,
async
({
mount
,
page
})
=>
{
test
(
'
with token filter and no pagination
'
,
async
({
mount
,
page
})
=>
{
await
page
.
route
(
API_URL
,
(
route
)
=>
route
.
fulfill
({
await
page
.
route
(
API_URL
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
erc1155A
]
}),
body
:
JSON
.
stringify
({
items
:
[
tokenTransferMock
.
erc1155A
]
}),
}));
}));
const
component
=
await
mount
(
const
component
=
await
mount
(
...
@@ -88,3 +99,160 @@ test.describe('mobile', () => {
...
@@ -88,3 +99,160 @@ test.describe('mobile', () => {
await
expect
(
component
).
toHaveScreenshot
();
await
expect
(
component
).
toHaveScreenshot
();
});
});
});
});
test
.
describe
(
'
socket
'
,
()
=>
{
test
(
'
without overload
'
,
async
({
mount
,
page
,
createSocket
})
=>
{
const
hooksConfigNoToken
=
{
router
:
{
query
:
{
hash
:
CURRENT_ADDRESS
},
},
};
const
API_URL_NO_TOKEN
=
buildApiUrl
(
'
address_token_transfers
'
,
{
hash
:
CURRENT_ADDRESS
})
+
'
?type=
'
;
await
page
.
route
(
API_URL_NO_TOKEN
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
tokenTransferMock
.
erc1155A
],
next_page_params
:
{
block_number
:
1
}
}),
}));
await
mount
(
<
TestApp
withSocket
>
<
Box
h=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
/>
<
AddressTokenTransfers
/>
</
TestApp
>,
{
hooksConfig
:
hooksConfigNoToken
},
);
const
socket
=
await
createSocket
();
const
channel
=
await
socketServer
.
joinChannel
(
socket
,
`addresses:
${
CURRENT_ADDRESS
.
toLowerCase
()
}
`
);
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
socketServer
.
sendMessage
(
socket
,
channel
,
'
token_transfer
'
,
{
token_transfers
:
[
tokenTransferMock
.
erc1155B
,
tokenTransferMock
.
erc1155C
]
});
await
page
.
waitForSelector
(
'
tbody tr:nth-child(3)
'
);
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
4
);
});
test
(
'
with overload
'
,
async
({
mount
,
page
,
createSocket
})
=>
{
const
hooksConfigNoToken
=
{
router
:
{
query
:
{
hash
:
CURRENT_ADDRESS
},
},
};
const
API_URL_NO_TOKEN
=
buildApiUrl
(
'
address_token_transfers
'
,
{
hash
:
CURRENT_ADDRESS
})
+
'
?type=
'
;
await
page
.
route
(
API_URL_NO_TOKEN
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
tokenTransferMock
.
erc1155A
],
next_page_params
:
{
block_number
:
1
}
}),
}));
await
mount
(
<
TestApp
withSocket
>
<
Box
h=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
/>
<
AddressTokenTransfers
overloadCount=
{
2
}
/>
</
TestApp
>,
{
hooksConfig
:
hooksConfigNoToken
},
);
const
socket
=
await
createSocket
();
const
channel
=
await
socketServer
.
joinChannel
(
socket
,
`addresses:
${
CURRENT_ADDRESS
.
toLowerCase
()
}
`
);
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
socketServer
.
sendMessage
(
socket
,
channel
,
'
token_transfer
'
,
{
token_transfers
:
[
tokenTransferMock
.
erc1155B
,
tokenTransferMock
.
erc1155C
]
});
await
page
.
waitForSelector
(
'
tbody tr:nth-child(3)
'
);
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
3
);
const
counter
=
await
page
.
locator
(
'
tbody tr:nth-child(1)
'
).
textContent
();
expect
(
counter
?.
startsWith
(
'
1
'
)).
toBe
(
true
);
});
test
(
'
without overload, with filters
'
,
async
({
mount
,
page
,
createSocket
})
=>
{
const
hooksConfigWithFilter
=
{
router
:
{
query
:
{
hash
:
CURRENT_ADDRESS
,
type
:
'
ERC-1155
'
},
},
};
const
API_URL_WITH_FILTER
=
buildApiUrl
(
'
address_token_transfers
'
,
{
hash
:
CURRENT_ADDRESS
})
+
'
?type=ERC-1155
'
;
await
page
.
route
(
API_URL_WITH_FILTER
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
tokenTransferMock
.
erc1155A
],
next_page_params
:
{
block_number
:
1
}
}),
}));
await
mount
(
<
TestApp
withSocket
>
<
Box
h=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
/>
<
AddressTokenTransfers
/>
</
TestApp
>,
{
hooksConfig
:
hooksConfigWithFilter
},
);
const
socket
=
await
createSocket
();
const
channel
=
await
socketServer
.
joinChannel
(
socket
,
`addresses:
${
CURRENT_ADDRESS
.
toLowerCase
()
}
`
);
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
socketServer
.
sendMessage
(
socket
,
channel
,
'
token_transfer
'
,
{
token_transfers
:
[
tokenTransferMock
.
erc1155B
,
tokenTransferMock
.
erc20
]
});
await
page
.
waitForSelector
(
'
tbody tr:nth-child(3)
'
);
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
3
);
});
test
(
'
with overload, with filters
'
,
async
({
mount
,
page
,
createSocket
})
=>
{
const
hooksConfigWithFilter
=
{
router
:
{
query
:
{
hash
:
CURRENT_ADDRESS
,
type
:
'
ERC-1155
'
},
},
};
const
API_URL_WITH_FILTER
=
buildApiUrl
(
'
address_token_transfers
'
,
{
hash
:
CURRENT_ADDRESS
})
+
'
?type=ERC-1155
'
;
await
page
.
route
(
API_URL_WITH_FILTER
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
tokenTransferMock
.
erc1155A
],
next_page_params
:
{
block_number
:
1
}
}),
}));
await
mount
(
<
TestApp
withSocket
>
<
Box
h=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
/>
<
AddressTokenTransfers
overloadCount=
{
2
}
/>
</
TestApp
>,
{
hooksConfig
:
hooksConfigWithFilter
},
);
const
socket
=
await
createSocket
();
const
channel
=
await
socketServer
.
joinChannel
(
socket
,
`addresses:
${
CURRENT_ADDRESS
.
toLowerCase
()
}
`
);
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
socketServer
.
sendMessage
(
socket
,
channel
,
'
token_transfer
'
,
{
token_transfers
:
[
tokenTransferMock
.
erc1155B
,
tokenTransferMock
.
erc20
,
tokenTransferMock
.
erc1155C
,
tokenTransferMock
.
erc721
]
},
);
await
page
.
waitForSelector
(
'
tbody tr:nth-child(3)
'
);
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
3
);
const
counter
=
await
page
.
locator
(
'
tbody tr:nth-child(1)
'
).
textContent
();
expect
(
counter
?.
startsWith
(
'
1
'
)).
toBe
(
true
);
});
});
ui/address/AddressTokenTransfers.tsx
View file @
83723cb1
...
@@ -63,7 +63,13 @@ const matchFilters = (filters: Filters, tokenTransfer: TokenTransfer, address?:
...
@@ -63,7 +63,13 @@ const matchFilters = (filters: Filters, tokenTransfer: TokenTransfer, address?:
return
true
;
return
true
;
};
};
const
AddressTokenTransfers
=
({
scrollRef
}:
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
})
=>
{
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
// for tests only
overloadCount
?:
number
;
}
const
AddressTokenTransfers
=
({
scrollRef
,
overloadCount
=
OVERLOAD_COUNT
}:
Props
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
...
@@ -118,11 +124,12 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
...
@@ -118,11 +124,12 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
setSocketAlert
(
''
);
setSocketAlert
(
''
);
const
newItems
:
Array
<
TokenTransfer
>
=
[];
const
newItems
:
Array
<
TokenTransfer
>
=
[];
let
newCount
=
0
;
payload
.
token_transfers
.
forEach
(
transfer
=>
{
payload
.
token_transfers
.
forEach
(
transfer
=>
{
if
(
data
?.
items
&&
data
.
items
.
length
+
newItems
.
length
>=
OVERLOAD_COUNT
)
{
if
(
data
?.
items
&&
data
.
items
.
length
+
newItems
.
length
>=
overloadCount
)
{
if
(
matchFilters
(
filters
,
transfer
,
currentAddress
))
{
if
(
matchFilters
(
filters
,
transfer
,
currentAddress
))
{
setNewItemsCount
(
prev
=>
prev
+
1
)
;
newCount
++
;
}
}
}
else
{
}
else
{
if
(
matchFilters
(
filters
,
transfer
,
currentAddress
))
{
if
(
matchFilters
(
filters
,
transfer
,
currentAddress
))
{
...
@@ -131,6 +138,10 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
...
@@ -131,6 +138,10 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
}
}
});
});
if
(
newCount
>
0
)
{
setNewItemsCount
(
prev
=>
prev
+
newCount
);
}
if
(
newItems
.
length
>
0
)
{
if
(
newItems
.
length
>
0
)
{
queryClient
.
setQueryData
(
queryClient
.
setQueryData
(
getResourceKey
(
'
address_token_transfers
'
,
{
pathParams
:
{
hash
:
currentAddress
},
queryParams
:
{
...
filters
}
}),
getResourceKey
(
'
address_token_transfers
'
,
{
pathParams
:
{
hash
:
currentAddress
},
queryParams
:
{
...
filters
}
}),
...
...
ui/address/AddressTxs.pw.tsx
View file @
83723cb1
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
{
test
,
expect
}
from
'
@playwright/experimental-ct-react
'
;
import
{
test
as
base
,
expect
}
from
'
@playwright/experimental-ct-react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
base
as
txMock
}
from
'
mocks/txs/tx
'
;
import
*
as
txMock
from
'
mocks/txs/tx
'
;
import
*
as
socketServer
from
'
playwright/fixtures/socketServer
'
;
import
TestApp
from
'
playwright/TestApp
'
;
import
TestApp
from
'
playwright/TestApp
'
;
import
buildApiUrl
from
'
playwright/utils/buildApiUrl
'
;
import
buildApiUrl
from
'
playwright/utils/buildApiUrl
'
;
import
AddressTxs
from
'
./AddressTxs
'
;
import
AddressTxs
from
'
./AddressTxs
'
;
const
API_URL
=
buildApiUrl
(
'
address_txs
'
,
{
hash
:
'
0xd789a607CEac2f0E14867de4EB15b15C9FFB5859
'
});
const
CURRENT_ADDRESS
=
'
0xd789a607CEac2f0E14867de4EB15b15C9FFB5859
'
;
const
API_URL
=
buildApiUrl
(
'
address_txs
'
,
{
hash
:
CURRENT_ADDRESS
});
const
hooksConfig
=
{
const
hooksConfig
=
{
router
:
{
router
:
{
query
:
{
hash
:
'
0xd789a607CEac2f0E14867de4EB15b15C9FFB5859
'
},
query
:
{
hash
:
CURRENT_ADDRESS
},
},
},
};
};
const
test
=
base
.
extend
<
socketServer
.
SocketServerFixture
>
({
createSocket
:
socketServer
.
createSocket
,
});
// FIXME
// test cases which use socket cannot run in parallel since the socket server always run on the same port
test
.
describe
.
configure
({
mode
:
'
serial
'
});
test
(
'
address txs +@mobile +@desktop-xl
'
,
async
({
mount
,
page
})
=>
{
test
(
'
address txs +@mobile +@desktop-xl
'
,
async
({
mount
,
page
})
=>
{
await
page
.
route
(
API_URL
,
(
route
)
=>
route
.
fulfill
({
await
page
.
route
(
API_URL
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
txMock
,
txMock
],
next_page_params
:
{
block
:
1
}
}),
body
:
JSON
.
stringify
({
items
:
[
txMock
.
base
,
txMock
.
base
],
next_page_params
:
{
block
:
1
}
}),
}));
}));
const
component
=
await
mount
(
const
component
=
await
mount
(
...
@@ -32,3 +43,167 @@ test('address txs +@mobile +@desktop-xl', async({ mount, page }) => {
...
@@ -32,3 +43,167 @@ test('address txs +@mobile +@desktop-xl', async({ mount, page }) => {
await
expect
(
component
).
toHaveScreenshot
();
await
expect
(
component
).
toHaveScreenshot
();
});
});
test
.
describe
(
'
socket
'
,
()
=>
{
test
(
'
without overload
'
,
async
({
mount
,
page
,
createSocket
})
=>
{
await
page
.
route
(
API_URL
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
txMock
.
base
],
next_page_params
:
{
block
:
1
}
}),
}));
await
mount
(
<
TestApp
withSocket
>
<
Box
h=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
/>
<
AddressTxs
/>
</
TestApp
>,
{
hooksConfig
},
);
const
socket
=
await
createSocket
();
const
channel
=
await
socketServer
.
joinChannel
(
socket
,
`addresses:
${
CURRENT_ADDRESS
.
toLowerCase
()
}
`
);
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
socketServer
.
sendMessage
(
socket
,
channel
,
'
transaction
'
,
{
transactions
:
[
txMock
.
base2
,
txMock
.
base4
]
});
await
page
.
waitForSelector
(
'
tbody tr:nth-child(3)
'
);
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
4
);
});
test
(
'
with update
'
,
async
({
mount
,
page
,
createSocket
})
=>
{
await
page
.
route
(
API_URL
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
txMock
.
pending
],
next_page_params
:
{
block
:
1
}
}),
}));
await
mount
(
<
TestApp
withSocket
>
<
Box
h=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
/>
<
AddressTxs
/>
</
TestApp
>,
{
hooksConfig
},
);
const
socket
=
await
createSocket
();
const
channel
=
await
socketServer
.
joinChannel
(
socket
,
`addresses:
${
CURRENT_ADDRESS
.
toLowerCase
()
}
`
);
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
socketServer
.
sendMessage
(
socket
,
channel
,
'
transaction
'
,
{
transactions
:
[
txMock
.
base
,
txMock
.
base2
]
});
await
page
.
waitForSelector
(
'
tbody tr:nth-child(3)
'
);
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
3
);
});
test
(
'
with overload
'
,
async
({
mount
,
page
,
createSocket
})
=>
{
await
page
.
route
(
API_URL
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
txMock
.
base
],
next_page_params
:
{
block
:
1
}
}),
}));
await
mount
(
<
TestApp
withSocket
>
<
Box
h=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
/>
<
AddressTxs
overloadCount=
{
2
}
/>
</
TestApp
>,
{
hooksConfig
},
);
const
socket
=
await
createSocket
();
const
channel
=
await
socketServer
.
joinChannel
(
socket
,
`addresses:
${
CURRENT_ADDRESS
.
toLowerCase
()
}
`
);
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
socketServer
.
sendMessage
(
socket
,
channel
,
'
transaction
'
,
{
transactions
:
[
txMock
.
base2
,
txMock
.
base3
,
txMock
.
base4
]
});
await
page
.
waitForSelector
(
'
tbody tr:nth-child(3)
'
);
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
3
);
const
counter
=
await
page
.
locator
(
'
tbody tr:nth-child(1)
'
).
textContent
();
expect
(
counter
?.
startsWith
(
'
2
'
)).
toBe
(
true
);
});
test
(
'
without overload, with filters
'
,
async
({
mount
,
page
,
createSocket
})
=>
{
const
hooksConfigWithFilter
=
{
router
:
{
query
:
{
hash
:
CURRENT_ADDRESS
,
filter
:
'
from
'
},
},
};
const
API_URL_WITH_FILTER
=
buildApiUrl
(
'
address_txs
'
,
{
hash
:
CURRENT_ADDRESS
})
+
'
?filter=from
'
;
await
page
.
route
(
API_URL_WITH_FILTER
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
txMock
.
base
],
next_page_params
:
{
block
:
1
}
}),
}));
await
mount
(
<
TestApp
withSocket
>
<
Box
h=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
/>
<
AddressTxs
/>
</
TestApp
>,
{
hooksConfig
:
hooksConfigWithFilter
},
);
const
socket
=
await
createSocket
();
const
channel
=
await
socketServer
.
joinChannel
(
socket
,
`addresses:
${
CURRENT_ADDRESS
.
toLowerCase
()
}
`
);
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
socketServer
.
sendMessage
(
socket
,
channel
,
'
transaction
'
,
{
transactions
:
[
txMock
.
base2
,
txMock
.
base4
]
});
await
page
.
waitForSelector
(
'
tbody tr:nth-child(3)
'
);
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
3
);
});
test
(
'
with overload, with filters
'
,
async
({
mount
,
page
,
createSocket
})
=>
{
const
hooksConfigWithFilter
=
{
router
:
{
query
:
{
hash
:
CURRENT_ADDRESS
,
filter
:
'
from
'
},
},
};
const
API_URL_WITH_FILTER
=
buildApiUrl
(
'
address_txs
'
,
{
hash
:
CURRENT_ADDRESS
})
+
'
?filter=from
'
;
await
page
.
route
(
API_URL_WITH_FILTER
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
body
:
JSON
.
stringify
({
items
:
[
txMock
.
base
],
next_page_params
:
{
block
:
1
}
}),
}));
await
mount
(
<
TestApp
withSocket
>
<
Box
h=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
/>
<
AddressTxs
overloadCount=
{
2
}
/>
</
TestApp
>,
{
hooksConfig
:
hooksConfigWithFilter
},
);
const
socket
=
await
createSocket
();
const
channel
=
await
socketServer
.
joinChannel
(
socket
,
`addresses:
${
CURRENT_ADDRESS
.
toLowerCase
()
}
`
);
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
socketServer
.
sendMessage
(
socket
,
channel
,
'
transaction
'
,
{
transactions
:
[
txMock
.
base2
,
txMock
.
base3
,
txMock
.
base4
]
});
await
page
.
waitForSelector
(
'
tbody tr:nth-child(3)
'
);
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
3
);
const
counter
=
await
page
.
locator
(
'
tbody tr:nth-child(1)
'
).
textContent
();
expect
(
counter
?.
startsWith
(
'
1
'
)).
toBe
(
true
);
});
});
ui/address/AddressTxs.tsx
View file @
83723cb1
...
@@ -5,6 +5,7 @@ import React from 'react';
...
@@ -5,6 +5,7 @@ import React from 'react';
import
type
{
SocketMessage
}
from
'
lib/socket/types
'
;
import
type
{
SocketMessage
}
from
'
lib/socket/types
'
;
import
type
{
AddressFromToFilter
,
AddressTransactionsResponse
}
from
'
types/api/address
'
;
import
type
{
AddressFromToFilter
,
AddressTransactionsResponse
}
from
'
types/api/address
'
;
import
{
AddressFromToFilterValues
}
from
'
types/api/address
'
;
import
{
AddressFromToFilterValues
}
from
'
types/api/address
'
;
import
type
{
Transaction
}
from
'
types/api/transaction
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
getFilterValueFromQuery
from
'
lib/getFilterValueFromQuery
'
;
import
getFilterValueFromQuery
from
'
lib/getFilterValueFromQuery
'
;
...
@@ -26,7 +27,27 @@ const OVERLOAD_COUNT = 75;
...
@@ -26,7 +27,27 @@ const OVERLOAD_COUNT = 75;
const
getFilterValue
=
(
getFilterValueFromQuery
<
AddressFromToFilter
>
).
bind
(
null
,
AddressFromToFilterValues
);
const
getFilterValue
=
(
getFilterValueFromQuery
<
AddressFromToFilter
>
).
bind
(
null
,
AddressFromToFilterValues
);
const
AddressTxs
=
({
scrollRef
}:
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
})
=>
{
const
matchFilter
=
(
filterValue
:
AddressFromToFilter
,
transaction
:
Transaction
,
address
?:
string
)
=>
{
if
(
!
filterValue
)
{
return
true
;
}
if
(
filterValue
===
'
from
'
)
{
return
transaction
.
from
.
hash
===
address
;
}
if
(
filterValue
===
'
to
'
)
{
return
transaction
.
to
?.
hash
===
address
;
}
};
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
// for tests only
overloadCount
?:
number
;
}
const
AddressTxs
=
({
scrollRef
,
overloadCount
=
OVERLOAD_COUNT
}:
Props
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
...
@@ -69,30 +90,35 @@ const AddressTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivElement>}
...
@@ -69,30 +90,35 @@ const AddressTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivElement>}
return
;
return
;
}
}
const
newItems
=
[
...
prevData
.
items
];
const
newItems
:
Array
<
Transaction
>
=
[];
let
newCount
=
0
;
payload
.
transactions
.
forEach
(
tx
=>
{
payload
.
transactions
.
forEach
(
tx
=>
{
const
currIndex
=
newI
tems
.
findIndex
((
item
)
=>
item
.
hash
===
tx
.
hash
);
const
currIndex
=
prevData
.
i
tems
.
findIndex
((
item
)
=>
item
.
hash
===
tx
.
hash
);
if
(
currIndex
>
-
1
)
{
if
(
currIndex
>
-
1
)
{
newI
tems
[
currIndex
]
=
tx
;
prevData
.
i
tems
[
currIndex
]
=
tx
;
}
else
{
}
else
{
if
(
!
filterValue
||
if
(
matchFilter
(
filterValue
,
tx
,
currentAddress
))
{
(
filterValue
===
'
from
'
&&
tx
.
from
.
hash
===
currentAddress
)
||
if
(
newItems
.
length
+
prevData
.
items
.
length
>=
overloadCount
)
{
(
filterValue
===
'
to
'
&&
tx
.
to
?.
hash
===
currentAddress
)
newCount
++
;
)
{
if
(
newItems
.
length
>=
OVERLOAD_COUNT
)
{
setNewItemsCount
(
prev
=>
prev
+
1
);
}
else
{
}
else
{
newItems
.
unshift
(
tx
);
newItems
.
push
(
tx
);
}
}
}
}
}
}
});
});
if
(
newCount
>
0
)
{
setNewItemsCount
(
prev
=>
prev
+
newCount
);
}
return
{
return
{
...
prevData
,
...
prevData
,
items
:
newItems
,
items
:
[
...
newItems
,
...
prevData
.
items
,
],
};
};
});
});
};
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment