Synthetixio / synpress

Synpress is e2e testing framework based on Cypress.io and playwright with support for metamask.
https://synpress.io
MIT License
590 stars 188 forks source link

[๐Ÿ› Bug]: Cannot run test with npm setup #1139

Closed badgooooor closed 4 months ago

badgooooor commented 4 months ago

๐Ÿ”Ž Have you searched existing issues to avoid duplicates?

๐Ÿงช Have you tested your code using latest version of Synpress?

๐Ÿ’ก Are you able to provide enough information to be able to reproduce your issue locally?

Synpress version

3.7.2

Node.js version

v18.19.1

Operating system

14.5

Run mode

Playwright + Synpress (as plugin)

CI platform (if applicable)

No response

Are you running your tests inside docker? (if applicable)

What happened?

I tried to setup synpress test on playwright on my private working directory which currently using npm as package manager. Upon running, the error was prompted in console like this.

 TypeError: Cannot read properties of undefined (reading 'waitForTimeout')

       at ../fixtures.ts:44

      42 |
      43 |     // setup metamask
    > 44 |     await initialSetup(chromium, {
         |     ^
      45 |       secretWordsOrPrivateKey:
      46 |         "test test test test test test test test test test test junk",
      47 |       network: "optimism",

What is your expected behavior?

It should work correctly same as setup using pnpm

How to reproduce the bug.

I decided to retest this setup using synpress-example which originally using pnpm setup but install using npm instead and it has the same result as above.

This is step that I did to reproduce this issue

  1. cd playwright/isolated-state
  2. npm install
  3. npm run test

Relevant log output

Running 2 tests using 1 worker
  1) [chromium] โ€บ connect-wallet.spec.ts:9:5 โ€บ connect wallet using default metamask account โ”€โ”€โ”€โ”€โ”€โ”€โ”€

    TypeError: Cannot read properties of undefined (reading 'waitForTimeout')

       at ../fixtures.ts:44

      42 |
      43 |     // setup metamask
    > 44 |     await initialSetup(chromium, {
         |     ^
      45 |       secretWordsOrPrivateKey:
      46 |         "test test test test test test test test test test test junk",
      47 |       network: "optimism",

        at Object.fixBlankPage (/Users/yuttakhan.b/side-projects/synpress-examples/playwright/isolated-state/node_modules/@synthetixio/synpress/commands/playwright.js:392:16)
        at initialSetup (/Users/yuttakhan.b/side-projects/synpress-examples/playwright/isolated-state/node_modules/@synthetixio/synpress/commands/metamask.js:1269:22)
        at Object.context (/Users/yuttakhan.b/side-projects/synpress-examples/playwright/isolated-state/fixtures.ts:44:5)

  2) [chromium] โ€บ connect-wallet.spec.ts:17:5 โ€บ import private key and connect wallet using imported metamask account 

    TypeError: Cannot read properties of undefined (reading 'waitForTimeout')

       at ../fixtures.ts:44

      42 |
      43 |     // setup metamask
    > 44 |     await initialSetup(chromium, {
         |     ^
      45 |       secretWordsOrPrivateKey:
      46 |         "test test test test test test test test test test test junk",
      47 |       network: "optimism",

        at Object.fixBlankPage (/Users/yuttakhan.b/side-projects/synpress-examples/playwright/isolated-state/node_modules/@synthetixio/synpress/commands/playwright.js:392:16)
        at initialSetup (/Users/yuttakhan.b/side-projects/synpress-examples/playwright/isolated-state/node_modules/@synthetixio/synpress/commands/metamask.js:1269:22)
        at Object.context (/Users/yuttakhan.b/side-projects/synpress-examples/playwright/isolated-state/fixtures.ts:44:5)

  2 failed
    [chromium] โ€บ connect-wallet.spec.ts:9:5 โ€บ connect wallet using default metamask account โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    [chromium] โ€บ connect-wallet.spec.ts:17:5 โ€บ import private key and connect wallet using imported metamask account
itev4n7 commented 4 months ago

solution is simple but this is not the only issue, then it failing due to metamask popup if use privateKey :)

I didn't understand why this version is not beta... is not working from the box if you are using it as a plugin with playwright

solution for this error:

fixtures.ts

import { BrowserContext, test as base, chromium } from "@playwright/test";
import { prepareMetamask } from "@synthetixio/synpress/helpers";
import playwright from "@synthetixio/synpress/commands/playwright";

const contextOptions = {
  context: async ({}, use: any) => {
    const metamaskVersion = "11.15.1";
    const metamaskPath = await prepareMetamask(metamaskVersion);

    const browserArgs = [
      `--disable-extensions-except=${metamaskPath}`,
      `--load-extension=${metamaskPath}`,
      "--remote-debugging-port=9222",
      "--reset-browser-instance-between-tests",
    ];

    const context = await chromium.launchPersistentContext("", {
      headless: false,
      args: browserArgs,
    });
    await playwright.init(context.browser()); // this line make "metamaskWindow" to be set, in other cases it's undefined in initialSetup function
    await context.pages()[0].waitForTimeout(5000);
    await use(context);
    await context.close();
  },
};

export const test = base.extend<BrowserContext>(contextOptions);

export const expect = test.expect;

And make sure in test you don't use standard fixture page instead of it you need to use const page = context.pages()[0] Then use "initialSetup" inside test, but as I mentioned before wait for popup that is not handled by synpress after wallet creation if you pass a private key, with mnemonic phrase it works for me

Screenshot 2024-05-29 at 22 32 17
itev4n7 commented 4 months ago

For devs pay attention to "importAccount" function to fix that issue

...
if (secretWordsOrPrivateKey.includes(' ')) {
        // secret words
        await module.exports.importWallet(secretWordsOrPrivateKey, password);
      } else {
        // private key
        await module.exports.createWallet(password);
        await module.exports.importAccount(secretWordsOrPrivateKey); //here
      }

      // Enhanced Transaction Protection
      await playwright.waitAndClick(
        mainPageElements.accountModal.primaryButton,
      );
      await setupSettings(enableAdvancedSettings, enableExperimentalSettings);

      await module.exports.changeNetwork(network);
      ...

If we use initialSetup with private key in function importAccount it's not handle the Enhanced Transaction Protection popup

drptbl commented 4 months ago

@badgooooor @itev4n7 fixed in @synthetixio/synpress@3.7.3 - it was external contribution btw

badgooooor commented 4 months ago

@itev4n7 Just tested out the edited fixture you suggested earlier, it's working. Thanks. @drptbl From this issue, should the examples in synpress-example needed to update? At least for those who come in new would not for to this kind of pitfall.