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

isTestFile filter fails for window.__coverage__ object with Symbol key #908

Open
ioanajoj opened this issue Dec 5, 2024 · 0 comments
Open

Comments

@ioanajoj
Copy link

ioanajoj commented Dec 5, 2024

Logs

code-coverage combined NYC options { 'report-dir': './coverage', reporter: [ 'lcov', 'clover', 'json', 'json-summary' ], extension: [ '.js', '.cjs', '.mjs', '.ts', '.tsx', '.jsx' ], excludeAfterRemap: false } +0ms
code-coverage parsed sent coverage +0ms
code-coverage NYC file /Users/user/frontend/apps/my-app-tests/.nyc_output/out.json has 329 key(s) +5s
code-coverage 1 key /Users/user/frontend/apps/my-app/src/app/app.component.ts file path /Users/user/frontend/apps/my-app/src/app/app.component.ts +0ms
code-coverage 2 key /Users/user/frontend/libs/shared/util/core/src/lib/interfaces/base-query.interface.ts file path /Users/user/frontend/libs/shared/util/core/src/lib/interfaces/base-query.interface.ts +0ms
code-coverage 3 key /Users/user/frontend/libs/shared/util/core/src/lib/interfaces/base-record.interface.ts file path /Users/user/frontend/libs/shared/util/core/src/lib/interfaces/base-record.interface.ts +1ms
code-coverage in file /Users/user/frontend/apps/my-app-tests/.nyc_output/out.json all files are not found? false +98ms
code-coverage NYC file /Users/user/frontend/apps/my-app-tests/.nyc_output/out.json has 329 key(s) +62ms
code-coverage calling NYC reporter with options { 'report-dir': '/Users/user/frontend/apps/my-app-tests/coverage', reporter: [ 'lcov', 'clover', 'json', 'json-summary' ], extension: [ '.js', '.cjs', '.mjs', '.ts', '.tsx', '.jsx' ], excludeAfterRemap: false, 'temp-dir': '/Users/user/frontend/apps/my-app-tests/.nyc_output', tempDir: '/Users/user/frontend/apps/my-app-tests/.nyc_output', reportDir: '/Users/user/frontend/apps/my-app-tests/coverage' } +373ms
code-coverage current working directory is /Users/user/frontend/apps/my-app-tests +0ms
code-coverage after reporting, returning the report folder name /Users/user/frontend/apps/my-app-tests/coverage +786ms
code-coverage Final coverage in /Users/user/frontend/apps/my-app-tests/coverage/coverage-final.json +0ms
code-coverage There are 413 key(s) in /Users/user/frontend/apps/my-app-tests/coverage/coverage-final.json +34ms

Versions

  • What is this plugin's version? 3.13.6
  • What is the Cypress version? 13.15.2
  • What is the Node version? 22.4.1
  • What is the NPM version? 10.8.1
  • How do you instrument your application? with a loader loader: '@skyux-sdk/istanbul-instrumenter-loader', inside webpack config
  • When running tests, if you open the web application in a regular browser and open DevTools, do you see window.__coverage__ object? yes
  • Is there a .nyc_output folder? Is there a .nyc_output/out.json file? yes, not empty
  • Do you have any custom NYC settings in package.json (nyc object) or in other NYC config files? no
  • Do you run Cypress tests in a Docker container? no

Describe the bug
My app dynamically loads a wasm lib from assets at runtime:

const wasmFullUrl = joinParts(this._assetsUrl, 'my-wasm-lib/main.js');
const { init } = await import(/* webpackIgnore: true */ wasmFullUrl) as { init: () => Promise<WasmExports> };
const initResult = await init();

Once the cypress test passes the import line, inside the window.__coverage__ object, under Prototype, there is this key-value pair: Symbol(wasm type): 0.

image

After the test is run, while code coverage is processed, the window.__coverage__ object reaches this filter:

const coverage = Cypress._.omitBy(totalCoverage, isTestFile)

and apparently the lodash omitBy method will also go through key,value pairs inside Prototype, which makes the isTestFile method be called with the Symbol(wasm type) key, causing the following line to fail (where filePath is Symbol):

// inside isTestFile
const filename = filePath.replace(workingDir, '')

And eventually the test fails with:

TypeError: filePath.replace is not a function
Because this error occurred during a `after each` hook we are skipping all of the remaining tests.
    at isTestFile (webpack:///../../node_modules/@cypress/code-coverage/support-utils.js:31:0)
    at filterSpecsFromCoverage (webpack:///../../node_modules/@cypress/code-coverage/support-utils.js:41:0)
    at filterFilesFromCoverage (webpack:///../../node_modules/@cypress/code-coverage/support-utils.js:12:0)
    at sendCoverage (webpack:///../../node_modules/@cypress/code-coverage/support.js:20:0)
    at eval (webpack:///../../node_modules/@cypress/code-coverage/support.js:146:0)
    at Array.forEach (<anonymous>)
    at Context.eval (webpack:///../../node_modules/@cypress/code-coverage/support.js:145:0)

Workaround

// delete the symbol from the coverage prototype after each test, before it is processed by cypress/code-coverage
let windowObj = {};
const saveWindowCoverageObject = (win: any) => windowObj = win;
beforeEach(() => {
    cy.on('window:load', saveWindowCoverageObject);
});
afterEach(() => {
    let symbolKey;
    // eslint-disable-next-line no-underscore-dangle
    Cypress._.omitBy(windowObj.__coverage__, (_, key) => {
        if (typeof key === 'symbol') {
            symbolKey = key;
        }
        return typeof key === 'symbol';
    });
    // eslint-disable-next-line no-underscore-dangle
    delete windowObj.__coverage__.__proto__[symbolKey];
});

I tried to exclude the assets and the file that does the dynamic import from instrumentation, but the Symbol is still persisted inside the coverage object. I couldn't identify what actually adds the symbol or why.

It would be helpful if the post processing done inside filterSpecsFromCoverage could ignore the symbol keys in order to avoid this kind of failure.

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

1 participant