aws / aws-sdk-js-v3

Modularized AWS SDK for JavaScript.
Apache License 2.0
3.06k stars 573 forks source link

Destructuring of Node APIs causes Cypress to crash #3828

Closed calebpollman closed 2 months ago

calebpollman commented 2 years ago

Describe the bug

The @aws-sdk/shared-ini-file-loader package (and potentially others) includes destructuring of fs, a Node API in a couple files (here and here) which is undefined in the context of a browser. While this package is clearly not meant for browser usage, it is included as a dependency of some AWS SDK clients (for example @aws-sdk/client-pinpoint) which are.

Just having this package in our node_modules via installation of @aws-sdk/client-pinpoint is causing a Cypress test to crash when we attempt to import an unrelated package (see here)

Expected Behavior

Inclusion of the @aws-sdk/client-pinpoint package within an application's _nodemodules should not break Cypress

Current Behavior

The following error originated from your test code, not from Cypress.

  > Cannot read properties of undefined (reading 'readFile')

When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.

Cypress could not associate this error to any specific test.

We dynamically generated a new test to display this failure.
[node_modules/@aws-sdk/shared-ini-file-loader/dist-es/getSSOTokenFromFile.js:4:26](http://localhost:59308/__/#)
  2 | import { promises as fsPromises } from "fs";
  3 | import { getSSOTokenFilepath } from "./getSSOTokenFilepath";
> 4 | var readFile = fsPromises.readFile;
    |                          ^
  5 | export var getSSOTokenFromFile = function (ssoStartUrl) { return __awaiter(void 0, void 0, void 0, function () {
  6 |     var ssoTokenFilepath, ssoTokenText;
  7 |     return __generator(this, function (_a)

at ./node_modules/@aws-sdk/shared-ini-file-loader/dist-es/getSSOTokenFromFile.js ([webpack:///./node_modules/@aws-sdk/shared-ini-file-loader/dist-es/getSSOTokenFromFile.js:4:26](http://localhost:59308/__/#))
    at __webpack_require__ ([webpack:///webpack/bootstrap:19:1](http://localhost:59308/__/#))
    at ./node_modules/@aws-sdk/shared-ini-file-loader/dist-es/index.js ([webpack:///./node_modules/@aws-sdk/shared-ini-file-loader/dist-es/index.js:1:1](http://localhost:59308/__/#))
    at __webpack_require__ ([webpack:///webpack/bootstrap:19:1](http://localhost:59308/__/#))
    at ./cypress/integration/example/example.spec.js ([webpack:///./cypress/integration/example/example.spec.js:1:1](http://localhost:59308/__/#))
    at __webpack_require__ ([webpack:///webpack/bootstrap:19:1](http://localhost:59308/__/#))
    at 0 (http://localhost:59308/__cypress/tests?p=cypress/integration/example/example.spec.js:38543:19)
    at __webpack_require__ ([webpack:///webpack/bootstrap:19:1](http://localhost:59308/__/#))
    at eval ([webpack:///webpack/bootstrap:83:1](http://localhost:59308/__/#))
    at eval (http://localhost:59308/__cypress/tests?p=cypress/integration/example/example.spec.js:87:11)
From previous event:
    at runScriptsFromUrls (http://localhost:59308/__cypress/runner/cypress_runner.js:186281:137)
    at Object.runScripts (http://localhost:59308/__cypress/runner/cypress_runner.js:186296:13)
    at $Cypress.onSpecWindow (http://localhost:59308/__cypress/runner/cypress_runner.js:174692:77)

Reproduction Steps

Sample repo with directions: https://github.com/calebpollman/cypress-aws-sdk

Possible Solution

Only destructure the Node API contents within the scope of the functions that require their usage, example:

import fs from "fs";
import { getSSOTokenFilepath } from "./getSSOTokenFilepath";

/**
 * Cached SSO token retrieved from SSO login flow.
 */
export interface SSOToken {
  // SSOToken contents
}

/**
 * Returns the SSO token from the file system.
 */
export const getSSOTokenFromFile = async (ssoStartUrl: string) => {
  const { readFile } = fs.promises;
  const ssoTokenFilepath = getSSOTokenFilepath(ssoStartUrl);
  const ssoTokenText = await readFile(ssoTokenFilepath, "utf8");
  return JSON.parse(ssoTokenText) as SSOToken;
};

Additional Information/Context

No response

SDK version used

3.x

Environment details (OS name and version, etc.)

macOS Monterey, version 12.4

blochs commented 2 years ago

This was also seen in https://github.com/aws/aws-sdk-js-v3/issues/3354 and I'm running into it as well.

ajredniwja commented 2 years ago

Hey @calebpollman thanks for opening this issue and setting up repo for repro as well. Do you see similar errors when not using cypress? Could also be related to webpack bundling too, I'll post more findings once I run the code.

calebpollman commented 2 years ago

Thanks for picking this up @ajredniwja. It is specific to Cypress

raulbarreto-delivion commented 2 years ago

I'm also getting this same issue when running tests with jest

calebpollman commented 2 years ago

@ajredniwja Any updates?

kevinswarner commented 1 year ago

I am getting a similar problem when mocking the "fs" module in Jest.

MesutKurtulanPF commented 7 months ago

Error: Can't walk dependency graph: ENOENT: no such file or directory, lstat '/Users/Guest/X-Project/API-Automation/process' required by /Users/Guest/X-Project/API-Automation/node_modules/@aws-sdk/client-pinpoint/node_modules/@aws-sdk/util-user-agent-node/dist-cjs/index.js is this issue related to bug? I try to install "npm install @aws-sdk/client-pinpoint" and see this error

RanVaknin commented 2 months ago

Hi there,

The error observed here is likely not an issue with the SDK. It seems like Cypress is attempting to resolve functionalities from the fs module which is not supported in a browser environment. As a user of Cypress you'll likely have to shim it, or use something like https://www.npmjs.com/package/@cypress/webpack-preprocessor to pre process with webpack.

Thanks, Ran~

github-actions[bot] commented 2 months ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.