apache / superset

Apache Superset is a Data Visualization and Data Exploration Platform
https://superset.apache.org/
Apache License 2.0
61.84k stars 13.54k forks source link

Test suite failed to run - Custom Plugins #30297

Open sam-hieken opened 3 days ago

sam-hieken commented 3 days ago

Bug description

Hi,

I get the following error after generating and trying to build a custom visualization plugin (without making any code changes). I'm following the official tutorial from Preset.

 FAIL  test/plugin/buildQuery.test.ts
  ● Test suite failed to run

    The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/configuration#testenvironment-string.
    Consider using the "jsdom" test environment.

    ReferenceError: window is not defined

      17 |  * under the License.
      18 |  */
    > 19 | import { buildQueryContext, QueryFormData } from '@superset-ui/core';
         | ^
      20 |
      21 | /**
      22 |  * The buildQuery function is used to create an instance of QueryContext that's

      at Object.<anonymous> (node_modules/@superset-ui/core/lib/utils/logging.js:24:17)
      at Object.<anonymous> (node_modules/@superset-ui/core/lib/utils/index.js:45:39)
      at Object.<anonymous> (node_modules/@superset-ui/core/lib/index.js:13:14)
      at Object.require (src/plugin/buildQuery.ts:19:1)
      at Object.require (test/plugin/buildQuery.test.ts:19:1)

How to reproduce the bug

Follow the exact steps taken in Building Custom Viz Plugins in Superset with the latest repository:

# Install yo
npm i -g yo
cd superset-frontend/packages/generator-superset
npm i
npm link

cd /tmp
mkdir my-plugin
cd my-plugin/
yo @superset-ui/superset

At this point, when running npm ci && npm run build, you'll receive the error:

src/plugin/controlPanel.ts:22:3 - error TS6133: 'sections' is declared but its value is never read.

22   sections,
     ~~~~~~~~

This is where the expected output diverges from the tutorial; npm ci && npm run build should succeed with no errors or warnings, despite no code changes being made.

But anyway, for testing purposes, I don't care if sections isn't used; so I set "noUnusedLocals": false in tsconfig.json.

Now when I rerun npm ci && npm run build:

 FAIL  test/plugin/buildQuery.test.ts
  ● Test suite failed to run

    The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/configuration#testenvironment-string.
    Consider using the "jsdom" test environment.

    ReferenceError: window is not defined

      17 |  * under the License.
      18 |  */
    > 19 | import { buildQueryContext, QueryFormData } from '@superset-ui/core';
         | ^
      20 |
      21 | /**
      22 |  * The buildQuery function is used to create an instance of QueryContext that's

      at Object.<anonymous> (node_modules/@superset-ui/core/lib/utils/logging.js:24:17)
      at Object.<anonymous> (node_modules/@superset-ui/core/lib/utils/index.js:45:39)
      at Object.<anonymous> (node_modules/@superset-ui/core/lib/index.js:13:14)
      at Object.require (src/plugin/buildQuery.ts:19:1)
      at Object.require (test/plugin/buildQuery.test.ts:19:1)

Screenshots/recordings

N/A

Superset version

master / latest-dev

Python version

3.10

Node version

18 or greater

Browser

Not applicable

Additional context

I'm running Ubuntu 22.04, and my exact Node version is 20.13.1. It's also probably worth mentioning I used the Basic Chart type. Again, I followed the exact steps specified in Preset's official tutorial, which involved no code changes; I can't think of any reason this issue should occur.

Also, if anyone is having the same issue and looking for a workaround, the easiest I've found is to just edit buildQuery.test.ts (under the tests directory), remove the existing test case, and add in one that will always succeed (my apologies if there's an easier way to do this, I'm not familiar with jest):

describe('2a', () => {
  test('my test case', () => {
    expect(true).toBe(true); // Always expect true
  });
}); 

Thank you.

Checklist

dosubot[bot] commented 3 days ago

I found a similar unsolved discussion that might be relevant to your issue: Building Custom Viz Plugins in Superset [1]. Additionally, there was a closed issue related to module resolution: Cannot find module '@airbnb/config-babel' [2].

To resolve the "ReferenceError: window is not defined" error when running tests for a custom visualization plugin in Superset, you need to ensure that the global window object is properly mocked in your test environment. The provided shim.tsx file from the Superset repository already includes the necessary setup to mock the window object.

Here is the relevant part of the shim.tsx file that sets up the global window object:

const g = global as any;
g.window ??= Object.create(window);
g.window.location ??= { href: 'about:blank' };
g.window.performance ??= { now: () => new Date().getTime() };
g.window.Worker ??= Worker;
g.window.IntersectionObserver ??= IntersectionObserver;
g.window.ResizeObserver ??= ResizeObserver;
g.window.featureFlags ??= {};
g.URL.createObjectURL ??= () => '';
g.caches = new CacheStorage();

Object.defineProperty(window, 'matchMedia', {
  writable: true,
  value: jest.fn().mockImplementation(query => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(), // Deprecated
    removeListener: jest.fn(), // Deprecated
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    dispatchEvent: jest.fn(),
  })),
});

g.$ = jQuery(g.window);

Ensure that this shim.tsx file is imported and executed in your test setup. This will mock the window object and prevent the "ReferenceError: window is not defined" error.

If you haven't already, you can include this setup in your Jest configuration by adding the following to your Jest setup file (e.g., setupTests.ts):

import './path/to/shim.tsx';

This will ensure that the window object and other necessary mocks are available in your test environment [3].

To continue talking to Dosu, mention @dosu.

rusackas commented 3 days ago

@sam-hieken it might be as simple as Dosu suggests... would you be willing to open a PR adding this shim inclusion to the yeoman generator? I'd do it myself, but I'm short on time right now.

sam-hieken commented 3 days ago

@rusackas Thanks for the reply, I would, but it looks like the only shim.tsx file that exists is under superset-frontend/spec/helpers/shim.tsx. Doing a recursive search on my generated plugin's directory didn't show a shim.tsx file either. I'll tag dosu for more details, but that seems problematic

sam-hieken commented 3 days ago

@dosu Where is shim.tsx located? I don't see it in the directory generated for my plugin

dosubot[bot] commented 3 days ago

The shim.tsx file is located at superset-frontend/spec/helpers/shim.tsx [1].

To include this file in your generated plugin, you can modify the Yeoman generator templates. Specifically, you can add the shim.tsx file to the list of files created by the generator in the template files. Here are the steps to do this:

  1. Navigate to the Yeoman generator directory:

    cd superset-frontend/packages/generator-superset
  2. Open the generator templates and add the shim.tsx file to the list of files to be created. For example, you can add the following line to the generator's template configuration:

    create src/shim.tsx
  3. Ensure that the shim.tsx file is copied to the appropriate location in the generated plugin directory.

By doing this, the shim.tsx file will be included when the generator runs, and you can then import it in your Jest setup file to mock the window object and other necessary globals [2].

To continue talking to Dosu, mention @dosu.