Commit 1c504601 authored by Nate Wienert's avatar Nate Wienert Committed by GitHub

fix: using search hotkey enter navigates to the wrong result (#6735)

* fix: fix SearchBarDropdown selecting invalid result on enter after initial search when recent searches are filled

* add test

* Update cypress/e2e/universal-search.test.ts
Co-authored-by: default avatarZach Pomerantz <zzmp@uniswap.org>

* Update cypress/e2e/universal-search.test.ts
Co-authored-by: default avatarZach Pomerantz <zzmp@uniswap.org>

* Update cypress/e2e/universal-search.test.ts
Co-authored-by: default avatarZach Pomerantz <zzmp@uniswap.org>

* use searhc hotkey

* Revert ""

This reverts commit 7b04d5d575e8f776e8127e9b43c3fff6f74d8919.

* chore: gitignore cypress/downloads.html

---------
Co-authored-by: default avatarZach Pomerantz <zzmp@uniswap.org>
parent 2ef9e9b6
......@@ -46,6 +46,7 @@ notes.txt
package-lock.json
cypress/downloads
cypress/videos
cypress/screenshots
......
describe('Universal search bar', () => {
function openSearch() {
// can't just type "/" because on mobile it doesn't respond to that
cy.get('[data-cy="magnifying-icon"]').parent().eq(1).click()
}
beforeEach(() => {
cy.visit('/')
cy.get('[data-cy="magnifying-icon"]').parent().eq(1).click()
openSearch()
})
function getSearchBar() {
return cy.get('[data-cy="search-bar-input"]').last()
}
it('should yield clickable result for regular token or nft collection search term', () => {
// Search for uni token by name.
cy.get('[data-cy="search-bar-input"]').last().clear().type('uni')
getSearchBar().clear().type('uni')
cy.get('[data-cy="searchbar-token-row-UNI"]')
.should('contain.text', 'Uniswap')
.and('contain.text', 'UNI')
......@@ -16,6 +25,32 @@ describe('Universal search bar', () => {
cy.location('hash').should('equal', '#/tokens/ethereum/0x1f9840a85d5af5bf1d1762f925bdaddc4201f984')
})
it('should go to the selected result when recent results are shown', () => {
// Search for uni token by name.
getSearchBar().type('uni')
cy.get('[data-cy="searchbar-token-row-UNI"]')
// Clear search
getSearchBar().clear()
// Close search
getSearchBar().type('{esc}')
openSearch()
// Search a different token by name.
getSearchBar().type('eth')
// Validate ETH result now exists.
cy.get('[data-cy="searchbar-token-row-ETH"]')
// Hit enter
getSearchBar().type('{enter}')
// Validate we went to ethereum address
cy.url().should('contain', 'tokens/ethereum/NATIVE')
})
it.skip('should show recent tokens and popular tokens with empty search term', () => {
cy.get('[data-cy="magnifying-icon"]')
.parent()
......@@ -23,7 +58,7 @@ describe('Universal search bar', () => {
$navIcon.click()
})
// Recently searched UNI token should exist.
cy.get('[data-cy="search-bar-input"]').last().clear()
getSearchBar().clear()
cy.get('[data-cy="searchbar-dropdown"]')
.contains('[data-cy="searchbar-dropdown"]', 'Recent searches')
.find('[data-cy="searchbar-token-row-UNI"]')
......@@ -39,7 +74,7 @@ describe('Universal search bar', () => {
it.skip('should show blocked badge when blocked token is searched for', () => {
// Search for mTSLA, which is a blocked token.
cy.get('[data-cy="search-bar-input"]').last().clear().type('mtsla')
getSearchBar().clear().type('mtsla')
cy.get('[data-cy="searchbar-token-row-mTSLA"]').find('[data-cy="blocked-icon"]').should('exist')
})
})
This diff is collapsed.
import React from 'react'
import { useState } from 'react'
export const SuspendConditionally = (props: { if: boolean; children: React.ReactNode }) => {
useSuspendIf(props.if)
return <>{props.children}</>
}
function useSuspendIf(shouldSuspend = false) {
const [resolve, setResolve] = useState<((val?: unknown) => void) | undefined>()
if (!resolve && shouldSuspend) {
const promise = new Promise((res) => {
setResolve(res)
})
throw promise
} else if (resolve && !shouldSuspend) {
resolve()
setResolve(undefined)
}
}
import usePrevious from 'hooks/usePrevious'
import React, { Suspense } from 'react'
/**
* This is useful for keeping the "last rendered" components on-screen while any suspense
* is triggered below this component.
*
* It stores a reference to the current children, and then returns them as the fallback.
*/
export const SuspenseWithPreviousRenderAsFallback = (props: { children: React.ReactNode }) => {
const previousContents = usePrevious(props.children)
return <Suspense fallback={previousContents ?? null}>{props.children}</Suspense>
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment