Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add max timeouts for frame requests #3073

Merged
merged 10 commits into from
Oct 11, 2024
23 changes: 23 additions & 0 deletions .changeset/cool-walls-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
'@apps/laboratory': patch
'@reown/appkit-wallet': patch
'@reown/appkit-ui': patch
'@apps/demo': patch
'@apps/gallery': patch
'@reown/appkit-adapter-ethers': patch
'@reown/appkit-adapter-ethers5': patch
'@reown/appkit-adapter-polkadot': patch
'@reown/appkit-adapter-solana': patch
'@reown/appkit-adapter-wagmi': patch
'@reown/appkit': patch
'@reown/appkit-utils': patch
'@reown/appkit-cdn': patch
'@reown/appkit-common': patch
'@reown/appkit-core': patch
'@reown/appkit-experimental': patch
'@reown/appkit-polyfills': patch
'@reown/appkit-scaffold-ui': patch
'@reown/appkit-siwe': patch
---

Added maximum timeouts for frame requests
2 changes: 1 addition & 1 deletion apps/laboratory/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default defineConfig<ModalFixture>({
expect: {
timeout: getValue(60, 15) * 1000
},
timeout: 60 * 1000,
timeout: 90 * 1000,
magiziz marked this conversation as resolved.
Show resolved Hide resolved

use: {
/* Base URL to use in actions like `await page.goto('/')`. */
Expand Down
16 changes: 13 additions & 3 deletions apps/laboratory/tests/email.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ let page: ModalWalletPage
let validator: ModalWalletValidator
let context: BrowserContext
let browserPage: Page
/* eslint-enable init-declarations */
let email: Email
let tempEmail: string

// -- Setup --------------------------------------------------------------------
const emailTest = test.extend<{ library: string }>({
Expand All @@ -21,6 +22,8 @@ const emailTest = test.extend<{ library: string }>({
emailTest.describe.configure({ mode: 'serial' })

emailTest.beforeAll(async ({ browser, library }) => {
await page.page.context().setOffline(false)

context = await browser.newContext()
browserPage = await context.newPage()

Expand All @@ -33,8 +36,8 @@ emailTest.beforeAll(async ({ browser, library }) => {
if (!mailsacApiKey) {
throw new Error('MAILSAC_API_KEY is not set')
}
const email = new Email(mailsacApiKey)
const tempEmail = await email.getEmailAddressToUse()
email = new Email(mailsacApiKey)
tempEmail = await email.getEmailAddressToUse()
await page.emailFlow(tempEmail, context, mailsacApiKey)

await validator.expectConnected()
Expand Down Expand Up @@ -105,3 +108,10 @@ emailTest('it should disconnect correctly', async () => {
await page.disconnect()
await validator.expectDisconnected()
})

emailTest('it should abort request if it takes more than 30 seconds', async () => {
await page.page.context().setOffline(true)
await page.loginWithEmail(tempEmail, false)
await page.page.waitForTimeout(30_000)
enesozturk marked this conversation as resolved.
Show resolved Hide resolved
await validator.expectSnackbar('Something went wrong')
})
16 changes: 9 additions & 7 deletions apps/laboratory/tests/shared/pages/ModalPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export class ModalPage {
await this.enterOTP(otp)
}

async loginWithEmail(email: string) {
async loginWithEmail(email: string, validate = true) {
// Connect Button doesn't have a proper `disabled` attribute so we need to wait for the button to change the text
await this.page
.getByTestId('connect-button')
Expand All @@ -188,12 +188,14 @@ export class ModalPage {
await this.page.getByTestId('wui-email-input').locator('input').focus()
await this.page.getByTestId('wui-email-input').locator('input').fill(email)
await this.page.getByTestId('wui-email-input').locator('input').press('Enter')
await expect(
this.page.getByText(email),
`Expected current email: ${email} to be visible on the notification screen`
).toBeVisible({
timeout: 20_000
})
if (validate) {
await expect(
this.page.getByText(email),
`Expected current email: ${email} to be visible on the notification screen`
).toBeVisible({
timeout: 20_000
})
}
}

async loginWithSocial(socialOption: 'github', socialMail: string, socialPass: string) {
Expand Down
6 changes: 6 additions & 0 deletions apps/laboratory/tests/shared/validators/ModalValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,4 +306,10 @@ export class ModalValidator {
const modal = this.page.getByTestId('w3m-modal')
await expect(modal).toBeHidden()
}

async expectSnackbar(message: string) {
await expect(this.page.getByTestId('wui-snackbar-message')).toHaveText(message, {
timeout: MAX_WAIT
})
}
}
2 changes: 1 addition & 1 deletion packages/ui/src/composites/wui-snackbar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class WuiSnackbar extends LitElement {
icon=${this.icon}
background="opaque"
></wui-icon-box>`}
<wui-text variant="paragraph-500" color="fg-100">${this.message}</wui-text>
<wui-text variant="paragraph-500" color="fg-100" data-testid="wui-snackbar-message">${this.message}</wui-text>
`
}
}
Expand Down
14 changes: 10 additions & 4 deletions packages/wallet/src/W3mFrameProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ export class W3mFrameProvider {
return type.replace('@w3m-app/', '')
}

const abortController = new AbortController()

const type = replaceEventType(event.type)

const shouldCheckForTimeout = [
Expand All @@ -484,23 +486,27 @@ export class W3mFrameProvider {
.map(replaceEventType)
.includes(type)

if (shouldCheckForTimeout && this.onTimeout) {
// 15 seconds timeout
timer = setTimeout(this.onTimeout, 15_000)
if (shouldCheckForTimeout) {
timer = setTimeout(() => {
this.onTimeout?.()
abortController.abort()
}, 30_000)
}

return new Promise((resolve, reject) => {
const id = Math.random().toString(36).substring(7)
this.w3mLogger.logger.info?.({ event, id }, 'Sending app event')
this.w3mFrame.events.postAppEvent({ ...event, id } as W3mFrameTypes.AppEvent)
const abortController = new AbortController()

if (type === 'RPC_REQUEST') {
const rpcEvent = event as Extract<W3mFrameTypes.AppEvent, { type: '@w3m-app/RPC_REQUEST' }>
this.openRpcRequests = [...this.openRpcRequests, { ...rpcEvent.payload, abortController }]
}
abortController.signal.addEventListener('abort', () => {
if (type === 'RPC_REQUEST') {
reject(new Error('Request was aborted'))
} else {
reject(new Error('Something went wrong'))
}
})

Expand Down
Loading