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

Trouble confirming multiple transactions serially #411

Open
louis-md opened this issue May 14, 2022 · 5 comments
Open

Trouble confirming multiple transactions serially #411

louis-md opened this issue May 14, 2022 · 5 comments
Assignees

Comments

@louis-md
Copy link

louis-md commented May 14, 2022

Hello,

I had trouble confirming multiple transactions in a row. I have a loop that confirms them as follows (we know the number of transactions in advance):

cy
  .wrap(Array.from({ length: parseInt(numberOfTransactions) }, (x, i) => i++))
  .each(() => {
      cy.confirmMetamaskTransaction()
   })

It works well when all the transactions are already waiting for confirmation, waiting to start in parallel. However, in the scenario where there are x transactions following each other serially (one having to finish before the next is proposed for confirmation), only the first is confirmed, never the following ones. After the first one, it behaves as if synpress had lost all communication with metamask: it tries to confirm, but the transaction is never actually confirmed.

I tried to use cy.switchToMetamaskWindow() to confirm transactions manually, by clicking the buttons on the Metamask tab, but cypress functions does not seem to have any effect on that tab.

Thanks for the help, and for the great work on this package!

@noahgenesis
Copy link

noahgenesis commented Dec 23, 2022

Hey @louis-md were you able to figure out how to do this? I'm facing the same problem

@drptbl is this something that synpress can do?

In my case I'd like to sign a tx every time an specific element gets rendered, like:

cy.get('[data-cy="elemente-0"]').should('be.visible').then(() => cy.confirmMetamaskTransaction())
cy.get('[data-cy="elemente-1"]').should('be.visible').then(() => cy.confirmMetamaskTransaction())
cy.get('[data-cy="elemente-2"]').should('be.visible').then(() => cy.confirmMetamaskTransaction())

What happens is after the first tx signed, no subsequent tx gets signed

@louis-md
Copy link
Author

Hi @noahgenesis

I have actually, but I noticed the version I used when writing this issue (1.20) is now very outdated (the latest version is 3.0.5 as I'm writing this). So I would suggest first to use the latest synpress and see if the problem is still there.

If that's the case, what I ended up doing was patching synpress using patch-package (see the patch file below), and used huge arbitrary timeouts (10s + 2mns) between each transaction in the loop:

      if (numberOfTransactions !== '0') {
        // eslint-disable-next-line cypress/no-unnecessary-waiting
        cy.wait(10000)
        cy.wrap(Array.from({ length: parseInt(numberOfTransactions) }, (x, i) => i++))
          .each(() => { cy.confirmMetamaskTransaction(undefined) })
        cy.get(`#success-id`, { timeout: 120000 }).should('be.visible')
      }

This lets synpress the time to detect the transaction, choose gas price, etc., and do this for each transaction. It ended up working as expected.

This is probably not the most efficient solution, nor the most up to date, so any help is still welcome. If I update synpress in my project and find a better solution I'll also post it here.

The patch file generated with patch-package:

./patches/@Synthetixio+synpress+1.2.0.patch

diff --git a/node_modules/@synthetixio/synpress/commands/puppeteer.js b/node_modules/@synthetixio/synpress/commands/puppeteer.js
index 795fda1..64c4070 100644
--- a/node_modules/@synthetixio/synpress/commands/puppeteer.js
+++ b/node_modules/@synthetixio/synpress/commands/puppeteer.js
@@ -98,7 +98,8 @@ module.exports = {
   waitFor: async (selector, page = metamaskWindow) => {
     await page.waitForFunction(
       `document.querySelector('${selector}') && document.querySelector('${selector}').clientHeight != 0`,
-      { visible: true },
+      // Fix type error in Synpress and increase timeout for Metamask confirmations. See: https://github.com/Synthetixio/synpress/issues/418
+      { timeout: 120000 },
     );
     // puppeteer going too fast breaks metamask in corner cases
     await page.waitForTimeout(300);

@noahgenesis
Copy link

Thanks @louis-md! I'll give it a shot later on and come with the results

@neuodev neuodev self-assigned this Apr 19, 2023
@louis-md
Copy link
Author

louis-md commented May 14, 2023

Update: I updated synpress to 3.5.1 [later update, now to 3.7.1] and my hack-arounds don't work anymore. I've tried a few things but nothing seems to work.

I'll post here if I find a way out, but I guess the best solution would be to add some options to cy.confirmMetamaskTransaction() to accept either the n next transactions, or all of them.

@louis-md
Copy link
Author

Workaround found and posted in related issue #1042 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
@louis-md @neuodev @noahgenesis and others